diff --git a/config.json b/config.json index a9b33ed43..e7b75d83f 100644 --- a/config.json +++ b/config.json @@ -17,6 +17,7 @@ "hamming", "sum-of-multiples", "pythagorean-triplet", + "crypto-square", "luhn", "largest-series-product", "sieve", diff --git a/crypto-square/crypto_square_test.go b/crypto-square/crypto_square_test.go new file mode 100644 index 000000000..f4d8807af --- /dev/null +++ b/crypto-square/crypto_square_test.go @@ -0,0 +1,93 @@ +package cryptosquare + +import "testing" + +var tests = []struct { + pt string + ct string +}{ + { + "s#$%^&plunk", + "supnl k", + }, + { + "1, 2, 3 GO!", + "1g2o3", + }, + { + "1234", + "1324", + }, + { + "123456789", + "14725 8369", + }, + { + "123456789abc", + "15926 a37b4 8c", + }, + { + "Never vex thine heart with idle woes", + "neewl exhie vtetw ehaho ririe vntds", + }, + { + "ZOMG! ZOMBIES!!!", + "zzioo emmsg b", + }, + { + "Time is an illusion. Lunchtime doubly so.", + "tasne yinic dsmio hooel ntuil libsu uml", + }, + { + "We all know interspecies romance is weird.", + "wneia weore neaws scili prerl neoid ktcms", + }, + { + "Madness, and then illumination.", + "msemo aanin dninn dlaet ltshu i", + }, + { + "Vampires are people too!", + "vrela epems etpao oirpo", + }, + { + "", + "", + }, + { + "1", + "1", + }, + { + "12", + "12", + }, + { + "123", + "132", + }, + { + "12345678", + "14725 836", + }, + { + "123456789a", + "15926 a3748", + }, +} + +func TestEncode(t *testing.T) { + for _, test := range tests { + if ct := Encode(test.pt); ct != test.ct { + t.Fatalf("Encode(%q) = %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) + } + } +} diff --git a/crypto-square/example.go b/crypto-square/example.go new file mode 100644 index 000000000..0adb5cde7 --- /dev/null +++ b/crypto-square/example.go @@ -0,0 +1,35 @@ +package cryptosquare + +import ( + "math" + "strings" +) + +func norm(r rune) rune { + switch { + case r >= 'a' && r <= 'z' || r >= '0' && r <= '9': + return r + case r >= 'A' && r <= 'Z': + return r + 'a' - 'A' + } + return -1 +} + +func Encode(pt string) string { + pt = strings.Map(norm, pt) + cols := int(math.Ceil(math.Sqrt(float64(len(pt))))) + b := make([]byte, len(pt)+(len(pt)-1)/5) + px := 0 + for bx := range b { + if (bx+1)%6 == 0 { + b[bx] = ' ' + } else { + b[bx] = pt[px] + px += cols + if px >= len(pt) { + px = (px + 1) % cols + } + } + } + return string(b) +}