Code for the Advent of Code event
aoc advent-of-code
at rust 63 lines 1.6 kB view raw
1#!/usr/bin/env ruby 2# frozen_string_literal: true 3 4TYPES = { ?L => :empty, ?. => :floor, ?# => :occupied }.freeze 5SEATS = ARGF.readlines.map { |l| l.chomp.chars.map { TYPES[_1] } } 6 7def count_occupied(grid, x, y) 8 (y - 1..y + 1).flat_map { |y1| 9 (x - 1..x + 1).map { |x1| [x1, y1] } 10 }.reject { |x1, y1| 11 (x1 == x && y1 == y) || x1 < 0 || y1 < 0 12 }.count { |x1, y1| (grid[y1] || [])[x1] == :occupied } 13end 14 15def locate(grid, x, y, dir) 16 return nil if x < 0 || y < 0 || y >= grid.size 17 row = grid[y] 18 return nil if x >= row.size 19 return row[x] unless row[x] == :floor 20 locate grid, x + dir[0], y + dir[1], dir 21end 22 23def count_occupied2(grid, x, y) 24 (y - 1..y + 1).flat_map { |y1| 25 (x - 1..x + 1).map { |x1| [x1, y1] } 26 }.reject { |x1, y1| 27 (x1 == x && y1 == y) || x1 < 0 || y1 < 0 28 }.count { |x1, y1| locate(grid, x1, y1, [x1 - x, y1 - y]) == :occupied } 29end 30 31def copy(grid) 32 grid.map(&:dup) 33end 34 35def transform(grid, threshold, &counter) 36 newgrid = copy grid 37 (0...grid.size).each do |y| 38 (0...grid[y].size).each do |x| 39 occupied = counter.call(grid, x, y) 40 if grid[y][x] == :empty && occupied == 0 41 newgrid[y][x] = :occupied 42 elsif grid[y][x] == :occupied && occupied >= threshold 43 newgrid[y][x] = :empty 44 end 45 end 46 end 47 newgrid 48end 49 50def solve(threshold, &counter) 51 seats_copy = copy SEATS 52 53 loop do 54 hashed = seats_copy.hash 55 seats_copy = transform seats_copy, threshold, &counter 56 break if hashed == seats_copy.hash 57 end 58 59 puts seats_copy.sum { |r| r.count(:occupied) } 60end 61 62solve 4, &method(:count_occupied) 63solve 5, &method(:count_occupied2)