summaryrefslogtreecommitdiff
path: root/src/solvers
diff options
context:
space:
mode:
authorDennis Kobert <dennis@kobert.dev>2020-01-02 14:47:39 +0000
committerDennis Kobert <dennis@kobert.dev>2020-01-02 14:47:39 +0000
commit82a65a82873c6699f12c9c6186705e0089c58240 (patch)
tree42e26ecacdee54cc9b80fa9956bc956ed692b31f /src/solvers
parent20aaa152b25121f992480452a270ba1e0d5b5dd3 (diff)
parentedaccaaf15a526714f3de4e9e044341abd037885 (diff)
Merge branch 'master' of /var/repos/babel
Diffstat (limited to 'src/solvers')
-rw-r--r--src/solvers/incremental_block.rs133
-rwxr-xr-xsrc/solvers/mod.rs1
-rw-r--r--src/solvers/solver1.rs51
3 files changed, 185 insertions, 0 deletions
diff --git a/src/solvers/incremental_block.rs b/src/solvers/incremental_block.rs
new file mode 100644
index 0000000..d4ebb81
--- /dev/null
+++ b/src/solvers/incremental_block.rs
@@ -0,0 +1,133 @@
+use std::iter::repeat;
+use crate::solver::{Solver, wall_stats};
+use crate::structs::StoneWall;
+
+pub struct IncrementalBlockSover {
+ n: u32, h: u32, w: u32,
+ rows: Vec<Vec<(u32, u32)>>,
+}
+
+struct SubSolver<'s> {
+ solver: &'s mut IncrementalBlockSover,
+ start: u32,
+ count: u32,
+ heights: Vec<u32>,
+ // for all gaps the possible rows
+ gap_possibilities: Vec<Vec<u32>>,
+ pos: Vec<u32>,
+}
+
+impl<'s> SubSolver<'s> {
+ fn from_index(solver: &'s mut IncrementalBlockSover, index: u32) -> Option<Self> {
+ let gap_possibilities = vec![vec![]; index as usize];
+ let row_existence = vec![false; index as usize];
+ let start = solver.rows[0][index as usize].0 + 1;
+ for row in 1..solver.h {
+ let min_sz = start - solver.row_size(row);
+ for gap in 0..index {
+ if !solver.visited(row, min_sz + gap) {
+ gap_possibilities[gap as usize].push(row);
+ row_existence[row as usize] = true;
+ }
+ }
+ }
+ if row_existence.iter().all(|&x| x) {
+ Some(Self {
+ count: index,
+ start, solver,
+ heights: Vec::with_capacity(index as usize),
+ pos: vec![0; gap_possibilities.len()],
+ gap_possibilities,
+ })
+ } else { None }
+ }
+
+ fn increment_at(&mut self, n: u32) -> bool {
+ if self.pos[n as usize] as usize + 1 == self.gap_possibilities[n as usize].len() {
+ if n as usize + 1 == self.pos.len() {
+ false
+ } else {
+ self.increment_at(n + 1)
+ }
+ } else {
+ self.pos[n as usize] += 1;
+ true
+ }
+ }
+}
+
+impl<'s> Iterator for SubSolver<'s> {
+ type Item = ();
+
+ fn next(&mut self) -> Option<Self::Item> {
+ for (i, p) in self.pos.iter().enumerate().rev() {
+ t
+ }
+ None
+ }
+}
+
+impl IncrementalBlockSover {
+ fn generate_first_row(&mut self) {
+ let mut sum = 0;
+ self.rows[0] = (1..=self.n)
+ .map(|n| {
+ sum += n;
+ (sum - n, n)
+ })
+ .collect();
+ }
+
+ fn get_wall(&self) -> StoneWall {
+ let mut wall = StoneWall::create_empty(self.n);
+ for (h, row) in self.rows.iter().enumerate() {
+ for (n, &(_, stone)) in row.iter().enumerate() {
+ wall.set_stone(h as u32, n as u32, stone).unwrap()
+ }
+ }
+ wall
+ }
+
+ fn visited(&self, row: u32, stone: u32) -> bool {
+ self.rows[row as usize].iter()
+ .position(|&(_, s)| s == stone)
+ .is_some()
+ }
+
+ fn row_size(&self, row: u32) -> u32 {
+ self.rows[row as usize]
+ .last()
+ .map_or(0, |&(i, s)| i + s)
+ }
+}
+
+impl Solver for IncrementalBlockSover {
+ fn new(n: u32) -> Self {
+ let (h, w) = wall_stats(n);
+ Self {
+ n, h, w,
+ rows: repeat(Vec::with_capacity(h as usize))
+ .take(h as usize)
+ .collect()
+ }
+ }
+
+ fn solve(&mut self) -> StoneWall {
+ self.generate_first_row();
+ println!("{:?}", self.rows);
+ self.get_wall()
+ }
+
+ fn n(&self) -> u32 {
+ self.n
+ }
+
+ fn h(&self) -> u32 {
+ self.h
+ }
+
+ fn w(&self) -> u32 {
+ self.w
+ }
+}
+
diff --git a/src/solvers/mod.rs b/src/solvers/mod.rs
index 0b1d716..4fc1330 100755
--- a/src/solvers/mod.rs
+++ b/src/solvers/mod.rs
@@ -1 +1,2 @@
pub mod intuitive;
+pub mod incremental_block;
diff --git a/src/solvers/solver1.rs b/src/solvers/solver1.rs
new file mode 100644
index 0000000..ab1fbd1
--- /dev/null
+++ b/src/solvers/solver1.rs
@@ -0,0 +1,51 @@
+use crate::structs::{StoneWall, GapHeights};
+
+#[derive(Clone)]
+struct State {
+ stones_used: Vec<bool>,
+ gaps: GapHeights,
+}
+
+impl State {
+ fn from_gaps(gaps: GapHeights, n: u32) -> Self {
+ let h = n/2 + 1;
+ Self {
+ stones_used: vec![false; n * h],
+ gaps
+ }
+ }
+
+ fn stone_used(&self, n: u32, h: u32) -> bool {
+ self.stones_used.get()
+ }
+
+ fn as_wall(&self, n: u32) -> StoneWall {
+ self.gaps.as_stone_wall(n)
+ }
+}
+
+struct RecursiveSolver {
+ n: u32,
+ states: Vec<GapHeights>
+}
+
+impl Sover for RecursiveSolver {
+ fn new(n: u32) -> Self {
+ let w = (n/2 + 1) * (n - 1);
+ let gaps = GapHeights::create_empty(w);
+ Self {
+ n,
+ states: vec![State::from_gaps(gaps)]
+ }
+ }
+
+ fn solve(&mut self) -> Option<StoneWall> {
+ let w = self.w();
+ if let Some(state) = self.states.last() {
+ }
+ }
+
+ fn n(&self) -> u32 {
+ self.n
+ }
+}