Skip to content

Instantly share code, notes, and snippets.

@sarahzrf
Created December 12, 2021 05:33
Show Gist options
  • Save sarahzrf/79881cca4b9ad5cf99c520c963f22c80 to your computer and use it in GitHub Desktop.
Save sarahzrf/79881cca4b9ad5cf99c520c963f22c80 to your computer and use it in GitHub Desktop.
require 'set'
class CaveSystem
def initialize
@adjs = {}
end
def link(a, b)
(@adjs[a] ||= Set.new) << b
(@adjs[b] ||= Set.new) << a
end
def neighbors_at(a)
@adjs[a]
end
def paths(s, e, small_seen=Set.new, twice_yet=false)
return to_enum(__method__, s, e, small_seen, twice_yet) unless block_given?
if s == e
yield [e]
else
nbs = neighbors_at(s)
nbs -= small_seen if twice_yet
ss = small_seen
ss |= Set.new([s]) if s =~ /[a-z]+/
nbs.each do |nb|
next if nb == 'start'
tw = twice_yet || small_seen.include?(nb)
paths(nb, e, ss, tw) {|p| yield ([s] + p)}
end
end
end
end
cs = CaveSystem.new
$<.each do |line|
line.chomp =~ /(\w+)-(\w+)/
cs.link $1, $2
end
p cs.paths('start', 'end').count
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment