Skip to content

Instantly share code, notes, and snippets.

@seki
Last active June 7, 2025 11:15
Show Gist options
  • Select an option

  • Save seki/18089cf5ab448c3bebe683be2c082567 to your computer and use it in GitHub Desktop.

Select an option

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
Copy Markdown
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