Skip to content

Instantly share code, notes, and snippets.

@seki
Last active June 7, 2025 11:15
Show Gist options
  • Save seki/18089cf5ab448c3bebe683be2c082567 to your computer and use it in GitHub Desktop.
Save seki/18089cf5ab448c3bebe683be2c082567 to your computer and use it in GitHub Desktop.
toRubyでやったパズル
class Puzzle
def initialize(n=3)
@size = n
@goal = (n ** 2).times.to_a.rotate
end
def resolve(start)
raise 'invalid size' unless start.size == @goal.size
visited = Set.new
queue = [[start]]
while path = queue.shift
return path if path.last == @goal
movable(path.last) do |board|
next if visited.include?(board)
visited << board
queue << path + [board]
end
end
nil
end
def movable(board)
cur = board.index(0)
div, mod = cur.divmod(@size)
yield(move(board, cur, -1)) unless mod == 0
yield(move(board, cur, 1)) unless mod == @size - 1
yield(move(board, cur, -@size)) unless div == 0
yield(move(board, cur, @size)) unless div == @size - 1
end
def move(board, index, delta)
ary = board.dup
ary[index], ary[index + delta] = ary[index + delta], ary[index]
ary
end
end
pz = Puzzle.new
path = pz.resolve(9.times.to_a.sort_by {rand})
require 'pp'
PP.pp(path&.map {|x| x.each_slice(3).to_a}, $>, 14)
@seki
Copy link
Author

seki commented Jun 7, 2025

require 'set'が必要なバージョンもありそう

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment