轻松ROT13 Ruby"程序"神秘

时间:2016-11-17 18:21:25

标签: ruby rot13

我做了一个简单的ROT13计划,我不明白一件事:

a = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
(a.length+1).times do |i|
  print  a[i + 13]
  if i>13
    print a[i %14]
  end

end

输出:

NOPQRSTUVWXYZABCDEFGHIJKLM

如果我在+1之后没有添加a.length,则迭代以字母L结束。但是,如果我在迭代中使用print a[i],则通常以A开头,以Z结尾,不需要添加+1

有人可以为我解释这个谜吗?

3 个答案:

答案 0 :(得分:3)

如您所知,.times循环调用指定次数的块,向每次迭代传递递增的值。

如果我们说26.times {|i| puts i},它会打印0到25之间的值。最多但不包括最后一个值。

现在让我们走一圈。在第一次迭代时,i为0.因此我们打印字符串的第14个字符"N"(在索引13处,从零开始)。我们没有进入条件,因为0不大于13.在第二次迭代中,我们打印第15个字符"O"。并继续这样做,直到我们达到i=14

此时,"魔术"开始。首先,我们尝试打印字符串的第27个字符。没有这样的角色所以我们什么都没打印。然后触发条件,我们进去。

i % 14等于0,因此我们打印第0个字符"A"。下一次迭代我们在索引1(15 % 14)处打印字符,依此类推,直到.times完成其迭代并停止调用块。现在,为了使这个逻辑起作用,i 的最后一个值必须为26,这样我们就可以获得i % 14中的12个并打印"M"

整个字符串的长度为26.请记住,.times计算但不包括数字?这就是为什么我们在长度上添加一个,以便它从0到26的数量。这是个谜。

有许多方法可以改进此代码,您可以及时了解它们。 :)

更新

知道代码看起来很奇怪。当然,还有一个错误。当i为13时,我们第一次不打印我们不会进入该状态。我们浪费了一次迭代。这是"关闭1"的经典例子。一类错误。这里的代码的固定版本没有浪费迭代而且没有任何谜团:

a.length.times do |i|
  print  a[i + 13]
  if i > 12
    print a[i % 13]
  end
end

答案 1 :(得分:2)

我只需要一个快速腐烂的内衬纸,这是Google的第一个结果。我一直在搜索,发现@xfaider的一个超小型显示器对我的目的已经足够好了。

只需将其张贴在这里,供下一个想要单线的人使用。

string.tr("A-Za-z", "N-ZA-Mn-za-m")

答案 2 :(得分:1)

字母串的长度为26,但索引为0。在这种情况下,字母Z是索引号25.时间方法不会运行最后的迭代(26)。因此,为了解释这一点,我们在长度上添加+1。