|
@@ -124,7 +124,6 @@ impl Edge {
|
|
|
let shift_direction = if upright { -1 } else { 1 };
|
|
|
|
|
|
let shifted = (self.to_int() + shift_direction * shift_amount).rem_euclid(3);
|
|
|
- println!("Shifted: {}", shifted);
|
|
|
|
|
|
Edge::from_int(shifted)
|
|
|
}
|
|
@@ -136,6 +135,10 @@ pub fn generate_parts() -> HashMap<PartID, Part> {
|
|
|
(1, vec![Edge::LEFT, Edge::LEFT, Edge::BOTTOMTOP, Edge::BOTTOMTOP, Edge::RIGHT, Edge::BOTTOMTOP, Edge::LEFT]),
|
|
|
(2, vec![Edge::RIGHT, Edge::BOTTOMTOP, Edge::RIGHT, Edge::RIGHT, Edge::BOTTOMTOP]),
|
|
|
(3, vec![Edge::RIGHT, Edge::BOTTOMTOP, Edge::LEFT, Edge::BOTTOMTOP, Edge::RIGHT]),
|
|
|
+ (4, vec![Edge::BOTTOMTOP, Edge::RIGHT, Edge::RIGHT, Edge::RIGHT, Edge::RIGHT]),
|
|
|
+ (5, vec![Edge::LEFT, Edge::BOTTOMTOP, Edge::LEFT, Edge::LEFT, Edge::LEFT]),
|
|
|
+ (6, vec![Edge::RIGHT, Edge::RIGHT, Edge::RIGHT, Edge::BOTTOMTOP, Edge::BOTTOMTOP, Edge::RIGHT]),
|
|
|
+ (7, vec![Edge::LEFT, Edge::LEFT, Edge::BOTTOMTOP, Edge::LEFT, Edge::RIGHT, Edge::RIGHT]),
|
|
|
])
|
|
|
}
|
|
|
|
|
@@ -155,7 +158,7 @@ pub type MapIO = (MapSideIO, MapSideIO);
|
|
|
* Each cell can be a Barrier (meaning no part may be placed on the cell), Empty (meaning at the
|
|
|
* current time, it is not occupied by a part) or Occupied.
|
|
|
*/
|
|
|
-#[derive(Copy, Clone)]
|
|
|
+#[derive(PartialEq, Debug, Copy, Clone)]
|
|
|
pub enum Cell {
|
|
|
Barrier,
|
|
|
Empty,
|
|
@@ -175,6 +178,17 @@ impl Cell {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+impl std::fmt::Display for Cell {
|
|
|
+ fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
|
+ match self {
|
|
|
+ Cell::Barrier => write!(f, "B"),
|
|
|
+ Cell::Empty => write!(f, " "),
|
|
|
+ Cell::Occupied(id) => write!(f, "{}", id),
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* A triangular grid looks like this:
|
|
|
* __ __
|
|
@@ -288,14 +302,13 @@ pub fn check_part(map: &Map, part: &Part, x: u8, y: u8, rotation: Edge) -> bool
|
|
|
return false;
|
|
|
}
|
|
|
}
|
|
|
- println!("");
|
|
|
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
/* Once we have found a valid position with `check_part`, we can place the part on the map.
|
|
|
*/
|
|
|
-fn place_part(map: &mut Map, id: PartID, part: &Part, x: u8, y: u8, rotation: Edge) {
|
|
|
+pub fn place_part(map: &mut Map, id: PartID, part: &Part, x: u8, y: u8, rotation: Edge) {
|
|
|
map[y as usize][x as usize] = Cell::Occupied(id);
|
|
|
|
|
|
let mut mx : u8 = x;
|
|
@@ -304,6 +317,8 @@ fn place_part(map: &mut Map, id: PartID, part: &Part, x: u8, y: u8, rotation: Ed
|
|
|
for movement in part {
|
|
|
let rotated_movement = movement.rotate(&rotation, is_upright(x, y));
|
|
|
(mx, my) = move_along_edge(mx, my, rotated_movement).unwrap();
|
|
|
+ let prev = map[my as usize][mx as usize];
|
|
|
+ assert!(prev == Cell::Empty || prev == Cell::Occupied(id));
|
|
|
map[my as usize][mx as usize] = Cell::Occupied(id);
|
|
|
}
|
|
|
|
|
@@ -333,7 +348,7 @@ pub fn solve(map: &mut Map, parts: &[(PartID, &Part)]) -> Option<()>{
|
|
|
let (id, part) = parts[0];
|
|
|
|
|
|
|
|
|
- // Todo: limit to non-barrier positions
|
|
|
+ // TODO: restrict to list of non-barrier position to tighten the for loops
|
|
|
for x in 0..MAP_WIDTH {
|
|
|
for y in 0..MAP_HEIGHT {
|
|
|
if !map[y as usize][x as usize].is_empty() {
|
|
@@ -441,6 +456,38 @@ mod test {
|
|
|
assert_eq!(1, called);
|
|
|
|
|
|
}
|
|
|
-
|
|
|
|
|
|
+ #[test]
|
|
|
+ fn halting_problem() {
|
|
|
+ let B = Cell::Barrier;
|
|
|
+ let E = Cell::Empty;
|
|
|
+
|
|
|
+ let mut map : Map = [
|
|
|
+ [B, B, E, E, E, B, E, E, E, B, B, B, B, B, B, B],
|
|
|
+ [B, E, E, E, E, B, B, E, E, E, B, B, B, B, B, B],
|
|
|
+ [E, E, E, E, E, B, E, E, E, E, E, E, B, B, B, B],
|
|
|
+ [E, E, E, B, E, B, E, E, E, E, E, B, B, B, B, B],
|
|
|
+ [B, B, B, B, B, B, B, B, B, E, B, B, B, B, B, B],
|
|
|
+ ];
|
|
|
+
|
|
|
+ let parts = generate_parts();
|
|
|
+
|
|
|
+ let available_parts : Vec<(PartID, &Part)> = [2,3,4,5,6,7].iter()
|
|
|
+ .map(|x| (*x, &parts[&x]))
|
|
|
+ .collect();
|
|
|
+
|
|
|
+ let result = solve(&mut map, &available_parts);
|
|
|
+
|
|
|
+ assert!(result.is_some());
|
|
|
+
|
|
|
+ for y in 0..MAP_HEIGHT {
|
|
|
+ for x in 0..MAP_WIDTH {
|
|
|
+ print!("{}", map[y as usize][x as usize]);
|
|
|
+ }
|
|
|
+ println!("");
|
|
|
+ }
|
|
|
+ assert!(false);
|
|
|
+
|
|
|
+
|
|
|
+ }
|
|
|
}
|