use aoc_runner_derive::{aoc, aoc_generator}; use itertools::Itertools; #[aoc_generator(day5)] fn parse(input: &str) -> Vec<(Vec, Vec)> { input.lines() .map(str::chars) .map(itertools::Itertools::collect_vec) .map(|line| { (line[0..7].to_vec(), line[7..].to_vec()) }).collect_vec() } fn find_row(row_str: &Vec) -> u64 { let mut range = 0..=127; let mut queue = row_str.iter(); while range.try_len().unwrap() != 1 { match queue.next().unwrap() { 'F' => { let new_max = range.clone().last().unwrap() - (range.try_len().unwrap() / 2); range = range.clone().next().unwrap()..=new_max; }, 'B' => { let new_min = range.clone().next().unwrap() + (range.try_len().unwrap() / 2); range = new_min..=range.clone().last().unwrap(); }, _ => unreachable!() } } range.next().unwrap() as u64 } fn find_col(col_str: &Vec) -> u64 { let mut range = 0..=7; let mut queue = col_str.iter(); while range.try_len().unwrap() != 1 { match queue.next().unwrap() { 'L' => { let new_max = range.clone().last().unwrap() - (range.try_len().unwrap() / 2); range = range.clone().next().unwrap()..=new_max; }, 'R' => { let new_min = range.clone().next().unwrap() + (range.try_len().unwrap() / 2); range = new_min..=range.clone().last().unwrap(); }, _ => unreachable!() } } range.next().unwrap() as u64 } #[aoc(day5, part1)] fn part1(input: &Vec<(Vec, Vec)>) -> u64 { input.iter().map(|(row_str, col_str)| { let row = find_row(row_str); let col = find_col(col_str); (row * 8) + col }).max().unwrap() } #[aoc(day5, part2)] fn part2(input: &Vec<(Vec, Vec)>) -> u64 { let filled = input.iter().map(|(row_str, col_str)| { let row = find_row(row_str); let col = find_col(col_str); (row, col) }).collect_vec(); let mut all: Vec<(u64, u64)> = (0..=127).flat_map(|row| { let mut vec = vec![]; for col in 0..=7 { vec.push((row, col)) } vec }).collect_vec(); for full in filled { let idx = all.iter().position(|test| test == &full).unwrap(); all.remove(idx); } for seats in all.windows(2) { if seats[1].0 - seats[0].0 > 1 && seats[1].1 as i32 - seats[0].1 as i32 > 1 { return (seats[1].0 * 8) + seats[1].1 } } unreachable!("mega cringe") } #[cfg(test)] mod tests { use super::*; const EX: &str = r"FBFBBFFRLR BFFFBBFRRR FFFBBBFRRR BBFFBBFRLL"; #[test] fn part1_example() { assert_eq!(part1(&parse(EX)), 820); } // #[test] // fn part2_example() { // assert_eq!(part2(&parse("")), ""); // } }