advent-of-code-2021/day8/src/main.rs
Louis Vallat caad9cdfc6
Added day 8 code for part 1 and 2
Signed-off-by: Louis Vallat <louis@louis-vallat.xyz>
2021-12-10 12:13:43 +01:00

107 lines
3.4 KiB
Rust

use std::{fs, env, vec, collections::BTreeMap};
fn read_input(path: &str) -> String {
return fs::read_to_string(path).expect("Cannot read file.");
}
fn parse_input(s: &str) -> Vec<(Vec<&str>, Vec<&str>)> {
return s.lines()
.filter_map(|l| l.split_once(" | "))
.map(|t| (t.0.split_whitespace().collect(), t.1.split_whitespace().collect()))
.collect();
}
fn find_easy_numbers(v: &Vec<(Vec<&str>, Vec<&str>)>, s: &Vec<Vec<char>>) -> i32 {
let d = vec![s[1].len(), s[4].len(), s[7].len(), s[8].len()];
let mut c = 0;
for t in v {
for l in t.1.clone() {
if d.contains(&l.len()) {
c += 1;
}
}
}
return c;
}
fn learn_decode_table(c: &(Vec<&str>, Vec<&str>)) -> BTreeMap<char, char> {
let mut d: BTreeMap<char, char> = BTreeMap::new();
let mut o: BTreeMap<char, i32> = BTreeMap::new();
for i in c.0.clone() {
for e in i.chars() { o.insert(e, *o.get(&e).unwrap_or(&0) + 1); }
}
for i in o.clone() {
match i.1 {
4 => { d.insert(i.0, 'e'); }
6 => { d.insert(i.0, 'b'); }
9 => { d.insert(i.0, 'f'); }
_ => {}
}
}
let mut v = c.0.clone();
v.sort_by(|a,b| a.len().cmp(&b.len()));
for e in v.clone() {
if e.len() == 2 {
for f in e.chars() {
if !d.contains_key(&f) { d.insert(f, 'c'); }
}
} else if e.len() == 3 {
for f in e.chars() {
if !d.contains_key(&f) { d.insert(f, 'a'); }
}
} else if e.len() == 4 {
for f in e.chars() {
if !d.contains_key(&f) { d.insert(f, 'd'); }
}
} else if e.len() == 7 {
for f in e.chars() {
if !d.contains_key(&f) { d.insert(f, 'g'); }
}
}
}
return d;
}
fn decode_number(c: &(Vec<&str>, Vec<&str>), s: &Vec<Vec<char>>) -> i32 {
let d_table = learn_decode_table(c);
let mut decoded = 0;
for e in c.1.clone() {
let mut d: Vec<char> = vec![];
for l in e.chars() { d.push(*d_table.get(&l).unwrap()); }
d.sort();
let n = s.iter().position(|x| x.eq(&d)).unwrap() as i32;
decoded = decoded * 10 + n;
}
return decoded;
}
fn decode_and_sum(c: &Vec<(Vec<&str>, Vec<&str>)>, s: &Vec<Vec<char>>) -> i32 {
let mut i = 0;
for e in c { i += decode_number(e, s); }
return i;
}
fn main() {
let args: Vec<String> = env::args().collect();
let mut segs = vec![];
segs.push(vec!['a', 'b', 'c', 'e', 'f', 'g']); // 0
segs.push(vec![ 'c', 'f' ]); // 1
segs.push(vec!['a', 'c', 'd', 'e', 'g']); // 2
segs.push(vec!['a', 'c', 'd', 'f', 'g']); // 3
segs.push(vec![ 'b', 'c', 'd', 'f' ]); // 4
segs.push(vec!['a', 'b', 'd', 'f', 'g']); // 5
segs.push(vec!['a', 'b', 'd', 'e', 'f', 'g']); // 6
segs.push(vec!['a', 'c', 'f' ]); // 7
segs.push(vec!['a', 'b', 'c', 'd', 'e', 'f', 'g']); // 8
segs.push(vec!['a', 'b', 'c', 'd', 'f', 'g']); // 9
for arg in args.iter().skip(1) {
let input = read_input(&arg);
let vec_in = parse_input(&input);
println!("[{}]", &arg);
println!("\t[Part 1] => Answer is '{}'.", find_easy_numbers(&vec_in, &segs));
println!("\t[Part 2] => Answer is '{}'.", decode_and_sum(&vec_in, &segs));
}
}