🎉 Exercism Research is now launched. Help Exercism, help science and have some fun at research.exercism.io 🎉 # DukeFruitarian's solution

## to Crypto Square in the Elixir Track

Published at Aug 22 2019 · 0 comments
Instructions
Test suite
Solution

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 downcased.

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

``````"If man was meant to stay on the ground, god would have given us roots."
``````

is normalized to:

``````"ifmanwasmeanttostayonthegroundgodwouldhavegivenusroots"
``````

The plaintext should be organized in to a rectangle. The size of the rectangle (`r x c`) should be decided by the length of the message, such that `c >= r` and `c - r <= 1`, where `c` is the number of columns and `r` is the number of rows.

Our normalized text is 54 characters long, dictating a rectangle with `c = 8` and `r = 7`:

``````"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:

``````"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.

``````"imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn  sseoau "
``````

Notice that were we to stack these, we could visually decode the cyphertext back in to the original message:

``````"imtgdvs"
"fearwer"
"mayoogo"
"anouuio"
"ntnnlvt"
"wttddes"
"aohghn "
"sseoau "
``````

## Running tests

Execute the tests with:

``````\$ mix test
``````

### Pending tests

In the test suites, all but the first test have been skipped.

Once you get a test passing, you can unskip the next one by commenting out the relevant `@tag :pending` with a `#` symbol.

For example:

``````# @tag :pending
test "shouting" do
assert Bob.hey("WATCH OUT!") == "Whoa, chill out!"
end
``````

Or, you can enable all the tests by commenting out the `ExUnit.configure` line in the test suite.

``````# ExUnit.configure exclude: :pending, trace: true
``````

If you're stuck on something, it may help to look at some of the available resources out there where answers might be found.

## Source

J Dalbey's Programming Practice problems http://users.csc.calpoly.edu/~jdalbey/103/Projects/ProgrammingPractice.html

## Submitting Incomplete Solutions

It's possible to submit an incomplete solution so you can see how others have completed the exercise.

### crypto_square_test.exs

``````defmodule CryptoSquareTest do
use ExUnit.Case

# @tag :pending
test "empty string" do
assert CryptoSquare.encode("") == ""
end

@tag :pending
test "perfect square" do
assert CryptoSquare.encode("abcd") == "ac bd"
end

@tag :pending
test "uppercase string" do
assert CryptoSquare.encode("ABCD") == "ac bd"
end

@tag :pending
test "small imperfect square" do
assert CryptoSquare.encode("This is easy") == "tis hsy ie sa"
end

@tag :pending
test "punctuation and numbers" do
assert CryptoSquare.encode("1, 2, 3, Go! Go, for God's sake!") == "1gga 2ook 3fde gos ors"
end

@tag :pending
test "long string" do
msg = "If man was meant to stay on the ground, god would have given us roots."
cipher = "imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn sseoau"
assert CryptoSquare.encode(msg) == cipher
end
end``````

### test_helper.exs

``````ExUnit.start()
ExUnit.configure(exclude: :pending, trace: true)``````
``````defmodule CryptoSquare do
@doc """
Encode string square methods
## Examples

iex> CryptoSquare.encode("abcd")
"ac bd"
"""
@spec encode(String.t()) :: String.t()

def encode(""), do: ""

def encode(str) do
normalized = normalize(str)
matrix_size = get_matrix_size(normalized)

String.codepoints(normalized)
|> Enum.chunk_every(matrix_size, matrix_size, Stream.cycle([" "]))
|> List.zip()
|> Stream.map(fn tuple -> Tuple.to_list(tuple) |> Enum.join() end)
|> Enum.join(" ")
end

defp normalize(str) do
String.replace(str, ~r/[^\d\p{L}]/u, "")
|> String.downcase()
end

defp get_matrix_size(string) do
String.length(string)
|> :math.sqrt()
|> Float.ceil()
|> trunc()
end
end``````
{"ft_lang_label":"__label__en","ft_lang_prob":0.7374001,"math_prob":0.67876774,"size":4446,"snap":"2020-34-2020-40","text_gpt3_token_len":1192,"char_repetition_ratio":0.108284555,"word_repetition_ratio":0.050670642,"special_character_ratio":0.24269006,"punctuation_ratio":0.14285715,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.9682039,"pos_list":[0,1,2],"im_url_duplicate_count":[null,null,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2020-10-01T01:27:07Z\",\"WARC-Record-ID\":\"<urn:uuid:1f8f946f-0981-46f2-9b16-0f1c200d7095>\",\"Content-Length\":\"19934\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:4125b1d4-15e8-4d65-83e8-b7e69bef4146>\",\"WARC-Concurrent-To\":\"<urn:uuid:69b36171-93d5-4b1e-a6bb-957e64581a00>\",\"WARC-IP-Address\":\"18.202.93.204\",\"WARC-Target-URI\":\"https://exercism.io/tracks/elixir/exercises/crypto-square/solutions/0909ac39be4140d09e685dad06d9aadd\",\"WARC-Payload-Digest\":\"sha1:J5S3XVB76FLVHOPEECA5CY24D4C32D4D\",\"WARC-Block-Digest\":\"sha1:IANI5VVAKVSOYYMBF3OIC47CLCJDA5EL\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2020/CC-MAIN-2020-40/CC-MAIN-2020-40_segments_1600402130531.89_warc_CC-MAIN-20200930235415-20201001025415-00256.warc.gz\"}"}