107 lines
3.4 KiB
Rust
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));
|
|
}
|
|
}
|
|
|