aoc-2021-rust

git clone https://git.sinitax.com/sinitax/aoc-2021-rust
Log | Files | Refs | README | sfeed.txt

commit 67a315a49eb5f6a607c23a7c2af5116914ad1bc1
parent 2fea9d7c7acdc304f11ebee3fa89362763607388
Author: Louis Burda <quent.burda@gmail.com>
Date:   Wed, 19 Apr 2023 15:22:17 +0200

[Day 23] Replace vec of pos with const size array

Diffstat:
Msrc/23/src/main.rs | 60++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 34 insertions(+), 26 deletions(-)

diff --git a/src/23/src/main.rs b/src/23/src/main.rs @@ -15,7 +15,7 @@ struct Pos { #[derive(PartialEq,Eq,Hash,Clone)] struct DJKState { - agents: [Vec<Pos>; 4] + agents: [[Pos; 4]; 4] } #[derive(Clone)] @@ -30,8 +30,10 @@ struct MapConfig { hallway: Range, slot_x: Range, slot_y: Range, + agent_cnt: usize, + type_cnt: usize, initial: DJKState, - fixed: [Vec<bool>; 4] + fixed: [[bool; 4]; 4] } static AGENT_SYMBS: [char; 4] = ['A', 'B', 'C', 'D']; @@ -57,7 +59,7 @@ impl DJKState { return self.agents[at][ai].y == cfg.hallway_y; } - fn print(&self, map: &HashMap<Pos,char>) { + fn print(&self, cfg: &MapConfig, map: &HashMap<Pos,char>) { let maxx = map.iter().map(|(p,_)| p.x).max().unwrap(); let maxy = map.iter().map(|(p,_)| p.y).max().unwrap(); for y in 0..maxy+1 { @@ -67,9 +69,9 @@ impl DJKState { let mut nc = ' '; if c.is_some() { nc = if *c.unwrap() == '#' { '#' } else { ' ' }; - for t in 0..4 { - for agent in &self.agents[t] { - if &p == agent { + for t in 0..cfg.type_cnt { + for i in 0..cfg.agent_cnt { + if p == self.agents[t][i] { nc = AGENT_SYMBS[t]; break; } @@ -101,8 +103,10 @@ fn parse_input(input: &str) -> (HashMap<Pos,char>, MapConfig) { hallway: Range { min: 1, max: 12 }, slot_x: Range { min: 3, max: 10 }, slot_y: Range { min: 1, max: y - 1 }, - initial: DJKState { agents: [ vec![], vec![], vec![], vec![] ] }, - fixed: [ vec![], vec![], vec![], vec![] ], + agent_cnt: (y - 3) as usize, + type_cnt: 4, + initial: DJKState { agents: [ [Pos { x: 0, y: 0 }; 4]; 4 ] }, + fixed: [ [false; 4]; 4 ], }; return (map, cfg); @@ -110,8 +114,9 @@ fn parse_input(input: &str) -> (HashMap<Pos,char>, MapConfig) { fn heuristic(cfg: &MapConfig, state: &DJKState) -> isize { let mut cost: isize = 0; - for t in 0..4 { - for agent in &state.agents[t] { + for t in 0..cfg.type_cnt { + for i in 0..cfg.agent_cnt { + let agent = state.agents[t][i]; let slot_x = idx2slot!(cfg, t); if agent.x != slot_x { cost += agent.dist_to(&Pos { x: slot_x, y: cfg.hallway_y }); @@ -129,10 +134,11 @@ fn try_move_out(map: &HashMap<Pos,char>, cfg: &MapConfig, let mut minx: isize = cfg.hallway.min; let mut maxx: isize = cfg.hallway.max; - for t in 0..4 { - for (i,agent) in state.agents[t].iter().enumerate() { + for t in 0..cfg.type_cnt { + for i in 0..cfg.agent_cnt { if t == at && i == ai { continue; } + let agent = state.agents[t][i]; if agent.x == cur.x && agent.y < cur.y { return; } if agent.y == cfg.hallway_y { @@ -161,7 +167,7 @@ fn try_move_out(map: &HashMap<Pos,char>, cfg: &MapConfig, if res.is_none() || *res.unwrap() > ncost_g { if aoc::get_debug() > 1 { aoc::debugln!("MOVE OUT {} {}", ncost_g, ncost_f); - nstate.print(&map); + nstate.print(cfg, map); aoc::debugln!(""); } @@ -177,10 +183,11 @@ fn try_move_in(map: &HashMap<Pos,char>, cfg: &MapConfig, state: &DJKState, cost: isize, at: usize, ai: usize) { let mut slot_free_y = cfg.slot_y.max-1; - for t in 0..4 { - for (i,agent) in state.agents[t].iter().enumerate() { + for t in 0..cfg.type_cnt { + for i in 0..cfg.agent_cnt { if t == at && i == ai { continue; } + let agent = state.agents[t][i]; if agent.y == cfg.hallway_y { /* another agent is in the way */ if agent.x > state.agents[at][ai].x { @@ -206,7 +213,7 @@ fn try_move_in(map: &HashMap<Pos,char>, cfg: &MapConfig, if res.is_none() || *res.unwrap() > ncost_g { if aoc::get_debug() > 1 { aoc::debugln!("MOVE IN {} {}", ncost_g, ncost_f); - nstate.print(map); + nstate.print(cfg, map); aoc::debugln!(""); } @@ -227,8 +234,8 @@ fn try_move(map: &HashMap<Pos,char>, cfg: &MapConfig, } return false; } else { - for t in 0..4 { - for i in 0..state.agents[t].len() { + for t in 0..cfg.type_cnt { + for i in 0..cfg.agent_cnt { if !state.moved_in(t, i, cfg) { return false; } } } @@ -240,18 +247,19 @@ fn organize(map: &HashMap<Pos,char>, cfg: &mut MapConfig) -> Option<usize> { let mut active: PriorityQueue<DJKState,isize> = PriorityQueue::with_capacity(100000); let mut costmap: HashMap<DJKState,isize> = HashMap::with_capacity(100000); + let mut counts: [usize; 4] = [0; 4]; for (p,c) in map.iter() { let idx = AGENT_SYMBS.iter().position(|sc| sc == c); if idx.is_some() { - if p.x == idx2slot!(cfg, idx.unwrap()) { + let t = idx.unwrap(); + if p.x == idx2slot!(cfg, t) { let fixed = (p.y+1..cfg.slot_y.max) .all(|y| map.get(&Pos { x: p.x, y }).unwrap() == c); aoc::debugln!("{} {} {} -> {}", p.x, p.y, c, fixed); - cfg.fixed[idx.unwrap()].push(fixed); - } else { - cfg.fixed[idx.unwrap()].push(false); + cfg.fixed[t][counts[t]] = fixed; } - cfg.initial.agents[idx.unwrap()].push(p.clone()); + cfg.initial.agents[t][counts[t]] = p.clone(); + counts[t] += 1; } } active.push(cfg.initial.clone(), -heuristic(&cfg, &cfg.initial)); @@ -267,13 +275,13 @@ fn organize(map: &HashMap<Pos,char>, cfg: &mut MapConfig) -> Option<usize> { if aoc::get_debug() > 1 { aoc::debugln!("-----------------"); aoc::debugln!("LEN {}", active.len()); - state.print(&map); + state.print(&cfg, &map); aoc::debugln!(""); } aoc::debugln!("{}", cost_g); - for t in 0..4 { - for i in 0..state.agents[t].len() { + for t in 0..cfg.type_cnt { + for i in 0..cfg.agent_cnt { let done = try_move(&map, &cfg, &mut costmap, &mut active, &state, cost_g, t, i); if done {