F uniq(seq) [Char] seen L(x) seq I x !C seen seen.append(x) R seen F partition(seq, n) R (0 .< seq.len).step(n).map(i -> @seq[i .< i + @n]) F canonicalize(s) R s.uppercase().filter(c -> c.is_uppercase()).join(‘’).replace(‘J’, ‘I’) T Playfair [String = String] dec, enc F (key) V m = partition(uniq(canonicalize(key‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’)), 5) L(row) m L(i, j) cart_product(0.<5, 0.<5) I i != j .enc[row[i]‘’row[j]] = row[(i + 1) % 5]‘’row[(j + 1) % 5] L(ci) 0.<5 V c = [m[0][ci], m[1][ci], m[2][ci], m[3][ci], m[4][ci]] L(i, j) cart_product(0.<5, 0.<5) I i != j .enc[c[i]‘’c[j]] = c[(i + 1) % 5]‘’c[(j + 1) % 5] L(i1, j1, i2, j2) cart_product(0.<5, 0.<5, 0.<5, 0.<5) I i1 != i2 & j1 != j2 .enc[m[i1][j1]‘’m[i2][j2]] = m[i1][j2]‘’m[i2][j1] .dec = Dict(.enc.map((k, v) -> (v, k))) F encode(txt) V c = canonicalize(txt) [String] lst V i = 0 L i < c.len - 1 I c[i + 1] == c[i] lst [+]= c[i]‘X’ i++ E lst [+]= c[i]‘’c[i + 1] i += 2 I i == c.len - 1 lst [+]= c.last‘X’ R lst.map(a -> @.enc[a]).join(‘ ’) F decode(encoded) R partition(canonicalize(encoded), 2).map(p -> @.dec[p]).join(‘ ’) V playfair = Playfair(‘Playfair example’) V orig = ‘Hide the gold in...the TREESTUMP!!!’ print(‘Original: ’orig) V enc = playfair.encode(orig) print(‘Encoded: ’enc) print(‘Decoded: ’playfair.decode(enc))