generated from janezicmatej/aoc-template
Compare commits
4 Commits
0000030073
...
main
Author | SHA1 | Date | |
---|---|---|---|
00000340e7
|
|||
0000033060
|
|||
000003208e
|
|||
000003103e
|
32
data/examples/23.txt
Normal file
32
data/examples/23.txt
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
kh-tc
|
||||||
|
qp-kh
|
||||||
|
de-cg
|
||||||
|
ka-co
|
||||||
|
yn-aq
|
||||||
|
qp-ub
|
||||||
|
cg-tb
|
||||||
|
vc-aq
|
||||||
|
tb-ka
|
||||||
|
wh-tc
|
||||||
|
yn-cg
|
||||||
|
kh-ub
|
||||||
|
ta-co
|
||||||
|
de-co
|
||||||
|
tc-td
|
||||||
|
tb-wq
|
||||||
|
wh-td
|
||||||
|
ta-ka
|
||||||
|
td-qp
|
||||||
|
aq-cg
|
||||||
|
wq-ub
|
||||||
|
ub-vc
|
||||||
|
de-ta
|
||||||
|
wq-aq
|
||||||
|
wq-vc
|
||||||
|
wh-yn
|
||||||
|
ka-de
|
||||||
|
kh-ta
|
||||||
|
co-tc
|
||||||
|
wh-qp
|
||||||
|
tb-vc
|
||||||
|
td-yn
|
47
data/examples/24.txt
Normal file
47
data/examples/24.txt
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
x00: 1
|
||||||
|
x01: 0
|
||||||
|
x02: 1
|
||||||
|
x03: 1
|
||||||
|
x04: 0
|
||||||
|
y00: 1
|
||||||
|
y01: 1
|
||||||
|
y02: 1
|
||||||
|
y03: 1
|
||||||
|
y04: 1
|
||||||
|
|
||||||
|
ntg XOR fgs -> mjb
|
||||||
|
y02 OR x01 -> tnw
|
||||||
|
kwq OR kpj -> z05
|
||||||
|
x00 OR x03 -> fst
|
||||||
|
tgd XOR rvg -> z01
|
||||||
|
vdt OR tnw -> bfw
|
||||||
|
bfw AND frj -> z10
|
||||||
|
ffh OR nrd -> bqk
|
||||||
|
y00 AND y03 -> djm
|
||||||
|
y03 OR y00 -> psh
|
||||||
|
bqk OR frj -> z08
|
||||||
|
tnw OR fst -> frj
|
||||||
|
gnj AND tgd -> z11
|
||||||
|
bfw XOR mjb -> z00
|
||||||
|
x03 OR x00 -> vdt
|
||||||
|
gnj AND wpb -> z02
|
||||||
|
x04 AND y00 -> kjc
|
||||||
|
djm OR pbm -> qhw
|
||||||
|
nrd AND vdt -> hwm
|
||||||
|
kjc AND fst -> rvg
|
||||||
|
y04 OR y02 -> fgs
|
||||||
|
y01 AND x02 -> pbm
|
||||||
|
ntg OR kjc -> kwq
|
||||||
|
psh XOR fgs -> tgd
|
||||||
|
qhw XOR tgd -> z09
|
||||||
|
pbm OR djm -> kpj
|
||||||
|
x03 XOR y03 -> ffh
|
||||||
|
x00 XOR y04 -> ntg
|
||||||
|
bfw OR bqk -> z06
|
||||||
|
nrd XOR fgs -> wpb
|
||||||
|
frj XOR qhw -> z04
|
||||||
|
bqk OR frj -> z07
|
||||||
|
y03 OR x01 -> nrd
|
||||||
|
hwm AND bqk -> z03
|
||||||
|
tgd XOR rvg -> z12
|
||||||
|
tnw OR pbm -> gnj
|
39
data/examples/25.txt
Normal file
39
data/examples/25.txt
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
#####
|
||||||
|
.####
|
||||||
|
.####
|
||||||
|
.####
|
||||||
|
.#.#.
|
||||||
|
.#...
|
||||||
|
.....
|
||||||
|
|
||||||
|
#####
|
||||||
|
##.##
|
||||||
|
.#.##
|
||||||
|
...##
|
||||||
|
...#.
|
||||||
|
...#.
|
||||||
|
.....
|
||||||
|
|
||||||
|
.....
|
||||||
|
#....
|
||||||
|
#....
|
||||||
|
#...#
|
||||||
|
#.#.#
|
||||||
|
#.###
|
||||||
|
#####
|
||||||
|
|
||||||
|
.....
|
||||||
|
.....
|
||||||
|
#.#..
|
||||||
|
###..
|
||||||
|
###.#
|
||||||
|
###.#
|
||||||
|
#####
|
||||||
|
|
||||||
|
.....
|
||||||
|
.....
|
||||||
|
.....
|
||||||
|
#....
|
||||||
|
#.#..
|
||||||
|
#.#.#
|
||||||
|
#####
|
@@ -200,10 +200,16 @@ mod tests {
|
|||||||
use super::*;
|
use super::*;
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part_one() {
|
fn test_part_one() {
|
||||||
assert_eq!(part_one(&aoc::template::read_file("examples", 15)), Some(10092));
|
assert_eq!(
|
||||||
|
part_one(&aoc::template::read_file("examples", 15)),
|
||||||
|
Some(10092)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part_two() {
|
fn test_part_two() {
|
||||||
assert_eq!(part_two(&aoc::template::read_file("examples", 15)), Some(9021));
|
assert_eq!(
|
||||||
|
part_two(&aoc::template::read_file("examples", 15)),
|
||||||
|
Some(9021)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -91,4 +91,3 @@ pub fn part_two(input: &str) -> Option<String> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
aoc::solution!(18);
|
aoc::solution!(18);
|
||||||
|
|
||||||
|
@@ -66,6 +66,9 @@ mod tests {
|
|||||||
}
|
}
|
||||||
#[test]
|
#[test]
|
||||||
fn test_part_two() {
|
fn test_part_two() {
|
||||||
assert_eq!(part_two(&aoc::template::read_file("examples", 19)), Some(16));
|
assert_eq!(
|
||||||
|
part_two(&aoc::template::read_file("examples", 19)),
|
||||||
|
Some(16)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
88
src/bin/23.rs
Normal file
88
src/bin/23.rs
Normal file
@@ -0,0 +1,88 @@
|
|||||||
|
use std::collections::BTreeSet;
|
||||||
|
|
||||||
|
use hashbrown::{HashMap, HashSet};
|
||||||
|
use itertools::Itertools;
|
||||||
|
|
||||||
|
fn parse_graph(input: &str) -> HashMap<&str, BTreeSet<&str>> {
|
||||||
|
let nodes: HashSet<_> = input.lines().filter_map(|x| x.split_once('-')).collect();
|
||||||
|
let mut graph: HashMap<_, BTreeSet<_>> = HashMap::new();
|
||||||
|
for (n1, n2) in nodes.iter().copied() {
|
||||||
|
graph.entry(n1).or_default().insert(n2);
|
||||||
|
graph.entry(n2).or_default().insert(n1);
|
||||||
|
}
|
||||||
|
|
||||||
|
graph
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_one(input: &str) -> Option<usize> {
|
||||||
|
let graph = parse_graph(input);
|
||||||
|
|
||||||
|
let mut triples = HashSet::new();
|
||||||
|
for (n1, neigh) in graph.iter() {
|
||||||
|
for n2 in neigh.iter().copied() {
|
||||||
|
for n3 in graph[n2].iter() {
|
||||||
|
if graph[n3].contains(n1) && n1.starts_with('t') {
|
||||||
|
let mut triple = [n1, n2, n3];
|
||||||
|
triple.sort();
|
||||||
|
triples.insert(triple);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
triples.len().into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two(input: &str) -> Option<String> {
|
||||||
|
let graph = parse_graph(input);
|
||||||
|
|
||||||
|
let p: BTreeSet<_> = graph.keys().copied().collect();
|
||||||
|
let r = HashSet::new();
|
||||||
|
let x = BTreeSet::new();
|
||||||
|
|
||||||
|
let mut maximals = HashSet::new();
|
||||||
|
|
||||||
|
let mut stack = Vec::new();
|
||||||
|
stack.push((r, p, x));
|
||||||
|
|
||||||
|
while let Some((r, mut p, mut x)) = stack.pop() {
|
||||||
|
if p.is_empty() && x.is_empty() {
|
||||||
|
let mut password = r.iter().copied().collect_vec();
|
||||||
|
password.sort();
|
||||||
|
|
||||||
|
maximals.insert(password.join(","));
|
||||||
|
}
|
||||||
|
|
||||||
|
while let Some(pp) = p.pop_last() {
|
||||||
|
let mut nr = r.clone();
|
||||||
|
nr.insert(pp);
|
||||||
|
|
||||||
|
let np = &p & &graph[pp];
|
||||||
|
let nx = &x & &graph[pp];
|
||||||
|
|
||||||
|
stack.push((nr, np, nx));
|
||||||
|
|
||||||
|
x.insert(pp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
maximals.into_iter().max_by_key(|x| x.len())
|
||||||
|
}
|
||||||
|
|
||||||
|
aoc::solution!(23);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
assert_eq!(part_one(&aoc::template::read_file("examples", 23)), Some(7));
|
||||||
|
}
|
||||||
|
#[test]
|
||||||
|
fn test_part_two() {
|
||||||
|
assert_eq!(
|
||||||
|
part_two(&aoc::template::read_file("examples", 23)),
|
||||||
|
Some("co,de,ka,ta".to_string())
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
132
src/bin/24.rs
Normal file
132
src/bin/24.rs
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
|
use hashbrown::HashMap;
|
||||||
|
use itertools::Itertools;
|
||||||
|
use regex::Regex;
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Copy)]
|
||||||
|
enum Gate {
|
||||||
|
And,
|
||||||
|
Or,
|
||||||
|
XOr,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct LogicGate<'a> {
|
||||||
|
input_one: &'a str,
|
||||||
|
input_two: &'a str,
|
||||||
|
output: &'a str,
|
||||||
|
gate: Gate,
|
||||||
|
}
|
||||||
|
|
||||||
|
fn parse_input(input: &str) -> (HashMap<&str, bool>, Vec<LogicGate>) {
|
||||||
|
let (uvals, uevals) = input.split_once("\n\n").unwrap();
|
||||||
|
let vals: HashMap<_, _> = uvals
|
||||||
|
.lines()
|
||||||
|
.map(|x| x.split_once(": ").unwrap())
|
||||||
|
.map(|(k, v)| (k, v == "1"))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let mut logic_gates = Vec::new();
|
||||||
|
let re = Regex::new(r#"((?:\w|\d){3}) (AND|XOR|OR) ((?:\w|\d){3}) -> ((?:\w|\d){3})"#).unwrap();
|
||||||
|
for capt in re.captures_iter(uevals) {
|
||||||
|
let input_one = capt.get(1).unwrap().as_str();
|
||||||
|
let gate = match capt.get(2).unwrap().as_str() {
|
||||||
|
"AND" => Gate::And,
|
||||||
|
"OR" => Gate::Or,
|
||||||
|
"XOR" => Gate::XOr,
|
||||||
|
_ => unreachable!(),
|
||||||
|
};
|
||||||
|
let input_two = capt.get(3).unwrap().as_str();
|
||||||
|
let output = capt.get(4).unwrap().as_str();
|
||||||
|
logic_gates.push(LogicGate {
|
||||||
|
input_one,
|
||||||
|
input_two,
|
||||||
|
output,
|
||||||
|
gate,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
(vals, logic_gates)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_one(input: &str) -> Option<usize> {
|
||||||
|
let (mut vals, logic_gates) = parse_input(input);
|
||||||
|
let mut queue = VecDeque::from(logic_gates);
|
||||||
|
|
||||||
|
while let Some(s) = queue.pop_front() {
|
||||||
|
if !vals.contains_key(s.input_one) || !vals.contains_key(s.input_two) {
|
||||||
|
queue.push_back(s);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
let v1 = vals[s.input_one];
|
||||||
|
let v2 = vals[s.input_two];
|
||||||
|
|
||||||
|
let o = match s.gate {
|
||||||
|
Gate::And => v1 & v2,
|
||||||
|
Gate::Or => v1 | v2,
|
||||||
|
Gate::XOr => v1 ^ v2,
|
||||||
|
};
|
||||||
|
|
||||||
|
vals.insert(s.output, o);
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut zs = vals
|
||||||
|
.into_iter()
|
||||||
|
.filter(|x| x.0.starts_with('z'))
|
||||||
|
.collect_vec();
|
||||||
|
zs.sort();
|
||||||
|
zs.into_iter()
|
||||||
|
.enumerate()
|
||||||
|
.filter(|x| x.1 .1)
|
||||||
|
.map(|(i, _)| 1 << i)
|
||||||
|
.sum::<usize>()
|
||||||
|
.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two(_input: &str) -> Option<String> {
|
||||||
|
// Used graphviz for this part
|
||||||
|
// ```rs
|
||||||
|
// let (_, logic_gates) = parse_input(input);
|
||||||
|
// println!("digraph A {{");
|
||||||
|
// for (idx, lg) in logic_gates.iter().enumerate() {
|
||||||
|
// let LogicGate {
|
||||||
|
// input_one: i1,
|
||||||
|
// input_two: i2,
|
||||||
|
// output: o1,
|
||||||
|
// gate: g,
|
||||||
|
// } = lg;
|
||||||
|
// println!("{i1} -> {g:?}_{idx}");
|
||||||
|
// println!("{i2} -> {g:?}_{idx}");
|
||||||
|
// println!("{g:?}_{idx} -> {o1}");
|
||||||
|
// }
|
||||||
|
// println!("}}");
|
||||||
|
// ```
|
||||||
|
//
|
||||||
|
// and then pipe to dot
|
||||||
|
// ```bash
|
||||||
|
// ... | dot -Tsvg -Kneato > grpah.svg
|
||||||
|
// ```
|
||||||
|
//
|
||||||
|
// i looked for errors in the pattern and found below
|
||||||
|
// solution for my input
|
||||||
|
|
||||||
|
let mut res = ["fkp", "z06", "z11", "ngr", "z31", "mfm", "bpt", "krj"];
|
||||||
|
res.sort();
|
||||||
|
res.join(",").to_string().into()
|
||||||
|
}
|
||||||
|
|
||||||
|
aoc::solution!(24);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
assert_eq!(
|
||||||
|
part_one(&aoc::template::read_file("examples", 24)),
|
||||||
|
Some(2024)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
57
src/bin/25.rs
Normal file
57
src/bin/25.rs
Normal file
@@ -0,0 +1,57 @@
|
|||||||
|
pub fn part_one(input: &str) -> Option<usize> {
|
||||||
|
let mut keys = Vec::new();
|
||||||
|
let mut locks = Vec::new();
|
||||||
|
|
||||||
|
for key_or_lock in input.split("\n\n") {
|
||||||
|
let lock = key_or_lock
|
||||||
|
.lines()
|
||||||
|
.next()
|
||||||
|
.unwrap()
|
||||||
|
.chars()
|
||||||
|
.all(|x| x == '#');
|
||||||
|
|
||||||
|
let mut columns = [0; 5];
|
||||||
|
for (idx, c) in key_or_lock.lines().flat_map(|x| x.chars().enumerate()) {
|
||||||
|
if c == '#' {
|
||||||
|
columns[idx] += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove top or bottom row from count
|
||||||
|
for c in columns.iter_mut() {
|
||||||
|
*c -= 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if lock {
|
||||||
|
locks.push(columns);
|
||||||
|
} else {
|
||||||
|
keys.push(columns);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut count = 0;
|
||||||
|
for k in keys.iter() {
|
||||||
|
for l in locks.iter() {
|
||||||
|
if k.iter().zip(l.iter()).all(|(k, l)| k + l <= 5) {
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
count.into()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn part_two(_input: &str) -> Option<String> {
|
||||||
|
"Happy christmas!".to_string().into()
|
||||||
|
}
|
||||||
|
|
||||||
|
aoc::solution!(25);
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
#[test]
|
||||||
|
fn test_part_one() {
|
||||||
|
assert_eq!(part_one(&aoc::template::read_file("examples", 25)), Some(3));
|
||||||
|
}
|
||||||
|
}
|
@@ -1,9 +1,7 @@
|
|||||||
mod grid;
|
|
||||||
mod direction;
|
mod direction;
|
||||||
|
mod grid;
|
||||||
mod point;
|
mod point;
|
||||||
|
|
||||||
pub use grid::Grid;
|
|
||||||
pub use direction::Direction;
|
pub use direction::Direction;
|
||||||
|
pub use grid::Grid;
|
||||||
pub use point::Point;
|
pub use point::Point;
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user