day 11 and part1 day9+10
This commit is contained in:
135
src/day10.rs
Normal file
135
src/day10.rs
Normal 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
121
src/day11.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
142
src/day2.rs
142
src/day2.rs
@@ -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
116
src/day9.rs
Normal 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);
|
||||
}
|
||||
}
|
||||
@@ -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 }
|
||||
|
||||
Reference in New Issue
Block a user