day 11 and part1 day9+10

This commit is contained in:
2025-12-11 23:09:01 +01:00
parent 203402971b
commit 76ffeb8ef0
7 changed files with 1884 additions and 6 deletions

1371
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -7,3 +7,5 @@ edition = "2024"
[dependencies]
aoc-runner = "0.3.0"
aoc-runner-derive = "0.3.0"
itertools = "0.14.0"
faer = "0.23"

135
src/day10.rs Normal file
View File

@@ -0,0 +1,135 @@
use std::collections::{HashMap, HashSet};
use itertools::Itertools;
#[aoc(day10, part1)]
pub fn part1(input: &str) -> u32 {
let machines = parse(input);
for machine in &machines {
println!(
"num buttons: {} num lights: {} diff: {}",
machine.buttons.len(),
machine.lights.len(),
machine.buttons.len() as i32 - machine.lights.len() as i32
);
}
machines.into_iter().map(|m| m.button_presses()).sum()
}
#[aoc(day10, part2)]
pub fn part2(input: &str) -> u32 {
let machines = parse(input);
machines.into_iter().map(|m| m.joltage_presses()).sum()
}
#[derive(Debug, Clone)]
struct Machine {
lights: Vec<bool>,
buttons: Vec<Vec<u32>>,
joltage: Vec<u32>,
}
impl Machine {
fn joltage_presses(self: Machine) -> u32 {
// Method: Set up a linear set of equations A^Tx=b, where A contains
// the coordinates of the buttons (one row per button) plus coordinates
// associated with optimisation parameters
0
}
fn button_presses(self: Machine) -> u32 {
let mut lightsmap: HashMap<u32, bool> = HashMap::new();
for (i, v) in self.lights.iter().enumerate() {
lightsmap.insert(i as u32, *v);
}
for i in 1..self.buttons.len() {
let combinations = self.buttons.iter().permutations(i);
for combination in combinations {
let mut result = combination
.into_iter()
.flatten()
.collect::<Vec<&u32>>()
.iter()
.counts()
.iter()
.map(|(k, v)| (***k, v % 2 == 1))
.collect::<HashMap<u32, bool>>();
for i in 0..self.lights.len() {
if !result.contains_key(&(i as u32)) {
result.insert(i as u32, false);
}
}
if result == lightsmap {
return i.try_into().unwrap();
}
}
}
0
}
}
fn parse(input: &str) -> Vec<Machine> {
input.lines().map(|l| parse_machine(l)).collect()
}
fn parse_machine(line: &str) -> Machine {
let mut columns = line.split_whitespace().into_iter();
let lights = columns
.next()
.unwrap()
.strip_prefix("[")
.unwrap()
.strip_suffix("]")
.unwrap()
.chars()
.map(|x| x == '#')
.collect();
let buttons = columns
.clone()
.take_while(|&col| col.chars().next().unwrap() == '(')
.map(|col| {
col.strip_prefix("(")
.unwrap()
.strip_suffix(")")
.unwrap()
.split(",")
.map(|x| x.parse::<u32>().unwrap())
.collect::<Vec<u32>>()
})
.collect::<Vec<Vec<u32>>>();
let joltage = columns
.last()
.unwrap()
.strip_prefix("{")
.unwrap()
.strip_suffix("}")
.unwrap()
.split(",")
.map(|x| x.parse::<u32>().unwrap())
.collect();
Machine {
lights,
buttons,
joltage,
}
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT_EXAMPLE: &str = "\
[.##.] (3) (1,3) (2) (2,3) (0,2) (0,1) {3,5,4,7}
[...#.] (0,2,3,4) (2,3) (0,4) (0,1,2) (1,2,3,4) {7,5,12,7,2}
[.###.#] (0,1,2,3,4) (0,3,4) (0,1,2,4,5) (1,2) {10,11,11,5,10,5}
";
#[test]
fn test_part1() {
assert_eq!(part1(INPUT_EXAMPLE), 7);
}
#[test]
fn test_part2() {
assert_eq!(part2(INPUT_EXAMPLE), 33);
}
}

121
src/day11.rs Normal file
View File

@@ -0,0 +1,121 @@
use std::collections::HashMap;
use faer::Mat;
#[aoc(day11, part1)]
pub fn part1(input: &str) -> u64 {
let (idx_map, adj_matrix) = parse(input);
sum_paths_mat(idx_map["you"], idx_map["out"], &adj_matrix)
}
#[aoc(day11, part2)]
pub fn part2(input: &str) -> u64 {
let (idx_map, adj_matrix) = parse(input);
[("svr", "fft"), ("fft", "dac"), ("dac", "out")]
.iter()
.map(|(i, j)| sum_paths_mat(idx_map[i], idx_map[j], &adj_matrix))
.product::<u64>()
+ [("svr", "dac"), ("dac", "fft"), ("fft", "out")]
.iter()
.map(|(i, j)| sum_paths_mat(idx_map[i], idx_map[j], &adj_matrix))
.product::<u64>()
}
fn sum_paths_mat(start_idx: usize, end_idx: usize, adj_matrix: &Vec<Vec<usize>>) -> u64 {
let n: usize = adj_matrix
.iter()
.flatten()
.max()
.unwrap()
.max(&end_idx)
.max(&start_idx)
.clone()
+ 1;
let adj_mat = Mat::from_fn(n, n, |i, j| {
adj_matrix.get(i).unwrap_or(&Vec::new()).contains(&j) as u64 as f64
});
let mut step = adj_mat.clone();
let mut paths = 0;
loop {
paths = paths + step[(start_idx, end_idx)] as u64;
step = &adj_mat * step;
if step.sum() < 0.1 {
break;
}
}
paths
}
// fn sum_paths(start_idx: usize, end_idx: usize, adj_matrix: &Vec<Vec<usize>>) -> u64 {
// adj_matrix
// .get(start_idx)
// .unwrap_or(&Vec::new())
// .iter()
// .map(|x| match x {
// x if x == &end_idx => 1,
// x if x == &start_idx => 0,
// _ => sum_paths(*x, end_idx, adj_matrix),
// })
// .sum()
// }
fn parse(input: &str) -> (HashMap<&str, usize>, Vec<Vec<usize>>) {
let mut idx_map: HashMap<&str, usize> = input
.lines()
.enumerate()
.map(|(i, l)| (l.split_once(':').unwrap().0, i))
.collect();
idx_map.insert("out", idx_map.len() + 1);
let adj_matrix: Vec<Vec<usize>> = input
.lines()
.map(|l| l.split_once(": ").unwrap().1)
.map(|l| {
l.split_ascii_whitespace()
.map(|w| *idx_map.get(w).unwrap())
.collect::<Vec<usize>>()
})
.collect();
(idx_map, adj_matrix)
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT_EXAMPLE: &str = "\
aaa: you hhh
you: bbb ccc
bbb: ddd eee
ccc: ddd eee fff
ddd: ggg
eee: out
fff: out
ggg: out
hhh: ccc fff iii
iii: out\
";
const INPUT_EXAMPLE_2: &str = "\
svr: aaa bbb
aaa: fft
fft: ccc
bbb: tty
tty: ccc
ccc: ddd eee
ddd: hub
hub: fff
eee: dac
dac: fff
fff: ggg hhh
ggg: out
hhh: out\
";
#[test]
fn test_part1() {
assert_eq!(part1(INPUT_EXAMPLE), 5);
}
#[test]
fn test_part2() {
assert_eq!(part2(INPUT_EXAMPLE_2), 2);
}
}

View File

@@ -1,17 +1,147 @@
#[aoc(day2, part1)]
pub fn part1(input: &str) -> i64 {
0
pub fn part1(input: &str) -> u64 {
let ranges = parse(input);
for line in ranges.iter() {
println!("{:?}", line);
}
let invalid_ids = invalid_ids(ranges);
invalid_ids.iter().sum()
}
#[aoc(day2, part2)]
pub fn part2(input: &str) -> u64 {
let ranges = parse(input);
for line in ranges.iter() {
println!("{:?}", line);
}
let invalid_ids = invalid_ids_2(ranges);
invalid_ids.iter().sum()
}
fn parse(input: &str) -> Vec<(&str, &str)> {
input
.split(',')
.map(|x| (x.split('-').nth(0).unwrap(), x.split('-').nth(1).unwrap()))
.collect()
}
fn invalid_ids_2(ranges: Vec<(&str, &str)>) -> Vec<u64> {
let mut result = Vec::new();
for (start, end) in ranges {
for i in start.parse::<u64>().unwrap()..=end.parse::<u64>().unwrap() {
let i_str = i.to_string();
println!("{}", i_str);
let i_len = i_str.len();
for rl in 1..=i_len {
if i_len % rl != 0 {
continue;
}
let mut condition = true;
for a in (0..i_len - rl).step_by(rl) {
println!(
"{:?} {:?} {:?} {} {}",
i_str,
&i_str[a..(a + rl)],
&i_str[(a + rl)..(a + 2 * rl)],
a,
rl
);
if i_str[a..(a + rl)] != i_str[(a + rl)..(a + 2 * rl)] {
condition = false;
break;
}
}
if condition {
result.push(i);
}
}
}
}
result
}
fn invalid_ids(ranges: Vec<(&str, &str)>) -> Vec<u64> {
let mut result = Vec::new();
for (start, end) in ranges {
for i in start.parse::<u64>().unwrap()..=end.parse::<u64>().unwrap() {
let i_str = i.to_string();
let i_len = i_str.len();
if i_len % 2 == 0 {
//println!("{}: {}-{}", i, &i_str[..i_len / 2], &i_str[i_len / 2..]);
if i_str[..i_len / 2] == i_str[i_len / 2..] {
result.push(i);
}
}
}
}
// for (start, end) in ranges {
// let start_len = start.chars().count().to_owned();
// let end_len = end.chars().count().to_owned();
// let half_len = [start_len, end_len]
// .into_iter()
// .filter(|x| x % 2 == 0)
// .max()
// .unwrap_or(0)
// / 2;
// if half_len == 0 {
// continue;
// }
// let start_num = String::from(
// start
// .chars()
// .take(1.max(start_len - half_len))
// .collect::<String>(),
// )
// .parse::<u64>()
// .unwrap();
// let end_num = String::from(end.chars().take(end_len - half_len).collect::<String>())
// .parse::<u64>()
// .unwrap();
// let inner_start = String::from(start)[1.max(end_len / 2)..]
// .parse::<u64>()
// .unwrap_or(0);
// let inner_end = String::from(end)[(end_len / 2)..].parse::<u64>().unwrap();
// println!("{}-{}", start, end);
// println!("{} {}", start_num, end_num);
// println!("{} {}", inner_start, inner_end);
// for num in start_num..=end_num {
// if (inner_start..=inner_end).contains(&num) {
// let id = num * 10_u64.pow(half_len as u32) + num;
// if id.to_string().len() % 2 == 0 || id.to_string().len() == 1 {
// println!("{}", id);
// result.push(id)
// }
// }
// }
// // println!("{:?}", result);
// }
// // println!("{:?}", result);
result
}
#[cfg(test)]
mod tests {
use super::*;
const EXAMPLE_INPUT: &str = "\
11-22,95-115,998-1012,1188511880-1188511890,222220-222224,\
1698522-1698528,446443-446449,38593856-38593862,565653-565659,\
824824821-824824827,2121212118-2121212124\
";
#[test]
fn test_part2() {
assert_eq!(part2(EXAMPLE_INPUT), 4174379265);
}
#[test]
fn test_part1() {
let cases = vec![("11-22", 33), ("11-22,95-115", 132)];
for case in cases {
assert_eq!(part1(case.0), case.1);
}
assert_eq!(part1(EXAMPLE_INPUT), 1227775554);
}
}

116
src/day9.rs Normal file
View File

@@ -0,0 +1,116 @@
#[aoc(day9, part1)]
pub fn part1(input: &str) -> i64 {
let mut coords = parse(input);
coords.sort_unstable_by_key(|x| x.0 + x.1);
//println!("{:?}", coords);
let mut area = 0;
for (x1, y1) in coords.iter().rev().take(10) {
for (x2, y2) in coords.iter().take(10) {
area = area.max((x1 - x2 + 1) * (y1 - y2 + 1));
//println!("{}", area);
}
}
area
}
#[aoc(day9, part2)]
pub fn part2(input: &str) -> i64 {
let mut coords = parse(input);
let (x_lines, y_lines) = rg_lines(&coords);
coords.sort_unstable_by_key(|x| x.0 + x.1);
println!("{:?}", coords);
println!("{:?}", x_lines);
println!("{:?}", y_lines);
let mut area = 0;
for (x1, y1) in coords.iter() {
for (x2, y2) in coords.iter() {
if y_lines
.iter()
.filter(|(x, y_a, y_b)| x2 == x && y_a <= y1 && y1 <= y_b)
.count()
> 1
// && x_lines
// .iter()
// .filter(|(x, y_a, y_b)| x1 == x && y_a <= y2 && y2 <= y_b)
// .count()
// > 1
// && y_lines
// .iter()
// .filter(|(y, x_a, x_b)| y1 == y && x_a <= x2 && x2 <= x_b)
// .count()
// > 1
// && x_lines
// .iter()
// .filter(|(y, x_a, x_b)| y2 == y && x_a <= x1 && x1 <= x_b)
// .count()
// > 1
{
println!("check");
area = area.max((x1 - x2 + 1) * (y1 - y2 + 1));
}
}
}
area
}
fn rg_lines(coords: &Vec<(i64, i64)>) -> (Vec<(i64, i64, i64)>, Vec<(i64, i64, i64)>) {
let x_lines = coords
.iter()
.map(|(x1, y1)| {
coords
.iter()
.filter(move |(x2, y2)| x1 == x2 && y1 < y2)
.map(move |(x2, y2)| (*x1, *y1, *y2))
})
.flatten()
.collect();
let y_lines = coords
.iter()
.map(|(x1, y1)| {
coords
.iter()
.filter(move |(x2, y2)| y1 == y2 && x1 < x2)
.map(move |(x2, y2)| (*y1, *x1, *x2))
})
.flatten()
.collect();
(x_lines, y_lines)
}
fn parse(input: &str) -> Vec<(i64, i64)> {
input
.lines()
.map(|l| {
let mut nums = l.split(",").map(|x| x.parse::<i64>().unwrap());
(nums.next().unwrap(), nums.next().unwrap())
})
.collect()
}
#[cfg(test)]
mod tests {
use super::*;
const INPUT_EXAMPLE: &str = "\
7,1
11,1
11,7
9,7
9,5
2,5
2,3
7,3
";
#[test]
fn test_part1() {
assert_eq!(part1(INPUT_EXAMPLE), 50)
}
#[test]
fn test_part2() {
assert_eq!(part2(INPUT_EXAMPLE), 24);
}
}

View File

@@ -5,11 +5,14 @@ extern crate aoc_runner_derive;
pub mod day1;
// pub mod day2;
// pub mod day10;
pub mod day11;
pub mod day3;
pub mod day4;
pub mod day5;
pub mod day6;
pub mod day7;
pub mod day8;
// pub mod day9;
aoc_lib! { year = 2025 }