From a9797560cf261903fe3088c7f63cf86d7fc3ee35 Mon Sep 17 00:00:00 2001 From: Alpha Chen Date: Thu, 24 Dec 2020 18:27:21 -0800 Subject: [PATCH] [2020][ruby][24.x] --- 2020/ruby/day_24.rb | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 2020/ruby/day_24.rb diff --git a/2020/ruby/day_24.rb b/2020/ruby/day_24.rb new file mode 100644 index 0000000..ca10422 --- /dev/null +++ b/2020/ruby/day_24.rb @@ -0,0 +1,50 @@ +require "strscan" + +def parse(line) + deltas = [] + + ss = StringScanner.new(line) + until ss.eos? + deltas << case + when ss.scan(/e/) then [ 1, -1, 0] + when ss.scan(/se/) then [ 0, -1, 1] + when ss.scan(/sw/) then [-1, 0, 1] + when ss.scan(/w/) then [-1, 1, 0] + when ss.scan(/nw/) then [ 0, 1, -1] + when ss.scan(/ne/) then [ 1, 0, -1] + else fail + end + end + + deltas.inject {|(x,y,z),(dx,dy,dz)| [x+dx, y+dy, z+dz] } +end + +tiles = Hash.new(false) +ARGF.read.split("\n").map {|line| parse(line) } + .each do |tile| + tiles[tile] = !tiles[tile] + end + +NEIGHBORS = %w[ e se sw w nw ne ].map {|dir| parse(dir) } +def tick(tiles) + candidates = tiles.keys.flat_map {|coord| + [ + coord, + *NEIGHBORS.map {|n| coord.zip(n).map {|c,d| c + d }}, + ] + } + candidates.map {|coord| + live_neighbors = NEIGHBORS.map {|n| coord.zip(n).map {|c,d| c + d }}.count {|c| tiles[c] } + if tiles[coord] + [coord, (1..2).cover?(live_neighbors)] + else + [coord, live_neighbors == 2] + end + }.to_h.select {|_,v| v } +end + +100.times do + tiles = tick(tiles) +end + +p tiles.values.count(true)