Code for the Advent of Code event
aoc advent-of-code
at rust 72 lines 1.5 kB view raw
1#!/usr/bin/env ruby 2# frozen_string_literal: true 3 4require 'matrix' 5 6def md(a, b) 7 (a[0] - b[0]).abs + (a[1] - b[1]).abs 8end 9 10def wmd(a, b) 11 ax, _ay = a[0], a[1] 12 d = md(a, b) 13 x_min, x_max, y_min, y_max = a[0] - d, a[0] + d, a[1] - d, a[1] + d 14 15 (x_min..x_max).map do |x| 16 xd = (ax - x).abs 17 yf, yt = y_min + xd, y_max - xd 18 [Vector[x, yf], Vector[x, yt]] 19 end 20end 21 22pairs = ARGF.read.scan(/-?\d+/).map(&:to_i).each_slice(4).map { [Vector[_1, _2], Vector[_3, _4]] } 23 24beacons = Set[*pairs.map(&:last)] 25invalid = Set[] 26 27Y = 2_000_000 28 29pairs.each do |s, b| 30 cols = wmd(s, b).to_a 31 cols.each do |c| 32 invalid.add(c[0][0]) if (c[0][1]..c[1][1]).include?(Y) && !beacons.include?(Vector[c[0][0], Y]) 33 end 34end 35 36puts invalid.size 37 38def perimiter(s, b) 39 d = md(s, b) 40 41 left = s[0] - d 42 steps = (1..d).to_a 43 steps = steps + [nil] + steps.reverse 44 45 result = [] 46 47 ((s[0] - d)..(s[0] + d)).each do |x| 48 y_step = steps[x - left] 49 unless y_step.nil? 50 result.push Vector[x, s[1] + y_step] 51 result.push Vector[x, s[1] - y_step] 52 end 53 end 54 55 result 56end 57 58distances = pairs.map { |s, b| [s, md(s, b)] } 59 60MAX = 4_000_000 61 62pairs.each do |sensor, beacon| 63 perims = perimiter(sensor, beacon).reject { |v| v[0] < 0 || v[0] > MAX || v[1] < 0 || v[1] > MAX } 64 others = distances.reject { |s, _| s == sensor } 65 66 perims.each do |v| 67 if others.all? { |o, d| md(o, v) > d } 68 puts (v[0] * MAX) + v[1] 69 exit 70 end 71 end 72end