diff options
| author | mhsn <mail@mhsn.net> | 2026-03-18 21:48:13 +0000 |
|---|---|---|
| committer | mhsn <mail@mhsn.net> | 2026-03-18 21:48:13 +0000 |
| commit | 86bac31392a76da84817eec020d2b84d099b3cc1 (patch) | |
| tree | e2ee52db59b86b914d5b4bcceb19c9b5d899fff4 /2024 | |
| parent | 62fe361fc42dea75deaf7ac31c0ba6ba80e26a9c (diff) | |
| download | puzzles-86bac31392a76da84817eec020d2b84d099b3cc1.tar.gz puzzles-86bac31392a76da84817eec020d2b84d099b3cc1.zip | |
Diffstat (limited to '2024')
60 files changed, 0 insertions, 1852 deletions
diff --git a/2024/01/python.py b/2024/01/python.py deleted file mode 100755 index 425f6c7..0000000 --- a/2024/01/python.py +++ /dev/null @@ -1,14 +0,0 @@ -#!/usr/bin/env python3 - -from collections import Counter -from fileinput import input - -L, R = zip(*[[int(n) for n in s.split()] for s in input()]) - -silver = sum(abs(left - right) for left, right in zip(sorted(L), sorted(R))) - -L, R = Counter(L), Counter(R) -gold = sum(n * L[n] * R[n] for n in list(L & R)) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/01/raku.raku b/2024/01/raku.raku deleted file mode 100755 index c4a44e0..0000000 --- a/2024/01/raku.raku +++ /dev/null @@ -1,5 +0,0 @@ -#!/usr/bin/env raku - -my $ids := ([Z] lines>>.words)>>.sort>>.list; -say "silver: ", ([Z-] $ids)>>.abs.sum; -say "gold: ", ([<<*>>] $ids>>.Bag).kxxv.sum; diff --git a/2024/01/rust/Cargo.lock b/2024/01/rust/Cargo.lock deleted file mode 100644 index 7010c56..0000000 --- a/2024/01/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aoc_2024-01" -version = "0.1.0" diff --git a/2024/01/rust/Cargo.toml b/2024/01/rust/Cargo.toml deleted file mode 100644 index 0e9bfaa..0000000 --- a/2024/01/rust/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "aoc_2024-01" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/2024/01/rust/src/main.rs b/2024/01/rust/src/main.rs deleted file mode 100644 index c1648cf..0000000 --- a/2024/01/rust/src/main.rs +++ /dev/null @@ -1,31 +0,0 @@ -use std::collections::HashMap; -use std::io; - -fn main() -> io::Result<()> { - let (mut ls, mut rs): (Vec<u64>, Vec<u64>) = io::stdin() - .lines() - .map(|line| { - line.unwrap() - .split_whitespace() - .map(|s| s.parse().unwrap()) - .collect::<Vec<u64>>() - }) - .map(|xs| (xs[0], xs[1])) - .unzip(); - - ls.sort_unstable(); - rs.sort_unstable(); - - let mut counts = HashMap::new(); - rs.iter().for_each(|&x| { - *counts.entry(x).or_insert(0) += 1; - }); - - let silver: u64 = ls.iter().zip(rs).map(|(x, y)| x.abs_diff(y)).sum(); - let gold: u64 = ls.iter().map(|x| x * counts.get(x).unwrap_or(&0)).sum(); - - println!("silver: {silver}"); - println!("gold: {gold}"); - - return Ok(()); -} diff --git a/2024/02/python.py b/2024/02/python.py deleted file mode 100755 index f2c807d..0000000 --- a/2024/02/python.py +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input - -reports = [[int(level) for level in report.split()] for report in input()] - - -def incr(xs): - return all(x < y and y - x <= 3 for x, y in zip(xs, xs[1:])) - - -def safe(xs): - return incr(xs) or incr(xs[::-1]) - - -def drops(xs): - return (xs[:idx] + xs[idx + 1 :] for idx, _ in enumerate(xs)) - - -silver = sum(safe(rep) for rep in reports) -gold = sum(any(safe(mod) for mod in drops(rep)) for rep in reports) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/02/raku.raku b/2024/02/raku.raku deleted file mode 100755 index 9b930de..0000000 --- a/2024/02/raku.raku +++ /dev/null @@ -1,9 +0,0 @@ -#!/usr/bin/env raku - -my @rs = lines>>.words.map(&cache); - -sub incr ($r) { $r.rotor(2=>-1).map({ ([-] $_) (elem) (1..3)}).all }; -sub safe ($r) { so $r.&incr || $r.reverse.&incr }; - -say "silver: ", @rs.map(&safe).sum; -say "gold: ", @rs.map({ $_.combinations($_-1).map(&safe).any.so }).sum; diff --git a/2024/02/rust/Cargo.lock b/2024/02/rust/Cargo.lock deleted file mode 100644 index f3a3299..0000000 --- a/2024/02/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aoc_2024-02" -version = "0.1.0" diff --git a/2024/02/rust/Cargo.toml b/2024/02/rust/Cargo.toml deleted file mode 100644 index 6030837..0000000 --- a/2024/02/rust/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "aoc_2024-02" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/2024/02/rust/src/main.rs b/2024/02/rust/src/main.rs deleted file mode 100644 index 2007837..0000000 --- a/2024/02/rust/src/main.rs +++ /dev/null @@ -1,33 +0,0 @@ -#![feature(iter_map_windows)] - -use std::io; - -fn main() { - let input: Vec<Vec<i64>> = io::stdin() - .lines() - .map(|line| { - line.unwrap() - .split_whitespace() - .map(str::parse::<i64>) - .collect() - }) - .collect::<Result<Vec<_>, _>>() - .unwrap(); - - let silver: usize = input.iter().filter(|&xs| all_safe(xs)).count(); - let gold: usize = input.iter().filter(|&xs| drop_safe(xs)).count(); - println!("silver: {silver}"); - println!("gold: {gold}"); -} - -fn all_safe(xs: &Vec<i64>) -> bool { - let mut diffs = xs.iter().map_windows(|&[x, y]| y - x).peekable(); - let dir = diffs.peek().unwrap_or(&1).signum(); - diffs.all(|d| (1..=3).contains(&d.abs()) && d.signum() == dir) -} - -fn drop_safe(xs: &Vec<i64>) -> bool { - (0..xs.len()) - .map(|idx| xs.split_at(idx)) - .any(|(left, right)| all_safe(&[left, &right[1..]].concat())) -} diff --git a/2024/03/python.py b/2024/03/python.py deleted file mode 100755 index f456580..0000000 --- a/2024/03/python.py +++ /dev/null @@ -1,23 +0,0 @@ -#!/usr/bin/env python3 - -import re -from fileinput import input - -s = "\n".join(input()) - -silver = sum(int(x) * int(y) for x, y in re.findall(r"mul\((\d{1,3}),(\d{1,3})\)", s)) - -gold = 0 -active = True -for g in re.findall(r"(?:mul\((\d{1,3}),(\d{1,3})\))|(don't\(\))|(do\(\))", s): - match g, active: - case (x, y, "", ""), True: - gold += int(x) * int(y) - case (_, _, "don't()", _), _: - active = False - case (_, _, _, "do()"), _: - active = True - - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/03/raku.raku b/2024/03/raku.raku deleted file mode 100755 index 38f040e..0000000 --- a/2024/03/raku.raku +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env raku - -my $p = slurp; - -sub p2 (($on, $tot), ($i, |n)) { - given $i { - when "mul" { return ($on , $tot + [*] $on, |n.list) } - when "do" { return (1 , $tot) } - when "don't" { return (0 , $tot) } - } -}; - -$p ~~ m:g/ mul\((\d ** 1..3)\,(\d ** 1..3)\) /; -say "silver: ", $/.map({ [*] $_.list }).sum; - -$p ~~ m:g/ (mul)\((\d ** 1..3)\,(\d ** 1..3)\) | (do)\(\) | (don\'t)\(\) /; -say "gold: ", ([[&p2]] <1 0>, |$/)[1]; diff --git a/2024/03/rust/Cargo.lock b/2024/03/rust/Cargo.lock deleted file mode 100644 index a7a6f57..0000000 --- a/2024/03/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aoc_2024-03" -version = "0.1.0" diff --git a/2024/03/rust/Cargo.toml b/2024/03/rust/Cargo.toml deleted file mode 100644 index 97ec307..0000000 --- a/2024/03/rust/Cargo.toml +++ /dev/null @@ -1,4 +0,0 @@ -[package] -name = "aoc_2024-03" -version = "0.1.0" -edition = "2021" diff --git a/2024/03/rust/src/main.rs b/2024/03/rust/src/main.rs deleted file mode 100644 index b268463..0000000 --- a/2024/03/rust/src/main.rs +++ /dev/null @@ -1,68 +0,0 @@ -use std::io::{self, Read}; - -#[derive(Debug)] -enum Instruction { - Do, - Dont, - Mul(u64, u64), -} - -impl From<&Instruction> for u64 { - fn from(val: &Instruction) -> Self { - match val { - Instruction::Mul(x, y) => x * y, - _ => 0, - } - } -} - -fn main() -> io::Result<()> { - let mut program = String::new(); - io::stdin().read_to_string(&mut program)?; - - let instrs = (0..program.len()) - .filter_map(|idx| { - let next = &program[idx..]; - if next.starts_with("do()") { - Some(Instruction::Do) - } else if next.starts_with("don't()") { - Some(Instruction::Dont) - } else if next.starts_with("mul(") { - let mut first = 0; - let mut curr = 0; - - for ch in next.bytes().skip(4) { - match (ch, curr) { - ((b'0'..=b'9'), _) => curr = curr * 10 + (ch - b'0') as u64, - (_, 0) => return None, - (b',', _) => { - first = curr; - curr = 0; - } - (b')', _) => { - return Some(Instruction::Mul(first, curr)); - } - _ => return None, - }; - } - None - } else { - None - } - }) - .collect::<Vec<_>>(); - - let silver: u64 = instrs.iter().map(u64::from).sum(); - let (gold, _) = instrs - .iter() - .fold((0 as u64, true), |(acc, on), instr| match (instr, on) { - (Instruction::Do, _) => (acc, true), - (Instruction::Dont, _) => (acc, false), - (Instruction::Mul(_, _), true) => (acc + u64::from(instr), true), - _ => (acc, on), - }); - println!("silver: {silver}"); - println!("gold: {gold}"); - - return Ok(()); -} diff --git a/2024/04/python.py b/2024/04/python.py deleted file mode 100755 index fe5021b..0000000 --- a/2024/04/python.py +++ /dev/null @@ -1,29 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input - -grid = { - complex(idx, idy): c - for idy, line in enumerate(input()) - for idx, c in enumerate(line.strip()) -} -dirs = {complex(dx, dy) for dx in [-1, 0, 1] for dy in [-1, 0, 1]} - - -def xmas(x, v): - return all(grid.get(x + n * v) == c for n, c in enumerate("XMAS")) - - -def x_mas(x, v): - return ( - grid.get(x) == "A" - and grid.get(x + v) == grid.get(x + 1j * v) == "M" - and grid.get(x - v) == grid.get(x - 1j * v) == "S" - ) - - -silver = sum(xmas(x, v) for x in grid.keys() for v in dirs) -gold = sum(x_mas(x, v) for x in grid.keys() for v in dirs if abs(v) > 1) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/04/raku.raku b/2024/04/raku.raku deleted file mode 100755 index 6055fe4..0000000 --- a/2024/04/raku.raku +++ /dev/null @@ -1,8 +0,0 @@ -#!/usr/bin/env raku - -my @g = lines.map: *.comb.Array; - -@g.map: *.say; -say "---"; - -say @g[.[0]; .[1] .. .[1]+3] for (^@g X ^@g[0])[^4]; diff --git a/2024/04/rust/Cargo.lock b/2024/04/rust/Cargo.lock deleted file mode 100644 index 832036f..0000000 --- a/2024/04/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aoc_2024-04" -version = "0.1.0" diff --git a/2024/04/rust/Cargo.toml b/2024/04/rust/Cargo.toml deleted file mode 100644 index e872faf..0000000 --- a/2024/04/rust/Cargo.toml +++ /dev/null @@ -1,4 +0,0 @@ -[package] -name = "aoc_2024-04" -version = "0.1.0" -edition = "2021" diff --git a/2024/04/rust/src/main.rs b/2024/04/rust/src/main.rs deleted file mode 100644 index 191e461..0000000 --- a/2024/04/rust/src/main.rs +++ /dev/null @@ -1,82 +0,0 @@ -use std::io; - -fn main() -> io::Result<()> { - let grid = io::stdin() - .lines() - .flatten() - .map(|line| line.chars().collect()) - .collect::<Vec<Vec<char>>>(); - let grid = Grid(grid); - - let silver: usize = silver(&grid); - let gold: usize = gold(&grid); - - println!("silver: {silver}"); - println!("gold: {gold}"); - - return Ok(()); -} - -struct Grid(Vec<Vec<char>>); - -impl Grid { - fn at(&self, (x, y): (isize, isize)) -> Option<&char> { - self.0 - .get(usize::try_from(y).ok()?)? - .get(usize::try_from(x).ok()?) - } - - fn check<'a>( - &self, - (x, y): (isize, isize), - mut pat: impl Iterator<Item = &'a ((isize, isize), char)>, - ) -> bool { - pat.all(|((dx, dy), ch)| self.at((x + dx, y + dy)).is_some_and(|c| c == ch)) - } - - fn pts(&self) -> impl Iterator<Item = (isize, isize)> + use<'_> { - (0..self.0[0].len()).flat_map(|x| (0..self.0.len()).map(move |y| (x as isize, y as isize))) - } -} - -fn silver(grid: &Grid) -> usize { - let dirs = vec![ - (-1, -1), - (-1, 0), - (-1, 1), - (0, -1), - (0, 1), - (1, -1), - (1, 0), - (1, 1), - ]; - - let xmases: Vec<Vec<((isize, isize), char)>> = dirs - .iter() - .map(|(dx, dy)| { - (0..4) - .map(move |n| (dx * n, dy * n)) - .zip("XMAS".chars()) - .collect() - }) - .collect(); - - grid.pts() - .flat_map(|p| xmases.iter().map(move |xmas| grid.check(p, xmas.iter()))) - .filter(|p| *p) - .count() -} - -fn gold(grid: &Grid) -> usize { - let dirs = vec![(-1, -1), (1, -1), (0, 0), (-1, 1), (1, 1)]; - - let xmases: Vec<Vec<((isize, isize), char)>> = vec!["MMASS", "SMASM", "SSAMM", "MSAMS"] - .iter() - .map(|x| dirs.clone().into_iter().zip(x.chars()).collect()) - .collect(); - - grid.pts() - .flat_map(|p| xmases.iter().map(move |xmas| grid.check(p, xmas.iter()))) - .filter(|p| *p) - .count() -} diff --git a/2024/05/python.py b/2024/05/python.py deleted file mode 100755 index 9e81978..0000000 --- a/2024/05/python.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input -from functools import cmp_to_key -from itertools import takewhile - -inp = map(str.strip, input()) -ordering = set(takewhile(bool, inp)) -us = list(inp) - - -def cmp(x, y): - return (f"{y}|{x}" in ordering) * 2 - 1 # hehe - - -silver = 0 -gold = 0 - -for u in us: - pre = u.split(",") - post = list(sorted(pre, key=cmp_to_key(cmp))) - - mid = int(post[len(post) // 2]) - if pre == post: - silver += mid - else: - gold += mid - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/05/raku.raku b/2024/05/raku.raku deleted file mode 100755 index a13cf5a..0000000 --- a/2024/05/raku.raku +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env raku - -my (@rs, @us) := slurp.split("\n\n")>>.lines; - -sub mid(@u) { - my @s = @u.sort({ "$^a|$^b" !(elem) @rs }); - return (@u Z== @s).all.so ?? ($_, 0) !! (0, $_) with @s[@s/2]; -} - -(("silver: ", "gold: ") Z~ [Z+] @us>>.split(",").map(&mid)).map(&say); diff --git a/2024/05/rust/Cargo.lock b/2024/05/rust/Cargo.lock deleted file mode 100644 index 5ae963b..0000000 --- a/2024/05/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aoc_2024-05" -version = "0.1.0" diff --git a/2024/05/rust/Cargo.toml b/2024/05/rust/Cargo.toml deleted file mode 100644 index de0fa13..0000000 --- a/2024/05/rust/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "aoc_2024-05" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/2024/05/rust/src/main.rs b/2024/05/rust/src/main.rs deleted file mode 100644 index 0db788d..0000000 --- a/2024/05/rust/src/main.rs +++ /dev/null @@ -1,42 +0,0 @@ -#![feature(slice_split_once)] - -use std::cmp::Ordering::{Greater, Less}; -use std::collections::HashSet; -use std::io; - -fn main() -> io::Result<()> { - let mut lines = io::stdin().lines().flatten(); - let mut set = HashSet::<(u16, u16)>::new(); - - while let Some(s) = lines.next() { - if let Some((a, b)) = s.split_once('|') { - set.insert((a.parse().unwrap(), b.parse().unwrap())); - } else { - break; - } - } - - let mut silver: usize = 0; - let mut gold: usize = 0; - - for line in lines { - let mut nums: Vec<u16> = line.split(',').map(|n| n.parse().unwrap()).collect(); - let mid = nums.len() / 2; - - if nums.is_sorted_by(|&a, &b| set.contains(&(a, b))) { - silver += nums[mid] as usize; - } else { - gold += *nums - .select_nth_unstable_by(mid, |&a, &b| match set.contains(&(a, b)) { - true => Less, - false => Greater, - }) - .1 as usize; - } - } - - println!("silver: {silver}"); - println!("gold: {gold}"); - - return Ok(()); -} diff --git a/2024/06/python.py b/2024/06/python.py deleted file mode 100755 index 52b61d0..0000000 --- a/2024/06/python.py +++ /dev/null @@ -1,57 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input - -obstacles = set() -seen = set() - -xmax, ymax = 0, 0 -for idy, line in enumerate(input()): - ymax = max(ymax, idy) - for idx, c in enumerate(line.strip()): - xmax = max(xmax, idx) - match c: - case "^": - pos = complex(idx, idy) - dir = 0 - 1j - case "#": - obstacles.add(complex(idx, idy)) - - -def is_loop(pos, obst): - seen_ = set() - dir = 0 - 1j - while 0 <= pos.real <= xmax and 0 <= pos.imag <= ymax: - if (pos, dir) in seen_: - return True - seen_.add((pos, dir)) - if pos + dir in obstacles or pos + dir == obst: - # Rotate cw - dir *= 1j - continue - pos += dir - return False - - -gold = 0 -for idx in range(xmax + 1): - for idy in range(ymax + 1): - if complex(idx, idy) == pos: - continue - else: - gold += is_loop(pos, complex(idx, idy)) - - -while 0 <= pos.real <= xmax and 0 <= pos.imag <= ymax: - seen.add(pos) - if pos + dir in obstacles: - # Rotate cw - dir *= 1j - continue - pos += dir - - -silver = len(seen) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/06/rust/Cargo.lock b/2024/06/rust/Cargo.lock deleted file mode 100644 index 01e64d2..0000000 --- a/2024/06/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aoc_2024-06" -version = "0.1.0" diff --git a/2024/06/rust/Cargo.toml b/2024/06/rust/Cargo.toml deleted file mode 100644 index 01c1304..0000000 --- a/2024/06/rust/Cargo.toml +++ /dev/null @@ -1,4 +0,0 @@ -[package] -name = "aoc_2024-06" -version = "0.1.0" -edition = "2021" diff --git a/2024/06/rust/src/main.rs b/2024/06/rust/src/main.rs deleted file mode 100644 index ca78bcd..0000000 --- a/2024/06/rust/src/main.rs +++ /dev/null @@ -1,105 +0,0 @@ -use std::collections::HashSet; -use std::{collections::HashMap, io}; - -#[derive(Clone)] -enum Cell { - Empty, - Obstacle, -} - -#[derive(Clone)] -enum Direction { - L = 0b1, - R = 0b10, - U = 0b100, - D = 0b1000, -} - -impl Direction { - fn shift(&self, point: (isize, isize)) -> (isize, isize) { - let (x, y) = point; - match self { - Direction::L => (x - 1, y), - Direction::R => (x + 1, y), - Direction::U => (x, y - 1), - Direction::D => (x, y + 1), - } - } - - fn rotate(&self) -> Self { - use Direction::*; - match self { - L => U, - R => D, - U => R, - D => L, - } - } -} - -fn main() -> io::Result<()> { - let mut map = HashMap::new(); - let mut start = None; - io::stdin() - .lines() - .flatten() - .enumerate() - .flat_map(|(y, line)| { - line.chars() - .enumerate() - .map(|(x, ch)| ([x as isize, y as isize], ch)) - .collect::<Vec<_>>() - }) - .for_each(|([x, y], ch)| match ch { - '.' => { - map.insert((x, y), Cell::Empty); - } - '^' => { - map.insert((x, y), Cell::Empty); - start = Some((x, y)) - } - '#' => { - map.insert((x, y), Cell::Obstacle); - } - _ => panic!(), - }); - let start = start.unwrap(); - - let visited = path_len(&map, start.clone()).unwrap(); - let silver: usize = visited.len(); - let gold: usize = visited - .iter() - .filter(|&p| { - let mut map = map.clone(); - map.insert(*p, Cell::Obstacle); - path_len(&map, start.clone()).is_none() - }) - .count(); - println!("silver: {silver}"); - println!("gold: {gold}"); - - return Ok(()); -} - -fn path_len( - map: &HashMap<(isize, isize), Cell>, - mut pos: (isize, isize), -) -> Option<HashSet<(isize, isize)>> { - let mut visited = HashMap::new(); - let mut dir = Direction::U; - - loop { - let before = visited.entry(pos).or_insert(0 as u8); - if *before & dir.clone() as u8 > 0 { - return None; - } - *before |= dir.clone() as u8; - - let ahead = dir.shift(pos); - match map.get(&ahead) { - Some(Cell::Empty) => pos = ahead, - Some(Cell::Obstacle) => dir = dir.rotate(), - None => return Some(visited.into_keys().collect()), - }; - } -} diff --git a/2024/07/python.py b/2024/07/python.py deleted file mode 100755 index 008af39..0000000 --- a/2024/07/python.py +++ /dev/null @@ -1,37 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input - -lines = [line.strip() for line in input()] - - -def solve(w, acc, rest, gold=False): - if not rest: - return w == acc - if w < acc: - return False - head, *rest = rest - return ( - solve(w, acc + head, rest, gold) - or solve(w, acc * head, rest, gold) - or (gold and solve(w, int(str(acc) + str(head)), rest, gold)) - ) - - -silver = 0 -gold = 0 - -for line in lines: - want, nums = line.split(":") - want = int(want) - nums = [int(n) for n in nums.split()] - head, *rest = nums - - if solve(want, head, rest): - silver += want - if solve(want, head, rest, True): - gold += want - - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/07/rust/Cargo.lock b/2024/07/rust/Cargo.lock deleted file mode 100644 index d1897ed..0000000 --- a/2024/07/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aoc_2024-07" -version = "0.1.0" diff --git a/2024/07/rust/Cargo.toml b/2024/07/rust/Cargo.toml deleted file mode 100644 index c64c1b5..0000000 --- a/2024/07/rust/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "aoc_2024-07" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/2024/07/rust/src/main.rs b/2024/07/rust/src/main.rs deleted file mode 100644 index df586b1..0000000 --- a/2024/07/rust/src/main.rs +++ /dev/null @@ -1,71 +0,0 @@ -use std::io; - -fn main() -> io::Result<()> { - let eqns = io::stdin() - .lines() - .flatten() - .collect::<Vec<_>>() - .iter() - .map(|line| line.split_once(": ").unwrap()) - .map(|(ans, nums)| { - ( - ans.parse::<u64>().unwrap(), - nums.split_whitespace() - .map(|s| s.parse::<u64>().unwrap()) - .collect::<Vec<_>>(), - ) - }) - .collect::<Vec<_>>(); - - let silver: u64 = eqns.iter().map(crate::silver).sum(); - let gold: u64 = eqns.iter().map(crate::gold).sum(); - - println!("silver: {silver}"); - println!("gold: {gold}"); - - return Ok(()); -} - -fn concat(x: &u64, y: &u64) -> u64 { - x * (10u64.pow(y.ilog10() + 1)) + y -} - -fn calibration(want: u64, x: &u64, y: &u64, rest: &[u64], gold: bool) -> bool { - if *x > want { - return false; - } - match rest { - [] => want == x + y || want == x * y || (gold && want == concat(x, y)), - [z, rest @ ..] => { - calibration(want, &(x + y), z, rest, gold) - || calibration(want, &(x * y), z, rest, gold) - || (gold && calibration(want, &concat(x, y), z, rest, gold)) - } - } -} - -fn silver((want, nums): &(u64, Vec<u64>)) -> u64 { - match nums.as_slice() { - [x, y, rest @ ..] => { - if calibration(*want, x, y, rest, false) { - *want - } else { - 0 - } - } - _ => 0, - } -} - -fn gold((want, nums): &(u64, Vec<u64>)) -> u64 { - match nums.as_slice() { - [x, y, rest @ ..] => { - if calibration(*want, x, y, rest, true) { - *want - } else { - 0 - } - } - _ => 0, - } -} diff --git a/2024/08/python.py b/2024/08/python.py deleted file mode 100755 index 783203b..0000000 --- a/2024/08/python.py +++ /dev/null @@ -1,51 +0,0 @@ -#!/usr/bin/env python3 - -from collections import defaultdict -from fileinput import input -from itertools import product - -antennas = defaultdict(set) -x_max, y_max = 0, 0 - -for idy, line in enumerate(input()): - y_max = max(y_max, idy) - for idx, c in enumerate(line.strip()): - x_max = max(x_max, idx) - if c == ".": - continue - - antennas[c].add(complex(idx, idy)) - -nodes = set() -for vs in antennas.values(): - for v1, v2 in product(vs, vs): - if v1 == v2: - continue - vec = v2 - v1 - nodes.add(v1 + 2 * vec) - nodes.add(v2 - 2 * vec) - -nodes = {n for n in nodes if 0 <= n.real <= x_max and 0 <= n.imag <= y_max} - -gold_nodes = set() -for vs in antennas.values(): - for v1, v2 in product(vs, vs): - if v1 == v2: - continue - vec = v2 - v1 - start = v1 - while 0 <= start.real <= x_max and 0 <= start.imag <= y_max: - gold_nodes.add(start) - start += vec - - start = v2 - while 0 <= start.real <= x_max and 0 <= start.imag <= y_max: - gold_nodes.add(start) - start -= vec - - -silver = len(nodes) -gold = len(gold_nodes) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/08/rust/Cargo.lock b/2024/08/rust/Cargo.lock deleted file mode 100644 index e91e374..0000000 --- a/2024/08/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aoc_2024-08" -version = "0.1.0" diff --git a/2024/08/rust/Cargo.toml b/2024/08/rust/Cargo.toml deleted file mode 100644 index bb3b056..0000000 --- a/2024/08/rust/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "aoc_2024-08" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/2024/08/rust/src/main.rs b/2024/08/rust/src/main.rs deleted file mode 100644 index 4fc3286..0000000 --- a/2024/08/rust/src/main.rs +++ /dev/null @@ -1,74 +0,0 @@ -use std::{ - collections::{HashMap, HashSet}, - io, -}; - -fn main() -> io::Result<()> { - let mut antennae: HashMap<char, Vec<(i32, i32)>> = HashMap::new(); - - let grid = io::stdin() - .lines() - .flatten() - .map(|s| s.chars().collect()) - .collect::<Vec<Vec<char>>>(); - - let max = grid.first().unwrap().len() as i32; - let may = grid.len() as i32; - grid.iter() - .enumerate() - .flat_map(|(y, row)| { - row.iter() - .enumerate() - .filter(|(_, &c)| c != '.') - .map(move |(x, &c)| (c, (x as i32, y as i32))) - }) - .for_each(|(c, p)| antennae.entry(c).or_default().push(p)); - - let mut silver = HashSet::new(); - let mut gold = HashSet::new(); - for ps in antennae.values() { - for (n, &p) in ps.iter().enumerate() { - for &t in &ps[n+1..] { - antinodes(p, t, (max, may), false).for_each(|n| { - silver.insert(n); - }); - antinodes(p, t, (max, may), true).for_each(|n| { - gold.insert(n); - }); - } - } - } - - let silver = silver.len(); - let gold = gold.len(); - println!("silver: {silver}"); - println!("gold: {gold}"); - - return Ok(()); -} - -fn antinodes( - a: (i32, i32), - b: (i32, i32), - max: (i32, i32), - gold: bool, -) -> impl Iterator<Item = (i32, i32)> { - let dx = b.0 - a.0; - let dy = b.1 - a.1; - let in_range = move |(x, y)| (0..max.0).contains(&x) && (0..max.1).contains(&y); - if !gold { - vec![(a.0 - dx, a.1 - dy), (b.0 + dx, b.1 + dy)] - } else { - (0..) - .map(|n| (a.0 - n * dx, a.1 - n * dy)) - .take_while(move |&p| in_range(p)) - .chain( - (0..) - .map(|n| (b.0 + n * dx, b.1 + n * dy)) - .take_while(move |&p| in_range(p)), - ) - .collect() - } - .into_iter() - .filter(move |&p| in_range(p)) -} diff --git a/2024/09/python.py b/2024/09/python.py deleted file mode 100755 index 1cf450e..0000000 --- a/2024/09/python.py +++ /dev/null @@ -1,62 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input - -disk = list(input())[0].strip() - -id_ = -1 -blocks = [] -tail = 0 -file = True -for c in disk: - blocks.append([tail, tail + int(c), (id_ := id_ + 1) if file else -1]) - tail += int(c) - file = not file - - -def expand(bs): - return [x for a, b, x in sorted(bs) for _ in range(b - a)] - - -def debug(bs): - print("".join(str(b) if b != -1 else "." for b in expand(bs))) - - -# Silver -expanded = expand(blocks) -tail = len(expanded) - 1 -fill = expanded.index(-1) -while fill < tail: - expanded[fill] = expanded[tail] - expanded[tail] = -1 - while expanded[tail] == -1: - tail -= 1 - while expanded[fill] != -1: - fill += 1 -silver = sum(idx * n for idx, n in enumerate(expanded) if n != -1) - - -# Gold -for move in blocks[::-1]: - print(move) - ma, mb, mx = move - if mx == -1: - continue - mlen = mb - ma - for tidx, to in enumerate(blocks): - ta, tb, tx = to - if ta >= ma: - break - if tx != -1: - continue - if (tlen := tb - ta) < mlen: - continue - move[2] = -1 - to[2] = mx - to[1] = ta + mlen - blocks.insert(tidx + 1, [ta + mlen, tb, -1]) - break -gold = sum(idx * n for idx, n in enumerate(expand(blocks)) if n != -1) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/09/rust/Cargo.lock b/2024/09/rust/Cargo.lock deleted file mode 100644 index 1a4e400..0000000 --- a/2024/09/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aoc_2024-09" -version = "0.1.0" diff --git a/2024/09/rust/Cargo.toml b/2024/09/rust/Cargo.toml deleted file mode 100644 index b440a8b..0000000 --- a/2024/09/rust/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "aoc_2024-09" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/2024/09/rust/src/main.rs b/2024/09/rust/src/main.rs deleted file mode 100644 index fa7c021..0000000 --- a/2024/09/rust/src/main.rs +++ /dev/null @@ -1,100 +0,0 @@ -#![feature(iter_array_chunks)] - -use std::io; - -fn main() -> io::Result<()> { - let disk_map = io::stdin() - .lines() - .flatten() - .next() - .unwrap() - .chars() - .map(|c| c as u8 - b'0') - .collect(); - - let silver: usize = silver(&disk_map); - let gold: usize = gold(&disk_map); - println!("silver: {silver}"); - println!("gold: {gold}"); - - return Ok(()); -} - -fn silver(input: &Vec<u8>) -> usize { - let mut blocks = input - .iter() - .chain([0, 0].iter()) // lol - .array_chunks() - .enumerate() - .map(|(n, [&f, &s])| [[Some(n)].repeat(f as usize), [None].repeat(s as usize)]) - .flatten() - .flatten() - .collect::<Vec<_>>(); - - let mut l = 0; - let mut r = blocks.len() - 1; - loop { - while blocks[r].is_none() { - r -= 1; - } - while blocks[l].is_some() { - l += 1; - } - if l >= r { - break; - } - let [left, right] = blocks.get_disjoint_mut([l, r]).unwrap(); - left.replace(right.take().unwrap()); - } - - blocks - .iter() - .enumerate() - .map(|(n, id)| n * id.unwrap_or_default()) - .sum() -} - -fn gold(input: &Vec<u8>) -> usize { - let mut blocks = input - .iter() - .chain([0, 0].iter()) // lol - .array_chunks() - .enumerate() - .map(|(n, [&f, &s])| [(Some(n), f as usize), (None, s as usize)]) - .flatten() - .collect::<Vec<_>>(); - - let mut r = blocks.len(); - while r > 0 { - r -= 1; - let (Some(_), f) = blocks[r] else { - continue; - }; - - // find some empty space and maybe split - let Some(l) = blocks.iter().position(|b| b.0.is_none() && b.1 >= f) else { - continue; - }; - if l > r { - continue; - }; - - let (_, s) = &mut blocks[l]; - - let diff = *s - f; - if diff > 0 { - *s = f; - blocks.insert(l + 1, (None, diff)); - r += 1; - } - blocks.swap(l, r); - } - - blocks - .iter() - .map(|&(id, n)| [id].repeat(n)) - .flatten() - .enumerate() - .map(|(n, id)| n * id.unwrap_or_default()) - .sum() -} diff --git a/2024/10/python.py b/2024/10/python.py deleted file mode 100755 index 88892b6..0000000 --- a/2024/10/python.py +++ /dev/null @@ -1,43 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input - -grid = [[int(c) for c in line.strip()] for line in input()] - -starts = { - (idx, idy) for idy, line in enumerate(grid) for idx, n in enumerate(line) if n == 0 -} - -# print(*grid, sep="\n") -# print(starts) - - -def score_trailhead(start, gold): - score = 0 - q = [start] - seen = set() - while q: - x, y = q.pop() - seen.add((x, y)) - - h = grid[y][x] - if h == 9: - score += 1 - continue - for dx, dy in [(0, 1), (0, -1), (1, 0), (-1, 0)]: - nx, ny = x + dx, y + dy - if ((nx, ny) in seen and not gold) or not ( - 0 <= nx < len(grid) and 0 <= ny < len(grid[0]) - ): - continue - - if grid[ny][nx] == h + 1: - q.append((nx, ny)) - return score - - -silver = sum(score_trailhead(start, False) for start in starts) -gold = sum(score_trailhead(start, True) for start in starts) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/10/rust/Cargo.lock b/2024/10/rust/Cargo.lock deleted file mode 100644 index de24ddf..0000000 --- a/2024/10/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aoc_2024-10" -version = "0.1.0" diff --git a/2024/10/rust/Cargo.toml b/2024/10/rust/Cargo.toml deleted file mode 100644 index 787d795..0000000 --- a/2024/10/rust/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "aoc_2024-10" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/2024/10/rust/src/main.rs b/2024/10/rust/src/main.rs deleted file mode 100644 index b5b3825..0000000 --- a/2024/10/rust/src/main.rs +++ /dev/null @@ -1,52 +0,0 @@ -use std::collections::HashSet; -use std::io; - -fn main() -> io::Result<()> { - let grid: Vec<Vec<u8>> = io::stdin() - .lines() - .flatten() - .map(|s| s.chars().map(|c| c.to_digit(10).unwrap() as u8).collect()) - .collect(); - - let starts = grid - .iter() - .enumerate() - .flat_map(|(y, row)| row.iter().enumerate().map(move |(x, d)| (x, y, d))) - .filter_map(|(x, y, d)| (*d == 0).then_some((y, x))) - .collect::<Vec<_>>(); - - let silver: usize = starts.iter().map(|&s| trailheads(s, &grid, false)).sum(); - let gold: usize = starts.iter().map(|&s| trailheads(s, &grid, true)).sum(); - - println!("silver: {silver}"); - println!("gold: {gold}"); - - return Ok(()); -} - -fn trailheads(start: (usize, usize), grid: &Vec<Vec<u8>>, count_paths: bool) -> usize { - let mut seen = HashSet::new(); - let mut tot = 0; - let mut q = vec![start]; - - while let Some(curr @ (y, x)) = q.pop() { - seen.insert(curr); - let h = grid[y][x]; - if h == 9 { - tot += 1; - continue; - } - - [ - ((y + 1).min(grid.len() - 1), x), - (y, (x + 1).min(grid[0].len() - 1)), - (y.saturating_sub(1), x), - (y, x.saturating_sub(1)), - ] - .iter() - .filter(|&&(ny, nx)| grid[ny][nx] == h + 1) - .filter(|next| count_paths || !seen.contains(next)) - .for_each(|&n| q.push(n)); - } - tot -} diff --git a/2024/11/python.py b/2024/11/python.py deleted file mode 100755 index 37f658e..0000000 --- a/2024/11/python.py +++ /dev/null @@ -1,30 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input -from functools import cache -from math import floor, log - -stones = [int(x) for x in input().readline().split()] - - -@cache -def blink(s, n): - if n == 0: - return 1 - - if s == 0: - return blink(1, n - 1) - - digits = floor(log(s, 10) + 1e-6) + 1 - if digits % 2 == 0: - left, right = divmod(s, 10 ** (digits // 2)) - return blink(left, n - 1) + blink(right, n - 1) - - return blink(s * 2024, n - 1) - - -silver = sum(blink(s, 25) for s in stones) -gold = sum(blink(s, 75) for s in stones) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/11/rust/Cargo.lock b/2024/11/rust/Cargo.lock deleted file mode 100644 index 22c9989..0000000 --- a/2024/11/rust/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 4 - -[[package]] -name = "aoc_2024-11" -version = "0.1.0" diff --git a/2024/11/rust/Cargo.toml b/2024/11/rust/Cargo.toml deleted file mode 100644 index 67185f7..0000000 --- a/2024/11/rust/Cargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "aoc_2024-11" -version = "0.1.0" -edition = "2021" - -[dependencies] diff --git a/2024/11/rust/src/main.rs b/2024/11/rust/src/main.rs deleted file mode 100644 index e352ec4..0000000 --- a/2024/11/rust/src/main.rs +++ /dev/null @@ -1,43 +0,0 @@ -use std::{collections::HashMap, io}; - -fn blink(k @ (s, n): (u64, u64), cache: &mut HashMap<(u64, u64), u64>) -> u64 { - if n == 0 { - return 1; - } - if let Some(v) = cache.get(&k) { - return *v; - } - - // cache this - let v = { - if s == 0 { - return blink((1, n - 1), cache); - } - let digits = s.ilog10() + 1; - let mid = 10u64.pow(digits / 2); - if digits % 2 == 0 { - blink((s / mid, n - 1), cache) + blink((s % mid, n - 1), cache) - } else { - blink((s * 2024, n - 1), cache) - } - }; - - *cache.entry(k).or_insert(v) -} - -fn main() -> io::Result<()> { - let line = io::stdin().lines().flatten().next().unwrap(); - let stones = line - .split_whitespace() - .map(|s| s.parse::<u64>().unwrap()) - .collect::<Vec<_>>(); - - let mut cache = HashMap::new(); - let silver: u64 = stones.iter().map(|s| blink((*s, 25), &mut cache)).sum(); - let gold: u64 = stones.iter().map(|s| blink((*s, 75), &mut cache)).sum(); - - println!("silver: {silver}"); - println!("gold: {gold}"); - - return Ok(()); -} diff --git a/2024/12/python.py b/2024/12/python.py deleted file mode 100755 index 81761bc..0000000 --- a/2024/12/python.py +++ /dev/null @@ -1,49 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input - -grid = { - complex(idx, idy): c - for idy, line in enumerate(input()) - for idx, c in enumerate(line.strip()) -} -xmax = int(max(x.real for x in grid.keys())) -ymax = int(max(x.imag for x in grid.keys())) - -seen = set() - -silver = 0 - -for x in range(xmax + 1): - for y in range(ymax + 1): - c = complex(x, y) - if c in seen: - continue - - # Flood fill - char = grid[c] - perimeter = area = 0 - queue = [c] - while queue: - curr = queue.pop() - if curr in seen: - continue - seen.add(curr) - - for dir in [1, -1, 1j, -1j]: - next_ = curr + dir - if ( - not (0 <= next_.real <= xmax and 0 <= next_.imag <= ymax) - or grid[next_] != char - ): - perimeter += 1 - continue - - queue.append(next_) - area += 1 - silver += perimeter * area - -gold = 0 - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/13/python.py b/2024/13/python.py deleted file mode 100755 index e78e35f..0000000 --- a/2024/13/python.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 - -import re -from fileinput import input -from itertools import batched - -lines = [line.strip() for line in input()] - - -re_button = r"Button [A|B]: X\+(\d+), Y\+(\d+)" -re_prize = r"Prize: X=(\d+), Y=(\d+)" - - -def solve(machine, gold): - m = re.fullmatch( - r"Button A: X\+(\d+), Y\+(\d+)Button B: X\+(\d+), Y\+(\d+)Prize: X=(\d+), Y=(\d+)", - "".join(machine), - ) - # 2x2 matrix solve - ax, ay, bx, by, px, py = map(int, m.groups()) - if gold: - px += 10000000000000 - py += 10000000000000 - det = ax * by - ay * bx - - A = (by * px - bx * py) / det - B = (-ay * px + ax * py) / det - - # Check solutions are ints - if abs(int(A) - A) < 1e-7 and abs(int(B) - B) < 1e-7: - return 3 * int(A) + int(B) - else: - return 0 - - -silver = sum(solve(b, False) for b in batched(lines, 4)) -gold = sum(solve(b, True) for b in batched(lines, 4)) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/14/python.py b/2024/14/python.py deleted file mode 100755 index 2bb6cb4..0000000 --- a/2024/14/python.py +++ /dev/null @@ -1,64 +0,0 @@ -#!/usr/bin/env python3 - -import re -from fileinput import input -from itertools import groupby -from math import prod - -XMAX, YMAX = 11, 7 # for test -XMAX, YMAX = 101, 103 # for aoc - -robots = [ - re.fullmatch(r"p=(\d+),(\d+) v=(-?\d+),(-?\d+)", line.strip()).groups() - for line in input() -] -robots = [ - (complex(int(px), int(py)), complex(int(vx), int(vy))) for px, py, vx, vy in robots -] - - -def move(p, v, s): - e = p + v * s - return complex(e.real % XMAX, e.imag % YMAX) - - -def quad(x): - return (x.real < XMAX // 2, x.imag < YMAX // 2) - - -def is_quad(x): - return x.real != XMAX // 2 and x.imag != YMAX // 2 - - -def draw(s): - print(f"Seconds passed: {s}") - moved = {move(p, v, s) for p, v in robots} - for x in range(XMAX): - for y in range(YMAX): - print( - "#" if complex(x, y) in moved else " ", - end="", - ) - print() - print("-" * XMAX) - - -moved = groupby( - sorted( - filter(is_quad, (move(p, v, 100) for p, v in robots)), - key=quad, - ), - quad, -) - - -silver = prod(sum(1 for _ in k) for _, k in moved) -gold = 0 - -print("silver:", silver) -print("gold:", gold) - -s = 0 -while s < 10_000: - draw(s) - s += 1 diff --git a/2024/15/python.py b/2024/15/python.py deleted file mode 100755 index 4cfd48c..0000000 --- a/2024/15/python.py +++ /dev/null @@ -1,83 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input -from itertools import takewhile - -inp = map(str.strip, input()) - -grid = { - complex(x, y): c - for y, line in enumerate(takewhile(bool, inp)) - for x, c in enumerate(line) -} -grid_gold = {} -for p, c in grid.items(): - p += p.real - match c: - case "#" | ".": - grid_gold[p] = grid_gold[p + 1] = c - case "O": - grid_gold[p] = "[" - grid_gold[p + 1] = "]" - case "@": - grid_gold[p] = "@" - grid_gold[p + 1] = "." - - -moves = "".join(inp) - -bot = next(p for p, c in grid.items() if c == "@") -bot_gold = bot + bot.real - - -def debug(grid): - xmax, ymax = (max(p.real for p in grid.keys()), max(p.imag for p in grid.keys())) - for y in range(int(ymax) + 1): - for x in range(int(xmax) + 1): - print(grid[complex(x, y)], end="") - print() - print() - - -def push(grid, x, v, modify=True): - match grid[x], v: - case ".", _: - return True - case "#", _: - return False - case "[", (1j | -1j) if push(grid, x + v, v, modify) and push( - grid, x + v + 1, v, modify - ): - if modify: - grid[x + v] = grid[x] - grid[x + v + 1] = grid[x + 1] - grid[x] = "." - grid[x + 1] = "." - return True - case "[", (1j | -1j): - return False - # Push other one - case "]", (1j | -1j): - return push(grid, x - 1, v, modify) - case _, _ if push(grid, x + v, v, modify): - if modify: - grid[x + v] = grid[x] - return True - - -dirs = {">": 1, "v": 1j, "<": -1, "^": -1j} -for m in map(dirs.get, moves): - if push(grid, bot, m): - grid[bot] = "." - bot += m - if push(grid_gold, bot_gold, m, modify=False): - push(grid_gold, bot_gold, m, modify=True) - grid_gold[bot_gold] = "." - bot_gold += m - - -silver = int(sum(p.real + 100 * p.imag for p, c in grid.items() if c == "O")) -gold = int(sum(p.real + 100 * p.imag for p, c in grid_gold.items() if c == "[")) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/16/python.py b/2024/16/python.py deleted file mode 100755 index fda3714..0000000 --- a/2024/16/python.py +++ /dev/null @@ -1,31 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input - -grid = { - complex(idx, idy): c - for idy, line in enumerate(input()) - for idx, c in enumerate(line.strip()) -} -start = next(p for p, c in grid.items() if c == "S") -end = next(p for p, c in grid.items() if c == "E") - -q = [(0, (start, 1))] -seen = set() -while q: - curr = min(q, key=lambda x: x[0]) - d, (pos, vel) = curr - q.remove(curr) - if (pos, vel) in seen: - continue - if pos == end: - silver = d - break - seen.add((pos, vel)) - - if grid[pos + vel] != "#": - q.append((d + 1, (pos + vel, vel))) - q.append((d + 1000, (pos, vel * 1j))) - q.append((d + 1000, (pos, vel * -1j))) - -print("silver:", silver) diff --git a/2024/17/python.py b/2024/17/python.py deleted file mode 100755 index 9ea7de4..0000000 --- a/2024/17/python.py +++ /dev/null @@ -1,68 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input -from itertools import takewhile, zip_longest - -inp = map(str.strip, input()) -regs = [int(r[2]) for r in (line.split() for line in takewhile(bool, inp))] -prog = [int(o) for o in next(inp).split()[1].split(",")] -out = [] - - -def run(prog, ra, rb, rc): - out = [] - ir = 0 - while ir < len(prog): - instr, op = prog[ir], prog[ir + 1] - combo = {4: ra, 5: rb, 6: rc} - cop = combo.get(op, op) - match instr: - case 0: - ra = ra >> cop - case 1: - rb ^= op - case 2: - rb = cop & 0b111 - case 3 if ra: - ir = op - 2 - case 4: - rb ^= rc - case 5: - yield cop & 0b111 - case 6: - rb = ra >> cop - case 7: - rc = ra >> cop - ir += 2 - return out - - -def match(prog, ra): - return ( - got == want - for got, want in zip_longest( - reversed(list(run(prog, ra, 0, 0))), - reversed(prog), - ) - ) - - -def find_a(prog): - q = list(range(8)) - while True: - curr = q.pop(0) - if all(match(prog, curr)): - return curr - - best = sum(match(prog, curr)) - for n in range(8): - ra = (curr << 3) + n - if sum(match(prog, ra)) > best: - q.append(ra) - - -silver = ",".join(map(str, run(prog, *regs))) -gold = find_a(prog) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/18/python.py b/2024/18/python.py deleted file mode 100755 index 1f987c6..0000000 --- a/2024/18/python.py +++ /dev/null @@ -1,47 +0,0 @@ -#!/usr/bin/env python3 - -from bisect import bisect_left -from collections import deque -from fileinput import input - -coords = [line.strip().split(",") for line in input()] -grid = {complex(int(x), int(y)): t for t, [x, y] in enumerate(coords)} - - -def solve(size, delay): - q = deque([(0, 0)]) - seen = set() - while q: - curr, t = q.popleft() - if curr in seen: - continue - if curr == complex(size, size): - return t - seen.add(curr) - - for d in [1, -1, 1j, -1j]: - x = curr + d - if not (0 <= x.real <= size and 0 <= x.imag <= size): - continue - if x in grid and grid[x] < delay: - continue - q.append((x, t + 1)) - return None - - -silver = solve(70, 1024) -# silver = solve(6, 12) # test.txt - -gold = ",".join( - coords[ - bisect_left( - list(range(len(grid))), - True, - key=lambda x: solve(70, x) is None, - ) - - 1 - ] -) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/19/python.py b/2024/19/python.py deleted file mode 100755 index efd3272..0000000 --- a/2024/19/python.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input -from functools import cache -from itertools import takewhile - -inp = map(str.strip, input()) -towels = [t.strip() for t in next(takewhile(bool, inp)).split(",")] -designs = [d for d in inp if d] - -# Construct trie -trie = {} -for towel in towels: - prev = None - curr = trie - for t in towel: - term, succ = curr.setdefault(t, (False, {})) - prev = curr - curr = succ - prev[towel[-1]] = (True, curr) - - -@cache -def steps(design, n=0): - if n == len(design): - return 1 - ways = 0 - curr = trie - for d, s in enumerate(design[n:], start=1): - if s not in curr: - return ways - term, curr = curr[s] - if term: - ways += steps(design, n + d) - return ways - - -silver = sum(map(bool, map(steps, designs))) -gold = sum(map(steps, designs)) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/20/python.py b/2024/20/python.py deleted file mode 100755 index 610f1a3..0000000 --- a/2024/20/python.py +++ /dev/null @@ -1,40 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input - -grid = { - complex(idx, idy): c - for idy, line in enumerate(input()) - for idx, c in enumerate(line.strip()) -} -start = next(p for p, c in grid.items() if c == "S") -end = next(p for p, c in grid.items() if c == "E") - -times = {} -q = [(start, 0)] -while q: - curr, t = q.pop() - if curr in times: - continue - times[curr] = t - for d in [1, -1, 1j, -1j]: - x = curr + d - if x not in grid or grid[x] == "#": - continue - q.append((x, t + 1)) - - -def cheat(x, y, d): - dist = int(abs(x.real - y.real) + abs(x.imag - y.imag)) - if dist > d: - return False - saved = times[y] - times[x] - dist - return saved >= 100 - - -silver = sum(cheat(x, y, 2) for x in times.keys() for y in times.keys()) -gold = sum(cheat(x, y, 20) for x in times.keys() for y in times.keys()) - - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/21/python.py b/2024/21/python.py deleted file mode 100755 index 5873d65..0000000 --- a/2024/21/python.py +++ /dev/null @@ -1,42 +0,0 @@ -#!/usr/bin/env python3 - -from fileinput import input -from functools import cache - -seqs = [s.strip() for s in input()] - -numpad = { - "0": {"^": "2", ">": "A"}, - "1": {"^": "4", ">": "2"}, - "2": {"^": "5", ">": "3", "v": "0", "<": "1"}, - "3": {"^": "6", "v": "A", "<": "2"}, - "4": {"^": "7", ">": "5", "v": "1"}, - "5": {"^": "8", ">": "6", "v": "2", "<": "4"}, - "6": {"^": "9", "v": "3", "<": "5"}, - "7": {">": "8", "v": "4"}, - "8": {">": "9", "v": "5", "<": "7"}, - "9": {"v": "6", "<": "8"}, - "A": {"^": "3", "<": "0"}, -} -dirpad = { - "^": {">": "A", "v": "v"}, - ">": {"^": "A", "<": "v"}, - "v": {"^": "^", ">": ">", "<": "<"}, - "<": {">": "v"}, - "A": {"v": ">", "<": "^"}, -} - - -silver = 0 -gold = 0 - - -@cache -def move(a, b, n): - pass - - -print(seqs) - -print("silver:", silver) -print("gold:", gold) diff --git a/2024/22/python.py b/2024/22/python.py deleted file mode 100755 index 98d8898..0000000 --- a/2024/22/python.py +++ /dev/null @@ -1,59 +0,0 @@ -#!/usr/bin/env python3 - -from collections import Counter, deque -from fileinput import input -from itertools import islice - -lines = [int(line.strip()) for line in input()] - - -def secrets(secret): - x = secret - while True: - yield x - x ^= x << 6 - x &= 0xFFFFFF - x ^= x >> 5 - x &= 0xFFFFFF - x ^= x << 11 - x &= 0xFFFFFF - - -def prices(it): - for s in it: - yield s % 10 - - -def diff(it): - prev = next(it) - for curr in it: - yield curr, curr - prev - prev = curr - - -def to_seqs(it, n=4): - head = map(lambda x: x[1], islice(it, n - 1)) - q = deque(head, maxlen=n) - for price, diff in it: - q.append(diff) - yield price, tuple(q) - - -def seq_sells(it): - sells = {} - for price, diff in it: - if diff in sells: - continue - sells[diff] = price - return sells - - -best_seqs = Counter() -for x in lines: - best_seqs += seq_sells(to_seqs(islice(diff(prices(secrets(x))), 2000))) - -silver = sum(next(islice(secrets(x), 2000, None)) for x in lines) -gold = best_seqs.most_common(1)[0][1] - -print("silver:", silver) -print("gold:", gold) |
