Part 1 solution for 2021 day 4
[?]
Dec 8, 2021, 1:04 AM
P7M5N7HRGJBPQPN6NTYYG56EWFZQWGC62AFO6TAIXCSDRPKX3LNQCDependencies
Change contents
- file addition: day4.rs[4.16]
use std::collections::HashMap;fn time_bingo<RI: IntoIterator<Item = CI>, CI: IntoIterator<Item = u8>>(draws: &HashMap<u8, usize>,board: RI,) -> usize {let mut col_notes: [usize; 5] = [0; 5];let mut soonest_row = usize::MAX;for row in board {let mut this_row = 0;for (x, c) in row.into_iter().enumerate() {let t = draws.get(&c).copied().unwrap_or(usize::MAX);this_row = this_row.max(t);col_notes[x] = col_notes[x].max(t);}soonest_row = soonest_row.min(this_row);}std::iter::once(soonest_row).chain(col_notes.iter().copied()).min().unwrap()}fn score_board<RI: IntoIterator<Item = CI>, CI: IntoIterator<Item = u8>>(draws: &HashMap<u8, usize>,board: RI,step: usize,) -> usize {board.into_iter().flat_map(IntoIterator::into_iter).filter(|n| match draws.get(n) {None => true,Some(s) => s > &step,}).map(<u8 as Into<usize>>::into).sum()}fn parse_draws(line: &str) -> HashMap<u8, usize> {line.split(',').flat_map(|x| x.parse().ok()).enumerate().map(|(i, x)| (x, i)).collect()}fn parse_boards<I: Iterator<Item = S>, S: AsRef<str>>(input: &mut I) -> Vec<Vec<Vec<u8>>> {input.filter(|l| l.as_ref().len() > 0).groups_of(5).map(|chunk| {chunk.iter().map(|line| {line.as_ref().split_whitespace().flat_map(|ns| ns.parse().ok()).collect()}).collect()}).collect()}fn main() {use std::io::BufRead;let filename = std::env::args().nth(1).expect("Expected filename");let file = std::io::BufReader::new(std::fs::File::open(<String as AsRef<std::path::Path>>::as_ref(&filename)).unwrap(),);let mut lines = file.lines();let draws = lines.next().map(|l| parse_draws(&l.unwrap())).expect("File is empty");let boards = parse_boards(&mut lines.flat_map(Result::ok));let (score,step) = boards.iter().map(|board| {let step = time_bingo(&draws, board.iter().map(|r| r.iter().copied()));(score_board(&draws,board.iter().map(|r| r.iter().copied()),step), step)}).min_by(|(_,a),(_,b)| a.cmp(b)).unwrap();println!("Time: {}", step);println!("Score: {}", score);let (last_called,_) = draws.iter().filter(|(_,w)| *w == &step).next().unwrap();println!("Last called: {}", last_called);println!("Product: {}", score * <u8 as Into<usize>>::into(*last_called));}struct Groups<I> {inner: I,group_size: usize,}impl<I: Sized + Iterator> Iterator for Groups<I> {type Item = Vec<<I as Iterator>::Item>;fn next(&mut self) -> Option<Self::Item> {if self.group_size == 0 {None} else {let mut result = Vec::with_capacity(self.group_size);for _ in 0..self.group_size {match self.inner.next() {Some(a) => {result.push(a);}None => {break;}}}if result.len() == 0 {self.group_size = 0;None} else {Some(result)}}}}trait Groupable: Sized + Iterator {fn groups_of(self, size: usize) -> Groups<Self>;}impl<I: Sized + Iterator> Groupable for I {fn groups_of(self, size: usize) -> Groups<Self> {Groups {inner: self,group_size: size,}}} - edit in 2021/Cargo.toml at line 21
[[bin]]name = "day4"path = "day4.rs"