Обратите внимание, что ваш index_to_coordinates
принимает [3, 3]
(в дополнение к сглаженному индексу 3
) в качестве аргумента, но это избыточно.Вам нужна информация о том, что каждая строка в матрице имеет длину 3
, а сглаженный индекс 3
.
3.divmod(3).reverse # => [0, 1]
divmod
дает вам пару фактор и остаток.Поскольку вы ожидаете порядок: x-координата (остаток), а затем y-координата (частное), вам нужно reverse
, чтобы перевернуть порядок.
Отредактировано в соответствии с изменением в вопросе
Примечание: я предполагаю, что рубин 1.9 в следующем.Я не хочу беспокоиться о ruby 1.8.При необходимости переведите его на ruby 1.8 самостоятельно.Это должно быть легко.
Предположим, у вас есть структура:
[
[
[0, 1, 2, 3]
[4, 5, 6, 7]
[8, 9, 10, 11]
]
[
[12, 13, 14, 15]
[16, 17, 18, 19]
[20, 21, 22, 23]
]
]
, так что размер этой структуры представлен как [2, 3, 4].В общем, мы можем выразить размер в виде массива sizes
.Вы можете преобразовать это в массив flattened
, который представляет размер каждого измерения, когда вся структура сглаживается до этого измерения:
flattened = sizes.dup.drop(1)
(1...flattened.length).reverse_each{|i| flattened[i-1] *= flattened[i]}
С конкретным примером:
flattened # => [12, 4]
Это означает, что самый большой цикл равен 12, следующий - 4. Предположим, вам нужна координата 7
.Чтобы получить это, вы делаете:
index = 7
coordinate = flattened.each_with_object([]) do |size, array|
quotient, index = index.divmod(size)
array.push(quotient)
end
coordinate.push(index)
Это даст вам:
coordinate # => [0, 1, 3]