mirror of
https://github.com/mx42/aoc2024.rs.git
synced 2026-01-14 05:49:53 +01:00
feat: day 9 p2 + fmt / clippy
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
140
src/bin/09.rs
140
src/bin/09.rs
@@ -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) {
|
||||||
@@ -71,11 +149,13 @@ impl MemoryP1 {
|
|||||||
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user