aboutsummaryrefslogtreecommitdiff
path: root/day10/part2
blob: 5a55d7d4062b7e80d6d2ea14b49803991522514c (plain)
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
#!/usr/bin/env ruby

class KnotHash
  def initialize
    @list = (0...256).to_a
    @skip = 0
    @ptr = 0
  end

  def reverse_sublist(len)
    if @ptr + len > @list.length then
      reverse_wrapping_sublist(len)
    else
      reverse_contained_sublist(len)
    end

    inc_ptr(len)
  end

  def compress
    p = 0
    out = []

    16.times do
      out << @list[p...p+16].inject(:^)
      p += 16
    end

    return out
  end

  def hexdigest
    dense = self.compress
    hex = dense.map { |i| "%02x" % i }
    return hex.join
  end

  def to_a
    return @list
  end

  def to_s
    l = @list.dup
    l[@ptr] = "[#{l[@ptr]}]"
    return "#{l.join(' ')} skip = #{@skip}"
  end

  private

  def reverse_wrapping_sublist(len)
    dbl = @list.dup + @list.dup
    sublist = dbl[@ptr...@ptr+len].reverse

    (@ptr...@ptr+len).each do |i|
      @list[i % @list.length] = sublist[i-@ptr]
    end
  end

  def reverse_contained_sublist(len)
    sublist = @list[@ptr...@ptr+len].reverse

    (@ptr...@ptr+len).each do |i|
      @list[i] = sublist[i-@ptr]
    end
  end

  def inc_ptr(len)
    @ptr += len
    @ptr += @skip
    @ptr = @ptr % @list.length
    @skip += 1
  end
end

input = gets.chomp.chars.map(&:ord) + [17,31,73,47,23]

hash = KnotHash.new

64.times do
  input.each do |len|
    hash.reverse_sublist(len)
  end
end

puts hash.hexdigest