1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99
//! # [Day 10: Knot Hash](http://adventofcode.com/2017/day/10) //! //! You come across some programs that are trying to implement a software //! emulation of a hash based on knot-tying. The hash these programs are //! implementing isn't very strong, but you decide to help them anyway. You //! make a mental note to remind the Elves later not to <span //! title="NEW CRYPTOSYSTEM WHO DIS">invent their own cryptographic //! functions</span>. //! //! This hash function simulates tying a knot in a circle of string with 256 //! marks on it. Based on the input to be hashed, the function repeatedly //! selects a span of string, brings the ends together, and gives the span a //! half-twist to reverse the order of the marks within it. After doing this //! many times, the order of the marks is used to build the resulting hash. //! //! ```text //! 4--5 pinch 4 5 4 1 //! / \ 5,0,1 / \/ \ twist / \ / \ //! 3 0 --> 3 0 --> 3 X 0 //! \ / \ /\ / \ / \ / //! 2--1 2 1 2 5 //! ``` //! //! See [knot_hash](../knot_hash/index.html) use super::knot_hash; /// However, you should instead use the standard list size of `256` (with /// values `0` to `255`) and the sequence of *lengths* in your puzzle input. /// Once this process is complete, *what is the result of multiplying the /// first two numbers in the list*? pub fn part1(input: &str) -> u16 { let lengths = input .split(',') .map(|l| l.parse::<u8>().expect("Unexpected non-u8 length")) .collect::<Vec<_>>(); let hash = knot_hash::hash_lengths(255, &lengths, 1); (hash[0] as u16) * (hash[1] as u16) } /// Finally, the standard way to represent a Knot Hash is as a single /// [hexadecimal] string; the final output is the dense hash in hexadecimal /// notation. Because each number in your dense hash will be between `0` and /// `255` (inclusive), always represent each number as two hexadecimal /// digits (including a leading zero as necessary). So, if your first three /// numbers are `64, 7, 255`, they correspond to the hexadecimal numbers /// `40, 07, ff`, and so the first six characters of the hash would be /// `4007ff`. Because every Knot Hash is sixteen such numbers, the /// hexadecimal representation is always `32` hexadecimal digits (`0`-`f`) /// long. /// /// Here are some example hashes: /// /// - The empty string becomes `a2582a3a0e66e6e86e3812dcb672a272`. /// /// ``` /// # use advent_solutions::advent2017::day10::part2; /// assert_eq!(part2(""), "a2582a3a0e66e6e86e3812dcb672a272"); /// ``` /// /// - `AoC 2017` becomes `33efeb34ea91902bb2f59c9920caa6cd`. /// /// ``` /// # use advent_solutions::advent2017::day10::part2; /// assert_eq!(part2("AoC 2017"), "33efeb34ea91902bb2f59c9920caa6cd"); /// ``` /// /// - `1,2,3` becomes `3efbe78a8d82f29979031a4aa0b16a9d`. /// /// ``` /// # use advent_solutions::advent2017::day10::part2; /// assert_eq!(part2("1,2,3"), "3efbe78a8d82f29979031a4aa0b16a9d"); /// ``` /// /// - `1,2,4` becomes `63960835bcdc130f0b66d7ff4f6a5a8e`. /// /// ``` /// # use advent_solutions::advent2017::day10::part2; /// assert_eq!(part2("1,2,4"), "63960835bcdc130f0b66d7ff4f6a5a8e"); /// ``` /// /// Treating your puzzle input as a string of ASCII characters, *what is the /// Knot Hash of your puzzle input?* Ignore any leading or trailing /// whitespace you might encounter. /// /// [hexadecimal]: https://en.wikipedia.org/wiki/Hexadecimal pub fn part2(input: &str) -> String { knot_hash::hash_str(input, 64).iter() .map(|x| format!("{:02x}", x)) .collect::<String>() } pub fn parse_input(input: &str) -> &str { &input[..input.len() - 1] } test_day!("10", 4480, "c500ffe015c83b60fad2e4b7d59dabc4");