Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parallel letter frequency #426

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
18 changes: 18 additions & 0 deletions config.json
Original file line number Diff line number Diff line change
Expand Up @@ -1833,6 +1833,24 @@
"recursion"
],
"difficulty": 4
},
{
"slug": "parallel-letter-frequency",
"name": "Parallel Letter Frequency",
"uuid": "a9e52150-65bc-44a9-9ef6-95b995aea794",
"practices": [
"strings",
"lists",
"dicts",
"regular-expressions"
],
"prerequisites": [
"strings",
"lists",
"dicts",
"regular-expressions"
],
"difficulty": 5
}
]
},
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Create a function that returns the total frequency of each letter in a list of texts and that employs parallelism.
17 changes: 17 additions & 0 deletions exercises/practice/parallel-letter-frequency/.meta/config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"authors": [
"kahgoh"
],
"files": {
"solution": [
"src/parallel_letter_frequency.gleam"
],
"test": [
"test/parallel_letter_frequency_test.gleam"
],
"example": [
".meta/example.gleam"
]
},
"blurb": "Count the frequency of letters in texts using parallel computation."
}
49 changes: 49 additions & 0 deletions exercises/practice/parallel-letter-frequency/.meta/example.gleam
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import gleam/dict.{type Dict}
import gleam/list
import gleam/option.{type Option, None, Some}
import gleam/otp/task
Copy link
Sponsor Member

@lpil lpil Mar 17, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This hasn't been taught yet by this point, and it's an indirect dependency so it'll emit a warning.

It would be best if the concept of an OTP task had been taught prior to having the student use it.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed the CI build failed as I had added the OTP task to the prerequisite, although it hasn't been added yet. I've since it removed it and raised #454.

import gleam/regex
import gleam/string

fn increment_count(existing: Option(Int)) -> Int {
case existing {
None -> 1
Some(value) -> value + 1
}
}

fn count_graphemes(text: String, acc: Dict(String, Int)) -> Dict(String, Int) {
case string.pop_grapheme(text) {
Ok(#(next, tail)) -> {
let assert Ok(re) = regex.from_string("[0-9\\s,\\p{P}]")
case regex.check(re, next) {
True -> count_graphemes(tail, acc)
False ->
count_graphemes(
tail,
dict.update(acc, string.lowercase(next), increment_count),
)
}
}
Error(Nil) -> acc
}
}

fn add_counts(acc: Dict(String, Int), elems: Dict(String, Int)) {
dict.fold(over: elems, from: acc, with: fn(acc, grapheme, count) {
dict.update(acc, grapheme, fn(ex) {
case ex {
None -> count
Some(value) -> value + count
}
})
})
}

pub fn calculate_frequencies(texts: List(String)) -> Dict(String, Int) {
list.map(texts, fn(text) {
task.async(fn() { count_graphemes(text, dict.new()) })
})
|> list.map(fn(task) { task.await(task, 10_000) })
|> list.fold(from: dict.new(), with: add_counts)
}
49 changes: 49 additions & 0 deletions exercises/practice/parallel-letter-frequency/.meta/tests.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# 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"

[adf8e57b-8e54-4483-b6b8-8b32c115884c]
description = "many small texts"
11 changes: 11 additions & 0 deletions exercises/practice/parallel-letter-frequency/gleam.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
name = "parallel_letter_frequency"
version = "0.1.0"

[dependencies]
gleam_bitwise = "~> 1.2"
gleam_otp = "~> 0.7 or ~> 1.0"
gleam_stdlib = "~> 0.32 or ~> 1.0"
simplifile = "~> 1.0"

[dev-dependencies]
exercism_test_runner = "~> 1.4"
26 changes: 26 additions & 0 deletions exercises/practice/parallel-letter-frequency/manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# This file was generated by Gleam
# You typically do not need to edit this file

packages = [
{ name = "argv", version = "1.0.1", build_tools = ["gleam"], requirements = [], otp_app = "argv", source = "hex", outer_checksum = "A6E9009E50BBE863EB37D963E4315398D41A3D87D0075480FC244125808F964A" },
{ name = "exercism_test_runner", version = "1.7.0", build_tools = ["gleam"], requirements = ["argv", "gap", "glance", "gleam_community_ansi", "gleam_erlang", "gleam_json", "gleam_stdlib", "simplifile"], otp_app = "exercism_test_runner", source = "hex", outer_checksum = "2FC1BADB19BEC2AE77BFD2D3A606A014C85412A7B874CAFC4BA8CF04B0B257CD" },
{ name = "gap", version = "1.1.0", build_tools = ["gleam"], requirements = ["gleam_community_ansi", "gleam_stdlib"], otp_app = "gap", source = "hex", outer_checksum = "2EE1B0A17E85CF73A0C1D29DA315A2699117A8F549C8E8D89FA8261BE41EDEB1" },
{ name = "glance", version = "0.8.2", build_tools = ["gleam"], requirements = ["gleam_stdlib", "glexer"], otp_app = "glance", source = "hex", outer_checksum = "ACF09457E8B564AD7A0D823DAFDD326F58263C01ACB0D432A9BEFDEDD1DA8E73" },
{ name = "gleam_bitwise", version = "1.3.1", build_tools = ["gleam"], requirements = [], otp_app = "gleam_bitwise", source = "hex", outer_checksum = "B36E1D3188D7F594C7FD4F43D0D2CE17561DE896202017548578B16FE1FE9EFC" },
{ name = "gleam_community_ansi", version = "1.4.0", build_tools = ["gleam"], requirements = ["gleam_community_colour", "gleam_stdlib"], otp_app = "gleam_community_ansi", source = "hex", outer_checksum = "FE79E08BF97009729259B6357EC058315B6FBB916FAD1C2FF9355115FEB0D3A4" },
{ name = "gleam_community_colour", version = "1.3.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_community_colour", source = "hex", outer_checksum = "A49A5E3AE8B637A5ACBA80ECB9B1AFE89FD3D5351FF6410A42B84F666D40D7D5" },
{ name = "gleam_erlang", version = "0.24.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "26BDB52E61889F56A291CB34167315780EE4AA20961917314446542C90D1C1A0" },
{ name = "gleam_json", version = "1.0.0", build_tools = ["gleam"], requirements = ["gleam_stdlib", "thoas"], otp_app = "gleam_json", source = "hex", outer_checksum = "8B197DD5D578EA6AC2C0D4BDC634C71A5BCA8E7DB5F47091C263ECB411A60DF3" },
{ name = "gleam_otp", version = "0.10.0", build_tools = ["gleam"], requirements = ["gleam_erlang", "gleam_stdlib"], otp_app = "gleam_otp", source = "hex", outer_checksum = "0B04FE915ACECE539B317F9652CAADBBC0F000184D586AAAF2D94C100945D72B" },
{ name = "gleam_stdlib", version = "0.36.0", build_tools = ["gleam"], requirements = [], otp_app = "gleam_stdlib", source = "hex", outer_checksum = "C0D14D807FEC6F8A08A7C9EF8DFDE6AE5C10E40E21325B2B29365965D82EB3D4" },
{ name = "glexer", version = "0.7.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "glexer", source = "hex", outer_checksum = "4484942A465482A0A100936E1E5F12314DB4B5AC0D87575A7B9E9062090B96BE" },
{ name = "simplifile", version = "1.5.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "simplifile", source = "hex", outer_checksum = "EB9AA8E65E5C1E3E0FDCFC81BC363FD433CB122D7D062750FFDF24DE4AC40116" },
{ name = "thoas", version = "0.4.1", build_tools = ["rebar3"], requirements = [], otp_app = "thoas", source = "hex", outer_checksum = "4918D50026C073C4AB1388437132C77A6F6F7C8AC43C60C13758CC0ADCE2134E" },
]

[requirements]
exercism_test_runner = { version = "~> 1.4" }
gleam_bitwise = { version = "~> 1.2" }
gleam_otp = { version = "~> 0.7 or ~> 1.0" }
gleam_stdlib = { version = "~> 0.32 or ~> 1.0" }
simplifile = { version = "~> 1.0" }
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import gleam/dict.{type Dict}

pub fn calculate_frequencies(texts: List(String)) -> Dict(String, Int) {
todo
}