-
Notifications
You must be signed in to change notification settings - Fork 0
/
day20.ps1
156 lines (117 loc) · 3.98 KB
/
day20.ps1
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
# --- Day 20: Grove Positioning System ---
# Picture a wagon wheel with numbers written on the rim between the spokes.
# Lift the number of interest above the wheel, then spin the wheel that number of positions, and re-insert
# When all numbers on the wheel have been visited. Find where the Zero is located ,
# then rotate the wheel 1000,2000, and 3000 times, and look for first number to the right of zero
function rot([System.Collections.ArrayList]$t,[int]$times)
{
$direction = [math]::Sign($times)
$rotations = [math]::abs($times)
while ($rotations -gt 0) {
#rotate array +/- 1
$last = $t.count - 1
$first = 0
# if the number is negative, rotate right
if ($direction -eq -1 ) {
$tmp = $t[$last]
[void]$t.RemoveAt($last)
[void]$t.Insert($first,$tmp)
$rotations--
# positive, rotate left
} elseif ($direction -eq 1) {
$tmp = $t[$first]
[void]$t.RemoveAt($first)
[void]$t.add($tmp)
$rotations--
}
}
}
class score {
[int64]$value
[int]$originalindex
score ([int64]$v, [int]$idx) {
$this.value = $v
$this.originalindex = $idx
}
}
#$data= @(1, 2, -3, 3, -2, 0, 4)
$data = Get-Content .\input.txt
$s = New-Object "System.Collections.ArrayList"
for ($x=0; $x -lt $data.Count; $x++) {
$tmp = [score]::new($data[$x],$x)
$s.add($tmp)
}
# part 1
#step through each number based on the original index
for ($x=0; $x-lt $s.Count; $x++) {
# save the current score (number and index) that's about to be moved
foreach ($i in $s) {
if ($i.originalindex -eq $x) {
$current = [score]::new($i.value, $i.originalindex);
break;
}
}
#find current values location on the wheel before rotation
for ($j=0; $j -lt $s.Count; $j++) { if ($s[$j].originalindex -eq $current.originalindex) {$oldindex = $j;break } }
$s.RemoveAt($oldindex)
rot $s ($current.value % $s.Count )
$s.insert($oldindex,$current)
}
# Locate the index where the value 0 is.
for ($j=0;$j -lt $s.Count; $j++) {
if ($s[$j].value -eq 0) { $zero = $j}
}
# The wording on the question didnt' make sense to me.
# Originall I thought it meant mixing 1000x, then looking for the value after zero
# But it meant mix once, then spin the wheel.
$total = 0
rol $s 1000
$total += $s[$zero].value
rol $s 1000
$total += $s[$zero].value
rol $s 1000
$total += $s[$zero].value
"Total: {0}" -f $total
##
# Part 2
##
# Multiply each number by 811589153
# Mix 10x.
$key = 811589153
#$data= @(1, 2, -3, 3, -2, 0, 4)
$data = Get-Content .\input.txt
$s = New-Object "System.Collections.ArrayList"
for ($x=0; $x -lt $data.Count; $x++) {
$tmp = [score]::new(($data[$x]*$key),$x)
$s.add($tmp)
}
# part 1
#step through each number based on the original index
for ($mixes = 0; $mixes -lt 10; $mixes++) {
for ($x=0; $x-lt $s.Count; $x++) {
# save the current score (number and index) that's about to be moved
foreach ($i in $s) {
if ($i.originalindex -eq $x) {
$current = [score]::new($i.value, $i.originalindex);
break;
}
}
#find current values location on the wheel before rotation
for ($j=0; $j -lt $s.Count; $j++) { if ($s[$j].originalindex -eq $current.originalindex) {$oldindex = $j;break } }
$s.RemoveAt($oldindex)
rot $s ($current.value % $s.Count )
$s.insert($oldindex,$current)
}
}
# Locate the index where the value 0 is.
for ($j=0;$j -lt $s.Count; $j++) {
if ($s[$j].value -eq 0) { $zero = $j}
}
$total = 0
rol $s 1000
$total += $s[$zero].value
rol $s 1000
$total += $s[$zero].value
rol $s 1000
$total += $s[$zero].value
"Total: {0}" -f $total