Add parallel-letter-frequency exercise (#170)
This commit is contained in:
@@ -420,6 +420,14 @@
|
||||
"practices": [],
|
||||
"prerequisites": [],
|
||||
"difficulty": 3
|
||||
},
|
||||
{
|
||||
"slug": "parallel-letter-frequency",
|
||||
"name": "Parallel Letter Frequency",
|
||||
"uuid": "8f55c666-41f7-42df-abf2-7133af0cb36a",
|
||||
"practices": [],
|
||||
"prerequisites": [],
|
||||
"difficulty": 6
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
# Instructions
|
||||
|
||||
Count the frequency of letters in texts using parallel computation.
|
||||
|
||||
Parallelism is about doing things in parallel that can also be done sequentially.
|
||||
A common example is counting the frequency of letters.
|
||||
Employ parallelism to calculate the total frequency of each letter in a list of texts.
|
||||
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"authors": [
|
||||
"erikschierboom"
|
||||
],
|
||||
"files": {
|
||||
"solution": [
|
||||
"parallel-letter-frequency.8th"
|
||||
],
|
||||
"test": [
|
||||
"test.8th"
|
||||
],
|
||||
"example": [
|
||||
".meta/example.8th"
|
||||
]
|
||||
},
|
||||
"blurb": "Count the frequency of letters in texts using parallel computation."
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
needs array/parallel
|
||||
|
||||
: increment-frequency \ m n -- m
|
||||
0 m:!? swap ' n:1+ m:op!
|
||||
;
|
||||
|
||||
: letters \ s -- a
|
||||
/\p{L}/ r:/
|
||||
;
|
||||
|
||||
: letter-frequencies \ s -- m
|
||||
s:lc letters ( dup -rot increment-frequency ) {} const a:reduce
|
||||
;
|
||||
|
||||
: merge-frequencies \ a -- m
|
||||
( ( >r dup -rot 0 m:@? r> n:+ rot swap m:! ) m:each drop ) {} const a:reduce
|
||||
;
|
||||
|
||||
: >frequencies \ a -- m
|
||||
a:len ' letter-frequencies swap a:map-par merge-frequencies
|
||||
;
|
||||
@@ -0,0 +1,50 @@
|
||||
# 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.
|
||||
|
||||
[c054d642-c1fa-4234-8007-9339f2337886]
|
||||
description = "no texts"
|
||||
|
||||
[818031be-49dc-4675-b2f9-c4047f638a2a]
|
||||
description = "one text with one letter"
|
||||
|
||||
[c0b81d1b-940d-4cea-9f49-8445c69c17ae]
|
||||
description = "one text with multiple letters"
|
||||
|
||||
[708ff1e0-f14a-43fd-adb5-e76750dcf108]
|
||||
description = "two texts with one letter"
|
||||
|
||||
[1b5c28bb-4619-4c9d-8db9-a4bb9c3bdca0]
|
||||
description = "two texts with multiple letters"
|
||||
|
||||
[6366e2b8-b84c-4334-a047-03a00a656d63]
|
||||
description = "ignore letter casing"
|
||||
|
||||
[92ebcbb0-9181-4421-a784-f6f5aa79f75b]
|
||||
description = "ignore whitespace"
|
||||
|
||||
[bc5f4203-00ce-4acc-a5fa-f7b865376fd9]
|
||||
description = "ignore punctuation"
|
||||
|
||||
[68032b8b-346b-4389-a380-e397618f6831]
|
||||
description = "ignore numbers"
|
||||
|
||||
[aa9f97ac-3961-4af1-88e7-6efed1bfddfd]
|
||||
description = "Unicode letters"
|
||||
|
||||
[7b1da046-701b-41fc-813e-dcfb5ee51813]
|
||||
description = "combination of lower- and uppercase letters, punctuation and white space"
|
||||
|
||||
[4727f020-df62-4dcf-99b2-a6e58319cb4f]
|
||||
description = "large texts"
|
||||
include = false
|
||||
|
||||
[adf8e57b-8e54-4483-b6b8-8b32c115884c]
|
||||
description = "many small texts"
|
||||
173
exercises/practice/parallel-letter-frequency/libs/exercism/test
Normal file
173
exercises/practice/parallel-letter-frequency/libs/exercism/test
Normal file
@@ -0,0 +1,173 @@
|
||||
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
|
||||
|
||||
|
||||
: 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: «" . . "»" . cr
|
||||
" Expected: «" . . "»" . 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: =
|
||||
;
|
||||
|
||||
: eps_eq? \ n x x -- T
|
||||
\ are the items the same kind?
|
||||
2dup >kind swap >kind n:=
|
||||
!if 2drop false ;then
|
||||
number? !if 2drop false ;then
|
||||
rot n:~=
|
||||
;
|
||||
|
||||
: 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
|
||||
;
|
||||
|
||||
: approx_equal? \ s x w n -- | s w x n --
|
||||
run-test? !if 3drop test-skipped ;; then
|
||||
-rot isword? !if swap then
|
||||
w:exec
|
||||
4 check-depth
|
||||
3dup \ so test-failed can show actual and expected
|
||||
eps_eq?
|
||||
if rot drop test-passed else rot drop 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
|
||||
;
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
: >frequencies \ a -- m
|
||||
|
||||
;
|
||||
70
exercises/practice/parallel-letter-frequency/test.8th
Normal file
70
exercises/practice/parallel-letter-frequency/test.8th
Normal file
@@ -0,0 +1,70 @@
|
||||
"parallel-letter-frequency.8th" f:include
|
||||
needs exercism/test
|
||||
with: test
|
||||
12 tests
|
||||
|
||||
"no texts"
|
||||
( [] >frequencies )
|
||||
{}
|
||||
equal?
|
||||
|
||||
SKIP-REST-OF-TESTS
|
||||
|
||||
"one text with one letter"
|
||||
( ["a"] >frequencies )
|
||||
{"a": 1}
|
||||
equal?
|
||||
|
||||
"one text with multiple letters"
|
||||
( ["bbcccd"] >frequencies )
|
||||
{"b": 2, "c": 3, "d": 1}
|
||||
equal?
|
||||
|
||||
"two texts with one letter"
|
||||
( ["e", "f"] >frequencies )
|
||||
{"e": 1, "f": 1}
|
||||
equal?
|
||||
|
||||
"two texts with multiple letters"
|
||||
( ["ggh", "hhi"] >frequencies )
|
||||
{"g": 2, "h": 3, "i": 1}
|
||||
equal?
|
||||
|
||||
"ignore letter casing"
|
||||
( ["m", "M"] >frequencies )
|
||||
{"m": 2}
|
||||
equal?
|
||||
|
||||
"ignore whitespace"
|
||||
( [" ", " ", "
|
||||
"] >frequencies )
|
||||
{}
|
||||
equal?
|
||||
|
||||
"ignore punctuation"
|
||||
( ["!", "?", ";", ",", "."] >frequencies )
|
||||
{}
|
||||
equal?
|
||||
|
||||
"ignore numbers"
|
||||
( ["1", "2", "3", "4", "5", "6", "7", "8", "9"] >frequencies )
|
||||
{}
|
||||
equal?
|
||||
|
||||
"Unicode letters"
|
||||
( ["本", "φ", "ほ", "ø"] >frequencies )
|
||||
{"本": 1, "φ": 1, "ほ": 1, "ø": 1}
|
||||
equal?
|
||||
|
||||
"combination of lower- and uppercase letters, punctuation and white space"
|
||||
( ["There, peeping among the cloud-wrack above a dark tower high up in the mountains, Sam saw a white star twinkle for a while. The beauty of it smote his heart, as he looked up out of the forsaken land, and hope returned to him. For like a shaft, clear and cold, the thought pierced him that in the end, the shadow was only a small and passing thing: there was light and high beauty forever beyond its reach."] >frequencies )
|
||||
{"a": 32, "b": 4, "c": 6, "d": 14, "e": 37, "f": 7, "g": 8, "h": 29, "i": 19, "k": 6, "l": 12, "m": 7, "n": 19, "o": 22, "p": 7, "r": 17, "s": 16, "t": 30, "u": 9, "v": 2, "w": 9, "y": 4}
|
||||
equal?
|
||||
|
||||
"many small texts"
|
||||
( ["abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc", "abbccc"] >frequencies )
|
||||
{"a": 50, "b": 100, "c": 150}
|
||||
equal?
|
||||
|
||||
end-of-tests
|
||||
;with
|
||||
Reference in New Issue
Block a user