diff --git a/2021/day4/src/bingo.rs b/2021/day4/src/bingo.rs index 109015b..e66bba2 100644 --- a/2021/day4/src/bingo.rs +++ b/2021/day4/src/bingo.rs @@ -1,15 +1,17 @@ +type BingoNumber = ([usize; 2], u32, bool); + #[derive(Debug, PartialEq)] pub struct BingoCard { - grid: Vec<([usize; 2], u32, bool)>, + grid: Vec, } impl BingoCard { pub fn from_input(input: &[&str]) -> Self { - let row_count = input.len(); + let col_length = input.len(); let grid = input .iter() - .zip(0..row_count) + .zip(0..col_length) .map(|(line, y)| { let mut row_numbers = line .replace(" ", " ") @@ -25,10 +27,10 @@ impl BingoCard { .zip(0..col_count) .map(|(n, x)| ([x, y], *n, false)) // .into_iter() - .collect::>() + .collect::>() }) .flatten() - .collect::>(); + .collect::>(); BingoCard { grid } } @@ -67,6 +69,71 @@ fn mark_card(card: &mut BingoCard, bingo_num: &u32) { } } +fn check_card(card: &BingoCard) -> Vec<&u32> { + let marked_cards = card + .grid + .iter() + .filter(|(_, _, mark)| *mark == true) + .collect::>(); + + let col_length = card + .grid + .iter() + .filter(|([x, _], _, _)| *x == 0) + .map(|([_, y], _, _)| y) + .max() + .unwrap() + .clone() + + 1; + + let row_length = card + .grid + .iter() + .filter(|([_, y], _, _)| *y == 0) + .map(|([x, _], _, _)| x) + .max() + .unwrap() + .clone() + + 1; + + println!("col_length = {}", col_length); + println!("row_length = {}", row_length); + + // (0..col_length).flat_map(|y| { + // (0..row_length).flat_map(|x| { + + // TODO: improve this to map over and return Vec of all winning to find ties!! + + for y in 0..col_length { + let marked_in_col = marked_cards + .iter() + .filter(|([_, card_y], _, _)| *card_y == y) + .map(|([_, _], num, _)| num) + .collect::>(); + + println!("{:?}", marked_in_col); + + if marked_in_col.len() == col_length { + return marked_in_col; + } + + for x in 0..row_length { + let marked_in_row = marked_cards + .iter() + .filter(|([card_x, _], _, _)| *card_x == x) + .map(|([_, _], num, _)| num) + .collect::>(); + + if marked_in_row.len() == row_length { + return marked_in_row; + } + } + } + // .collect::)>>() + + return vec![]; +} + #[cfg(test)] mod tests { @@ -145,6 +212,74 @@ mod tests { assert_eq!(actual_card, expected_marked_card_4); } + #[test] + fn check_card_example_row_losing() { + #[rustfmt::skip] + let losing_card = BingoCard { grid: vec![ + ([0,0], 22, false),([1,0], 13, false),([2,0], 17, false),([3,0], 11, false),([4,0], 0, false), + ([0,1], 8, false),([1,1], 2, false),([2,1], 23, false),([3,1], 4, false),([4,1], 24, false), + ([0,2], 21, true),([1,2], 9, true),([2,2], 14, true),([3,2], 16, false),([4,2], 7, false), + ([0,3], 6, false),([1,3], 10, false),([2,3], 3, false),([3,3], 18, false),([4,3], 5, false), + ([0,4], 1, false),([1,4], 12, false),([2,4], 20, false),([3,4], 15, false),([4,4], 19, false), + ]}; + + let actual_result = check_card(&losing_card); + let expected_result: Vec<&u32> = vec![]; + + assert_eq!(actual_result, expected_result); + } + + #[test] + fn check_card_example_row_winning() { + #[rustfmt::skip] + let losing_card = BingoCard { grid: vec![ + ([0,0], 22, false),([1,0], 13, false),([2,0], 17, false),([3,0], 11, false),([4,0], 0, false), + ([0,1], 8, false),([1,1], 2, false),([2,1], 23, false),([3,1], 4, false),([4,1], 24, false), + ([0,2], 21, true),([1,2], 9, true),([2,2], 14, true),([3,2], 16, true),([4,2], 7, true), + ([0,3], 6, false),([1,3], 10, false),([2,3], 3, false),([3,3], 18, false),([4,3], 5, false), + ([0,4], 1, false),([1,4], 12, false),([2,4], 20, false),([3,4], 15, false),([4,4], 19, false), + ]}; + + let actual_result = check_card(&losing_card); + let expected_result: Vec<&u32> = vec![&21, &9, &14, &16, &7]; + + assert_eq!(actual_result, expected_result); + } + + #[test] + fn check_card_example_col_losing() { + #[rustfmt::skip] + let losing_card = BingoCard { grid: vec![ + ([0,0], 22, true),([1,0], 13, false),([2,0], 17, false),([3,0], 11, false),([4,0], 0, false), + ([0,1], 8, true),([1,1], 2, false),([2,1], 23, false),([3,1], 4, false),([4,1], 24, false), + ([0,2], 21, true),([1,2], 9, false),([2,2], 14, false),([3,2], 16, false),([4,2], 7, false), + ([0,3], 6, false),([1,3], 10, false),([2,3], 3, false),([3,3], 18, false),([4,3], 5, false), + ([0,4], 1, false),([1,4], 12, false),([2,4], 20, false),([3,4], 15, false),([4,4], 19, false), + ]}; + + let actual_result = check_card(&losing_card); + let expected_result: Vec<&u32> = vec![]; + + assert_eq!(actual_result, expected_result); + } + + #[test] + fn check_card_example_col_winning() { + #[rustfmt::skip] + let losing_card = BingoCard { grid: vec![ + ([0,0], 22, true),([1,0], 13, false),([2,0], 17, false),([3,0], 11, false),([4,0], 0, false), + ([0,1], 8, true),([1,1], 2, false),([2,1], 23, false),([3,1], 4, false),([4,1], 24, false), + ([0,2], 21, true),([1,2], 9, false),([2,2], 14, false),([3,2], 16, false),([4,2], 7, false), + ([0,3], 6, true),([1,3], 10, false),([2,3], 3, false),([3,3], 18, false),([4,3], 5, false), + ([0,4], 1, true),([1,4], 12, false),([2,4], 20, false),([3,4], 15, false),([4,4], 19, false), + ]}; + + let actual_result = check_card(&losing_card); + let expected_result: Vec<&u32> = vec![&22, &8, &21, &6, &1]; + + assert_eq!(actual_result, expected_result); + } + #[test] fn construct_empty_bingo_card_from_input() { let input = vec![];