This document is focused on Ruby, using the exercise called Crypto Square on Exercism. +The current version of the exercise description may have changed.[1]
+Crypto Square Iteration 1
+Version 1
+| + + | ++Indentation in Ruby is two spaces, not tab, not four spaces. +We can use a variance from consistent style, though, to bring attention to an area when needed. +A very nice side effect from consistent style adherence! + | +
1class Crypto
+ 2
+ 3private (1)
+ 4
+ 5 attr_reader :text
+ 6
+ 7 def initialize(text)
+ 8 @text = text.downcase.scan(/\w/).freeze (2)
+ 9 end
+10
+11 def cipher
+12 return text if text.empty?
+13 chars = Math.sqrt(text.size).ceil
+14 length = chars * (text.size / chars.to_f).ceil
+15 (0...chars).map do |start|
+16 (start...length).step(chars).map { |i| text.fetch(i, ' ') }.join
+17 end
+18 end
+19
+20public
+21
+22 def ciphertext
+23 cipher.join(' ')
+24 end
+25
+26end
+| 1 | +Indentation in Ruby is two spaces, so this is contrary to convention | +
| 2 | +Explanation of why we would want to freeze this, and if it is immune to garbage collection | +
Crypto Square iteration 2
+Version 2
+This is the second iteration as submitted to Exercism.
+ 1class Crypto
+ 2
+ 3private
+ 4
+ 5 attr_reader :text
+ 6
+ 7 def initialize(text)
+ 8 @text = text.downcase.gsub(/\W/, '').freeze
+ 9 end
+10
+11 def cipher
+12 cols = Math.sqrt(text.size).ceil
+13 text.scan(/.{1,#{cols}}/).map { |s| s.ljust(cols).chars }.transpose
+14 end
+15
+16public
+17
+18 def ciphertext
+19 return text if text.empty?
+20 @cipher ||= cipher.map(&:join).join(' ')
+21 end
+22
+23end
+Crypto Square Version 3
+Version 3
+ 1class Crypto
+ 2
+ 3private
+ 4
+ 5 attr_reader :text
+ 6
+ 7 def initialize(text)
+ 8 @text = text.downcase.gsub(/\W/, '').freeze
+ 9 end
+10
+11 def cipher
+12 cols = Math.sqrt(text.size).ceil
+13 miss = text.size.modulo(cols) #avoid ljust on every string (comment)
+14 adjusted = miss.zero? ? text : text + ' ' * (cols - miss)
+15 adjusted.scan(/.{1,#{cols}}/).map(&:chars).transpose
+16 end
+17
+18public
+19
+20 def ciphertext
+21 return text if text.empty?
+22 @cipher ||= cipher.map(&:join).join(' ')
+23 end
+24
+25end
+