Преобразование простого кода из Python в Ruby - PullRequest
0 голосов
/ 07 октября 2019

У меня есть следующий код на 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 Code:

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: конфигурация.txt - это текстовый файл, содержащий следующие строки:

A-1
B-4:2
C-3

1 Ответ

1 голос
/ 08 октября 2019

В Python встроенная функция range не включена, поэтому она не возвращает последнее число. Ruby не использует функцию , у него есть пара операторов - двухточечная форма .. создает диапазон, включающий последнее число, и трехточечную форму ..., что исключает высокое значение. См. документацию для получения дополнительной информации.

Ваш опубликованный код имеет несколько дополнительных ошибок и не очень идиоматичен, но ваша ошибка вызвана использованием инклюзивной формы, что приводит кВозвращается значение nil, когда индекс выходит за пределы. Диапазон (largestToMove...diskPositions.length) будет эквивалентен функции Python.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...