Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- require 'pp'
- input = File.readlines(ARGV[0] || 'example').map(&:rstrip)
- start_row = start_col = 0
- input.each_with_index do |line, row|
- if (col = line.index('S'))
- start_row = row
- start_col = col
- break
- end
- end
- puts "start at #{start_row}, #{start_col}"
- width = input[0].length
- height = input.length
- # start by searching cardinal directions clockwise beacuse we don't
- # know what shape pipe 'S' is
- paths = []
- # up
- r, c = start_row-1, start_col
- if r >= 0 && r < height && c >= 0 && c < width
- if '|7F'.index(input[r][c])
- paths << [r, c]
- end
- end
- # right
- r, c = start_row, start_col+1
- if r >= 0 && r < height && c >= 0 && c < width
- if '-J7'.index(input[r][c])
- paths << [r, c]
- end
- end
- # down
- r, c = start_row+1, start_col
- if r >= 0 && r < height && c >= 0 && c < width
- if '|LJ'.index(input[r][c])
- paths << [r, c]
- end
- end
- # left
- r, c = start_row, start_col-1
- if r >= 0 && r < height && c >= 0 && c < width
- if '-LF'.index(input[r][c])
- paths << [r, c]
- end
- end
- p paths
- # clean up map
- clean = [nil] * height
- height.times { clean[_1] = '.' * width}
- visited = {}
- at = paths[0]
- loop do
- #puts "at #{at.join(', ')}"
- visited[at] = true
- r, c = at
- clean[r][c] = input[r][c]
- candidates =
- case input[r][c]
- when '|' then [[r-1, c], [r+1, c]]
- when '-' then [[r, c-1], [r, c+1]]
- when 'L' then [[r-1, c], [r, c+1]]
- when 'J' then [[r-1, c], [r, c-1]]
- when '7' then [[r, c-1], [r+1, c]]
- when 'F' then [[r+1, c], [r, c+1]]
- when 'S' then break
- else
- next
- end
- #puts "candidates: #{candidates.inspect}"
- candidates.each do |pos|
- r, c = pos
- if r < 0 || r >= height || c < 0 || c >= width
- raise "#{at.join(', ')} -> #{r}, #{c} (out of bounds)"
- end
- if !visited[pos] # take this path
- #puts "taking [#{r}][#{c}] = #{input[r][c]}"
- at = pos
- break
- end
- end
- #puts "\nat #{at}"
- #pp clean
- end
- puts
- clean.each {puts _1}
- # now, follow both paths simultaneously until
- counts = [nil] * height
- height.times { counts[_1] = '.' * width}
- counts[start_row][start_col] = '0'
- visited = {[start_row, start_col] => true}
- n = 1
- max = 0
- loop do
- puts "at #{paths[0].join(', ')} | #{paths[1].join(', ')}"
- nxt = paths.map do |at|
- visited[at] = true
- r, c = at
- counts[r][c] = (n % 10).to_s
- max = n if n > max
- candidates =
- case input[r][c]
- when '|' then [[r-1, c], [r+1, c]]
- when '-' then [[r, c-1], [r, c+1]]
- when 'L' then [[r-1, c], [r, c+1]]
- when 'J' then [[r-1, c], [r, c-1]]
- when '7' then [[r, c-1], [r+1, c]]
- when 'F' then [[r+1, c], [r, c+1]]
- when 'S' then [] # XXX at end! what do?
- else []
- end
- take = nil
- candidates.each do |pos|
- r, c = pos
- if r < 0 || r >= height || c < 0 || c >= width
- raise "#{at.join(', ')} -> #{r}, #{c} (out of bounds)"
- end
- if !visited[pos] # take this path
- puts "taking [#{r}][#{c}] = #{input[r][c]}"
- take = pos
- break
- end
- end
- if !take
- puts "no path to take! end?"
- end
- puts "at #{at} -> #{take}"
- take
- end
- print "nxt: "
- p nxt
- break if nxt.all?{_1 == nil}
- paths = nxt
- n += 1
- end
- puts
- counts.each {puts _1}
- puts
- puts "max step = #{max}"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement