这是一个类似于 Khalid 的解决方案。
如果两个元素可以彼此相邻而无需换行,则它们被认为是相邻的。所以9
和0
被认为是相邻的元素。
该算法循环遍历每组三个连续元素,并检查第一个和第三个是否相邻。如果它们是相邻的,那么中间的值一定是乱序的。
我将给定的列表加入到自身中,从而创建一个大小为 20 的数组。这处理了将数字移动到列表开头或结尾的特殊情况。
# checks if two given numbers are adjacent or not, independent of wrapping
def adjacent?(a, b)
(a - b).abs == 1 || [a, b].sort == [0, 9]
end
# finds the misplaced number in a list
def misplaced_number(list)
middle_index = 1
(list + list).each_cons(3).find { |first, second, third|
adjacent?(first, third)
}[middle_index]
end
通过以下测试进行了检查。由于模棱两可,第二次也是最后一次测试失败了。
test([2, 3, 0, 4, 5, 6, 7, 8, 9, 1], 0)
test([5, 6, 7, 9, 8, 0, 1, 2, 3, 4], 8) # [FAIL: result = 9]
test([7, 6, 5, 4, 3, 8, 2, 1, 0, 9], 8)
test([0, 5, 1, 2, 3, 4, 6, 7, 8, 9], 5)
test([4, 3, 0, 2, 1, 9, 8, 7, 6, 5], 0)
test([2, 4, 5, 6, 7, 8, 9, 0, 1, 3], 2) # [FAIL: result = 3]
def test(list, expected)
result = misplaced_number(list)
assert result == expected_value, "Got #{result} but expected #{expected} from list #{list}"
end