Code for the Advent of Code event
aoc advent-of-code
at rust 90 lines 2.3 kB view raw
1#!/usr/bin/env ruby 2# frozen_string_literal: true 3 4require 'matrix' 5 6start = nil 7 8GRID = ARGF.readlines(chomp: true).map.with_index do |line, y| 9 line.chars.each_with_index do |char, x| 10 start = Vector[x, y] if char == ?S 11 end 12end 13 14HEIGHT = GRID.size 15WIDTH = GRID[0].size 16raise 'Input must be square' unless HEIGHT == WIDTH 17SIZE = HEIGHT 18 19DIRS = [Vector[1, 0], Vector[-1, 0], Vector[0, 1], Vector[0, -1]].freeze 20 21P2_STEPS = 26_501_365 22 23def reachable(poses) 24 poses.flat_map { |pos| DIRS.map { pos + _1 }.reject { |pos| 25 GRID[pos[1] % HEIGHT][pos[0] % WIDTH] == '#' 26 } } 27end 28 29poses = [start] 30values = [] 31n = 0 32 33until values.size == 3 34 n += 1 35 poses = reachable(poses).uniq 36 puts poses.size if n == 64 37 values.push poses.size if n == (P2_STEPS % SIZE) + (SIZE * values.size) 38end 39 40# because magic reasons tells us it's polynomial shitfuckery: 41# P(x) = ax² + bx + c 42# x here is more like the number of grids we've moved 43# 44# P(0) = a * 0² + b * 0 + c 45# = c 46# 47# P(1) = a * 1² + b + c 48# P(1) = a + b + c 49# b = P(1) - a - c 50# 51# P(2) = a * 2² + 2b + c 52# P(2) = 4a + 2b + c 53# 4a = P(2) - 2b - c 54# a = (P(2) - 2b - c) / 4 55# a = (P(2) - 2 * (P(1) - a - c) - c) / 4 56# a = (P(2) - 2 * P(1) + 2a + 2c - c) / 4 57# a = (P(2) - 2 * P(1) + 2a + c) / 4 58# 4a = P(2) - 2 * P(1) + 2a + c 59# 2a = P(2) - 2 * P(1) + c 60# a = (P(2) - 2 * P(1) + c) / 2 61# 62# so because the first three values for P(x) are in `values`: 63# c = P(0) = values[0] 64# a = (P(2) - 2 * P(1) + c) / 2 = (values[2] - 2 * values[1] + c) / 2 65# b = P(1) - a - c = values[1] - a - c 66 67C = values[0] 68A = (values[2] - (2 * values[1]) + C) / 2 69B = values[1] - A - C 70 71# Given that number of steps in part 2 apparently must end on an edge, 72# get which grid index we are on I guess? 73 74# Subtract the steps from start to first edge, 75# so that when we are there, we are on grid index 0 76# i.e. if P2_STEPS would be 65: (65 - 131 / 2) / 131 == 0 77# Each amount of SIZE after that is one more grid, so grid index 78# is simply remaining steps divided by the SIZE 79X = (P2_STEPS - (SIZE / 2)) / SIZE 80 81# puts "Values: #{values}" 82# puts "X = #{X}" 83# puts "A = #{A}" 84# puts "B = #{B}" 85# puts "C = #{C}" 86 87puts (A * (X**2)) + (B * X) + C 88 89# With this, I'm going to put it officially: 90# AoC 2023 day 21 part 2 can suck Santa's lollipop.