Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use core::panicking::panic;
- use std::fmt::{Debug, Display, Formatter};
- use itertools::Itertools;
- use pathfinding::prelude::{dijkstra, astar};
- use crate::day23::Amphipods::{Amber, Bronze, Copper, Desert};
- use crate::day23::IsOccupied::{No, Yes};
- #[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
- struct Space {
- hallway: [IsOccupied; 11],
- room1: [IsOccupied; 2],
- //0th index is the top of the room
- room2: [IsOccupied; 2],
- room3: [IsOccupied; 2],
- room4: [IsOccupied; 2],
- }
- #[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
- struct Space2 {
- hallway: [IsOccupied; 11],
- //0th index is the top of the room
- rooms: [[IsOccupied; 4]; 4],
- }
- #[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
- enum Amphipods {
- Amber,
- Bronze,
- Copper,
- Desert,
- }
- #[derive(Debug, Eq, PartialEq, Hash, Clone, Copy)]
- enum IsOccupied {
- Yes(Amphipods),
- No,
- }
- impl Display for IsOccupied {
- fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
- match self
- {
- Yes(Amber) => {write!(f, "A")},
- Yes(Bronze) => {write!(f, "B")},
- Yes(Copper) => {write!(f, "C")},
- Yes(Desert) => {write!(f, "D")},
- No => {write!(f, ".")}
- }
- }
- }
- impl Display for Space{
- fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
- let hallway = self.hallway;
- let room1 = self.room1;
- let room2 = self.room2;
- let room3 = self.room3;
- let room4 = self.room4;
- write!(f, "#############\n#{}{}{}{}{}{}{}{}{}{}{}#\n###{}#{}#{}#{}###\n #{}#{}#{}#{}#\n #########",
- hallway[0], hallway[0], hallway[0], hallway[0], hallway[0], hallway[0], hallway[0], hallway[0], hallway[0], hallway[0], hallway[0],
- room1[0], room2[0], room3[0], room4[0],
- room1[1], room2[1], room3[1], room4[1],
- )
- }
- }
- const AMBER_MOVE_COST: u16 = 1;
- const BRONZE_MOVE_COST: u16 = 10;
- const COPPER_MOVE_COST: u16 = 100;
- const DESERT_MOVE_COST: u16 = 1000;
- fn charToAmphipods(c: char) -> IsOccupied
- {
- match c {
- 'A' => { Yes(Amber) }
- 'B' => { Yes(Bronze) }
- 'C' => { Yes(Copper) }
- 'D' => { Yes(Desert) }
- _ => { panic!() }
- }
- }
- pub fn day23_2()
- {
- let input = include_str!("../temp23").lines().skip(2)
- .flat_map(|x| x.trim().split('#').filter(|&x| !x.is_empty()).map(|x| x.chars().at_most_one().unwrap().unwrap())).collect_vec();
- let initialState = Space2 {
- hallway: [No, No, No, No, No, No, No, No, No, No, No, ],
- rooms: [[charToAmphipods(input[0]), Yes(Desert), Yes(Desert), charToAmphipods(input[4])],
- [charToAmphipods(input[1]), Yes(Copper), Yes(Bronze), charToAmphipods(input[5])],
- [charToAmphipods(input[2]), Yes(Bronze), Yes(Amber), charToAmphipods(input[6])],
- [charToAmphipods(input[3]), Yes(Amber), Yes(Copper), charToAmphipods(input[7])]],
- };
- let finState = Space2 {
- hallway: [No, No, No, No, No, No, No, No, No, No, No, ],
- rooms: [[Yes(Amber), Yes(Amber), Yes(Amber), Yes(Amber)],
- [Yes(Bronze), Yes(Bronze), Yes(Bronze), Yes(Bronze)],
- [Yes(Copper), Yes(Copper), Yes(Copper), Yes(Copper)],
- [Yes(Desert), Yes(Desert), Yes(Desert), Yes(Desert)]],
- };
- let res = astar(&initialState, |x| {
- let mut ret: Vec<_> = Vec::new();
- for (pos, Thing) in x.hallway.iter().enumerate()
- {
- //IF anything is in the hallway that can move to its final spot
- match Thing {
- Yes(a) => {
- let home = amph_to_room_index(a);
- let room_num = amph_to_room(a);
- if x.rooms[home][0] == No {
- let clear = routeIsClear2(x, (0, pos), (room_num, 0));
- let occupier = Yes(*a);
- if clear.0 {
- if x.rooms[home][1] == occupier && x.rooms[home][2] == occupier && x.rooms[home][3] == occupier {
- // can move into the top spot
- let mut new_space = x.clone();
- new_space.hallway[pos] = No;
- new_space.rooms[home][0] = occupier;
- ret.push((new_space, clear.1 * amph_to_cost(a)));
- } else if x.rooms[home][1] == No && x.rooms[home][2] == occupier && x.rooms[home][3] == occupier {
- //can move into the second spot
- let mut new_space = x.clone();
- new_space.hallway[pos] = No;
- new_space.rooms[home][1] = occupier;
- ret.push((new_space, (clear.1 + 1) * amph_to_cost(a)));
- } else if x.rooms[home][1] == No && x.rooms[home][2] == No && x.rooms[home][3] == occupier {
- //can move into the third spot
- let mut new_space = x.clone();
- new_space.hallway[pos] = No;
- new_space.rooms[home][2] = occupier;
- ret.push((new_space, (clear.1 + 2) * amph_to_cost(a)));
- } else if x.rooms[home][1] == No && x.rooms[home][2] == No && x.rooms[home][3] == No {
- //can move into the fourth spot
- let mut new_space = x.clone();
- new_space.hallway[pos] = No;
- new_space.rooms[home][3] = occupier;
- ret.push((new_space, (clear.1 + 3) * amph_to_cost(a)));
- }
- }
- }
- }
- No => {}
- }
- }
- //if anything is in a top row or anything is in an unobstructed bottom row it can move to the hallway if route is clear
- for (roomIndex, room) in x.rooms.iter().enumerate() {
- let belongs_to = Yes(room_index_to_amph(roomIndex));
- //check top row moves
- match room[0] {
- Yes(a) => {
- if (room[1] != belongs_to || room[2] != belongs_to || room[3] != belongs_to) || room[0] != belongs_to
- {
- for (pos, &thing) in x.hallway.iter().enumerate()
- {
- if pos == 2 || pos == 4 || pos == 6 || pos == 8 || thing != No { continue; } //invalid moves, cant move to those positions, cant move if someone is there
- let clear = routeIsClear2(x, (roomIndex + 1, 0), (0, pos));
- if clear.0 {
- let mut new_space = x.clone();
- new_space.hallway[pos] = Yes(a);
- new_space.rooms[roomIndex][0] = No;
- ret.push((new_space, clear.1 * amph_to_cost(&a)));
- }
- }
- }
- }
- No => {}
- }
- //check second row moves
- match room[1] {
- Yes(a) => {
- if (room[2] != belongs_to || room[3] != belongs_to) || room[1] != belongs_to
- {
- for (pos, &thing) in x.hallway.iter().enumerate()
- {
- if pos == 2 || pos == 4 || pos == 6 || pos == 8 || thing != No { continue; } //invalid moves, cant move to those positions, cant move if someone is there
- let clear = routeIsClear2(x, (roomIndex + 1, 1), (0, pos));
- if clear.0 {
- let mut new_space = x.clone();
- new_space.hallway[pos] = Yes(a);
- new_space.rooms[roomIndex][1] = No;
- ret.push((new_space, clear.1 * amph_to_cost(&a)));
- }
- }
- }
- }
- No => {}
- }
- //check third row moves
- match room[2] {
- Yes(a) => {
- if (room[3] != belongs_to) || room[2] != belongs_to
- {
- for (pos, &thing) in x.hallway.iter().enumerate()
- {
- if pos == 2 || pos == 4 || pos == 6 || pos == 8 || thing != No { continue; } //invalid moves, cant move to those positions, cant move if someone is there
- let clear = routeIsClear2(x, (roomIndex + 1, 1), (0, pos));
- if clear.0 && room[1] == No {
- let mut new_space = x.clone();
- new_space.hallway[pos] = Yes(a);
- new_space.rooms[roomIndex][2] = No;
- ret.push((new_space, (clear.1 + 1) * amph_to_cost(&a)));
- }
- }
- }
- }
- No => {}
- }
- //check fourth row moves
- match room[3] {
- Yes(a) => {
- if room[3] != belongs_to
- {
- for (pos, &thing) in x.hallway.iter().enumerate()
- {
- if pos == 2 || pos == 4 || pos == 6 || pos == 8 || thing != No { continue; } //invalid moves, cant move to those positions, cant move if someone is there
- let clear = routeIsClear2(x, (roomIndex + 1, 1), (0, pos));
- if clear.0 && room[1] == No && room[2] == No {
- let mut new_space = x.clone();
- new_space.hallway[pos] = Yes(a);
- new_space.rooms[roomIndex][3] = No;
- ret.push((new_space, (clear.1 + 2) * amph_to_cost(&a)));
- }
- }
- }
- }
- No => {}
- }
- }
- ret
- }
- , |x| {
- let mut ret = 0;
- //commented out heuristic because it made runtime go from 150ms to 175ms
- /*//min add all the hallway moves
- for (pos, Thing) in x.hallway.iter().enumerate() {
- match Thing {
- Yes(a) => { ret += routeIsClear2(x, (0, pos), (amph_to_room(a), 0)).1 * amph_to_cost(a) }
- No => {}
- }
- }
- //cost of moving to the correct room, or into and out of the room if you are stacked badly
- for (roomIndex, room) in x.rooms.iter().enumerate() {
- let belongs_to = Yes(room_index_to_amph(roomIndex));
- for (row_idx, &row) in room.iter().enumerate() {
- let mut is_not_good_below = false;
- for i in row_idx+1..4 {
- is_not_good_below |= room[i] != belongs_to;
- }
- match row {
- Yes(a) => {
- if is_not_good_below || row != belongs_to
- {
- let temp_loc = match roomIndex {
- 0 => {3},
- 1 => {if a == Amber { 3 } else { 5 }},
- 2 => {if a == Desert { 7 } else { 5 }},
- 3 => {7}
- _ => {unreachable!()}
- };
- let hallwayLoc = (0, temp_loc);
- let finishLoc = (amph_to_room(&a), 0);
- let spaces_to_move = routeIsClear2(x, (roomIndex + 1, 0), hallwayLoc).1 + routeIsClear2(x, hallwayLoc, finishLoc).1 + row_idx as u16;
- ret += (spaces_to_move * amph_to_cost(&a))
- }
- }
- No => {}
- }
- }
- }*/
- ret
- }, |x| x.eq(&finState)).unwrap();
- println!("ANS {}", res.1);
- return;
- }
- pub fn day23_1A_STAR() {
- let input = include_str!("../temp23").lines().skip(2)
- .flat_map(|x| x.trim().split('#').filter(|&x| !x.is_empty()).map(|x| x.chars().at_most_one().unwrap().unwrap())).collect_vec();
- let initialState = Space {
- hallway: [No, No, No, No, No, No, No, No, No, No, No, ],
- room1: [charToAmphipods(input[0]), charToAmphipods(input[4])],
- room2: [charToAmphipods(input[1]), charToAmphipods(input[5])],
- room3: [charToAmphipods(input[2]), charToAmphipods(input[6])],
- room4: [charToAmphipods(input[3]), charToAmphipods(input[7])],
- };
- //dbg!(initialState);
- let finState = Space {
- hallway: [No, No, No, No, No, No, No, No, No, No, No, ],
- room1: [Yes(Amber), Yes(Amber)],
- room2: [Yes(Bronze), Yes(Bronze)],
- room3: [Yes(Copper), Yes(Copper)],
- room4: [Yes(Desert), Yes(Desert)],
- };
- let res = astar(&initialState, |x| {
- let mut ret: Vec<_> = Vec::new();
- //println!("SEARCHING THIS SPACE: ");
- //println!("{}", x);
- //IF anything is in the hallway that can move to its final spot
- for (pos, Thing) in x.hallway.iter().enumerate()
- {
- match Thing {
- Yes(Amber) => {
- if x.room1[0] == No {
- let clear = routeIsClear(x, (0, pos), (1, 0));
- if clear.0 && x.room1[1] == Yes(Amber)
- {
- //can move into top spot
- let mut new_space = x.clone();
- new_space.hallway[pos] = No;
- new_space.room1[0] = Yes(Amber);
- ret.push((new_space, clear.1 * AMBER_MOVE_COST));
- //println!("FOUND MOVE TYPE 1: ");
- //println!("{}", &new_space);
- } else if x.room1[1] == No && clear.0 {
- //can move into bottom spot
- let mut new_space = x.clone();
- new_space.hallway[pos] = No;
- new_space.room1[1] = Yes(Amber);
- ret.push((new_space, (clear.1 + 1) * AMBER_MOVE_COST));
- //println!("FOUND MOVE TYPE 2: ");
- //println!("{}", new_space);
- }
- }
- }
- Yes(Bronze) => {
- if x.room2[0] == No {
- let clear = routeIsClear(x, (0, pos), (2, 0));
- if clear.0 && x.room2[1] == Yes(Bronze)
- {
- //can move into top spot
- let mut new_space = x.clone();
- new_space.hallway[pos] = No;
- new_space.room2[0] = Yes(Bronze);
- ret.push((new_space, clear.1 * BRONZE_MOVE_COST));
- //println!("FOUND MOVE TYPE 3: ");
- //println!("{}", new_space);
- } else if x.room2[1] == No && clear.0 {
- //can move into bottom spot
- let mut new_space = x.clone();
- new_space.hallway[pos] = No;
- new_space.room2[1] = Yes(Bronze);
- ret.push((new_space, (clear.1 + 1) * BRONZE_MOVE_COST));
- //println!("FOUND MOVE TYPE 4: ");
- //println!("{}", new_space);
- }
- }
- }
- Yes(Copper) => {
- if x.room3[0] == No {
- let clear = routeIsClear(x, (0, pos), (3, 0));
- if clear.0 && x.room3[1] == Yes(Copper)
- {
- //can move into top spot
- let mut new_space = x.clone();
- new_space.hallway[pos] = No;
- new_space.room3[0] = Yes(Copper);
- ret.push((new_space, clear.1 * COPPER_MOVE_COST));
- //println!("FOUND MOVE TYPE 5: ");
- //println!("{}", new_space);
- } else if x.room3[1] == No && clear.0 {
- //can move into bottom spot
- let mut new_space = x.clone();
- new_space.hallway[pos] = No;
- new_space.room3[1] = Yes(Copper);
- ret.push((new_space, (clear.1 + 1) * COPPER_MOVE_COST));
- //println!("FOUND MOVE TYPE 6: ");
- //println!("{}", new_space);
- }
- }
- }
- Yes(Desert) => {
- if x.room4[0] == No {
- let clear = routeIsClear(x, (0, pos), (4, 0));
- if clear.0 && x.room4[1] == Yes(Desert)
- {
- //can move into top spot
- let mut new_space = x.clone();
- new_space.hallway[pos] = No;
- new_space.room4[0] = Yes(Desert);
- ret.push((new_space, clear.1 * DESERT_MOVE_COST));
- //println!("FOUND MOVE TYPE 7: ");
- //println!("{}", new_space);
- } else if x.room4[1] == No && clear.0 {
- //can move into bottom spot
- let mut new_space = x.clone();
- new_space.hallway[pos] = No;
- new_space.room4[1] = Yes(Desert);
- ret.push((new_space, (clear.1 + 1) * DESERT_MOVE_COST));
- //println!("FOUND MOVE TYPE 8: ");
- //println!("{}", new_space);
- }
- }
- }
- No => { continue; }
- }
- }
- //if anything is in a top row or anything is in an unobstructed bottom row it can move to the hallway if route is clear
- //check bottom row moves
- match x.room1[1] {
- Yes(Amber) => {}
- Yes(a) => {
- for (pos, &thing) in x.hallway.iter().enumerate() {
- if pos == 2 || pos == 4 || pos == 6 || pos == 8 { continue; }
- if thing == No {
- let clear = routeIsClear(x, (1, 1), (0, pos));
- if clear.0 {
- let mut new_space = x.clone();
- new_space.hallway[pos] = Yes(a);
- new_space.room1[1] = No;
- ret.push((new_space, clear.1 * amph_to_cost(&a)));
- //println!("FOUND MOVE TYPE 9: ");
- //println!("{}", new_space);
- }
- }
- }
- }
- No => {}
- }
- match x.room2[1] {
- Yes(Bronze) => {}
- Yes(a) => {
- for (pos, &thing) in x.hallway.iter().enumerate() {
- if pos == 2 || pos == 4 || pos == 6 || pos == 8 { continue; }
- if thing == No {
- let clear = routeIsClear(x, (2, 1), (0, pos));
- if clear.0 {
- let mut new_space = x.clone();
- new_space.hallway[pos] = Yes(a);
- new_space.room2[1] = No;
- ret.push((new_space, clear.1 * amph_to_cost(&a)));
- //println!("FOUND MOVE TYPE 10: ");
- //println!("{}", new_space);
- }
- }
- }
- }
- No => {}
- }
- match x.room3[1] {
- Yes(Copper) => {}
- Yes(a) => {
- for (pos, &thing) in x.hallway.iter().enumerate() {
- if pos == 2 || pos == 4 || pos == 6 || pos == 8 { continue; }
- if thing == No {
- let clear = routeIsClear(x, (3, 1), (0, pos));
- if clear.0 {
- let mut new_space = x.clone();
- new_space.hallway[pos] = Yes(a);
- new_space.room3[1] = No;
- ret.push((new_space, clear.1 * amph_to_cost(&a)));
- //println!("FOUND MOVE TYPE 11: ");
- //println!("{}", new_space);
- }
- }
- }
- }
- No => {}
- }
- match x.room4[1] {
- Yes(Desert) => {}
- Yes(a) => {
- for (pos, &thing) in x.hallway.iter().enumerate() {
- if pos == 2 || pos == 4 || pos == 6 || pos == 8 { continue; }
- if thing == No {
- let clear = routeIsClear(x, (4, 1), (0, pos));
- if clear.0 {
- let mut new_space = x.clone();
- new_space.hallway[pos] = Yes(a);
- new_space.room4[1] = No;
- ret.push((new_space, clear.1 * amph_to_cost(&a)));
- //println!("FOUND MOVE TYPE 12: ");
- //println!("{}", new_space);
- }
- }
- }
- }
- No => {}
- }
- // check top rooms for moves
- match x.room1[0] {
- Yes(a) => {
- if x.room1[1] != Yes(Amber) || (x.room1[1] == Yes(Amber) && Yes(a) != Yes(Amber))
- {
- for (pos, &thing) in x.hallway.iter().enumerate() {
- if pos == 2 || pos == 4 || pos == 6 || pos == 8 { continue; }
- if thing == No {
- let clear = routeIsClear(x, (1, 0), (0, pos));
- if clear.0 {
- let mut new_space = x.clone();
- new_space.hallway[pos] = Yes(a);
- new_space.room1[0] = No;
- ret.push((new_space, clear.1 * amph_to_cost(&a)));
- //println!("FOUND MOVE TYPE 13: ");
- //println!("{}", new_space);
- }
- }
- }
- }
- }
- No => {}
- }
- match x.room2[0] {
- Yes(a) => {
- if x.room2[1] != Yes(Bronze) || (x.room2[1] == Yes(Bronze) && Yes(a) != Yes(Bronze))
- {
- for (pos, &thing) in x.hallway.iter().enumerate() {
- if pos == 2 || pos == 4 || pos == 6 || pos == 8 { continue; }
- if thing == No {
- let clear = routeIsClear(x, (2, 0), (0, pos));
- if clear.0 {
- let mut new_space = x.clone();
- new_space.hallway[pos] = Yes(a);
- new_space.room2[0] = No;
- ret.push((new_space, clear.1 * amph_to_cost(&a)));
- //println!("FOUND MOVE TYPE 14: ");
- //println!("{}", new_space);
- }
- }
- }
- }
- }
- No => {}
- }
- match x.room3[0] {
- Yes(a) => {
- if x.room3[1] != Yes(Copper) || (x.room3[1] == Yes(Copper) && Yes(a) != Yes(Copper))
- {
- for (pos, &thing) in x.hallway.iter().enumerate() {
- if pos == 2 || pos == 4 || pos == 6 || pos == 8 { continue; }
- if thing == No {
- let clear = routeIsClear(x, (3, 0), (0, pos));
- if clear.0 {
- let mut new_space = x.clone();
- new_space.hallway[pos] = Yes(a);
- new_space.room3[0] = No;
- ret.push((new_space, clear.1 * amph_to_cost(&a)));
- //println!("FOUND MOVE TYPE 15: ");
- //println!("{}", new_space);
- }
- }
- }
- }
- }
- No => {}
- }
- match x.room4[0] {
- Yes(a) => {
- if x.room4[1] != Yes(Desert) || (x.room4[1] == Yes(Desert) && Yes(a) != Yes(Desert))
- {
- for (pos, &thing) in x.hallway.iter().enumerate() {
- if pos == 2 || pos == 4 || pos == 6 || pos == 8 { continue; }
- if thing == No {
- let clear = routeIsClear(x, (4, 0), (0, pos));
- if clear.0 {
- let mut new_space = x.clone();
- new_space.hallway[pos] = Yes(a);
- new_space.room4[0] = No;
- ret.push((new_space, clear.1 * amph_to_cost(&a)));
- //println!("FOUND MOVE TYPE 16: ");
- //println!("{}", new_space);
- }
- }
- }
- }
- }
- No => {}
- }
- // we don't need room to room movement all has to go through a hallway anyway
- ret
- },
- |x| {
- let mut ret = 0;
- //min add all the hallway moves
- for (pos, Thing) in x.hallway.iter().enumerate() {
- match Thing {
- Yes(a) => {ret += routeIsClear(x, (0, pos), (amph_to_room(a), 0)).1 * amph_to_cost(a)}
- No => {}
- }
- }
- //add all the top moves
- match x.room1[0] {
- Yes(a) => {
- if x.room1[1] != Yes(Amber) || (x.room1[1] == Yes(Amber) && Yes(a) != Yes(Amber))
- {
- let hallwayLoc = (0,3);
- let finishLoc = (amph_to_room(&a), 0);
- let spaces_to_move = routeIsClear(x, (1,0), hallwayLoc).1 + routeIsClear(x, hallwayLoc,finishLoc).1;
- ret += spaces_to_move * amph_to_cost(&a)
- }
- }
- No => {}
- }
- match x.room2[0] {
- Yes(a) => {
- if x.room2[1] != Yes(Bronze) || (x.room2[1] == Yes(Bronze) && Yes(a) != Yes(Bronze))
- {
- let hallwayLoc = (0,if a == Amber { 3 } else { 5 } );
- let finishLoc = (amph_to_room(&a), 0);
- let spaces_to_move = routeIsClear(x, (2,0), hallwayLoc).1 + routeIsClear(x, hallwayLoc,finishLoc).1;
- ret += spaces_to_move * amph_to_cost(&a)
- }
- }
- No => {}
- }
- match x.room3[0] {
- Yes(a) => {
- if x.room3[1] != Yes(Copper) || (x.room3[1] == Yes(Copper) && Yes(a) != Yes(Copper))
- {
- let hallwayLoc = (0,if a == Desert { 7 } else { 5 } );
- let finishLoc = (amph_to_room(&a), 0);
- let spaces_to_move = routeIsClear(x, (3,0), hallwayLoc).1 + routeIsClear(x, hallwayLoc,finishLoc).1;
- ret += spaces_to_move * amph_to_cost(&a)
- }
- }
- No => {}
- }
- match x.room4[0] {
- Yes(a) => {
- if x.room4[1] != Yes(Desert) || (x.room4[1] == Yes(Desert) && Yes(a) != Yes(Desert))
- {
- let hallwayLoc = (0,7);
- let finishLoc = (amph_to_room(&a), 0);
- let spaces_to_move = routeIsClear(x, (4,0), hallwayLoc).1 + routeIsClear(x, hallwayLoc,finishLoc).1;
- ret += spaces_to_move * amph_to_cost(&a)
- }
- }
- No => {}
- }
- //add all the bottom moves
- match x.room1[1] {
- Yes(Amber) => {}
- Yes(a) => {
- let hallwayLoc = (0,3);
- let finishLoc = (amph_to_room(&a), 0);
- let spaces_to_move = routeIsClear(x, (1,1), hallwayLoc).1 + routeIsClear(x, hallwayLoc,finishLoc).1;
- ret += spaces_to_move * amph_to_cost(&a)
- }
- No => {}
- }
- match x.room2[1] {
- Yes(Bronze) => {}
- Yes(a) => {
- let hallwayLoc = (0,if a == Amber { 3 } else { 5 } );
- let finishLoc = (amph_to_room(&a), 0);
- let spaces_to_move = routeIsClear(x, (2,1), hallwayLoc).1 + routeIsClear(x, hallwayLoc,finishLoc).1;
- ret += spaces_to_move * amph_to_cost(&a)
- }
- No => {}
- }
- match x.room3[1] {
- Yes(Copper) => {}
- Yes(a) => {
- let hallwayLoc = (0,if a == Desert { 7 } else { 5 } );
- let finishLoc = (amph_to_room(&a), 0);
- let spaces_to_move = routeIsClear(x, (3,1), hallwayLoc).1 + routeIsClear(x, hallwayLoc,finishLoc).1;
- ret += spaces_to_move * amph_to_cost(&a)
- }
- No => {}
- }
- match x.room4[1] {
- Yes(Desert) => {}
- Yes(a) => {
- let hallwayLoc = (0,3);
- let finishLoc = (amph_to_room(&a), 0);
- let spaces_to_move = routeIsClear(x, (4,1), hallwayLoc).1 + routeIsClear(x, hallwayLoc,finishLoc).1;
- ret += spaces_to_move * amph_to_cost(&a)
- }
- No => {}
- }
- ret
- }
- ,
- |x| x.eq(&finState)).unwrap();
- println!("ANS {}", res.1);
- return;
- }
- fn amph_to_cost(a: &Amphipods) -> u16
- {
- match a {
- Amber => {AMBER_MOVE_COST}
- Bronze => {BRONZE_MOVE_COST}
- Copper => {COPPER_MOVE_COST}
- Desert => {DESERT_MOVE_COST}
- }
- }
- fn amph_to_room(a: &Amphipods) -> usize
- {
- match a {
- Amber => {1}
- Bronze => {2}
- Copper => {3}
- Desert => {4}
- }
- }
- fn amph_to_room_index(a: &Amphipods) -> usize
- {
- match a {
- Amber => {0}
- Bronze => {1}
- Copper => {2}
- Desert => {3}
- }
- }
- fn room_index_to_amph(index: usize) -> Amphipods
- {
- match index {
- 0 => {Amber}
- 1 => {Bronze}
- 2 => {Copper}
- 3 => {Desert}
- _ => {unreachable!()}
- }
- }
- ///will check if route from (start, end) (exclusive on both) so you must check if the end is clear,
- /// is clear of obstacles, and the amount of spaces moved
- /// start end are room and position where room 0 is the hallway.
- /// (0, x) means in hallway (1-4, x) means in rooms
- fn routeIsClear(space: &Space, start: (usize, usize), end: (usize, usize)) -> (bool, u16) {
- let mut ret = (false, 0);
- match (start, end) {
- //hallway to rooms
- //start 0,0
- ((0, 0), (1, 0)) => {
- if space.hallway[1] == No
- {
- ret.0 = true;
- }
- ret.1 = 3;
- }
- ((0, 0), (1, 1)) => {
- if space.hallway[1] == No &&
- space.room1[0] == No {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 0), (2, 0)) => {
- if space.hallway[1] == No && space.hallway[3] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- ((0, 0), (2, 1)) => {
- if space.hallway[1] == No && space.hallway[3] == No
- && space.room2[1] == No {
- ret.0 = true
- }
- ret.1 = 6;
- }
- ((0, 0), (3, 0)) => {
- if space.hallway[1] == No && space.hallway[3] == No && space.hallway[5] == No {
- ret.0 = true
- }
- ret.1 = 7;
- }
- ((0, 0), (3, 1)) => {
- if space.hallway[1] == No && space.hallway[3] == No && space.hallway[5] == No &&
- space.room3[0] == No {
- ret.0 = true
- }
- ret.1 = 8;
- }
- ((0, 0), (4, 0)) => {
- if space.hallway[1] == No && space.hallway[3] == No && space.hallway[5] == No && space.hallway[7] == No {
- ret.0 = true
- }
- ret.1 = 7;
- }
- ((0, 0), (4, 1)) => {
- if space.hallway[1] == No && space.hallway[3] == No && space.hallway[5] == No && space.hallway[7] == No &&
- space.room4[0] == No {
- ret.0 = true
- }
- ret.1 = 8;
- }
- //start 0,1
- ((0, 1), (1, 0)) => {
- ret = (true, 2)
- }
- ((0, 1), (1, 1)) => {
- if
- space.room1[0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 1), (2, 0)) => {
- if space.hallway[3] == No {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 1), (2, 1)) => {
- if space.hallway[3] == No &&
- space.room2[0] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- ((0, 1), (3, 0)) => {
- if space.hallway[3] == No && space.hallway[5] == No {
- ret.0 = true
- }
- ret.1 = 6;
- }
- ((0, 1), (3, 1)) => {
- if space.hallway[3] == No && space.hallway[5] == No &&
- space.room3[0] == No {
- ret.0 = true
- }
- ret.1 = 7;
- }
- ((0, 1), (4, 0)) => {
- if space.hallway[3] == No && space.hallway[5] == No && space.hallway[7] == No {
- ret.0 = true
- }
- ret.1 = 8;
- }
- ((0, 1), (4, 1)) => {
- if space.hallway[3] == No && space.hallway[5] == No && space.hallway[7] == No &&
- space.room4[0] == No {
- ret.0 = true
- }
- ret.1 = 9;
- }
- //start 0,3
- ((0, 3), (1, 0)) => {
- ret = (true, 2)
- }
- ((0, 3), (1, 1)) => {
- if
- space.room1[0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 3), (2, 0)) => {
- ret = (true, 2)
- }
- ((0, 3), (2, 1)) => {
- if
- space.room2[0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 3), (3, 0)) => {
- if space.hallway[5] == No {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 3), (3, 1)) => {
- if space.hallway[5] == No &&
- space.room3[0] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- ((0, 3), (4, 0)) => {
- if space.hallway[5] == No && space.hallway[7] == No {
- ret.0 = true
- }
- ret.1 = 6;
- }
- ((0, 3), (4, 1)) => {
- if space.hallway[5] == No && space.hallway[7] == No &&
- space.room4[0] == No {
- ret.0 = true
- }
- ret.1 = 7;
- }
- //start 0,5
- ((0, 5), (1, 0)) => {
- if space.hallway[3] == No {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 5), (1, 1)) => {
- if space.hallway[3] == No &&
- space.room1[0] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- ((0, 5), (2, 0)) => {
- ret = (true, 2)
- }
- ((0, 5), (2, 1)) => {
- if
- space.room2[0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 5), (3, 0)) => {
- ret = (true, 2)
- }
- ((0, 5), (3, 1)) => {
- if
- space.room3[0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 5), (4, 0)) => {
- if space.hallway[7] == No
- {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 5), (4, 1)) => {
- if space.hallway[7] == No &&
- space.room4[0] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- //start 0,7
- ((0, 7), (1, 0)) => {
- if space.hallway[3] == No && space.hallway[5] == No {
- ret.0 = true
- }
- ret.1 = 6;
- }
- ((0, 7), (1, 1)) => {
- if space.hallway[3] == No && space.hallway[5] == No &&
- space.room1[0] == No {
- ret.0 = true
- }
- ret.1 = 7;
- }
- ((0, 7), (2, 0)) => {
- if space.hallway[5] == No {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 7), (2, 1)) => {
- if space.hallway[5] == No &&
- space.room2[0] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- ((0, 7), (3, 0)) => {
- ret = (true, 2)
- }
- ((0, 7), (3, 1)) => {
- if
- space.room3[0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 7), (4, 0)) => {
- ret = (true, 2)
- }
- ((0, 7), (4, 1)) => {
- if
- space.room4[0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- //start 0,9
- ((0, 9), (1, 0)) => {
- if space.hallway[3] == No && space.hallway[5] == No && space.hallway[7] == No
- {
- ret.0 = true
- }
- ret.1 = 8;
- }
- ((0, 9), (1, 1)) => {
- if space.hallway[3] == No && space.hallway[5] == No && space.hallway[7] == No &&
- space.room1[0] == No {
- ret.0 = true
- }
- ret.1 = 9;
- }
- ((0, 9), (2, 0)) => {
- if space.hallway[5] == No && space.hallway[7] == No
- {
- ret.0 = true
- }
- ret.1 = 6;
- }
- ((0, 9), (2, 1)) => {
- if space.hallway[5] == No && space.hallway[7] == No &&
- space.room2[0] == No {
- ret.0 = true
- }
- ret.1 = 7;
- }
- ((0, 9), (3, 0)) => {
- if space.hallway[7] == No
- {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 9), (3, 1)) => {
- if space.hallway[7] == No &&
- space.room3[0] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- ((0, 9), (4, 0)) => {
- ret = (true, 2)
- }
- ((0, 9), (4, 1)) => {
- if
- space.room4[0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 10), a) => {
- let start09 = routeIsClear(space, (0, 9), a);
- ret = (start09.0 && space.hallway[9] == No, start09.1 + 1)
- }
- //room to hallway
- (a, b) => {
- //dbg!(a, b);
- ret = routeIsClear(space, b, a);
- }
- }
- ret
- }
- ///will check if route from (start, end) (exclusive on both) so you must check if the end is clear,
- /// is clear of obstacles, and the amount of spaces moved
- /// start end are room and position where room 0 is the hallway.
- /// (0, x) means in hallway (1-4, x) means in rooms
- fn routeIsClear2(space: &Space2, start: (usize, usize), end: (usize, usize)) -> (bool, u16) {
- let mut ret = (false, 0);
- //dbg!(start, end);
- match (start, end) {
- //hallway to rooms
- //start 0,0
- ((0, 0), (1, 0)) => {
- if space.hallway[1] == No
- {
- ret.0 = true;
- }
- ret.1 = 3;
- }
- ((0, 0), (1, 1)) => {
- if space.hallway[1] == No &&
- space.rooms[0][0] == No {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 0), (2, 0)) => {
- if space.hallway[1] == No && space.hallway[3] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- ((0, 0), (2, 1)) => {
- if space.hallway[1] == No && space.hallway[3] == No
- && space.rooms[1][1] == No {
- ret.0 = true
- }
- ret.1 = 6;
- }
- ((0, 0), (3, 0)) => {
- if space.hallway[1] == No && space.hallway[3] == No && space.hallway[5] == No {
- ret.0 = true
- }
- ret.1 = 7;
- }
- ((0, 0), (3, 1)) => {
- if space.hallway[1] == No && space.hallway[3] == No && space.hallway[5] == No &&
- space.rooms[2][0] == No {
- ret.0 = true
- }
- ret.1 = 8;
- }
- ((0, 0), (4, 0)) => {
- if space.hallway[1] == No && space.hallway[3] == No && space.hallway[5] == No && space.hallway[7] == No {
- ret.0 = true
- }
- ret.1 = 7;
- }
- ((0, 0), (4, 1)) => {
- if space.hallway[1] == No && space.hallway[3] == No && space.hallway[5] == No && space.hallway[7] == No &&
- space.rooms[3][0] == No {
- ret.0 = true
- }
- ret.1 = 8;
- }
- //start 0,1
- ((0, 1), (1, 0)) => {
- ret = (true, 2)
- }
- ((0, 1), (1, 1)) => {
- if
- space.rooms[0][0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 1), (2, 0)) => {
- if space.hallway[3] == No {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 1), (2, 1)) => {
- if space.hallway[3] == No &&
- space.rooms[1][0] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- ((0, 1), (3, 0)) => {
- if space.hallway[3] == No && space.hallway[5] == No {
- ret.0 = true
- }
- ret.1 = 6;
- }
- ((0, 1), (3, 1)) => {
- if space.hallway[3] == No && space.hallway[5] == No &&
- space.rooms[2][0] == No {
- ret.0 = true
- }
- ret.1 = 7;
- }
- ((0, 1), (4, 0)) => {
- if space.hallway[3] == No && space.hallway[5] == No && space.hallway[7] == No {
- ret.0 = true
- }
- ret.1 = 8;
- }
- ((0, 1), (4, 1)) => {
- if space.hallway[3] == No && space.hallway[5] == No && space.hallway[7] == No &&
- space.rooms[3][0] == No {
- ret.0 = true
- }
- ret.1 = 9;
- }
- //start 0,3
- ((0, 3), (1, 0)) => {
- ret = (true, 2)
- }
- ((0, 3), (1, 1)) => {
- if
- space.rooms[0][0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 3), (2, 0)) => {
- ret = (true, 2)
- }
- ((0, 3), (2, 1)) => {
- if
- space.rooms[1][0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 3), (3, 0)) => {
- if space.hallway[5] == No {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 3), (3, 1)) => {
- if space.hallway[5] == No &&
- space.rooms[2][0] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- ((0, 3), (4, 0)) => {
- if space.hallway[5] == No && space.hallway[7] == No {
- ret.0 = true
- }
- ret.1 = 6;
- }
- ((0, 3), (4, 1)) => {
- if space.hallway[5] == No && space.hallway[7] == No &&
- space.rooms[3][0] == No {
- ret.0 = true
- }
- ret.1 = 7;
- }
- //start 0,5
- ((0, 5), (1, 0)) => {
- if space.hallway[3] == No {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 5), (1, 1)) => {
- if space.hallway[3] == No &&
- space.rooms[0][0] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- ((0, 5), (2, 0)) => {
- ret = (true, 2)
- }
- ((0, 5), (2, 1)) => {
- if
- space.rooms[1][0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 5), (3, 0)) => {
- ret = (true, 2)
- }
- ((0, 5), (3, 1)) => {
- if
- space.rooms[2][0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 5), (4, 0)) => {
- if space.hallway[7] == No
- {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 5), (4, 1)) => {
- if space.hallway[7] == No &&
- space.rooms[3][0] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- //start 0,7
- ((0, 7), (1, 0)) => {
- if space.hallway[3] == No && space.hallway[5] == No {
- ret.0 = true
- }
- ret.1 = 6;
- }
- ((0, 7), (1, 1)) => {
- if space.hallway[3] == No && space.hallway[5] == No &&
- space.rooms[0][0] == No {
- ret.0 = true
- }
- ret.1 = 7;
- }
- ((0, 7), (2, 0)) => {
- if space.hallway[5] == No {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 7), (2, 1)) => {
- if space.hallway[5] == No &&
- space.rooms[1][0] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- ((0, 7), (3, 0)) => {
- ret = (true, 2)
- }
- ((0, 7), (3, 1)) => {
- if
- space.rooms[2][0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 7), (4, 0)) => {
- ret = (true, 2)
- }
- ((0, 7), (4, 1)) => {
- if
- space.rooms[3][0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- //start 0,9
- ((0, 9), (1, 0)) => {
- if space.hallway[3] == No && space.hallway[5] == No && space.hallway[7] == No
- {
- ret.0 = true
- }
- ret.1 = 8;
- }
- ((0, 9), (1, 1)) => {
- if space.hallway[3] == No && space.hallway[5] == No && space.hallway[7] == No &&
- space.rooms[0][0] == No {
- ret.0 = true
- }
- ret.1 = 9;
- }
- ((0, 9), (2, 0)) => {
- if space.hallway[5] == No && space.hallway[7] == No
- {
- ret.0 = true
- }
- ret.1 = 6;
- }
- ((0, 9), (2, 1)) => {
- if space.hallway[5] == No && space.hallway[7] == No &&
- space.rooms[1][0] == No {
- ret.0 = true
- }
- ret.1 = 7;
- }
- ((0, 9), (3, 0)) => {
- if space.hallway[7] == No
- {
- ret.0 = true
- }
- ret.1 = 4;
- }
- ((0, 9), (3, 1)) => {
- if space.hallway[7] == No &&
- space.rooms[2][0] == No {
- ret.0 = true
- }
- ret.1 = 5;
- }
- ((0, 9), (4, 0)) => {
- ret = (true, 2)
- }
- ((0, 9), (4, 1)) => {
- if
- space.rooms[3][0] == No {
- ret.0 = true
- }
- ret.1 = 3;
- }
- ((0, 10), a) => {
- let start09 = routeIsClear2(space, (0, 9), a);
- ret = (start09.0 && space.hallway[9] == No, start09.1 + 1)
- }
- //room to hallway
- (a, b) => {
- //dbg!(a, b);
- ret = routeIsClear2(space, b, a);
- }
- }
- ret
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement