Guest User

Untitled

a guest
Jul 20th, 2018
78
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.24 KB | None | 0 0
  1. use std::cmp::{Ordering};
  2. use std::mem::replace;
  3.  
  4. type ConstraintList = Vec<usize>;
  5.  
  6. #[derive(Clone, Copy, PartialEq, Eq)]
  7. pub enum Square {
  8. Unknown,
  9. Empty,
  10. Filled,
  11. }
  12.  
  13. // The ConstraintList is a list of the lengths of contigious blocks of Filled Squares. (With any non-zero number of Empty between)
  14. // Any number, including zero, of Empty are allowed before or after the first/last blocks
  15. // Return true if the given iterator is consistent with the given constraint,
  16. // i.e. does not contradict the given lengths by having a block that is too long or a block interrupted by an Empty.
  17. fn validate_line(consts: &ConstraintList, line: impl Iterator<Item=Square>) -> bool {
  18. let block_lengths = RepIterator::new(line)
  19. .filter(|&(v, _)| v == Square::Filled)
  20. .map(|(_, c)| c); // Converts the current state into an iterator of the same format (i.e. lengths of filled sqs) as the constraint
  21.  
  22. let v: Vec<_> = block_lengths.collect();
  23. let mut block_lengths = v.into_iter();
  24.  
  25. let mut constraints = consts.iter().cloned();
  26. loop {
  27. let (blo, co) = (block_lengths.next(), constraints.next());
  28. return match (blo, co) {
  29. (Some(bl), Some(co)) => match bl.cmp(&co) {
  30. Ordering::Greater => false,
  31. Ordering::Equal => continue,
  32. Ordering::Less => block_lengths.next().is_none(),
  33. },
  34. (Some(_), None) => false,
  35. (None, _) => true,
  36. };
  37. }
  38. }
  39.  
  40.  
  41.  
  42.  
  43. // Convert an Iterator<T> into an Iterator<(T, usize)> that yields each element, and the number of times that element is repeated by the original Iterator
  44. pub struct RepIterator<T, I>
  45. where
  46. T: Eq,
  47. I: Iterator<Item = T>,
  48. {
  49. iter: I,
  50. last_item: Option<T>,
  51. count: usize,
  52. }
  53.  
  54. impl<T, I> RepIterator<T, I>
  55. where
  56. T: Eq,
  57. I: Iterator<Item = T>,
  58. {
  59. pub fn new(iter: I) -> RepIterator<T, I> {
  60. RepIterator {
  61. iter,
  62. last_item: None,
  63. count: 0,
  64. }
  65. }
  66. }
  67.  
  68. impl<T, I> Iterator for RepIterator<T, I>
  69. where
  70. T: Eq,
  71. I: Iterator<Item = T> + Sized,
  72. {
  73. type Item = (T, usize);
  74. fn next(&mut self) -> Option<Self::Item> {
  75. loop {
  76. match self.iter.next() {
  77. None => {
  78. let old = self.last_item.take();
  79. let old_count = replace(&mut self.count, 0);
  80. return old.map(|v| (v, old_count));
  81. // Might be in the middle of a string of Some values, so return that, then return None if we get another None
  82. // Doesn't matter if the count of None is wrong
  83. }
  84. Some(ref item) if Some(item) == self.last_item.as_ref() => {
  85. self.count += 1;
  86. }
  87. Some(item) => {
  88. let old = replace(&mut self.last_item, Some(item));
  89. let c = replace(&mut self.count, 1);
  90. if let Some(i) = old {
  91. return Some((i, c));
  92. }
  93. }
  94. }
  95. }
  96. }
  97. }
  98.  
  99. fn main() {
  100. let real_vals = vec![Square::Filled, Square::Empty, Square::Empty, Square::Empty];
  101. let consts = vec![4];
  102. let truf = validate_line(&consts, real_vals.into_iter());
  103. assert!(!truf);
  104.  
  105.  
  106. }
Add Comment
Please, Sign In to add comment