144 lines
3.9 KiB
Rust
144 lines
3.9 KiB
Rust
use std::collections::HashSet;
|
|
use std::error::Error;
|
|
use std::fs::File;
|
|
use std::io::{self, BufRead};
|
|
use std::vec::Vec;
|
|
|
|
struct Line {
|
|
known_digits: Vec<HashSet<char>>,
|
|
unknown_digits: Vec<HashSet<char>>,
|
|
}
|
|
|
|
fn parse_input(line: String) -> Line {
|
|
let mut parts = line.split("|").map(|p| p.trim());
|
|
let known: Vec<HashSet<char>> = parts
|
|
.next()
|
|
.unwrap()
|
|
.split(" ")
|
|
.map(|d| HashSet::from_iter(d.chars()))
|
|
.collect();
|
|
let unknown: Vec<HashSet<char>> = parts
|
|
.next()
|
|
.unwrap()
|
|
.split(" ")
|
|
.map(|d| HashSet::from_iter(d.chars()))
|
|
.collect();
|
|
|
|
Line {
|
|
known_digits: known,
|
|
unknown_digits: unknown,
|
|
}
|
|
}
|
|
|
|
fn main() -> Result<(), Box<dyn Error>> {
|
|
let file = File::open("inputs/day8.txt")?;
|
|
let mut lines: Vec<Line> = io::BufReader::new(file)
|
|
.lines()
|
|
.map(|l| parse_input(l.unwrap()))
|
|
.collect();
|
|
|
|
let mut count1 = 0;
|
|
let mut answer2 = 0;
|
|
for line in lines.iter() {
|
|
let one = line.known_digits.iter().find(|d| d.len() == 2).unwrap();
|
|
println!("Identified one: {:?}", one);
|
|
|
|
let seven = line.known_digits.iter().find(|d| d.len() == 3).unwrap();
|
|
println!("Identified seven: {:?}", seven);
|
|
|
|
let four = line.known_digits.iter().find(|d| d.len() == 4).unwrap();
|
|
println!("Identified four: {:?}", four);
|
|
|
|
let eight = line.known_digits.iter().find(|d| d.len() == 7).unwrap();
|
|
println!("Identified eight: {:?}", eight);
|
|
|
|
for unknown in line.unknown_digits.iter() {
|
|
if unknown == one || unknown == seven || unknown == four || unknown == eight {
|
|
count1 += 1;
|
|
}
|
|
}
|
|
|
|
// Part 2
|
|
|
|
let nine = line
|
|
.known_digits
|
|
.iter()
|
|
.find(|d| d.len() == 6 && d.is_superset(seven) && d.is_superset(four))
|
|
.unwrap();
|
|
println!("Identified nine: {:?}", nine);
|
|
|
|
let three = line
|
|
.known_digits
|
|
.iter()
|
|
.find(|d| d.len() == 5 && d.is_superset(one))
|
|
.unwrap();
|
|
println!("Identified three: {:?}", three);
|
|
|
|
let zero = line
|
|
.known_digits
|
|
.iter()
|
|
.find(|d| {
|
|
d.len() == 6 && d.is_superset(one) && d.is_superset(seven) && !d.is_superset(three)
|
|
})
|
|
.unwrap();
|
|
println!("Identified zero: {:?}", zero);
|
|
|
|
let six = line
|
|
.known_digits
|
|
.iter()
|
|
.find(|d| d.len() == 6 && d != &zero && d != &nine)
|
|
.unwrap();
|
|
println!("Identified six: {:?}", six);
|
|
|
|
let five = line
|
|
.known_digits
|
|
.iter()
|
|
.find(|d| d.len() == 5 && d.is_subset(nine) && d != &three)
|
|
.unwrap();
|
|
println!("Identified five: {:?}", five);
|
|
|
|
let two = line
|
|
.known_digits
|
|
.iter()
|
|
.find(|d| d.len() == 5 && d != &three && d != &five)
|
|
.unwrap();
|
|
println!("Identified two: {:?}", two);
|
|
|
|
let mut base = 1;
|
|
let mut reading = 0;
|
|
for digit in line.unknown_digits.iter().rev() {
|
|
let d = if digit == zero {
|
|
0
|
|
} else if digit == one {
|
|
1
|
|
} else if digit == two {
|
|
2
|
|
} else if digit == three {
|
|
3
|
|
} else if digit == four {
|
|
4
|
|
} else if digit == five {
|
|
5
|
|
} else if digit == six {
|
|
6
|
|
} else if digit == seven {
|
|
7
|
|
} else if digit == eight {
|
|
8
|
|
} else {
|
|
9
|
|
};
|
|
reading += d * base;
|
|
base *= 10;
|
|
}
|
|
println!("Reading: {}", reading);
|
|
answer2 += reading;
|
|
}
|
|
|
|
println!("Answer1: {}", count1);
|
|
|
|
println!("Answer2: {}", answer2);
|
|
|
|
Ok(())
|
|
}
|