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:
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 {