diff --git a/Cargo.lock b/Cargo.lock index 0ceb48e..951ed46 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -21,6 +21,7 @@ checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" name = "advent_of_code" version = "0.12.0" dependencies = [ + "bitvec", "chrono", "dhat", "itertools", @@ -81,6 +82,18 @@ version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "bitvec" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bc2832c24239b0141d5674bb9174f9d68a8b5b3f2753311927c172ca46f7e9c" +dependencies = [ + "funty", + "radium", + "tap", + "wyz", +] + [[package]] name = "bumpalo" version = "3.14.0" @@ -144,6 +157,12 @@ version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" +[[package]] +name = "funty" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e6d5a32815ae3f33302d95fdcb2ce17862f8c65363dcfd29360480ba1001fc9c" + [[package]] name = "gimli" version = "0.28.1" @@ -321,6 +340,12 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "radium" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc33ff2d4973d518d823d61aa239014831e521c75da58e3df4840d3f47749d09" + [[package]] name = "redox_syscall" version = "0.4.1" @@ -450,6 +475,12 @@ dependencies = [ "libc", ] +[[package]] +name = "tap" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" + [[package]] name = "thousands" version = "0.2.0" @@ -651,3 +682,12 @@ name = "windows_x86_64_msvc" version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" + +[[package]] +name = "wyz" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05f360fc0b24296329c78fda852a1e9ae82de9cf7b27dae4b7f62f118f77b9ed" +dependencies = [ + "tap", +] diff --git a/Cargo.toml b/Cargo.toml index b866718..d0c5a85 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,7 @@ today = ["chrono"] test_lib = [] [dependencies] +bitvec = "1.0.1" # Template dependencies chrono = { version = "0.4.38", optional = true } diff --git a/data/examples/10.txt b/data/examples/10.txt new file mode 100644 index 0000000..dd91d7b --- /dev/null +++ b/data/examples/10.txt @@ -0,0 +1,3 @@ +[.##.] (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} diff --git a/src/bin/10.rs b/src/bin/10.rs new file mode 100644 index 0000000..438d5da --- /dev/null +++ b/src/bin/10.rs @@ -0,0 +1,87 @@ +advent_of_code::solution!(10); + +use itertools::Itertools; +use bitvec::{bitvec, vec::BitVec}; + +fn parse_line(line: &str) -> Option<(BitVec, Vec, Vec)>{ + let fields = line.split(' ').collect_vec(); + let goal: BitVec = fields[0].chars().filter_map(|c| { + match c { + '.' => Some(false), + '#' => Some(true), + _ => None + } + }).collect(); + // println!("{goal:?}"); + + let buttons = fields[1..fields.len()-1].iter().map(|b| { + let mut button_flag = bitvec![0; 10]; // BitVec::with_capacity(10); + let buttons = &b[1..b.len()-1]; + + // println!("{buttons:?}"); + for v in buttons.split(',').map(|v| v.parse::().unwrap()) { + // println!("{v}"); + button_flag.insert(v, true); + } + button_flag + }).collect_vec(); + let joltage_str = fields[fields.len()-1]; + let joltage = joltage_str[1..joltage_str.len()-1].split(',').map(|j| j.parse::().unwrap()).collect_vec(); + + Some((goal, buttons, joltage)) +} + +pub fn part_one(input: &str) -> Option { + let mut total_key_presses = 0; + for line in input.lines().filter(|l| !l.is_empty()) { + let (goal, buttons, _) = parse_line(line).unwrap(); + // println!("goal: {goal:?}"); + // println!("buttons ({}): {buttons:?}", buttons.len()); + // println!("result: {result}"); + + // cycle through all permutations of button presses + let mut least_presses = u32::MAX; + for ii in 0..2_usize.pow(buttons.len() as u32) { + let mut state = goal.clone(); + + for (bidx, b) in buttons.iter().enumerate() { + if ii >> bidx & 1 == 1 { + state ^= b; + } + } + + // println!("new state {state}"); + if state.count_ones() == 0 { + let key_presses = ii.count_ones(); + // println!("Found solution in {key_presses} key presses!"); + if key_presses < least_presses { + least_presses = key_presses + } + } + } + total_key_presses += least_presses; + } + + Some(total_key_presses as u64) +} + +pub fn part_two(input: &str) -> Option { + None +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_part_one() { + let result = part_one(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, Some(7)); + } + + #[test] + fn test_part_two() { + let result = part_two(&advent_of_code::template::read_file("examples", DAY)); + assert_eq!(result, None); + } +}