-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path22.tcl
executable file
·92 lines (85 loc) · 2.56 KB
/
22.tcl
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
#!/usr/bin/env tclsh
proc aoc_22 { } {
set result [list]
set data1 [aoc_read "22.data" 1 =]
set data2 [aoc_read "22.data" 2 =]
# Part 1
if {1} {
set count 0
foreach secret [split $data1 "\n"] {
#puts "$secret: [calculate_n $secret 2000]"
incr count [calculate_n $secret 2000]
}
lappend result $count
}
# Part 2
if {1} {
set orders [buyer_orders [split $data2 "\n"] 2000]
set bananas_pattern [best_pattern $orders]
#puts $bananas_pattern
lappend result [lindex $bananas_pattern 0]
}
return $result
}
proc best_pattern { orders } {
set most_bananas 0
set best_pattern {}
foreach {pattern bananas} $orders {
if {$bananas > $most_bananas} {
set most_bananas $bananas
set best_pattern $pattern
}
}
return [list $most_bananas $best_pattern]
}
proc buyer_orders { secrets n } {
set buyer_n 1
foreach secret $secrets {
set clues [list]
for {set i 0} {$i < $n} {incr i; set secret $secret_new} {
set secret_new [calculate $secret]
set order_old [string index $secret end]
set order_new [string index $secret_new end]
set clue [expr { $order_new - $order_old }]
set clues [list {*}[lrange $clues end-2 end] $clue]
if {[llength $clues] < 4} continue
if {$order_new < 0} continue
if {[info exists buyer($buyer_n.$clues)]} continue
set buyer($buyer_n.$clues) sold
incr orders_s($clues) $order_new
}
incr buyer_n
}
return [array get orders_s]
}
proc calculate_n { secret n } {
for {set i 0} {$i < $n} {incr i} {
set secret [calculate $secret]
}
return $secret
}
proc calculate { secret } {
set step1 [expr { $secret * 64 }]
set secret [mix $secret $step1]
set secret [prune $secret]
set step2 [expr { entier($secret / 32) }]
set secret [mix $secret $step2]
set secret [prune $secret]
set step3 [expr { $secret * 2048 }]
set secret [mix $secret $step3]
set secret [prune $secret]
return $secret
}
proc mix { secret number } {
expr { $number ^ $secret }
}
proc prune { secret } {
expr { $secret % 16777216 }
}
# --------------------------------------------------------------------
if {[file tail $argv0] eq [file tail [info script]]} {
source "rd.tcl"
# Example results: 37327623 23
# My results: 16953639210 1863
puts [aoc_22]
}