-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
7 changed files
with
247 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
*.beam | ||
*.ez | ||
build | ||
erl_crash.dump |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Help | ||
|
||
## Running the tests | ||
|
||
To run the tests, run the command `gleam test` from within the exercise directory. | ||
|
||
## Submitting your solution | ||
|
||
You can submit your solution using the `exercism submit src/crypto_square.gleam` command. | ||
This command will upload your solution to the Exercism website and print the solution page's URL. | ||
|
||
It's possible to submit an incomplete solution which allows you to: | ||
|
||
- See how others have completed the exercise | ||
- Request help from a mentor | ||
|
||
## Need to get help? | ||
|
||
If you'd like help solving the exercise, check the following pages: | ||
|
||
- The [Gleam track's documentation](https://exercism.org/docs/tracks/gleam) | ||
- The [Gleam track's programming category on the forum](https://forum.exercism.org/c/programming/gleam) | ||
- [Exercism's programming category on the forum](https://forum.exercism.org/c/programming/5) | ||
- The [Frequently Asked Questions](https://exercism.org/docs/using/faqs) | ||
|
||
Should those resources not suffice, you could submit your (incomplete) solution to request mentoring. | ||
|
||
To get help if you're having trouble, you can use one of the following resources: | ||
|
||
- [gleam.run](https://gleam.run/documentation/) is the gleam official documentation. | ||
- [Discord](https://discord.gg/Fm8Pwmy) is the discord channel. | ||
- [StackOverflow](https://stackoverflow.com/questions/tagged/gleam) can be used to search for your problem and see if it has been answered already. You can also ask and answer questions. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
# Crypto Square | ||
|
||
Welcome to Crypto Square on Exercism's Gleam Track. | ||
If you need help running the tests or submitting your code, check out `HELP.md`. | ||
|
||
## Instructions | ||
|
||
Implement the classic method for composing secret messages called a square code. | ||
|
||
Given an English text, output the encoded version of that text. | ||
|
||
First, the input is normalized: the spaces and punctuation are removed from the English text and the message is down-cased. | ||
|
||
Then, the normalized characters are broken into rows. | ||
These rows can be regarded as forming a rectangle when printed with intervening newlines. | ||
|
||
For example, the sentence | ||
|
||
```text | ||
"If man was meant to stay on the ground, god would have given us roots." | ||
``` | ||
|
||
is normalized to: | ||
|
||
```text | ||
"ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots" | ||
``` | ||
|
||
The plaintext should be organized into a rectangle as square as possible. | ||
The size of the rectangle should be decided by the length of the message. | ||
|
||
If `c` is the number of columns and `r` is the number of rows, then for the rectangle `r` x `c` find the smallest possible integer `c` such that: | ||
|
||
- `r * c >= length of message`, | ||
- and `c >= r`, | ||
- and `c - r <= 1`. | ||
|
||
Our normalized text is 54 characters long, dictating a rectangle with `c = 8` and `r = 7`: | ||
|
||
```text | ||
"ifmanwas" | ||
"meanttos" | ||
"tayonthe" | ||
"groundgo" | ||
"dwouldha" | ||
"vegivenu" | ||
"sroots " | ||
``` | ||
|
||
The coded message is obtained by reading down the columns going left to right. | ||
|
||
The message above is coded as: | ||
|
||
```text | ||
"imtgdvsfearwermayoogoanouuiontnnlvtwttddesaohghnsseoau" | ||
``` | ||
|
||
Output the encoded text in chunks that fill perfect rectangles `(r X c)`, with `c` chunks of `r` length, separated by spaces. | ||
For phrases that are `n` characters short of the perfect rectangle, pad each of the last `n` chunks with a single trailing space. | ||
|
||
```text | ||
"imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau " | ||
``` | ||
|
||
Notice that were we to stack these, we could visually decode the ciphertext back in to the original message: | ||
|
||
```text | ||
"imtgdvs" | ||
"fearwer" | ||
"mayoogo" | ||
"anouuio" | ||
"ntnnlvt" | ||
"wttddes" | ||
"aohghn " | ||
"sseoau " | ||
``` | ||
|
||
## Source | ||
|
||
### Created by | ||
|
||
- @erikschierboom | ||
|
||
### Based on | ||
|
||
J Dalbey's Programming Practice problems - https://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
name = "crypto_square" | ||
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" | ||
gleam_erlang = ">= 0.25.0 and < 1.0.0" | ||
|
||
[dev-dependencies] | ||
exercism_test_runner = "~> 1.4" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# 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.25.0", build_tools = ["gleam"], requirements = ["gleam_stdlib"], otp_app = "gleam_erlang", source = "hex", outer_checksum = "054D571A7092D2A9727B3E5D183B7507DAB0DA41556EC9133606F09C15497373" }, | ||
{ 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_erlang = { version = ">= 0.25.0 and < 1.0.0"} | ||
gleam_otp = { version = "~> 0.7 or ~> 1.0" } | ||
gleam_stdlib = { version = "~> 0.32 or ~> 1.0" } | ||
simplifile = { version = "~> 1.0" } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import gleam/float | ||
import gleam/int | ||
import gleam/list | ||
import gleam/regex | ||
import gleam/result | ||
import gleam/string | ||
|
||
pub fn ciphertext(plaintext: String) -> String { | ||
let assert Ok(re) = regex.from_string("[^a-z0-9]") | ||
|
||
let normalized = | ||
plaintext | ||
|> string.lowercase | ||
|> regex.split(with: re) | ||
|> string.concat | ||
|
||
let len = string.length(normalized) | ||
let assert Ok(cols) = | ||
int.square_root(len) | ||
|> result.map(float.ceiling) | ||
|> result.map(float.truncate) | ||
|
||
let rows = | ||
int.to_float(len) /. int.to_float(cols) | ||
|> float.ceiling | ||
|> float.truncate | ||
|
||
normalized | ||
|> string.pad_right(rows * cols, " ") | ||
|> string.to_graphemes | ||
|> list.sized_chunk(cols) | ||
|> list.transpose | ||
|> list.map(string.concat) | ||
|> string.join(" ") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
import crypto_square | ||
import exercism/should | ||
import exercism/test_runner | ||
|
||
pub fn main() { | ||
test_runner.main() | ||
} | ||
|
||
pub fn empty_plaintext_results_in_an_empty_ciphertext_test() { | ||
crypto_square.ciphertext("") | ||
|> should.equal("") | ||
} | ||
|
||
pub fn normalization_results_in_empty_plaintext_test() { | ||
crypto_square.ciphertext("... --- ...") | ||
|> should.equal("") | ||
} | ||
|
||
pub fn lowercase_test() { | ||
crypto_square.ciphertext("A") | ||
|> should.equal("a") | ||
} | ||
|
||
pub fn remove_spaces_test() { | ||
crypto_square.ciphertext(" b ") | ||
|> should.equal("b") | ||
} | ||
|
||
pub fn remove_punctuation_test() { | ||
crypto_square.ciphertext("@1,%!") | ||
|> should.equal("1") | ||
} | ||
|
||
pub fn plaintext_with_9_characters_results_in_3_chunks_of_3_characters_test() { | ||
crypto_square.ciphertext("This is fun!") | ||
|> should.equal("tsf hiu isn") | ||
} | ||
|
||
pub fn plaintext_with_8_characters_results_in_3_chunks_the_last_one_with_a_trailing_space_test() { | ||
crypto_square.ciphertext("Chill out.") | ||
|> should.equal("clu hlt io ") | ||
} | ||
|
||
pub fn plaintext_with_54_characters_results_in_7_chunks_the_last_two_with_trailing_spaces_test() { | ||
crypto_square.ciphertext( | ||
"If man was meant to stay on the ground, god would have given us roots.", | ||
) | ||
|> should.equal( | ||
"imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau ", | ||
) | ||
} |