pub use std::iter;
pub use itertools::izip;
-pub use itertools::Itertools as _;
+pub use itertools::Itertools;
pub fn default<T: Default>() -> T { Default::default() }
current[i] += d;
current
}).collect_vec();
- for i in 0..DIM {
- let min = points.iter().map(|p| p[i]).min().unwrap();
- for p in &mut points { p[i] -= min; }
- }
+ shape_abut_zero(&mut points);
points
})
}
+/// Translate `shape` so that its minimum coordinate in each dimension is 0
+pub fn shape_abut_zero(shape: &mut Shape) {
+ for i in 0..DIM {
+ let min = shape.iter().map(|p| p[i]).min().unwrap();
+ for p in &mut shape[..] { p[i] -= min; }
+ }
+}
+
pub fn shape_edges(shape: &Shape) -> impl Iterator<Item=[Point; 2]> + '_ {
shape
.iter()
.map(|(&a,&b)| [a,b])
}
+fn flip_coord(do_flip: bool, c: Coord) -> Coord {
+ if do_flip { MAX-c } else { c }
+}
+
pub fn shape_all_flippings(shape: &Shape) -> impl Iterator<Item=Shape> + '_ {
iter::repeat([false,true].into_iter())
.take(DIM)
.map(|inv: Vec<bool>| {
shape.iter().map(|p| {
let mut inv = inv.iter();
- p.map(|c| {
- if *inv.next().unwrap() { MAX-c } else { c }
- })
+ p.map(|c| flip_coord(*inv.next().unwrap(), c))
})
.collect_vec()
})
}
+pub fn shape_all_rotations(shape: &Shape) -> impl Iterator<Item=Shape> + '_ {
+ Itertools::cartesian_product(
+ 0..DIM,
+ [false,true],
+ ).map(|(rot, flip)| {
+ shape.iter().map(|pi| {
+ let mut po: Point = default();
+ for i in 0..DIM {
+ po[i] = flip_coord(flip, pi[(i + rot) % DIM]);
+ }
+ po
+ })
+ .collect_vec()
+ })
+}
+
pub fn print_shape(shape: &Shape) -> io::Result<()> {
let mut o = io::stdout().lock();
for vx in shape {