将简单代码从 python 转换为 ruby

Converting simple code from python to ruby

我在 python 上有以下代码:

f = open("configuration.txt", "r")
position = {}
counter = 0
with open("configuration.txt") as fileobj:
    for line in fileobj:
        for ch in line:
            if ch.isdigit():
                position[int(ch)] = counter
        counter+=1
# print(dict(sorted(position.items())))

position = dict(sorted(position.items()))
diskPositions = list(position.values())

disk = {0:'4',1:'3',2:'2',3:'1'}
pegs = {0:'A',1:'B',2:'C'}
# print(position)
def moveDisks(diskPositions, largestToMove, targetPeg):
    for badDisk in range(largestToMove, len(diskPositions)):
        currentPeg = diskPositions[badDisk]
        if diskPositions[badDisk] != targetPeg:
            otherPeg = 3 - targetPeg - currentPeg
            moveDisks(diskPositions, badDisk + 1, otherPeg)
            print(disk[badDisk], "-", pegs[targetPeg])
            diskPositions[badDisk] = targetPeg
            moveDisks(diskPositions, badDisk + 1, targetPeg)
            break;

moveDisks(diskPositions[::-1], 0, 2)

我需要将此代码转换为 ruby。我开始这样做,但我被卡住了,不知道错误在哪里,或者我在做什么不同。

运行它时,我在第 30 行收到以下由 nil 变量引起的错误:

/hanoi/final.rb:30:in `-': nil can't be coerced into Integer (TypeError)```

Ruby 代码:

f = open("configuration.txt", "r")
position = {}
counter = 0

def is_digit(look_ahead)
  look_ahead =~ /[[:digit:]]/
end

File.open('configuration.txt', 'r') do |f|
  f.each_line do |l| # iterate on each character
    l.each_char do |c|
      if is_digit(c)
        position[c.to_i] = counter
      end
    end
    counter+=1
  end
end

position = position.sort.to_h
disk_positions = position.values

disk = {0 => '4', 1 => '3', 2 => '2', 3 => '1'}
pegs = {0 => 'A', 1 => 'B', 2 => 'C'}

def moveDisks(diskPositions, largestToMove, targetPeg)
  for badDisk in (largestToMove..diskPositions.length)
    currentPeg = diskPositions[badDisk]
    if diskPositions[badDisk] != targetPeg
      otherPeg = 3 - targetPeg - currentPeg
      moveDisks(diskPositions, badDisk + 1, otherPeg)
      print disk[badDisk].to_s + "-", pegs[targetPeg].to_s
      diskPositions[badDisk] = targetPeg
      moveDisks(diskPositions, badDisk + 1, targetPeg)
      break
    end
  end
end

moveDisks(disk_positions.reverse, 0, 2)

PS:configuration.txt 是一个包含以下行的文本文件:

A-1
B-4:2
C-3

在Python中,内置的range函数是不包含的,所以它不会return最后一个数字。 Ruby 不使用 函数 ,它有几个 运算符 - 双点形式 .. 创建包括最后一个数字的范围,以及排除高值的三点形式 ...。有关详细信息,请参阅 documentation

您发布的代码有一些额外的错误并且不是很地道,但是您的错误是由于使用包含形式引起的,这导致当索引消失时 returned 为 nil 值的界限。 (largestToMove...diskPositions.length) 范围等同于 Python 函数。