Guest User

Untitled

a guest
Apr 24th, 2018
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.91 KB | None | 0 0
  1. extern crate itertools;
  2. use itertools::Itertools;
  3.  
  4. #[derive(Debug)]
  5. struct Problem {
  6. cells: Vec<(usize, usize, char)>,
  7. }
  8.  
  9. impl Problem {
  10. fn new(cells: &[(usize, usize, char)]) -> Problem {
  11. Problem {
  12. cells: cells.to_vec(),
  13. }
  14. }
  15. }
  16.  
  17. #[derive(Debug)]
  18. struct PartialSolution {
  19. cell_values: Vec<(usize, usize, char)>,
  20. empty_cells: Vec<(usize, usize)>,
  21. }
  22.  
  23. fn root(problem: &Problem) -> PartialSolution {
  24. let fixed_cells = problem
  25. .cells
  26. .iter()
  27. .map(|&(i, j, _)| (i, j))
  28. .collect::<Vec<_>>();
  29. PartialSolution {
  30. cell_values: Vec::new(),
  31. empty_cells: (0..9)
  32. .cartesian_product(0..9)
  33. .filter(|x| !fixed_cells.contains(x))
  34. .collect::<Vec<_>>(),
  35. }
  36. }
  37.  
  38. mod rule {
  39. pub enum RuleType {
  40. Row(usize),
  41. Column(usize),
  42. Square(usize, usize),
  43. }
  44.  
  45. pub fn create_rule(rule: RuleType) -> Vec<(usize, usize)> {
  46. use itertools::Itertools;
  47. match rule {
  48. RuleType::Row(i) => (0..9).map(|j| (i, j)).collect::<Vec<(usize, usize)>>(),
  49. RuleType::Column(j) => (0..9).map(|i| (i, j)).collect::<Vec<(usize, usize)>>(),
  50. RuleType::Square(x, y) => (3 * x..3 * (x + 1))
  51. .cartesian_product(3 * y..3 * (y + 1))
  52. .collect::<Vec<(usize, usize)>>(),
  53. }
  54. }
  55.  
  56. pub fn mask(cells: &[(usize, usize, char)], rule: &[(usize, usize)]) -> Vec<char> {
  57. use std::collections::HashMap;
  58. let cell_hash = cells
  59. .iter()
  60. .map(|&(x, y, z)| ((x, y), z))
  61. .collect::<HashMap<(usize, usize), char>>();
  62. rule.iter()
  63. .filter_map(|x| cell_hash.get(x))
  64. .map(|x| *x)
  65. .collect::<Vec<char>>()
  66. }
  67.  
  68. pub fn contains_duplicates<T>(xs: &[T]) -> bool
  69. where
  70. T: PartialEq,
  71. {
  72. match xs.split_first() {
  73. Some((y, ys)) => ys.contains(y) || contains_duplicates(ys),
  74. None => false,
  75. }
  76. }
  77.  
  78. pub fn check(cells: &[(usize, usize, char)], rule: &[(usize, usize)]) -> bool {
  79. //true if it passes, false otherwise
  80. !contains_duplicates(&mask(cells, rule))
  81. }
  82. }
  83.  
  84. fn reject(problem: &Problem, candidate: PartialSolution) -> bool {
  85. let all_rules = (0..9)
  86. .map(|x| rule::RuleType::Row(x))
  87. .chain((0..9).map(|x| rule::RuleType::Column(x)))
  88. .chain(
  89. (0..3)
  90. .cartesian_product(0..3)
  91. .map(|(x, y)| rule::RuleType::Square(x, y)),
  92. )
  93. .map(|x| rule::create_rule(x))
  94. .collect::<Vec<_>>();
  95. let all_cells = problem
  96. .cells
  97. .iter()
  98. .chain(candidate.cell_values.iter())
  99. .map(|x| *x)
  100. .collect::<Vec<(usize, usize, char)>>();
  101. !all_rules
  102. .iter()
  103. .all(|x| rule::check(all_cells.as_slice(), x))
  104. }
  105.  
  106. fn accept(problem: &Problem, candidate: PartialSolution) -> bool {
  107. let fixed_cells = problem
  108. .cells
  109. .iter()
  110. .chain(candidate.cell_values.iter())
  111. .map(|&(i, j, _)| (i, j))
  112. .collect::<Vec<_>>();
  113. let empty_cells = (0..9)
  114. .cartesian_product(0..9)
  115. .filter(|x| !fixed_cells.contains(x))
  116. .collect::<Vec<_>>();
  117. empty_cells.is_empty()
  118. }
  119.  
  120. fn output(problem: &Problem, candidate: PartialSolution) -> Vec<(usize, usize, char)> {
  121. problem
  122. .cells
  123. .iter()
  124. .chain(candidate.cell_values.iter())
  125. .map(|x| *x)
  126. .collect::<Vec<(usize, usize, char)>>()
  127. }
  128.  
  129. fn first(_problem: &Problem, candidate: &PartialSolution) -> Option<PartialSolution> {
  130. use std::iter;
  131. candidate
  132. .empty_cells
  133. .as_slice()
  134. .split_first()
  135. .map(|(&(i, j), xs)| PartialSolution {
  136. cell_values: candidate
  137. .cell_values
  138. .iter()
  139. .chain(iter::once(&(i, j, '1')))
  140. .map(|x| *x)
  141. .collect::<Vec<(usize, usize, char)>>(),
  142. empty_cells: xs.to_vec(),
  143. })
  144. }
  145.  
  146. fn next_value(c: &char) -> Option<char> {
  147. match *c {
  148. '1' => Some('2'),
  149. '2' => Some('3'),
  150. '3' => Some('4'),
  151. '4' => Some('5'),
  152. '5' => Some('6'),
  153. '6' => Some('7'),
  154. '7' => Some('8'),
  155. '8' => Some('9'),
  156. _ => None,
  157. }
  158. }
  159.  
  160. fn next(_problem: &Problem, candidate: &PartialSolution) -> Option<PartialSolution> {
  161. use std::iter;
  162. candidate
  163. .cell_values
  164. .as_slice()
  165. .split_last()
  166. .and_then(|(&(x, y, z), other_cells)| {
  167. next_value(&z).map(|value| PartialSolution {
  168. cell_values: other_cells
  169. .iter()
  170. .chain(iter::once(&(x, y, value)))
  171. .map(|x| *x)
  172. .collect::<Vec<(usize, usize, char)>>(),
  173. empty_cells: candidate.empty_cells.clone(),
  174. })
  175. })
  176. }
  177.  
  178. fn main() {
  179. let problem = Problem::new(&[(0, 0, '1'), (0, 1, '2'), (0, 2, '3'), (0, 3, '4')]);
  180. println!("{:?}", root(&problem));
  181.  
  182. let r = rule::create_rule(rule::RuleType::Square(0, 0));
  183. println!("{:?}", r);
  184.  
  185. println!("{:?}", rule::mask(problem.cells.as_slice(), r.as_slice()));
  186. println!("{:?}", rule::check(problem.cells.as_slice(), r.as_slice()));
  187.  
  188. println!("{:?}", first(&problem, &root(&problem)));
  189. let a = first(&problem,&root(&problem)).and_then(|x| next(&problem,&x)) ;
  190. println!("{:?}", a);
  191. let b = a.and_then(|x| next(&problem,&x)) ;
  192. println!("{:?}", b);
  193. let c = b.and_then(|x| next(&problem,&x)) ;
  194. println!("{:?}", c);
  195. let d = c.and_then(|x| next(&problem,&x)) ;
  196. println!("{:?}", d);
  197. let e = d.and_then(|x| next(&problem,&x)) ;
  198. println!("{:?}", e);
  199. let f = e.and_then(|x| next(&problem,&x)) ;
  200. println!("{:?}", f);
  201. let g = f.and_then(|x| next(&problem,&x)) ;
  202. println!("{:?}", g);
  203. let h = g.and_then(|x| next(&problem,&x)) ;
  204. println!("{:?}", h);
  205. let i = h.and_then(|x| next(&problem,&x)) ;
  206. println!("{:?}", i);
  207. }
Add Comment
Please, Sign In to add comment