feat: day 9 p2 + fmt / clippy

This commit is contained in:
Xavier Morel
2024-12-10 00:17:46 +01:00
parent 2825fdd2ca
commit 1639af81fc
2 changed files with 151 additions and 74 deletions

View File

@@ -15,14 +15,14 @@ impl Pos {
Self { x, y } Self { x, y }
} }
fn diff(&self, other: &Self) -> Self { fn diff(self, other: Self) -> Self {
Self { Self {
x: other.x - self.x, x: other.x - self.x,
y: other.y - self.y, y: other.y - self.y,
} }
} }
fn add(&self, other: &Self) -> Self { fn add(self, other: Self) -> Self {
Self { Self {
x: self.x + other.x, x: self.x + other.x,
y: self.y + other.y, y: self.y + other.y,
@@ -30,16 +30,15 @@ impl Pos {
} }
fn is_valid(&self, max: &Self) -> bool { fn is_valid(&self, max: &Self) -> bool {
self.x >= 0 && self.x < max.x self.x >= 0 && self.x < max.x && self.y >= 0 && self.y < max.y
&& self.y >= 0 && self.y < max.y
} }
} }
fn get_antinodes(p1: &Pos, p2: &Pos, max: &Pos) -> Vec<Pos> { fn get_antinodes(p1: &Pos, p2: &Pos, max: &Pos) -> Vec<Pos> {
let d1 = p1.diff(&p2); let d1 = p1.diff(*p2);
let d2 = p2.diff(&p1); let d2 = p2.diff(*p1);
let p1b = p1.add(&d2); let p1b = p1.add(d2);
let p2b = p2.add(&d1); let p2b = p2.add(d1);
let mut res: Vec<Pos> = Vec::new(); let mut res: Vec<Pos> = Vec::new();
if p1b.is_valid(max) { if p1b.is_valid(max) {
res.push(p1b); res.push(p1b);
@@ -50,31 +49,27 @@ fn get_antinodes(p1: &Pos, p2: &Pos, max: &Pos) -> Vec<Pos> {
res res
} }
fn get_antinodes_p2(p1: &Pos, p2: &Pos, max: &Pos) -> Vec<Pos> { fn get_antinodes_p2(p1: Pos, p2: Pos, max: &Pos) -> Vec<Pos> {
let d1 = p2.diff(&p1); let d1 = p2.diff(p1);
let mut succ1: Vec<Pos> = successors( let mut succ1: Vec<Pos> = successors(Some(p1), |p| {
Some(*p1), let s = p.add(d1);
|p| { if s.is_valid(max) {
let s = p.add(&d1); Some(s)
if s.is_valid(max) { } else {
Some(s) None
} else {
None
}
} }
).collect(); })
let d2 = p1.diff(&p2); .collect();
let succ2: Vec<Pos> = successors( let d2 = p1.diff(p2);
Some(*p2), let succ2: Vec<Pos> = successors(Some(p2), |p| {
|p| { let s = p.add(d2);
let s = p.add(&d2); if s.is_valid(max) {
if s.is_valid(max) { Some(s)
Some(s) } else {
} else { None
None
}
} }
).collect(); })
.collect();
succ1.extend(succ2); succ1.extend(succ2);
succ1.into_iter().map(|p| p.to_owned()).collect() succ1.into_iter().map(|p| p.to_owned()).collect()
} }
@@ -113,7 +108,7 @@ fn parse_line(line: &str, y: usize) -> Vec<(char, Pos)> {
// } // }
// } // }
fn parse_input(input: &str) -> (Pos, HashMap::<char, Vec<Pos>>) { fn parse_input(input: &str) -> (Pos, HashMap<char, Vec<Pos>>) {
let mut antenna: HashMap<char, Vec<Pos>> = HashMap::new(); let mut antenna: HashMap<char, Vec<Pos>> = HashMap::new();
let lines = input.lines().collect::<Vec<_>>(); let lines = input.lines().collect::<Vec<_>>();
let map_size = Pos::init(lines[0].len() as i8, lines.len() as i8); let map_size = Pos::init(lines[0].len() as i8, lines.len() as i8);
@@ -122,7 +117,7 @@ fn parse_input(input: &str) -> (Pos, HashMap::<char, Vec<Pos>>) {
.enumerate() .enumerate()
.flat_map(|(y, l)| parse_line(l, y)) .flat_map(|(y, l)| parse_line(l, y))
.for_each(|(c, p)| { .for_each(|(c, p)| {
antenna.entry(c).or_insert(Vec::new()).push(p); antenna.entry(c).or_default().push(p);
}); });
(map_size, antenna) (map_size, antenna)
} }
@@ -131,11 +126,12 @@ pub fn part_one(input: &str) -> Option<usize> {
let (map_size, antenna) = parse_input(input); let (map_size, antenna) = parse_input(input);
let mut antinodes: Vec<Pos> = antenna let mut antinodes: Vec<Pos> = antenna
.values() .values()
.flat_map(|ps| ps.into_iter() .flat_map(|ps| {
.combinations(2) ps.iter()
.flat_map(|a| get_antinodes(a[0], a[1], &map_size)) .combinations(2)
.collect::<Vec<_>>() .flat_map(|a| get_antinodes(a[0], a[1], &map_size))
) .collect::<Vec<_>>()
})
.collect(); .collect();
antinodes.sort(); antinodes.sort();
antinodes.dedup(); antinodes.dedup();
@@ -146,11 +142,12 @@ pub fn part_two(input: &str) -> Option<usize> {
let (map_size, antenna) = parse_input(input); let (map_size, antenna) = parse_input(input);
let mut antinodes: Vec<Pos> = antenna let mut antinodes: Vec<Pos> = antenna
.values() .values()
.flat_map(|ps| ps.into_iter() .flat_map(|ps| {
.combinations(2) ps.iter()
.flat_map(|a| get_antinodes_p2(a[0], a[1], &map_size)) .combinations(2)
.collect::<Vec<_>>() .flat_map(|a| get_antinodes_p2(*a[0], *a[1], &map_size))
) .collect::<Vec<_>>()
})
.collect(); .collect();
antinodes.sort(); antinodes.sort();
antinodes.dedup(); antinodes.dedup();

View File

@@ -1,26 +1,110 @@
advent_of_code::solution!(9); advent_of_code::solution!(9);
use std::collections::VecDeque;
const MEMORY_SIZE: usize = 100_000; const MEMORY_SIZE: usize = 100_000;
#[derive(Debug, Clone)]
struct Blocks {
file_id: Option<u16>,
size: u8,
}
impl Blocks {
fn get_checksum(&self, offset: u64) -> u64 {
if let Some(id) = self.file_id {
let mut chk: u64 = 0;
for x in 0..self.size {
chk += (offset + (x as u64)) * (id as u64);
}
chk
} else {
0
}
}
}
#[derive(Debug)] #[derive(Debug)]
struct MemoryP2 { struct MemoryP2 {
memory: VecDeque<Blocks>,
} }
impl MemoryP2 { impl MemoryP2 {
fn init(ds: Vec<u32>) -> Self { fn init(ds: Vec<u32>) -> Self {
todo!() let mut file_nb: u16 = 0;
let mut is_file = true;
let mut memory: VecDeque<Blocks> = VecDeque::new();
ds.into_iter().for_each(|bs| {
let file_id = if is_file {
let id = file_nb;
file_nb += 1;
is_file = false;
Some(id)
} else {
is_file = true;
None
};
if bs > 0 {
memory.push_back(Blocks {
file_id,
size: bs as u8,
});
}
});
Self { memory }
} }
fn fill_empty_blocks(&mut self) { fn fill_empty_blocks(&mut self) {
todo!() let mut new_list: VecDeque<Blocks> = VecDeque::new();
while !self.memory.is_empty() {
let mut cur = self.memory.pop_front().unwrap();
if cur.file_id.is_some() {
new_list.push_back(cur);
continue;
}
// try to find something fitting
let mut tmp: VecDeque<Blocks> = VecDeque::new();
let mut inserted = false;
while let Some(block) = self.memory.pop_back() {
if block.file_id.is_some() && block.size <= cur.size {
cur.size -= block.size;
let empty_size = block.size;
new_list.push_back(block);
inserted = true;
self.memory.push_back(Blocks {
file_id: None,
size: empty_size,
});
break;
} else {
tmp.push_front(block);
}
}
self.memory.extend(tmp);
if cur.size > 0 {
if inserted {
self.memory.push_front(cur);
} else {
new_list.push_back(cur);
}
}
}
self.memory = new_list;
} }
fn compute_checksum(&self) -> u64 { fn compute_checksum(&self) -> u64 {
todo!() let mut checksum: u64 = 0;
let mut offset = 0;
for block in &self.memory {
checksum += block.get_checksum(offset);
offset += block.size as u64;
}
checksum
} }
} }
#[derive(Debug)] #[derive(Debug)]
struct MemoryP1 { struct MemoryP1 {
memory: [Option<u16>; MEMORY_SIZE], memory: [Option<u16>; MEMORY_SIZE],
@@ -28,31 +112,25 @@ struct MemoryP1 {
impl MemoryP1 { impl MemoryP1 {
fn init(ds: Vec<u32>) -> Self { fn init(ds: Vec<u32>) -> Self {
let mut memory: [Option<u16>; 100_000] = [None; 100_000]; //[16; 100_000] = [0; 100_000]; let mut memory: [Option<u16>; 100_000] = [None; 100_000];
let mut offset: usize = 0; let mut offset: usize = 0;
let mut file_nb: u16 = 0; let mut file_nb: u16 = 0;
let mut is_file = true; let mut is_file = true;
ds ds.into_iter().for_each(|bs| match is_file {
.into_iter() true => {
.for_each(|bs| { for n in 0..bs {
match is_file { memory[offset + n as usize] = Some(file_nb);
true => {
for n in 0..bs {
memory[offset + n as usize] = Some(file_nb);
}
offset += bs as usize;
file_nb += 1;
is_file = false;
},
false => {
offset += bs as usize;
is_file = true;
}
} }
}); offset += bs as usize;
Self { file_nb += 1;
memory, is_file = false;
} }
false => {
offset += bs as usize;
is_file = true;
}
});
Self { memory }
} }
fn fill_empty_blocks(&mut self) { fn fill_empty_blocks(&mut self) {
@@ -70,12 +148,14 @@ impl MemoryP1 {
if back_cursor < front_cursor { if back_cursor < front_cursor {
finished = true; finished = true;
} }
if !finished && self.memory[back_cursor].is_some() && self.memory[front_cursor].is_none() { if !finished
&& self.memory[back_cursor].is_some()
&& self.memory[front_cursor].is_none()
{
self.memory[front_cursor] = self.memory[back_cursor]; self.memory[front_cursor] = self.memory[back_cursor];
self.memory[back_cursor] = None; self.memory[back_cursor] = None;
} }
} }
} }
fn compute_checksum(&self) -> u64 { fn compute_checksum(&self) -> u64 {
@@ -90,14 +170,14 @@ impl MemoryP1 {
} }
pub fn part_one(input: &str) -> Option<u64> { pub fn part_one(input: &str) -> Option<u64> {
let nbs: Vec<_> = input.chars().flat_map(|c|c.to_digit(10u32)).collect(); let nbs: Vec<_> = input.chars().flat_map(|c| c.to_digit(10u32)).collect();
let mut mem = MemoryP1::init(nbs); let mut mem = MemoryP1::init(nbs);
mem.fill_empty_blocks(); mem.fill_empty_blocks();
Some(mem.compute_checksum()) Some(mem.compute_checksum())
} }
pub fn part_two(input: &str) -> Option<u64> { pub fn part_two(input: &str) -> Option<u64> {
let nbs: Vec<_> = input.chars().flat_map(|c|c.to_digit(10u32)).collect(); let nbs: Vec<_> = input.chars().flat_map(|c| c.to_digit(10u32)).collect();
let mut mem = MemoryP2::init(nbs); let mut mem = MemoryP2::init(nbs);
mem.fill_empty_blocks(); mem.fill_empty_blocks();
Some(mem.compute_checksum()) Some(mem.compute_checksum())
@@ -116,6 +196,6 @@ mod tests {
#[test] #[test]
fn test_part_two() { fn test_part_two() {
let result = part_two(&advent_of_code::template::read_file("examples", DAY)); let result = part_two(&advent_of_code::template::read_file("examples", DAY));
assert_eq!(result, None); assert_eq!(result, Some(2858));
} }
} }