merry christmas, and to all a good AoC!
This commit is contained in:
parent
28f5eb17b0
commit
591f9b5294
6
day24/Cargo.toml
Normal file
6
day24/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "day24"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
545
day24/pbcopy
Normal file
545
day24/pbcopy
Normal file
File diff suppressed because one or more lines are too long
128
day24/src/main.rs
Normal file
128
day24/src/main.rs
Normal file
@ -0,0 +1,128 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
use std::env;
|
||||
use std::fs;
|
||||
|
||||
#[derive(Debug, Eq, PartialEq, Hash)]
|
||||
enum Wire<'a> {
|
||||
Value(bool),
|
||||
And(&'a str, &'a str),
|
||||
Or(&'a str, &'a str),
|
||||
Xor(&'a str, &'a str),
|
||||
}
|
||||
|
||||
fn main() {
|
||||
println!("Hello, AoC day 24!");
|
||||
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() != 2 {
|
||||
println!("wrong number of arguments!");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let file_path = &args[1];
|
||||
|
||||
let file = fs::read_to_string(file_path)
|
||||
.expect("should be able to read the file");
|
||||
|
||||
let (values, connections) = file.split_once("\n\n").expect("failed to split the file?");
|
||||
let mut wires: HashMap<&str, Wire> = HashMap::new();
|
||||
values
|
||||
.lines()
|
||||
.for_each(|x| {
|
||||
let (label, val_str) = x.split_once(": ").expect("wires should have a : in them");
|
||||
wires.insert(label, Wire::Value(val_str == "1"));
|
||||
});
|
||||
|
||||
connections
|
||||
.lines()
|
||||
.for_each(|line| {
|
||||
let (expr, label) = line.split_once(" -> ").expect("connections should have ->");
|
||||
let expression: Vec<_> = expr.split(" ").collect();
|
||||
let (a, op, b) = (expression[0], expression[1], expression[2]);
|
||||
wires.insert(label, match op {
|
||||
"AND" => Wire::And(a, b),
|
||||
"OR" => Wire::Or(a, b),
|
||||
"XOR" => Wire::Xor(a, b),
|
||||
_ => Wire::Value(false),
|
||||
});
|
||||
});
|
||||
|
||||
println!("{wires:?}");
|
||||
|
||||
// part a
|
||||
|
||||
let mut zs: Vec<String> = wires.keys()
|
||||
.filter(|name| name.starts_with("z"))
|
||||
.map(|name| name.to_string())
|
||||
.collect();
|
||||
|
||||
zs.sort();
|
||||
zs = zs.into_iter().rev().collect();
|
||||
for z in &zs { print!("{z}"); }
|
||||
print!("\n");
|
||||
|
||||
let mut part_a: u64 = 0;
|
||||
for z in &zs {
|
||||
part_a = part_a << 1;
|
||||
let this = get_value(z, &wires);
|
||||
if this { part_a = part_a + 1; }
|
||||
}
|
||||
|
||||
println!("the resulting z value is {part_a}");
|
||||
|
||||
// part b
|
||||
|
||||
println!("BEGIN GRAPHVIZ OUTPUT\n\n\n\n");
|
||||
println!("digraph addingmachine {{");
|
||||
for (label, wire) in &wires {
|
||||
match wire {
|
||||
Wire::Value(_) => print!("{label} [shape=box, color={}];", if label.starts_with("x") { "blue" } else { "red" }),
|
||||
_ => ()
|
||||
}
|
||||
}
|
||||
|
||||
for (label, wire) in &wires {
|
||||
match wire {
|
||||
Wire::Value(_) => (),
|
||||
Wire::And(a, b) => {
|
||||
if label.starts_with("z") { print!("{label} [shape=triangle, color=green];");
|
||||
} else { print!("{label} [shape=triangle];"); }
|
||||
print!("{a} -> {label};");
|
||||
print!("{b} -> {label};");
|
||||
},
|
||||
Wire::Or(a, b) => {
|
||||
if label.starts_with("z") { print!("{label} [shape=egg, color=green];");
|
||||
} else { print!("{label} [shape=egg];"); }
|
||||
print!("{a} -> {label};");
|
||||
print!("{b} -> {label};");
|
||||
},
|
||||
Wire::Xor(a, b) => {
|
||||
if label.starts_with("z") { print!("{label} [shape=star, color=green];");
|
||||
} else { print!("{label} [shape=star];"); }
|
||||
print!("{a} -> {label};");
|
||||
print!("{b} -> {label};");
|
||||
},
|
||||
}
|
||||
}
|
||||
println!("}}");
|
||||
println!("\n\n\n\nEND GRAPHVIZ OUTPUT");
|
||||
|
||||
println!("by direct inspection of the graph rendered by the above graphviz output,");
|
||||
println!("we find that the pairs that need to swap are z12+qdg, z19+vvf, z37+nvh, fgn+dck");
|
||||
let mut answer = vec!["z12", "qdg", "z19", "vvf", "z37", "nvh", "fgn", "dck"];
|
||||
answer.sort();
|
||||
print!("or, in order: ");
|
||||
for x in answer { print!("{x},"); }
|
||||
print!("\n");
|
||||
}
|
||||
|
||||
fn get_value<'a>(name: &'a str, system: &HashMap<&'a str, Wire>) -> bool {
|
||||
match system.get(name) {
|
||||
None => false,
|
||||
Some(Wire::Value(v)) => *v,
|
||||
Some(Wire::And(a, b)) => get_value(a, system) && get_value(b, system),
|
||||
Some(Wire::Or(a, b)) => get_value(a, system) || get_value(b, system),
|
||||
Some(Wire::Xor(a, b)) => get_value(a, system) ^ get_value(b, system),
|
||||
}
|
||||
}
|
6
day25/Cargo.toml
Normal file
6
day25/Cargo.toml
Normal file
@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "day25"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
84
day25/src/main.rs
Normal file
84
day25/src/main.rs
Normal file
@ -0,0 +1,84 @@
|
||||
use std::env;
|
||||
use std::fs;
|
||||
use std::iter::zip;
|
||||
|
||||
fn main() {
|
||||
println!("Hello, AoC day 24!");
|
||||
|
||||
let args: Vec<String> = env::args().collect();
|
||||
if args.len() != 2 {
|
||||
println!("wrong number of arguments!");
|
||||
std::process::exit(1);
|
||||
}
|
||||
|
||||
let file_path = &args[1];
|
||||
|
||||
let file = fs::read_to_string(file_path)
|
||||
.expect("should be able to read the file");
|
||||
|
||||
let keys = file.split("\n\n")
|
||||
.filter(|section| section.starts_with("....."))
|
||||
.map(string_transpose)
|
||||
.map(|vec_of_vec_of_char| vec_of_vec_of_char
|
||||
.into_iter()
|
||||
.map(|vec_of_char| vec_of_char
|
||||
.into_iter()
|
||||
.filter(|c| *c == '#')
|
||||
.count() - 1
|
||||
)
|
||||
.collect::<Vec<_>>()
|
||||
)
|
||||
.collect::<Vec<_>>();
|
||||
let locks = file.split("\n\n")
|
||||
.filter(|section| section.starts_with("#####"))
|
||||
.map(string_transpose)
|
||||
.map(|vec_of_vec_of_char| vec_of_vec_of_char
|
||||
.into_iter()
|
||||
.map(|vec_of_char| vec_of_char
|
||||
.into_iter()
|
||||
.filter(|c| *c == '#')
|
||||
.count() - 1
|
||||
)
|
||||
.collect::<Vec<_>>()
|
||||
)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
||||
println!("{keys:?}, {locks:?}");
|
||||
|
||||
let mut sum = 0;
|
||||
for lock in &locks {
|
||||
for key in &keys {
|
||||
if fits(lock, key) {
|
||||
sum += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
println!("the number of unique lock/key pairs is {sum}");
|
||||
}
|
||||
fn string_transpose(several_lines: &str) -> Vec<Vec<char>> {
|
||||
let mut output = Vec::with_capacity(several_lines.lines().next().unwrap().len());
|
||||
|
||||
for line in several_lines.lines() {
|
||||
for (idx, chr) in line.chars().enumerate() {
|
||||
if idx == output.len() {
|
||||
output.push(vec![]);
|
||||
}
|
||||
output[idx].push(chr);
|
||||
}
|
||||
}
|
||||
|
||||
return output
|
||||
}
|
||||
|
||||
fn fits(lock: &Vec<usize>, key: &Vec<usize>) -> bool {
|
||||
//println!("testing {lock:?} against {key:?}");
|
||||
for (tumbler, tooth) in zip(lock, key) {
|
||||
//println!("tumbler: {tumbler}; tooth: {tooth}");
|
||||
if *tumbler + *tooth > 5 {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
//println!("we good!");
|
||||
return true;
|
||||
}
|
Loading…
Reference in New Issue
Block a user