Guest User

Untitled

a guest
Dec 17th, 2017
85
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.63 KB | None | 0 0
  1. use std::collections::VecDeque;
  2. use std::env;
  3.  
  4. struct KnotHasher {
  5. current: usize,
  6. skip: usize,
  7. state: Vec<u8>,
  8. }
  9.  
  10. impl Default for KnotHasher {
  11. fn default() -> KnotHasher {
  12. let mut state = Vec::with_capacity(256);
  13. for i in 0..256 {
  14. state.push(i as u8);
  15. }
  16.  
  17. KnotHasher {
  18. current: 0,
  19. skip: 0,
  20. state,
  21. }
  22. }
  23. }
  24.  
  25. impl KnotHasher {
  26. fn round(&mut self, input: &[u8]) {
  27. let length = self.state.len();
  28. for &i in input {
  29. let i = i as usize;
  30. for j in 0..i / 2 {
  31. let a = (self.current + j) % length;
  32. let b = (self.current + i - j - 1) % length;
  33. self.state.swap(a, b);
  34. }
  35.  
  36. self.current = (self.current + i + self.skip) % length;
  37. self.skip += 1;
  38. }
  39. }
  40.  
  41. fn hash(&mut self, input: &[u8]) -> Vec<u8> {
  42. let mut input = input.to_vec();
  43. input.push(17);
  44. input.push(31);
  45. input.push(73);
  46. input.push(47);
  47. input.push(23);
  48.  
  49. for _ in 0..64 {
  50. self.round(&input);
  51. }
  52.  
  53. self.state
  54. .chunks(16)
  55. .map(|block| block.iter().fold(0, |acc, b| acc ^ b))
  56. .collect()
  57. }
  58. }
  59.  
  60. #[derive(Copy, Clone, Debug)]
  61. enum Cell {
  62. Free,
  63. Used,
  64. Region(u16),
  65. }
  66.  
  67. fn part1(input: &str) {
  68. let count: u32 = (0..128)
  69. .map(|n| {
  70. let value = format!("{}-{}", input, n);
  71. let mut hasher = KnotHasher::default();
  72. let hash = hasher.hash(value.as_bytes());
  73. hash.iter().map(|b| b.count_ones()).sum::<u32>()
  74. })
  75. .sum();
  76. println!("part 1: {}", count);
  77. }
  78.  
  79. fn part2(input: &str) {
  80. let mut grid: Vec<Vec<Cell>> = (0..128)
  81. .map(|n| {
  82. let value = format!("{}-{}", input, n);
  83. let mut hasher = KnotHasher::default();
  84. let hash = hasher.hash(value.as_bytes());
  85. if n == 2 {
  86. println!("{}={:?}", value, hash);
  87. }
  88. hash.iter()
  89. .flat_map(|b| {
  90. let binary = format!("{:08b}", b);
  91. binary
  92. .chars()
  93. .map(|bit| match bit {
  94. '0' => Cell::Free,
  95. '1' => Cell::Used,
  96. _ => unreachable!(),
  97. })
  98. .collect::<Vec<Cell>>()
  99. })
  100. .collect()
  101. })
  102. .collect();
  103.  
  104. let mut current_region = 0;
  105. for cy in 0..128 {
  106. for cx in 0..128 {
  107. match grid[cy][cx] {
  108. Cell::Free | Cell::Region(_) => continue,
  109. Cell::Used => {}
  110. }
  111.  
  112. current_region += 1;
  113. let mut queue = VecDeque::new();
  114. queue.push_back((cx, cy));
  115.  
  116. while let Some((x, y)) = queue.pop_front() {
  117. if let Cell::Used = grid[y][x] {
  118. grid[y][x] = Cell::Region(current_region);
  119. } else {
  120. continue;
  121. }
  122.  
  123. for &(dx, dy) in &[(0, -1), (-1, 0), (0, 1), (1, 0)] {
  124. let nx = x as isize + dx;
  125. let ny = y as isize + dy;
  126. if nx < 0 || nx > 127 || ny < 0 || ny > 127 {
  127. continue;
  128. }
  129.  
  130. queue.push_back((nx as usize, ny as usize));
  131. }
  132. }
  133. }
  134. }
  135.  
  136. println!("part 2: {}", current_region);
  137. }
  138.  
  139. fn main() {
  140. let input = env::args().nth(1).expect("input");
  141. part1(&input);
  142. part2(&input);
  143. }
Add Comment
Please, Sign In to add comment