Prechádzať zdrojové kódy

Functional candidate

Christoph Stelz 1 rok pred
rodič
commit
be4b723753
3 zmenil súbory, kde vykonal 105 pridanie a 141 odobranie
  1. BIN
      src/.lib.rs.swp
  2. 80 134
      src/lib.rs
  3. 25 7
      src/main.rs

BIN
src/.lib.rs.swp


+ 80 - 134
src/lib.rs

@@ -38,6 +38,14 @@ impl Coord {
         }
     }
 
+    pub fn rotate60(&self) -> Coord {
+        Coord {
+            a: 1 - self.c,
+            b: 1 - self.a,
+            c: 1 - self.b
+        }
+    }
+
 
     /**
      * Flip coordinate at the y-axis
@@ -58,7 +66,7 @@ impl Coord {
         }
     }
 
-    fn to_cartesian(&self) -> (i8, i8) {
+    pub fn to_cartesian(&self) -> (i8, i8) {
         (self.a - self.c + 1, 1 - self.b)
         //let y : i8 = 1 - self.b;
         //let x_offset : i8 = (self.b - 1).abs() / 2;
@@ -69,13 +77,36 @@ impl Coord {
         //return (x, y);
     }
 
-    fn translate_x(&self, x: i8) -> Coord {
+    pub fn translate_x(&self, x: i8) -> Coord {
         Coord::from_ab(self.a + x, self.b, self.upright())
     }
 
-    fn translate_y(&self, y: i8) -> Coord {
-        Coord::from_ab(self.a + y, self.b - 2 * y, self.upright())
+    pub fn translate_y(&self, y: i8, origin_upright: bool) -> Coord {
+        //let m = Coord::from_ab(self.a + y, self.b - 2 * y, self.upright());
+        //let k = Coord::from(self.a + y, self.b - 2 * y, self.c + y);
+
+        //assert_eq!(m,k);
+        //k
+        if origin_upright {
+            Coord::from_ab(self.a + (y + 1) / 2, self.b - y, self.upright())
+        } else {
+            Coord::from_ab(self.a + y / 2, self.b - y, self.upright())
+        }
     }
+
+    //pub fn translate_hy(&self, y: i8) -> Coord {
+    //    let t = self.translate_y(y / 2);
+    //    if y % 2 == 0 {
+    //        t
+    //    } else {
+    //        Coord {
+    //            a: self.a,
+    //            b: self.b - 1,
+    //            c: self.c + 1,
+    //        }
+    //    }
+
+    //}
 }
 impl std::ops::Add<Coord> for Coord {
     type Output = Coord;
@@ -189,8 +220,17 @@ where F: FnMut(i8, i8) -> bool
         let mut coord : Coord = if flipped { coordinate.flip() } else { coordinate.clone() };
         coord = coord.rotate(rotations);
 
-        let world_pos = coord.translate_x(x / 2).translate_y(y / 2);
-        let (wx, wy) = world_pos.to_cartesian();
+
+        let origin_upright = (x + y) % 2 == 0;
+        //println!("origin_upright: {}", origin_upright);
+        if !origin_upright {
+            coord = coord.rotate60();
+        }
+
+
+        coord = coord.translate_y(y, origin_upright).translate_x(x / 2);
+
+        let (wx, wy) = coord.to_cartesian();
 
         if in_bound(wx, wy) == false {
             return false;
@@ -222,7 +262,7 @@ pub fn check_part(map: &Map, part: &Part, x: i8, y: i8, rotations: u8, flipped:
     //println!("Testing {},{},{},{}", x, y, rotation.to_int(), flipped);
     let success = for_each_triangle(part, x, y, rotations, flipped, |x, y| {
         if !in_bound(x,y) {
-            return false;
+            return true; // TODO: switch this to false as opt
         }
 
         let prev = map[y as usize][x as usize];
@@ -248,16 +288,16 @@ pub fn place_part(map: &mut Map, id: PartID, part: &Part, x: i8, y: i8, rotation
     //println!("Placing {},{},{},{}", x, y, rotation.to_int(), flipped);
     for_each_triangle(part, x, y, rotations, flipped, |x, y| {
         if !in_bound(x,y) {
-            panic!();
+            return true
         }
         //println!("placing {},{}", x, y);
 
-        let prev = map[y as usize][x as usize];
-        if let Cell::Occupied(i) = prev {
-            assert_eq!(id, i);
-        } else {
-            assert!(prev.is_empty());
-        }
+        //let prev = map[y as usize][x as usize];
+        //if let Cell::Occupied(i) = prev {
+        //    assert_eq!(id, i);
+        //} else {
+        //    assert!(prev.is_empty());
+        //}
 
         map[y as usize][x as usize] = Cell::Occupied(id);
 
@@ -267,44 +307,51 @@ pub fn place_part(map: &mut Map, id: PartID, part: &Part, x: i8, y: i8, rotation
 
 ///* If a part is not placed right, we might need to remove it from the map again
 // */
-//fn erase_part(map: &mut Map, part: &Part, x: u8, y: u8, rotation: Edge, flipped: bool) {
-//    for_each_triangle(part, x, y, rotation, flipped, |x, y| {
-//        assert!(in_bound(x, y));
-//
-//        map[y as usize][x as usize] = Cell::Empty;
-//        true
-//    });
-//}
-//
-pub fn solve(map: Map, parts: &[(PartID, &Part)]) -> Option<()>{
+fn erase_part(map: &mut Map, part: &Part, x: i8, y: i8, rotation: u8, flipped: bool) {
+    for_each_triangle(part, x, y, rotation, flipped, |x, y| {
+        assert!(in_bound(x, y));
+
+        map[y as usize][x as usize] = Cell::Empty;
+        true
+    });
+}
+
+pub fn solve(map: &mut Map, parts: &[(PartID, &Part)]) -> Option<()>{
     if parts.len() == 0 {
         return Some(());
     }
 
     let (id, part) = parts[0];
-    println!("{} parts remaining", parts.len());
+    //println!("{} parts remaining", parts.len());
 
     // 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 {
+    for y in 0..MAP_HEIGHT {
+        for x in 0..MAP_WIDTH {
             if !map[y as usize][x as usize].is_empty() {
                 continue;
             }
 
             for rotation in [0, 1, 2] {
-                for flipped in [true, false] {
+                for flipped in [false, true] {
                     //println!("Testing rotation {} and flipped={}", rotation, flipped);
+                    //println!("x={},y={},r={},f={}", x, y,rotation,flipped);
                     let valid_position = check_part(&map, &part, x, y, rotation, flipped);
 
                     if valid_position {
                         // Place our part and try the others
-                        let mut map_copy = map.clone();
-                        place_part(&mut map_copy, id, &part, x, y, rotation, flipped);
-                        print_map(&map_copy);
-                        println!("\n");
-                        if let Some(()) = solve(map_copy, &parts[1..]) {
+                        //println!("Placing");
+                        place_part(map, id, &part, x, y, rotation, flipped);
+                        //print_map(&map);
+                        
+                        //println!("Erasing");
+                        //erase_part(map, &part, x, y, rotation, flipped);
+
+                        //println!("\n\n");
+                        if let Some(()) = solve(map, &parts[1..]) {
                             // We have found a valid solution we can pass back!
                             return Some(());
+                        } else {
+                            erase_part(map, &part, x, y, rotation, flipped);
                         }
                     }
                 }
@@ -407,107 +454,6 @@ mod test {
         assert_eq!(Coord::from(-1,0,3), Coord::from(2,0,0).translate_x(-3));
         assert_eq!(Coord::from(1,-1,2), Coord::from(-1,3,0).translate_y(2));
         assert_eq!(Coord::from(2,1,-1), Coord::from(3,-1,0).translate_y(-1));
-    }
-
-    #[test]
-    fn test_part1() {
-        let part = &generate_parts()[&1];
-        for p in part {
-            let (x,y) = p.to_cartesian();
-            println!("Part1: {} {}", x, y);
-        }
-
-    }
-    /*
-    #[test]
-    fn test_part_placement() {
-        let B = Cell::Barrier;
-        let E = Cell::Empty;
-
-        let map : Map = [
-            [B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B],
-            [B, B, E, E, B, B, B, B, B, B, B, B, B, B, B, B],
-            [B, B, E, E, E, B, B, B, B, B, B, B, B, B, B, B],
-            [B, B, E, B, B, B, B, B, B, B, B, B, B, B, B, B],
-            [B, B, B, B, B, B, B, B, B, B, B, B, B, B, B, B],
-        ];
-
-        let parts = generate_parts();
-        let brown_part = parts.get(&1).unwrap();
-
-
-        assert!(check_part(&map, &brown_part, 4, 2, Edge::BOTTOMTOP, false));
-        let mut called : usize = 0;
-        for x in 0..MAP_WIDTH {
-            for y in 0..MAP_HEIGHT {
-                for rotation in [Edge::LEFT, Edge::RIGHT, Edge::BOTTOMTOP] {
-                    if check_part(&map, &brown_part, x, y, rotation, false) {
-                        assert_eq!(Edge::BOTTOMTOP, rotation);
-                        assert_eq!((4, 2), (x, y));
-                        called += 1;
-                    }
-                }
-            }
-        }
-        assert_eq!(1, called);
-
-    }
-
-
-    #[test]
-    fn test_erasing() {
-        let E = Cell::Empty;
-        let map : Map = [
-            [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
-            [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
-            [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
-            [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
-            [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
-        ];
-        let parts = generate_parts();
-        let mut cmap = map.clone();
-
-        place_part(&mut cmap, 1, &parts[&1], 4, 4, Edge::BOTTOMTOP, true);
-        assert_ne!(map, cmap);
-        erase_part(&mut cmap, &parts[&1], 4, 4, Edge::BOTTOMTOP, true);
-
-        assert_eq!(map, cmap);
-
-
-    }
-
-    #[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);
-
 
     }
-*/
 }

+ 25 - 7
src/main.rs

@@ -9,10 +9,17 @@ fn main() {
     let mut map : Map = [
         [B, B, E, E, E, B, B, B, E, E, E, B, B, B, B, B],
         [B, E, E, E, E, E, B, B, B, E, E, E, B, B, B, B],
-        [E, E, E, E, E, E, E, B, E, E, E, E, E, E, B, B],
-        [E, E, E, E, E, E, E, B, E, E, E, E, E, B, B, B],
-        [B, E, E, E, B, E, B, B, B, B, B, E, B, B, B, B],
+        [E, E, E, E, E, E, B, B, E, E, E, E, E, E, B, B],
+        [E, E, E, B, E, B, B, 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],
     ];
+    //let mut map : Map = [
+    //    [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
+    //    [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
+    //    [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
+    //    [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
+    //    [E, E, E, E, E, E, E, E, E, E, E, E, E, E, E, E],
+    //];
     let parts = generate_parts();
 
     let available_parts : Vec<(PartID, &Part)> = [1,2,3,4,5,6,7].iter()
@@ -20,10 +27,21 @@ fn main() {
         .collect();
 
 
-    //let (_, part1) = available_parts[0];
-    //place_part(&mut map, 1, &parts[&1], 2, 2, 2, true);
-    //print_map(&map);
-    let result = solve(map, &available_parts[1..]);
+    //for p in &parts[&2] {
+    //    let m = p.translate_y(1, true);
+    //    println!("m = {},{},{}", m.a, m.b, m.c);
+    //    let (x,y) = p.rotate60().translate_y(1, false).translate_x(0).to_cartesian();
+
+
+    //    if y < 0 || y >= 16 || x < 0 || x >= 6 {
+    //        continue;
+    //    }
+    //    map[y as usize][x as usize] = Cell::Occupied(2);
+    //}
+
+    //place_part(&mut map, 2, &parts[&2], 0, 1, 0, false);
+    print_map(&map);
+    let result = solve(&mut map, &available_parts[1..]);
     assert!(result.is_some());
     print_map(&map);