Skip to content

Commit

Permalink
Add scrabble-score exercise (#244)
Browse files Browse the repository at this point in the history
  • Loading branch information
keiravillekode authored Dec 30, 2024
1 parent 56e25f6 commit f4ffce4
Show file tree
Hide file tree
Showing 14 changed files with 3,590 additions and 0 deletions.
8 changes: 8 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,14 @@
"searching"
]
},
{
"slug": "scrabble-score",
"name": "Scrabble Score",
"uuid": "1ddc9312-b16f-41fe-91c2-a1181d32fb15",
"practices": [],
"prerequisites": [],
"difficulty": 3
},
{
"slug": "collatz-conjecture",
"name": "Collatz Conjecture",
Expand Down
25 changes: 25 additions & 0 deletions exercises/practice/scrabble-score/.docs/instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Instructions

Your task is to compute a word's Scrabble score by summing the values of its letters.

The letters are valued as follows:

| Letter | Value |
| ---------------------------- | ----- |
| A, E, I, O, U, L, N, R, S, T | 1 |
| D, G | 2 |
| B, C, M, P | 3 |
| F, H, V, W, Y | 4 |
| K | 5 |
| J, X | 8 |
| Q, Z | 10 |

For example, the word "cabbage" is worth 14 points:

- 3 points for C
- 1 point for A
- 3 points for B
- 3 points for B
- 1 point for A
- 2 points for G
- 1 point for E
7 changes: 7 additions & 0 deletions exercises/practice/scrabble-score/.docs/introduction.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Introduction

[Scrabble][wikipedia] is a word game where players place letter tiles on a board to form words.
Each letter has a value.
A word's score is the sum of its letters' values.

[wikipedia]: https://en.wikipedia.org/wiki/Scrabble
2 changes: 2 additions & 0 deletions exercises/practice/scrabble-score/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
*.o
tests
19 changes: 19 additions & 0 deletions exercises/practice/scrabble-score/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"authors": [
"keiravillekode"
],
"files": {
"solution": [
"scrabble_score.asm"
],
"test": [
"scrabble_score_test.c"
],
"example": [
".meta/example.asm"
]
},
"blurb": "Given a word, compute the Scrabble score for that word.",
"source": "Inspired by the Extreme Startup game",
"source_url": "https://github.com/rchatley/extreme_startup"
}
36 changes: 36 additions & 0 deletions exercises/practice/scrabble-score/.meta/example.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
default rel

section .rodata
points: db 1, 3, 3, 2, 1, 4, 2, 4, 1, 8, 5, 1, 3, 1, 1, 3, 10, 1, 1, 1, 1, 4, 4, 8, 4, 10

section .text
global score
score:
cld
mov rsi, rdi
lea r8, [points]
xor r9, r9 ; total
xor r10, r10
xor rax, rax
jmp .read

.update:
or al, 32 ; force to lower-case
sub al, 'a'
cmp al, 26
jae .read ; jump if not a letter

mov r10b, byte [r8 + rax] ; look up letter value
add r9, r10

.read:
lodsb
test al, al
jnz .update

mov rax, r9
ret

%ifidn __OUTPUT_FORMAT__,elf64
section .note.GNU-stack noalloc noexec nowrite progbits
%endif
43 changes: 43 additions & 0 deletions exercises/practice/scrabble-score/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# This is an auto-generated file.
#
# Regenerating this file via `configlet sync` will:
# - Recreate every `description` key/value pair
# - Recreate every `reimplements` key/value pair, where they exist in problem-specifications
# - Remove any `include = true` key/value pair (an omitted `include` key implies inclusion)
# - Preserve any other key/value pair
#
# As user-added comments (using the # character) will be removed when this file
# is regenerated, comments can be added via a `comment` key.

[f46cda29-1ca5-4ef2-bd45-388a767e3db2]
description = "lowercase letter"

[f7794b49-f13e-45d1-a933-4e48459b2201]
description = "uppercase letter"

[eaba9c76-f9fa-49c9-a1b0-d1ba3a5b31fa]
description = "valuable letter"

[f3c8c94e-bb48-4da2-b09f-e832e103151e]
description = "short word"

[71e3d8fa-900d-4548-930e-68e7067c4615]
description = "short, valuable word"

[d3088ad9-570c-4b51-8764-c75d5a430e99]
description = "medium word"

[fa20c572-ad86-400a-8511-64512daac352]
description = "medium, valuable word"

[9336f0ba-9c2b-4fa0-bd1c-2e2d328cf967]
description = "long, mixed-case word"

[1e34e2c3-e444-4ea7-b598-3c2b46fd2c10]
description = "english-like word"

[4efe3169-b3b6-4334-8bae-ff4ef24a7e4f]
description = "empty input"

[3b305c1c-f260-4e15-a5b5-cb7d3ea7c3d7]
description = "entire alphabet available"
46 changes: 46 additions & 0 deletions exercises/practice/scrabble-score/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
AS = nasm

CFLAGS = -g -Wall -Wextra -pedantic -Werror
LDFLAGS =
ASFLAGS = -g -F dwarf -Werror

ifeq ($(shell uname -s),Darwin)
ifeq ($(shell sysctl -n hw.optional.arm64 2>/dev/null),1)
ALL_CFLAGS = -target x86_64-apple-darwin
endif
ALL_LDFLAGS = -Wl,-pie
ALL_ASFLAGS = -f macho64 --prefix _
else
ALL_LDFLAGS = -pie -Wl,--fatal-warnings
ALL_ASFLAGS = -f elf64
endif

ALL_CFLAGS += -std=c99 -fPIE -m64 $(CFLAGS)
ALL_LDFLAGS += $(LDFLAGS)
ALL_ASFLAGS += $(ASFLAGS)

C_OBJS = $(patsubst %.c,%.o,$(wildcard *.c))
AS_OBJS = $(patsubst %.asm,%.o,$(wildcard *.asm))
ALL_OBJS = $(filter-out example.o,$(C_OBJS) $(AS_OBJS) vendor/unity.o)

CC_CMD = $(CC) $(ALL_CFLAGS) -c -o $@ $<

all: tests
@./$<

tests: $(ALL_OBJS)
@$(CC) $(ALL_CFLAGS) $(ALL_LDFLAGS) -o $@ $(ALL_OBJS)

%.o: %.asm
@$(AS) $(ALL_ASFLAGS) -o $@ $<

%.o: %.c
@$(CC_CMD)

vendor/unity.o: vendor/unity.c vendor/unity.h vendor/unity_internals.h
@$(CC_CMD)

clean:
@rm -f *.o vendor/*.o tests

.PHONY: all clean
11 changes: 11 additions & 0 deletions exercises/practice/scrabble-score/scrabble_score.asm
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
default rel

section .text
global score
score:
; Provide your implementation here
ret

%ifidn __OUTPUT_FORMAT__,elf64
section .note.GNU-stack noalloc noexec nowrite progbits
%endif
81 changes: 81 additions & 0 deletions exercises/practice/scrabble-score/scrabble_score_test.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// Version: 0

#include "vendor/unity.h"

extern int score(const char *score);

void setUp(void) {
}

void tearDown(void) {
}

void test_lowercase_letter(void) {
TEST_ASSERT_EQUAL(1, score("a"));
}

void test_uppercase_letter(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL(1, score("A"));
}

void test_valuable_letter(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL(4, score("f"));
}

void test_short_word(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL(2, score("at"));
}

void test_short_valuable_word(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL(12, score("zoo"));
}

void test_medium_word(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL(6, score("street"));
}

void test_medium_valuable_word(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL(22, score("quirky"));
}

void test_long_mixedcase_word(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL(41, score("OxyphenButazone"));
}

void test_englishlike_word(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL(8, score("pinata"));
}

void test_empty_input(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL(0, score(""));
}

void test_entire_alphabet_available(void) {
TEST_IGNORE();
TEST_ASSERT_EQUAL(87, score("abcdefghijklmnopqrstuvwxyz"));
}

int main(void) {
UNITY_BEGIN();
RUN_TEST(test_lowercase_letter);
RUN_TEST(test_uppercase_letter);
RUN_TEST(test_valuable_letter);
RUN_TEST(test_short_word);
RUN_TEST(test_short_valuable_word);
RUN_TEST(test_medium_word);
RUN_TEST(test_medium_valuable_word);
RUN_TEST(test_long_mixedcase_word);
RUN_TEST(test_englishlike_word);
RUN_TEST(test_empty_input);
RUN_TEST(test_entire_alphabet_available);
return UNITY_END();
}
Loading

0 comments on commit f4ffce4

Please sign in to comment.