advent_of_code_2025

My (attempted) solutions to the 2025 Advent of Code
git clone https://git.eamoncaddigan.net/advent_of_code_2025.git
Log | Files | Refs | README

commit bcbc8279488f62e0eea4b986d5d59b6b5947d4f5
parent d733b17cc2fbb9b7109d8bced04696748fa3a242
Author: Eamon Caddigan <ec@eamoncaddigan.net>
Date:   Tue,  9 Dec 2025 14:31:27 -0800

Solve day 09, part 1

Diffstat:
Asrc/day09.R | 104+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 104 insertions(+), 0 deletions(-)

diff --git a/src/day09.R b/src/day09.R @@ -0,0 +1,104 @@ +#!/usr/bin/env Rscript + +source("src/utils.R") + +test_input <- c( + "7,1", + "11,1", + "11,7", + "9,7", + "9,5", + "2,5", + "2,3", + "7,3" +) +puzzle_input <- aoc_input(9) + +parse_input <- function(input_lines) { + input_lines |> + strsplit(",") |> + lapply(as.numeric) |> + (\(x) do.call(rbind, x))() +} + +point_lt <- function(p1, p2) { + p1[2] < p2[2] || p1[2] == p2[2] && p1[1] < p1[1] +} + +# Hacked together implementation of Graham Scan +# Not worrying about efficient stack implementation; R's lists should suffice I +# hope +# Note: not robust to real-world input +convex_hull <- function(points) { + find_p0 <- function(points) { + min_point_idx <- 1 + for (i in 2:nrow(points)) { + if (point_lt(points[i, ], points[min_point_idx, ])) { + min_point_idx <- i + } + } + min_point_idx + } + + right_turn <- function(p1, p2, p3) { + (p2[1] - p1[1]) * (p3[2] - p1[2]) - (p2[2] - p1[2]) * (p3[1] - p1[1]) < 0 + } + + sort_points <- function(points) { + p0 <- find_p0(points) + slope <- (points[-p0, 1] - points[p0, 1]) / (points[-p0, 2] - points[p0, 2]) + rbind( + points[p0, ], + (points[-p0, ])[order(slope, decreasing = TRUE), ] + ) + } + + points_sorted <- sort_points(points) + hull_list <- list() + for (i in seq_len(nrow(points_sorted))) { + while (length(hull_list) > 2 && right_turn( + hull_list[[length(hull_list) - 1]], + hull_list[[length(hull_list)]], + points_sorted[i, ] + )) { + hull_list[[length(hull_list)]] <- NULL + } + hull_list[[length(hull_list) + 1]] <- points_sorted[i, ] + } + do.call(rbind, hull_list) +} + +measure_square <- function(p1, p2) { + (abs(p1[1] - p2[1]) + 1) * (abs(p1[2] - p2[2]) + 1) +} + +largest_square_on_hull <- function(points) { + hull <- convex_hull(points) + largest_square <- NULL + for (i in 1:(nrow(hull) - 1)) { + for (j in 2:nrow(hull)) { + largest_square <- max( + largest_square, + measure_square(hull[i, ], hull[j, ]) + ) + } + } + largest_square +} + +part1 <- function(input_lines) { + input_lines |> + parse_input() |> + largest_square_on_hull() +} + +test_part1 <- function() { + stopifnot(part1(test_input) == 50) +} + +main <- function() { + test_part1() + cat("Part 1 solution: ", part1(puzzle_input), "\n") +} + +main()