- require 'minitest/autorun' 
-   
- class MovableChar 
-   def initialize value 
-     @value = value 
-     is_letter = @value =~ /[[:alpha:]]/ 
-   
-     @move_steps = is_letter ? @value.upcase.ord - 64 : 0 
-   end 
-   
-   attr_accessor :move_steps, :value 
-   
-   def mark_moved 
-     @move_steps = 0 
-   end 
- end 
-   
- def move(input) 
-   chars = input.chars.map { |c| MovableChar.new(c) } 
-   
-   while index_to_move = chars.find_index { |c| c.move_steps > 0 } 
-     char_to_move = chars.delete_at index_to_move 
-     new_index = (index_to_move + char_to_move.move_steps) % (chars.size + 1) 
-     char_to_move.mark_moved 
-     chars.insert(new_index, char_to_move) 
-   end 
-   
-   chars.map(&:value).join 
- end 
-   
- describe MovableChar do 
-   it 'computes moving steps for letters case insensitive' do 
-     assert_equal 1, MovableChar.new('a').move_steps 
-     assert_equal 1, MovableChar.new('A').move_steps 
-     assert_equal 4, MovableChar.new('d').move_steps 
-     assert_equal 4, MovableChar.new('D').move_steps 
-   end 
-   
-   it 'moving steps is zero for non-letters' do 
-     assert_equal 0, MovableChar.new('*').move_steps 
-     assert_equal 0, MovableChar.new('.').move_steps 
-     assert_equal 0, MovableChar.new('-').move_steps 
-     assert_equal 0, MovableChar.new('~').move_steps 
-   end 
-   
-   it 'is not allowed to move more than once' do 
-     c = MovableChar.new('a') 
-     c.mark_moved 
-     assert_equal 0, c.move_steps 
-   end 
- end 
-   
- describe :MovingLetters do 
-   def test_case_1 
-     assert_equal 'tca', move('cat') 
-   end 
-   
-   def test_case_2 
-     assert_equal '.F.NU', move('F.U.N') 
-   end 
-   
-   def test_case_3 
-     assert_equal 'goD', move('Dog') 
-   end 
-   
-   def test_case_4 
-     assert_equal '*hibey', move('hi*bye') 
-   end 
- end 
-   
				cmVxdWlyZSAnbWluaXRlc3QvYXV0b3J1bicKCmNsYXNzIE1vdmFibGVDaGFyCiAgZGVmIGluaXRpYWxpemUgdmFsdWUKICAgIEB2YWx1ZSA9IHZhbHVlCiAgICBpc19sZXR0ZXIgPSBAdmFsdWUgPX4gL1tbOmFscGhhOl1dLwoKICAgIEBtb3ZlX3N0ZXBzID0gaXNfbGV0dGVyID8gQHZhbHVlLnVwY2FzZS5vcmQgLSA2NCA6IDAKICBlbmQKCiAgYXR0cl9hY2Nlc3NvciA6bW92ZV9zdGVwcywgOnZhbHVlCgogIGRlZiBtYXJrX21vdmVkCiAgICBAbW92ZV9zdGVwcyA9IDAKICBlbmQKZW5kCgpkZWYgbW92ZShpbnB1dCkKICBjaGFycyA9IGlucHV0LmNoYXJzLm1hcCB7IHxjfCBNb3ZhYmxlQ2hhci5uZXcoYykgfQoKICB3aGlsZSBpbmRleF90b19tb3ZlID0gY2hhcnMuZmluZF9pbmRleCB7IHxjfCBjLm1vdmVfc3RlcHMgPiAwIH0KICAgIGNoYXJfdG9fbW92ZSA9IGNoYXJzLmRlbGV0ZV9hdCBpbmRleF90b19tb3ZlCiAgICBuZXdfaW5kZXggPSAoaW5kZXhfdG9fbW92ZSArIGNoYXJfdG9fbW92ZS5tb3ZlX3N0ZXBzKSAlIChjaGFycy5zaXplICsgMSkKICAgIGNoYXJfdG9fbW92ZS5tYXJrX21vdmVkCiAgICBjaGFycy5pbnNlcnQobmV3X2luZGV4LCBjaGFyX3RvX21vdmUpCiAgZW5kCgogIGNoYXJzLm1hcCgmOnZhbHVlKS5qb2luCmVuZAoKZGVzY3JpYmUgTW92YWJsZUNoYXIgZG8KICBpdCAnY29tcHV0ZXMgbW92aW5nIHN0ZXBzIGZvciBsZXR0ZXJzIGNhc2UgaW5zZW5zaXRpdmUnIGRvCiAgICBhc3NlcnRfZXF1YWwgMSwgTW92YWJsZUNoYXIubmV3KCdhJykubW92ZV9zdGVwcwogICAgYXNzZXJ0X2VxdWFsIDEsIE1vdmFibGVDaGFyLm5ldygnQScpLm1vdmVfc3RlcHMKICAgIGFzc2VydF9lcXVhbCA0LCBNb3ZhYmxlQ2hhci5uZXcoJ2QnKS5tb3ZlX3N0ZXBzCiAgICBhc3NlcnRfZXF1YWwgNCwgTW92YWJsZUNoYXIubmV3KCdEJykubW92ZV9zdGVwcwogIGVuZAoKICBpdCAnbW92aW5nIHN0ZXBzIGlzIHplcm8gZm9yIG5vbi1sZXR0ZXJzJyBkbwogICAgYXNzZXJ0X2VxdWFsIDAsIE1vdmFibGVDaGFyLm5ldygnKicpLm1vdmVfc3RlcHMKICAgIGFzc2VydF9lcXVhbCAwLCBNb3ZhYmxlQ2hhci5uZXcoJy4nKS5tb3ZlX3N0ZXBzCiAgICBhc3NlcnRfZXF1YWwgMCwgTW92YWJsZUNoYXIubmV3KCctJykubW92ZV9zdGVwcwogICAgYXNzZXJ0X2VxdWFsIDAsIE1vdmFibGVDaGFyLm5ldygnficpLm1vdmVfc3RlcHMKICBlbmQKCiAgaXQgJ2lzIG5vdCBhbGxvd2VkIHRvIG1vdmUgbW9yZSB0aGFuIG9uY2UnIGRvCiAgICBjID0gTW92YWJsZUNoYXIubmV3KCdhJykKICAgIGMubWFya19tb3ZlZAogICAgYXNzZXJ0X2VxdWFsIDAsIGMubW92ZV9zdGVwcwogIGVuZAplbmQKCmRlc2NyaWJlIDpNb3ZpbmdMZXR0ZXJzIGRvCiAgZGVmIHRlc3RfY2FzZV8xCiAgICBhc3NlcnRfZXF1YWwgJ3RjYScsIG1vdmUoJ2NhdCcpCiAgZW5kCgogIGRlZiB0ZXN0X2Nhc2VfMgogICAgYXNzZXJ0X2VxdWFsICcuRi5OVScsIG1vdmUoJ0YuVS5OJykKICBlbmQKCiAgZGVmIHRlc3RfY2FzZV8zCiAgICBhc3NlcnRfZXF1YWwgJ2dvRCcsIG1vdmUoJ0RvZycpCiAgZW5kCgogIGRlZiB0ZXN0X2Nhc2VfNAogICAgYXNzZXJ0X2VxdWFsICcqaGliZXknLCBtb3ZlKCdoaSpieWUnKQogIGVuZAplbmQK