Add scrabble-score exercise (#145)

This commit is contained in:
Erik Schierboom
2024-04-25 03:03:36 +02:00
committed by GitHub
parent c9907a16dd
commit 3314cd519a
9 changed files with 342 additions and 0 deletions

View File

@@ -284,6 +284,14 @@
"practices": [],
"prerequisites": [],
"difficulty": 1
},
{
"slug": "scrabble-score",
"name": "Scrabble Score",
"uuid": "e8db6509-44f0-428e-939b-25938e81b1ff",
"practices": [],
"prerequisites": [],
"difficulty": 3
}
]
},

View File

@@ -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

View File

@@ -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

View File

@@ -0,0 +1,19 @@
{
"authors": [
"erikschierboom"
],
"files": {
"solution": [
"scrabble-score.8th"
],
"test": [
"test.8th"
],
"example": [
".meta/example.8th"
]
},
"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"
}

View File

@@ -0,0 +1,11 @@
: letter-scores \ -- a
[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]
;
: score-letter \ n n -- n
letter-scores swap 'A n:- caseof n:+
;
: score \ s -- n
s:uc ' score-letter 0 s:reduce
;

View File

@@ -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"

View File

@@ -0,0 +1,162 @@
needs console/loaded
\ -----------------------------------------------------------------
ns: test
-1 var, test-count
var tests-passed
var tests-failed
var tests-skipped
true var, run-test
\ Some utility words
: array-insens-dot \ x -- \\ removes leading space on stringified arrays
dup >kind ns:a n:=
if
>s s:trim
then
.
;
: test-passed \ s x x -- \\ test name, expected value, actual value
2drop
1 tests-passed n:+!
con:green con:onBlack . space " ... OK" . con:white con:onBlack cr
;
: test-skipped \ s --
1 tests-skipped n:+!
con:cyan con:onBlack . space " ... SKIPPED" . con:white con:onBlack cr
;
: test-failed \ s x x -- \\ test name, expected value, actual value
1 tests-failed n:+!
rot
con:red con:onBlack . space " ... FAIL" . con:white con:onBlack cr
" Actual: «" . array-insens-dot "»" . cr
" Expected: «" . array-insens-dot "»" . cr cr
;
: isword? \ x -- x f
dup >kind ns:w n:=
;
: run-test? \ -- T
run-test @ if true else "RUN_ALL_TESTS" getenv n:>bool then
;
\ Num passed + num skipped + num failed should == num tests
: all-tests-run? \ -- T
tests-passed @ tests-skipped @ tests-failed @ n:+ n:+
test-count @ n:=
;
\ returns true if x is a date, false otherwise
: date? \ x -- x T
dup >kind ns:d n:=
;
\ adapted from 8th forum -- https://8th-dev.com/forum/index.php/topic,2745.0.html
: eq? \ x x -- T
\ are the items the same kind?
2dup >kind swap >kind n:=
!if 2drop false ;then
\ same kind: try different comparators
number? if n:= ;then
string? if s:= ;then
array? if ' eq? a:= 2nip ;then
map? if ' eq? m:= 2nip ;then
date? if d:= ;then
\ otherwise fall back to 'lazy evaluation'
l: =
;
: check-depth \ ... n -- ...
dup>r
n:1+ depth n:=
!if
con:red con:onBlack
"PANIC: expected stack depth to be " . r> . cr
"Stack is:" . cr
.s cr
255 die
then
rdrop
;
\ -----------------------------------------------------------------
\ status report at end of run
( all-tests-run?
!if con:red con:onBlack "... FAIL - not all tests completed" . con:white con:onBlack cr then
) onexit
\ Print a summary of the tests run
( con:white con:onBlack
test-count @ . space "tests planned - " .
tests-passed @ . space "passed - " .
tests-skipped @ . space "skipped - " .
tests-failed @ . space "failed" . cr
) onexit
\ -----------------------------------------------------------------
\ The public-facing words
\ -----------------------------------------------------------------
: equal? \ s x w -- | s w x --
run-test? !if 2drop test-skipped ;; then
isword? !if swap then
w:exec
3 check-depth
2dup \ so test-failed can show actual and expected
eq? if test-passed else test-failed then
;
: true? \ s w --
run-test? !if drop test-skipped ;; then
w:exec
2 check-depth
true swap dup \ so test-failed can show actual and expected
if test-passed else test-failed then
;
: false? \ s w --
run-test? !if drop test-skipped ;; then
w:exec
2 check-depth
false swap dup \ so test-failed can show actual and expected
!if test-passed else test-failed then
;
: null? \ s w --
run-test? !if drop test-skipped ;; then
w:exec
2 check-depth
null swap dup \ so test-failed can show actual and expected
G:null? nip if test-passed else test-failed then
;
: SKIP-REST-OF-TESTS false run-test ! ;
: tests \ n --
test-count !
;
\ Set the exit status:
\ 0 = all OK
\ 1 = not all tests were run (some error occurred)
\ 2 = some tests failed
: end-of-tests \ --
all-tests-run?
if
tests-failed @ 0 n:= if 0 else 2 then
else
1
then
die
;

View File

@@ -0,0 +1,3 @@
: score \ s -- n
;

View File

@@ -0,0 +1,64 @@
"scrabble-score.8th" f:include
needs exercism/test
with: test
11 tests
"lowercase letter"
( "a" score )
1
equal?
SKIP-REST-OF-TESTS
"uppercase letter"
( "A" score )
1
equal?
"valuable letter"
( "f" score )
4
equal?
"short word"
( "at" score )
2
equal?
"short, valuable word"
( "zoo" score )
12
equal?
"medium word"
( "street" score )
6
equal?
"medium, valuable word"
( "quirky" score )
22
equal?
"long, mixed-case word"
( "OxyphenButazone" score )
41
equal?
"english-like word"
( "pinata" score )
8
equal?
"empty input"
( "" score )
0
equal?
"entire alphabet available"
( "abcdefghijklmnopqrstuvwxyz" score )
87
equal?
end-of-tests
;with