use std::env::args; use std::fs::File; use std::io::BufRead; use std::io::BufReader; fn split_once<'a>(s: &'a str, sep: &str) -> (&'a str, &'a str) { let i = s.find(sep).unwrap(); let left = &s[..i]; let right = &s[i+sep.len()..]; return (left, right); } fn bin(code: &str) -> u8 { let mut u = 0; for c in code.chars() { u |= match c { 'a' => 0b0000001, 'b' => 0b0000010, 'c' => 0b0000100, 'd' => 0b0001000, 'e' => 0b0010000, 'f' => 0b0100000, 'g' => 0b1000000, _ => unreachable!(), }; } return u; } fn find bool + Copy>( codes: &mut Vec<&str>, len: usize, test: F ) -> u8 { for i in 0..codes.len() { if codes[i].len() == len { let b = bin(codes[i]); if test(b) { codes.swap_remove(i); return b; } } } unreachable!(); } fn sort(codes: Vec<&str>) -> [u8; 10] { let mut a = [0; 10]; let mut clone = codes.clone(); a[1] = find(&mut clone, 2, |_| true); a[4] = find(&mut clone, 4, |_| true); a[7] = find(&mut clone, 3, |_| true); a[8] = find(&mut clone, 7, |_| true); a[3] = find(&mut clone, 5, |b| b | a[1] == b); a[6] = find(&mut clone, 6, |b| b | a[1] == a[8]); a[0] = find(&mut clone, 6, |b| b | a[3] == a[8]); a[9] = find(&mut clone, 6, |_| true); a[5] = find(&mut clone, 5, |b| b | a[1] == a[9]); a[2] = find(&mut clone, 5, |_| true); return a; } fn index_of(numbers: &[T], a: T) -> usize { return numbers.iter().position(|b| a == *b).unwrap(); } fn main() { let path = args().nth(1).unwrap(); let file = File::open(path).unwrap(); let mut sum = 0; for line in BufReader::new(file).lines() { let l = line.unwrap(); let (left, right) = split_once(&l, " | "); let numbers = sort(left.split(" ").collect()); sum += right .split(" ") .enumerate() .map(|(i, a)| { let k = index_of(&numbers, bin(a)) as i32; let e = 10i32.pow((3 - i) as u32); return k * e; }) .sum::(); } print!("{}\n", sum); }