Advertisement
Guest User

Untitled

a guest
Dec 15th, 2024
128
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 3.42 KB | None | 0 0
  1. require 'matrix'
  2.  
  3. class Grid
  4.     attr_accessor :grid
  5.  
  6.     def initialize(grid)
  7.         self.grid = grid
  8.     end
  9.  
  10.     def [](idx)
  11.         if idx.class.method_defined?(:[])
  12.             self.grid[idx[0]][idx[1]]
  13.         else
  14.             self.grid[idx]
  15.         end
  16.     end
  17.  
  18.     def []=(idx, val)
  19.         if idx.class.method_defined?(:[])
  20.             self.grid[idx[0]][idx[1]] = val
  21.         else
  22.             self.grid[idx] = val
  23.         end
  24.     end
  25.  
  26.     def map(&)
  27.         self.grid.map(&)
  28.     end
  29.  
  30.     def rows
  31.         self.grid.count
  32.     end
  33.  
  34.     def columns
  35.         self.grid.first.count
  36.     end
  37. end
  38.  
  39. def print_grid(grid, robot)
  40.     system 'clear'
  41.     grid.map.with_index do |row, r|
  42.         line = row.map.with_index do |col, c|
  43.             if r == robot[0] && c == robot[1]
  44.                 '🤖'
  45.             elsif col == :free
  46.                 '  '
  47.             elsif col == :left
  48.                 '🔎'
  49.             elsif col == :right
  50.                 '🔍'
  51.             elsif col == :wall
  52.                 '🧱'
  53.             end
  54.         end
  55.         puts line.join
  56.     end
  57.     $stdin.gets
  58. end
  59.  
  60. def can_move?(grid, curr, dir)
  61.     case grid[curr+dir]
  62.     when :wall then false
  63.     when :free then true
  64.     when :left then can_move?(grid, curr+dir, dir) && can_move?(grid, curr + dir + Vector[0,1], dir)
  65.     when :right then can_move?(grid, curr+dir, dir) && can_move?(grid, curr + dir + Vector[0,-1], dir)
  66.     end
  67. end
  68.  
  69. def move(grid, curr, dir)
  70.     if grid[curr+dir] == :left
  71.         move(grid, curr + dir, dir)
  72.         move(grid, curr + dir + Vector[0,1], dir)
  73.     elsif grid[curr+dir] == :right
  74.         move(grid, curr + dir, dir)
  75.         move(grid, curr + dir + Vector[0,-1], dir)
  76.     end
  77.     grid[curr+dir] = grid[curr]
  78.     grid[curr] = :free
  79. end
  80.  
  81. file = IO.foreach(ARGV[0]).map(&:strip)
  82. cutoff = file.find_index('')
  83. robot = nil
  84. grid = Grid.new(file[...cutoff].map.with_index do |row, r|
  85.     row.split('').map.with_index do |col, c|
  86.         case col
  87.         when '@'
  88.             robot = Vector[r,c*2]
  89.             [:free, :free]
  90.         when '.' then [:free, :free]
  91.         when 'O' then [:left, :right]
  92.         when '#' then [:wall, :wall]
  93.         end
  94.     end.reduce(&:+)
  95. end)
  96.  
  97. # print_grid(grid, robot)
  98. file[(cutoff+1)..].join.split('').map do |c|
  99.     dir = case c
  100.     when '^' then Vector[-1,0]
  101.     when '>' then Vector[0,1]
  102.     when 'v' then Vector[1,0]
  103.     when '<' then Vector[0,-1]
  104.     end
  105.  
  106.     case grid[robot+dir]
  107.     when :wall
  108.         nil
  109.     when :free
  110.         robot += dir
  111.     when :left, :right
  112.         # If the robot's moving left or right, the same algorithm as before still works
  113.         if c == '<' || c == '>'
  114.             test = robot+dir
  115.             test += dir while grid[test] == :left || grid[test] == :right
  116.             if grid[test] == :free
  117.                 until test == robot
  118.                     grid[test] = grid[test - dir]
  119.                     test -= dir
  120.                 end
  121.                 robot += dir
  122.             end
  123.         # Otherwise, we need to use recursion
  124.         else
  125.             if can_move?(grid, robot, dir)
  126.                 move(grid, robot, dir)
  127.                 robot += dir
  128.             end
  129.         end
  130.     end
  131.  
  132.     # print_grid(grid, robot)
  133. end
  134.  
  135. res = (0...grid.rows).sum do |r|
  136.     (0...grid.columns).sum do |c|
  137.         grid[[r,c]] == :left ? (100 * r + c) : 0
  138.     end
  139. end
  140.  
  141. # print_grid(grid, robot)
  142. puts res
  143.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement