1
0

feat: solve day 8 part 2

This commit is contained in:
Rokas Puzonas 2021-12-10 13:51:58 +02:00
parent df6062873b
commit e68d359395
2 changed files with 118 additions and 2 deletions

View File

@ -1,5 +1,4 @@
use std::convert::TryInto;
use std::{convert::TryInto, collections::HashMap};
pub struct Entry([String; 10], [String; 4]);
@ -39,6 +38,104 @@ pub fn part1(entries: &[Entry]) -> u32 {
count
}
// Helper function which converts a string into a binary representation
// I did this is so that the order of the letters won't matter
fn signal_to_bitmask(signal: &str) -> u32 {
let mut bitmask = 0;
for c in signal.chars() {
match c {
'a' => bitmask += 0b0000001,
'b' => bitmask += 0b0000010,
'c' => bitmask += 0b0000100,
'd' => bitmask += 0b0001000,
'e' => bitmask += 0b0010000,
'f' => bitmask += 0b0100000,
'g' => bitmask += 0b1000000,
_ => bitmask += 0
}
}
return bitmask;
}
fn decode_signal(signal: &str, wire_loopup: &HashMap<u32, u32>) -> Option<u32> {
wire_loopup.get(&signal_to_bitmask(signal)).map(|n| *n)
}
fn decode_signals(signals: &[String], wire_loopup: &HashMap<u32, u32>) -> u32 {
let mut number = 0;
let n = signals.len();
for i in 0..n {
let value = decode_signal(&signals[i], wire_loopup).unwrap();
number += value * u32::pow(10, (n-i-1) as u32);
}
return number;
}
fn decode_wire_lookup(signals: &[String; 10]) -> HashMap<u32, u32> {
let mut wire_lookup = HashMap::new();
let mut bitmasks: [u32; 10] = [0; 10];
for i in 0..10 {
bitmasks[i] = signal_to_bitmask(&signals[i]);
}
let mut one_bitmask = 0;
let mut four_bitmask = 0;
// Decode all signals which have unique number of wires
for i in 0..10 {
let len = signals[i].len();
if len == 2 {
one_bitmask = bitmasks[i];
wire_lookup.insert(one_bitmask, 1);
} else if len == 3 {
wire_lookup.insert(bitmasks[i], 7);
} else if len == 4 {
four_bitmask = bitmasks[i];
wire_lookup.insert(four_bitmask, 4);
} else if len == 7 {
wire_lookup.insert(bitmasks[i], 8);
}
}
let fourdiff = four_bitmask ^ one_bitmask;
for i in 0..10 {
let len = signals[i].len();
if len == 5 {
if bitmasks[i] & one_bitmask == one_bitmask {
wire_lookup.insert(bitmasks[i], 3);
} else if bitmasks[i] & fourdiff == fourdiff {
wire_lookup.insert(bitmasks[i], 5);
} else {
wire_lookup.insert(bitmasks[i], 2);
}
} else if len == 6 {
if bitmasks[i] & four_bitmask == four_bitmask {
wire_lookup.insert(bitmasks[i], 9);
} else if bitmasks[i] & fourdiff == fourdiff {
wire_lookup.insert(bitmasks[i], 6);
} else {
wire_lookup.insert(bitmasks[i], 0);
}
}
}
return wire_lookup;
}
fn decode_entry(entry: &Entry) -> u32 {
let wire_lookup = decode_wire_lookup(&entry.0);
return decode_signals(&entry.1, &wire_lookup);
}
pub fn part2(entries: &[Entry]) -> u32 {
let mut sum = 0;
for entry in entries {
sum += decode_entry(entry);
}
sum
}
#[cfg(test)]
mod tests {
use super::*;
@ -61,4 +158,22 @@ mod tests {
let result = part1(&input);
assert_eq!(result, 26);
}
#[test]
fn part2_example() {
let input = vec![
Entry(["be" .into(), "cfbegad" .into(), "cbdgef" .into(), "fgaecd" .into(), "cgeb" .into(), "fdcge" .into(), "agebfd" .into(), "fecdb" .into(), "fabcd" .into(), "edb".into()], ["fdgacbe" .into(), "cefdb" .into(), "cefbgd" .into(), "gcbe".into()]),
Entry(["edbfga" .into(), "begcd" .into(), "cbg" .into(), "gc" .into(), "gcadebf" .into(), "fbgde" .into(), "acbgfd" .into(), "abcde" .into(), "gfcbed" .into(), "gfec".into()], ["fcgedb" .into(), "cgb" .into(), "dgebacf" .into(), "gc".into()]),
Entry(["fgaebd" .into(), "cg" .into(), "bdaec" .into(), "gdafb" .into(), "agbcfd" .into(), "gdcbef" .into(), "bgcad" .into(), "gfac" .into(), "gcb" .into(), "cdgabef".into()], ["cg" .into(), "cg" .into(), "fdcagb" .into(), "cbg".into()]),
Entry(["fbegcd" .into(), "cbd" .into(), "adcefb" .into(), "dageb" .into(), "afcb" .into(), "bc" .into(), "aefdc" .into(), "ecdab" .into(), "fgdeca" .into(), "fcdbega".into()], ["efabcd" .into(), "cedba" .into(), "gadfec" .into(), "cb".into()]),
Entry(["aecbfdg" .into(), "fbg" .into(), "gf" .into(), "bafeg" .into(), "dbefa" .into(), "fcge" .into(), "gcbea" .into(), "fcaegb" .into(), "dgceab" .into(), "fcbdga".into()], ["gecf" .into(), "egdcabf" .into(), "bgf" .into(), "bfgea".into()]),
Entry(["fgeab" .into(), "ca" .into(), "afcebg" .into(), "bdacfeg" .into(), "cfaedg" .into(), "gcfdb" .into(), "baec" .into(), "bfadeg" .into(), "bafgc" .into(), "acf".into()], ["gebdcfa" .into(), "ecba" .into(), "ca" .into(), "fadegcb".into()]),
Entry(["dbcfg" .into(), "fgd" .into(), "bdegcaf" .into(), "fgec" .into(), "aegbdf" .into(), "ecdfab" .into(), "fbedc" .into(), "dacgb" .into(), "gdcebf" .into(), "gf".into()], ["cefg" .into(), "dcbef" .into(), "fcge" .into(), "gbcadfe".into()]),
Entry(["bdfegc" .into(), "cbegaf" .into(), "gecbf" .into(), "dfcage" .into(), "bdacg" .into(), "ed" .into(), "bedf" .into(), "ced" .into(), "adcbefg" .into(), "gebcd".into()], ["ed" .into(), "bcgafe" .into(), "cdgba" .into(), "cbgef".into()]),
Entry(["egadfb" .into(), "cdbfeg" .into(), "cegd" .into(), "fecab" .into(), "cgb" .into(), "gbdefca" .into(), "cg" .into(), "fgcdab" .into(), "egfdb" .into(), "bfceg".into()], ["gbdfcae" .into(), "bgc" .into(), "cg" .into(), "cgb".into()]),
Entry(["gcafb" .into(), "gcf" .into(), "dcaebfg" .into(), "ecagb" .into(), "gf" .into(), "abcdeg" .into(), "gaef" .into(), "cafbge" .into(), "fdbac" .into(), "fegbdc".into()], ["fgae" .into(), "cfgab" .into(), "fg" .into(), "bagce".into()]),
];
let result = part2(&input);
assert_eq!(result, 61229);
}
}

View File

@ -37,6 +37,7 @@ fn run(day: i32, part: i32, input_filename: &str) {
"7.1" => println!("{}", day7::part1(&day7::parse_input(&contents).expect(parse_error_msg))),
"7.2" => println!("{}", day7::part2(&day7::parse_input(&contents).expect(parse_error_msg))),
"8.1" => println!("{}", day8::part1(&day8::parse_input(&contents))),
"8.2" => println!("{}", day8::part2(&day8::parse_input(&contents))),
_ => println!("Day {} part {} not found", day, part)
}
}