|
| 1 | +use std::cmp::Ordering::Equal; |
| 2 | +use itertools::Itertools; |
| 3 | + |
1 | 4 | advent_of_code::solution!(2);
|
2 | 5 |
|
3 | 6 | fn is_safe(data: &Vec<u32>) -> bool {
|
4 |
| - let mut previous_direction = None; |
5 |
| - for i in 0..(data.len() - 1) { |
6 |
| - let diff = data[i].abs_diff(data[i + 1]); |
7 |
| - if diff == 0 || diff > 3 { |
8 |
| - return false; |
9 |
| - } |
10 |
| - let direction = data[i].cmp(&data[i + 1]); |
11 |
| - match previous_direction { |
12 |
| - Some(previous_direction) => if previous_direction != direction { |
13 |
| - return false; |
14 |
| - }, |
15 |
| - None => previous_direction = Some(direction) |
16 |
| - } |
| 7 | + let direction = data[0].cmp(&data[1]); |
| 8 | + if direction == Equal { |
| 9 | + return false; |
17 | 10 | }
|
18 |
| - true |
| 11 | + data.iter().tuple_windows::<(&u32, &u32)>() |
| 12 | + .map(|(current, next)| (1..=3).contains(¤t.abs_diff(*next)) && current.cmp(next) == direction) |
| 13 | + .all(|valid| valid) |
19 | 14 | }
|
20 | 15 |
|
21 | 16 | fn is_safe_lenient(data: &Vec<u32>) -> bool {
|
22 | 17 | if is_safe(data) {
|
23 | 18 | return true;
|
24 | 19 | }
|
25 |
| - for i in 0..data.len() { |
| 20 | + (0..data.len()).any(|index| { |
26 | 21 | let mut modified_data = data.clone();
|
27 |
| - modified_data.remove(i); |
28 |
| - if is_safe(&modified_data) { |
29 |
| - return true |
30 |
| - } |
31 |
| - } |
32 |
| - false |
| 22 | + modified_data.remove(index); |
| 23 | + is_safe(&modified_data) |
| 24 | + }) |
33 | 25 | }
|
34 | 26 |
|
35 | 27 | fn count_safe_reports<P>(input: &str, predicate: P) -> u32
|
|
0 commit comments