# j0n3s's solution

## to Crypto Square in the Go Track

Published at Feb 10 2020 · 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 ciphertext back in to the original message:

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

## Coding the solution

Look for a stub file having the name crypto_square.go and place your solution code in that file.

## Running the tests

To run the tests run the command `go test` from within the exercise directory.

If the test suite contains benchmarks, you can run these with the `--bench` and `--benchmem` flags:

``````go test -v --bench . --benchmem
``````

Keep in mind that each reviewer will run benchmarks on a different machine, with different specs, so the results from these benchmark tests may vary.

## Further information

For more detailed information about the Go track, including how to get help if you're having trouble, please visit the exercism.io Go language page.

## 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.go

``````package cryptosquare

import "testing"

var tests = []struct {
pt string // plain text
ct string // cipher text
}{
{
"s#\$%^&plunk",
"su pn lk",
},
{
"1, 2, 3 GO!",
"1g 2o 3 ",
},
{
"1234",
"13 24",
},
{
"123456789",
"147 258 369",
},
{
"123456789abc",
"159 26a 37b 48c",
},
{
"Never vex thine heart with idle woes",
"neewl exhie vtetw ehaho ririe vntds",
},
{
"ZOMG! ZOMBIES!!!",
"zzi ooe mms gb ",
},
{
"Time is an illusion. Lunchtime doubly so.",
"tasney inicds miohoo elntu  illib  suuml ",
},
{
"We all know interspecies romance is weird.",
"wneiaw eorene awssci liprer lneoid ktcms ",
},
{
"msemo aanin dnin  ndla  etlt  shui ",
},
{
"Vampires are people too!",
"vrel aepe mset paoo irpo",
},
{
"",
"",
},
{
"1",
"1",
},
{
"12",
"1 2",
},
{
"12 3",
"13 2 ",
},
{
"12345678",
"147 258 36 ",
},
{
"123456789a",
"159 26a 37  48 ",
},
{
"If man was meant to stay on the ground god would have given us roots",
"imtgdvs fearwer mayoogo anouuio ntnnlvt wttddes aohghn  sseoau ",
},
{
"Have a nice day. Feed the dog & chill out!",
"hifei acedl veeol eddgo aatcu nyhht",
},
}

func TestEncode(t *testing.T) {
for _, test := range tests {
if ct := Encode(test.pt); ct != test.ct {
t.Fatalf(`Encode(%q):
got  %q
want %q`, test.pt, ct, test.ct)
}
}
}

func BenchmarkEncode(b *testing.B) {
for i := 0; i < b.N; i++ {
for _, test := range tests {
Encode(test.pt)
}
}
}``````
``````package cryptosquare

import (
"math"
"strings"
)

func Encode(s string) string {
normalized := strings.ToLower(s)
filtered := ""
for _, c := range normalized {
if (c >= 'a' && c <= 'z') || (c >= '0' && c <= '9') {
filtered += string(c)
}
}
size := len(filtered)
rows := int(math.Sqrt(float64(size)) + .5)
cols := rows

if rows*cols < size {
cols++
}
crypt := make([]string, rows*cols)
for i := range crypt {
val := " "
if i < size {
val = string(filtered[i])
}
origX := i / cols
origY := i - origX*cols
crypt[origY*(rows)+origX] = val
}
response := ""
for i, val := range crypt {
if i > 0 && i%rows == 0 {
response += " "
}
response += val
}
return response
}``````