Advertisement
krzysz00

Advent of code, day 10b

Dec 10th, 2017
95
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 1.75 KB | None | 0 0
  1. #!/usr/bin/env run-cargo-script
  2. // cargo-deps: itertools
  3. #![feature(inclusive_range_syntax)]
  4. extern crate itertools;
  5. use itertools::Itertools;
  6.  
  7. use std::io::{stdin};
  8.  
  9. fn reverse_circular<T>(array: &mut [T], from: usize, to: usize) {
  10.     // To can be over the length of the array, indexing is mod len
  11.     if to <= from {
  12.         return;
  13.     }
  14.     let to = to - 1;
  15.     let n_swaps = (to - from)/2 + 1;
  16.     for delta in 0..n_swaps {
  17.         let idx_a = (from + delta) % array.len();
  18.         let idx_b = (to - delta) % array.len();
  19.         array.swap(idx_a, idx_b);
  20.     }
  21. }
  22.  
  23. const EXTRA_LENGTHS: [usize; 5] = [17, 31, 73, 47, 23];
  24. fn sparse_hash(lengths: &[usize], n_rounds: usize) -> Vec<u8> {
  25.     let mut skip_length = 0;
  26.     let mut current_position = 0;
  27.  
  28.     let mut data: Vec<u8> = (0..=255).into_iter().collect();
  29.     for _ in 0..n_rounds {
  30.         for length in lengths.iter().chain(EXTRA_LENGTHS.iter()) {
  31.             reverse_circular(&mut data, current_position, current_position + length);
  32.             current_position = (current_position + length + skip_length) % data.len();
  33.             skip_length += 1;
  34.         }
  35.     }
  36.     data
  37. }
  38.  
  39. const BLOCK_SIZE: usize = 16;
  40. fn dense_hash(data: &[u8]) -> Vec<u8> {
  41.     data.chunks(BLOCK_SIZE)
  42.                 .map(|b| b.iter().cloned()
  43.                      .fold1(|x, y| x ^ y).expect("Empty block"))
  44.         .collect()
  45. }
  46.  
  47. const N_ROUNDS: usize = 64;
  48.  
  49. fn main() {
  50.     let mut line: String = String::new();
  51.     stdin().read_line(&mut line).expect("Error reading input");
  52.     let lengths: Vec<usize> = line.trim().bytes().map(|x| x as usize).collect();
  53.     let data = sparse_hash(&lengths, N_ROUNDS);
  54.     for byte in dense_hash(&data) {
  55.         print!("{:02x}", byte)
  56.     }
  57.     println!("");
  58. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement