chore: fmt + clippy

This commit is contained in:
Xavier Morel
2024-11-14 15:36:19 +01:00
parent 5eba391ebe
commit e243ca9498
3 changed files with 58 additions and 96 deletions

View File

@@ -136,8 +136,7 @@ impl State {
fn scan_steps(&mut self, steps: Vec<Step>) -> Vec<Pos> { fn scan_steps(&mut self, steps: Vec<Step>) -> Vec<Pos> {
steps steps
.into_iter() .into_iter()
.map(|step| self.all_locations_towards(&step)) .flat_map(|step| self.all_locations_towards(&step))
.flatten()
.collect() .collect()
} }
} }
@@ -158,13 +157,13 @@ fn parse_input(_input: &str) -> Vec<Step> {
_input _input
.to_string() .to_string()
.strip_suffix("\n") .strip_suffix("\n")
.unwrap_or(&_input) .unwrap_or(_input)
.split(", ") .split(", ")
.map(|s| { .map(|s| {
let (direction, value) = s.split_at(1); let (direction, value) = s.split_at(1);
let length: u32 = value let length: u32 = value.parse().unwrap_or_else(|_| {
.parse() panic!("{}", format!("invalid length! {:?}", value).to_string())
.expect(&format!("invalid length! {:?}", value).to_string()); });
match direction { match direction {
"L" => Step(Turn::Left, length), "L" => Step(Turn::Left, length),
"R" => Step(Turn::Right, length), "R" => Step(Turn::Right, length),

View File

@@ -29,25 +29,19 @@ impl PosP1 {
_y if _y > 1 => 1, _y if _y > 1 => 1,
_ => y, _ => y,
}; };
PosP1 {x: x, y: y} PosP1 { x, y }
} }
} }
impl Keypad for PosP1 { impl Keypad for PosP1 {
fn init() -> PosP1 { fn init() -> PosP1 {
Self { Self { x: 0, y: 0 }
x: 0,
y: 0,
}
} }
fn to_digit(self) -> char { fn to_digit(self) -> char {
let row_offset = (self.y * -1) + 1; let row_offset = -self.y + 1;
let col_offset = self.x + 1; let col_offset = self.x + 1;
char::from_digit( char::from_digit(((row_offset * 3) + col_offset + 1).try_into().unwrap(), 10).unwrap()
((row_offset * 3) + col_offset + 1).try_into().unwrap(),
10
).unwrap()
} }
fn move_to(self, dir: &Dir) -> PosP1 { fn move_to(self, dir: &Dir) -> PosP1 {
@@ -60,12 +54,12 @@ impl Keypad for PosP1 {
} }
} }
const DISP_P2: [[char; 5]; 5]= [ const DISP_P2: [[char; 5]; 5] = [
['0', '0', '1', '0', '0', ], ['0', '0', '1', '0', '0'],
['0', '2', '3', '4', '0', ], ['0', '2', '3', '4', '0'],
['5', '6', '7', '8', '9', ], ['5', '6', '7', '8', '9'],
['0', 'A', 'B', 'C', '0', ], ['0', 'A', 'B', 'C', '0'],
['0', '0', 'D', '0', '0', ], ['0', '0', 'D', '0', '0'],
]; ];
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
@@ -77,12 +71,9 @@ struct PosP2 {
impl PosP2 { impl PosP2 {
fn from(row: usize, col: usize) -> Option<Self> { fn from(row: usize, col: usize) -> Option<Self> {
if row > 4 || col > 4 { if row > 4 || col > 4 {
return None return None;
} }
let res = PosP2 { let res = PosP2 { row, col };
row: row,
col: col,
};
if res.to_digit() == '0' { if res.to_digit() == '0' {
None None
} else { } else {
@@ -91,13 +82,9 @@ impl PosP2 {
} }
} }
impl Keypad for PosP2 { impl Keypad for PosP2 {
fn init() -> PosP2 { fn init() -> PosP2 {
Self { Self { row: 2, col: 0 }
row: 2,
col: 0
}
} }
fn to_digit(self) -> char { fn to_digit(self) -> char {
@@ -122,43 +109,43 @@ enum Dir {
Right, Right,
} }
fn compute_digit<T: Keypad>(input: T, path: &Vec<Dir>) -> T { fn compute_digit<T: Keypad>(input: T, path: &[Dir]) -> T {
path path.iter().fold(input, |pos, dir| pos.move_to(dir))
.into_iter()
.fold(input, |pos, dir| pos.move_to(dir))
} }
fn parse_input(input: &str) -> Vec<Vec<Dir>> { fn parse_input(input: &str) -> Vec<Vec<Dir>> {
input input
.to_string() .to_string()
.strip_suffix("\n") .strip_suffix("\n")
.unwrap_or(&input) .unwrap_or(input)
.split("\n") .split("\n")
.map(|s| s .map(|s| {
.chars() s.chars()
.map(|c| match c { .map(|c| match c {
'U' => Dir::Up, 'U' => Dir::Up,
'D' => Dir::Down, 'D' => Dir::Down,
'L' => Dir::Left, 'L' => Dir::Left,
'R' => Dir::Right, 'R' => Dir::Right,
_ => panic!("Invalid input!"), _ => panic!("Invalid input!"),
}) })
.collect() .collect()
).collect() })
.collect()
} }
fn solve<T: Keypad + Copy>(input: &str) -> Option<String> { fn solve<T: Keypad + Copy>(input: &str) -> Option<String> {
let dirs = parse_input(input); let dirs = parse_input(input);
let digit: T = T::init(); let digit: T = T::init();
let res: Vec<char> = dirs.into_iter().scan(digit, |digit, ds| { let res: Vec<char> = dirs
*digit = compute_digit(*digit, &ds); .into_iter()
Some(digit.to_digit()) .scan(digit, |digit, ds| {
}).collect(); *digit = compute_digit(*digit, &ds);
Some(digit.to_digit())
})
.collect();
Some(String::from_iter(res)) Some(String::from_iter(res))
} }
pub fn part_one(input: &str) -> Option<String> { pub fn part_one(input: &str) -> Option<String> {
solve::<PosP1>(input) solve::<PosP1>(input)
} }
@@ -173,15 +160,15 @@ mod tests {
#[test] #[test]
fn test_posp1_to_digit() { fn test_posp1_to_digit() {
assert_eq!(PosP1 {x: -1, y: 1}.to_digit(), '1'); assert_eq!(PosP1 { x: -1, y: 1 }.to_digit(), '1');
assert_eq!(PosP1 {x: 0, y: 1}.to_digit(), '2'); assert_eq!(PosP1 { x: 0, y: 1 }.to_digit(), '2');
assert_eq!(PosP1 {x: 1, y: 1}.to_digit(), '3'); assert_eq!(PosP1 { x: 1, y: 1 }.to_digit(), '3');
assert_eq!(PosP1 {x: -1, y: 0}.to_digit(), '4'); assert_eq!(PosP1 { x: -1, y: 0 }.to_digit(), '4');
assert_eq!(PosP1 {x: 0, y: 0}.to_digit(), '5'); assert_eq!(PosP1 { x: 0, y: 0 }.to_digit(), '5');
assert_eq!(PosP1 {x: 1, y: 0}.to_digit(), '6'); assert_eq!(PosP1 { x: 1, y: 0 }.to_digit(), '6');
assert_eq!(PosP1 {x: -1, y: -1}.to_digit(), '7'); assert_eq!(PosP1 { x: -1, y: -1 }.to_digit(), '7');
assert_eq!(PosP1 {x: 0, y: -1}.to_digit(), '8'); assert_eq!(PosP1 { x: 0, y: -1 }.to_digit(), '8');
assert_eq!(PosP1 {x: 1, y: -1}.to_digit(), '9'); assert_eq!(PosP1 { x: 1, y: -1 }.to_digit(), '9');
} }
#[test] #[test]

View File

@@ -1,10 +1,7 @@
advent_of_code::solution!(3); advent_of_code::solution!(3);
fn parse_line(input: &str) -> [u32; 3] { fn parse_line(input: &str) -> [u32; 3] {
let nb: Result<Vec<u32>, _> = input let nb: Result<Vec<u32>, _> = input.split_whitespace().map(str::parse).collect();
.split_whitespace()
.map(str::parse)
.collect();
if let Ok(nb) = nb { if let Ok(nb) = nb {
if nb.len() == 3 { if nb.len() == 3 {
return [nb[0], nb[1], nb[2]]; return [nb[0], nb[1], nb[2]];
@@ -26,7 +23,7 @@ fn parse_input(input: &str) -> Vec<[u32; 3]> {
fn parse_input_p2(input: &str) -> Vec<[u32; 3]> { fn parse_input_p2(input: &str) -> Vec<[u32; 3]> {
parse_input(input) parse_input(input)
.chunks(3) .chunks(3)
.map(|c| { .flat_map(|c| {
let v = c.to_vec(); let v = c.to_vec();
if v.len() != 3 { if v.len() != 3 {
println!("{:?}", v); println!("{:?}", v);
@@ -34,44 +31,23 @@ fn parse_input_p2(input: &str) -> Vec<[u32; 3]> {
} }
let vs = [v[0], v[1], v[2]]; let vs = [v[0], v[1], v[2]];
// LAAAAAAZY... Could have transposed // LAAAAAAZY... Could have transposed
let [ let [[ta1, tb1, tc1], [ta2, tb2, tc2], [ta3, tb3, tc3]] = vs;
[ta1, tb1, tc1], [[ta1, ta2, ta3], [tb1, tb2, tb3], [tc1, tc2, tc3]].to_vec()
[ta2, tb2, tc2],
[ta3, tb3, tc3],
] = vs;
[
[ta1, ta2, ta3],
[tb1, tb2, tb3],
[tc1, tc2, tc3],
].to_vec()
}) })
.flatten()
.collect() .collect()
} }
fn is_valid(triangle: &[u32; 3]) -> bool { fn is_valid(triangle: &[u32; 3]) -> bool {
let &[a, b, c] = triangle; let &[a, b, c] = triangle;
(a + b) > c (a + b) > c && (b + c) > a && (c + a) > b
&& (b + c) > a
&& (c + a) > b
} }
pub fn part_one(input: &str) -> Option<u32> { pub fn part_one(input: &str) -> Option<u32> {
Some( Some(parse_input(input).into_iter().filter(is_valid).count() as u32)
parse_input(input)
.into_iter()
.filter(is_valid)
.count() as u32
)
} }
pub fn part_two(input: &str) -> Option<u32> { pub fn part_two(input: &str) -> Option<u32> {
Some( Some(parse_input_p2(input).into_iter().filter(is_valid).count() as u32)
parse_input_p2(input)
.into_iter()
.filter(is_valid)
.count() as u32
)
} }
#[cfg(test)] #[cfg(test)]