summaryrefslogtreecommitdiff
path: root/aoc/2025/05
diff options
context:
space:
mode:
Diffstat (limited to 'aoc/2025/05')
-rwxr-xr-xaoc/2025/05/python.py39
-rw-r--r--aoc/2025/05/rust/Cargo.lock7
-rw-r--r--aoc/2025/05/rust/Cargo.toml6
-rw-r--r--aoc/2025/05/rust/src/main.rs55
4 files changed, 107 insertions, 0 deletions
diff --git a/aoc/2025/05/python.py b/aoc/2025/05/python.py
new file mode 100755
index 0000000..9977623
--- /dev/null
+++ b/aoc/2025/05/python.py
@@ -0,0 +1,39 @@
+#!/usr/bin/env python3
+
+from itertools import takewhile
+from fileinput import input
+
+
+inp = map(str.strip, input())
+rs = [tuple(map(int, r.split("-"))) for r in takewhile(bool, inp)]
+ids = list(map(int, inp))
+
+
+def add(a: int, b: int, c: int, d: int) -> tuple[int, int] | None:
+ if c < a:
+ return add(c, d, a, b)
+ if b < c:
+ return None
+ return (a, max(b, d))
+
+
+done = False
+while not done:
+ ms = []
+ for r in rs:
+ for idx, m in enumerate(ms):
+ if new := add(*r, *m):
+ ms[idx] = new
+ break
+
+ else:
+ ms.append(r)
+ done = len(rs) == len(ms)
+ rs = ms
+
+
+silver = sum(1 for i in ids if any(lo <= i <= hi for lo, hi in rs))
+gold = sum(b - a + 1 for a, b in rs)
+
+print("silver:", silver)
+print("gold:", gold)
diff --git a/aoc/2025/05/rust/Cargo.lock b/aoc/2025/05/rust/Cargo.lock
new file mode 100644
index 0000000..ac79b17
--- /dev/null
+++ b/aoc/2025/05/rust/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 4
+
+[[package]]
+name = "puzzle"
+version = "0.1.0"
diff --git a/aoc/2025/05/rust/Cargo.toml b/aoc/2025/05/rust/Cargo.toml
new file mode 100644
index 0000000..26e4e77
--- /dev/null
+++ b/aoc/2025/05/rust/Cargo.toml
@@ -0,0 +1,6 @@
+[package]
+name = "puzzle"
+version = "0.1.0"
+edition = "2024"
+
+[dependencies]
diff --git a/aoc/2025/05/rust/src/main.rs b/aoc/2025/05/rust/src/main.rs
new file mode 100644
index 0000000..cd78338
--- /dev/null
+++ b/aoc/2025/05/rust/src/main.rs
@@ -0,0 +1,55 @@
+use std::io;
+
+fn main() {
+ let mut input = io::stdin().lines().flatten().map(|line| line);
+ let ranges = input.by_ref().take_while(|s| !s.is_empty()).map(|s| {
+ let (lo, hi) = s.split_once('-').unwrap();
+ (
+ lo.to_owned().parse().unwrap(),
+ hi.to_owned().parse().unwrap(),
+ )
+ });
+
+ let mut merged: Vec<(u64, u64)> = vec![];
+ for (mut lo, mut hi) in ranges {
+ let ldx = merged.partition_point(|&(_, max)| max < lo);
+ let mut rdx = merged.partition_point(|&(_, max)| max < hi);
+
+ let left = merged.get(ldx);
+ let right = merged.get(rdx);
+
+ // ldx = merged.len() -> left is none -> insert at end
+ let Some(&(llo, lhi)) = left else {
+ merged.push((lo, hi));
+ continue;
+ };
+
+ if (llo..=lhi).contains(&lo) {
+ lo = lo.min(llo); // include range start point
+ }
+
+ // rdx = merged.len() -> right is none -> merge with all
+ let Some(&(rlo, rhi)) = right else {
+ merged.drain(ldx..);
+ merged.push((lo, hi));
+ continue;
+ };
+
+ if (rlo..=rhi).contains(&hi) {
+ hi = hi.max(rhi);
+ rdx += 1;
+ }
+
+ merged.drain(ldx..rdx);
+ merged.insert(ldx, (lo, hi));
+ }
+
+ let silver = input
+ .map(|n| n.parse::<u64>().unwrap())
+ .filter(|id| merged.iter().any(|&(lo, hi)| (lo..=hi).contains(id)))
+ .count();
+ let gold: u64 = merged.iter().map(|(lo, hi)| hi - lo + 1).sum();
+
+ println!("silver: {silver}");
+ println!("gold: {gold}");
+}