require "random" class String @@nearby_chars = { 'q' => ['w', 'a'], 'w' => ['q', 'e', 's'], 'e' => ['w', 'r', 'd'], 'r' => ['e', 't', 'f'], 't' => ['r', 'y', 'g'], 'y' => ['t', 'h', 'u'], 'u' => ['y', 'j', 'i'], 'i' => ['u', 'k', 'o'], 'o' => ['i', 'l', 'p'], 'p' => ['o', 'l'], 'a' => ['q', 's', 'z'], 's' => ['w', 'r', 'a', 'x'], 'd' => ['s', 'e', 'f', 'x', 'c'], 'f' => ['d', 'r', 'x', 'c', 'v'], 'g' => ['f', 't', 'h', 'v', 'b'], 'h' => ['g', 'y', 'j', 'b', 'n'], 'j' => ['h', 'u', 'k', 'n', 'm'], 'k' => ['j', 'i', 'l', 'm'], 'l' => ['k', 'o', 'p'], 'z' => ['a', 's', 'x'], 'x' => ['z', 's', 'd', 'c'], 'c' => ['x', 'd', 'f', 'v'], 'v' => ['c', 'f', 'g', 'b'], 'b' => ['v', 'g', 'h', 'n'], 'n' => ['b', 'h', 'j', 'm'], 'm' => ['n', 'j', 'k', 'l'], ' ' => [' '] } def mutate return self if Random.rand > 0.1 mutations = [ ->mutate_modify, ->mutate_insert ] return mutations.sample(1)[0].call.mutate end def mutate_modify index = Random.rand(size) was_upcase = self[index].uppercase? char = self[index].downcase char = @@nearby_chars[char].sample(1)[0] char = char.upcase if was_upcase new_chars = chars new_chars[index] = char return new_chars.join("") end def mutate_insert index = Random.rand(size) return insert(index, ' ') end end