Created
May 17, 2023 21:01
-
-
Save graffhyrum/655b9750cbcc867292fe8151cc747091 to your computer and use it in GitHub Desktop.
Exercism Rust Minesweeper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| pub fn annotate(minefield: &[&str]) -> Vec<String> { | |
| let row_count = minefield.len(); | |
| if row_count == 0 { | |
| return vec![]; | |
| } | |
| let col_count = minefield[0].len(); | |
| if col_count == 0 { | |
| return vec![String::new()]; | |
| } | |
| // 2d u8 vector, 0 is space, 9 is a mine, 1-8 is number of mines | |
| let mut two_d_array: Vec<Vec<u8>> = vec![vec![0; col_count]; row_count]; | |
| let mut result: Vec<String> = vec![String::new(); row_count]; | |
| for (row_index, row) in minefield.iter().enumerate() { | |
| row.as_bytes().iter().enumerate().for_each(|(col_index, cell)| { | |
| if *cell == b'*' { | |
| two_d_array[row_index][col_index] = 9; | |
| // increment all surrounding cells | |
| for i in -1..=1 { | |
| for j in -1..=1 { | |
| if i == 0 && j == 0 { | |
| // ...unless it's the origin | |
| continue; | |
| } | |
| let row = row_index as i32 + i; | |
| let col = col_index as i32 + j; | |
| if row >= 0 && row < row_count as i32 && col >= 0 && col < col_count as i32 { | |
| let cell_val = two_d_array[row as usize][col as usize]; | |
| match cell_val { | |
| 9 => continue, // don't increment mines | |
| _ => two_d_array[row as usize][col as usize] += 1, | |
| } | |
| } | |
| } | |
| } | |
| } | |
| }); | |
| }; | |
| result = two_d_array.iter().map(|row| { | |
| row.iter().map(|cell| { | |
| // convert back to char | |
| match cell { | |
| 9 => '*', | |
| 0 => ' ', | |
| _ => (cell + 48) as char, | |
| } | |
| }).collect() | |
| }).collect(); | |
| result | |
| } | |
| enum Option { | |
| Some(i32), | |
| None, | |
| } | |
| enum Result { | |
| Ok(i32), | |
| Err(String), | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| use minesweeper::annotate; | |
| fn remove_annotations(board: &[&str]) -> Vec<String> { | |
| board.iter().map(|r| remove_annotations_in_row(r)).collect() | |
| } | |
| fn remove_annotations_in_row(row: &str) -> String { | |
| row.chars() | |
| .map(|ch| match ch { | |
| '*' => '*', | |
| _ => ' ', | |
| }) | |
| .collect() | |
| } | |
| fn run_test(test_case: &[&str]) { | |
| let cleaned = remove_annotations(test_case); | |
| let cleaned_strs = cleaned.iter().map(|r| &r[..]).collect::<Vec<_>>(); | |
| let expected = test_case.iter().map(|&r| r.to_string()).collect::<Vec<_>>(); | |
| assert_eq!(expected, annotate(&cleaned_strs)); | |
| } | |
| #[test] | |
| fn no_rows() { | |
| #[rustfmt::skip] | |
| run_test(&[ | |
| ]); | |
| } | |
| #[test] | |
| #[ignore] | |
| fn no_columns() { | |
| #[rustfmt::skip] | |
| run_test(&[ | |
| "", | |
| ]); | |
| } | |
| #[test] | |
| #[ignore] | |
| fn no_mines() { | |
| #[rustfmt::skip] | |
| run_test(&[ | |
| " ", | |
| " ", | |
| " ", | |
| ]); | |
| } | |
| #[test] | |
| #[ignore] | |
| fn board_with_only_mines() { | |
| #[rustfmt::skip] | |
| run_test(&[ | |
| "***", | |
| "***", | |
| "***", | |
| ]); | |
| } | |
| #[test] | |
| #[ignore] | |
| fn mine_surrounded_by_spaces() { | |
| #[rustfmt::skip] | |
| run_test(&[ | |
| "111", | |
| "1*1", | |
| "111", | |
| ]); | |
| } | |
| #[test] | |
| #[ignore] | |
| fn space_surrounded_by_mines() { | |
| #[rustfmt::skip] | |
| run_test(&[ | |
| "***", | |
| "*8*", | |
| "***", | |
| ]); | |
| } | |
| #[test] | |
| #[ignore] | |
| fn horizontal_line() { | |
| #[rustfmt::skip] | |
| run_test(&[ | |
| "1*2*1", | |
| ]); | |
| } | |
| #[test] | |
| #[ignore] | |
| fn horizontal_line_mines_at_edges() { | |
| #[rustfmt::skip] | |
| run_test(&[ | |
| "*1 1*", | |
| ]); | |
| } | |
| #[test] | |
| #[ignore] | |
| fn vertical_line() { | |
| #[rustfmt::skip] | |
| run_test(&[ | |
| "1", | |
| "*", | |
| "2", | |
| "*", | |
| "1", | |
| ]); | |
| } | |
| #[test] | |
| #[ignore] | |
| fn vertical_line_mines_at_edges() { | |
| #[rustfmt::skip] | |
| run_test(&[ | |
| "*", | |
| "1", | |
| " ", | |
| "1", | |
| "*", | |
| ]); | |
| } | |
| #[test] | |
| #[ignore] | |
| fn cross() { | |
| #[rustfmt::skip] | |
| run_test(&[ | |
| " 2*2 ", | |
| "25*52", | |
| "*****", | |
| "25*52", | |
| " 2*2 ", | |
| ]); | |
| } | |
| #[test] | |
| #[ignore] | |
| fn large_board() { | |
| #[rustfmt::skip] | |
| run_test(&[ | |
| "1*22*1", | |
| "12*322", | |
| " 123*2", | |
| "112*4*", | |
| "1*22*2", | |
| "111111", | |
| ]); | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment