-
Notifications
You must be signed in to change notification settings - Fork 3
/
main.go
124 lines (104 loc) · 2.18 KB
/
main.go
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
package main
import (
"fmt"
"strconv"
lib "github.com/teivah/advent-of-code"
)
func fs1(players, lastMarble int) int {
board := []int{0, 1}
scores := make([]int, players)
i := 1
for marble := 2; marble <= lastMarble; marble++ {
if marble%23 == 0 {
player := (marble - 1) % players
scores[player] += marble
j := lib.Mod(i-7, len(board))
scores[player] += board[j]
if j == 0 {
board = board[1:]
} else if j == len(board)-1 {
board = board[:len(board)-1]
} else {
res := copy(board[:j])
res = append(res, board[j+1:]...)
board = res
}
i = j
continue
}
i = (i + 1) % (len(board))
if i == 0 {
// Second
res := []int{0, marble}
res = append(res, board[1:]...)
board = res
i = 1
} else if i == len(board)-1 {
// Last
board = append(board, marble)
i++
} else {
// Middle
res := copy(board[:i+1])
res = append(res, marble)
res = append(res, board[i+1:]...)
board = res
i++
}
}
maxScore := lib.NewMaxer()
for _, score := range scores {
maxScore.Add(score)
}
return maxScore.Get()
}
func copy(s []int) []int {
res := make([]int, len(s))
for i, v := range s {
res[i] = v
}
return res
}
func fs2(players, lastMarble int) int {
scores := make([]int, players)
current := &Node{value: 0}
current.previous = current
current.next = current
for marble := 1; marble <= lastMarble; marble++ {
if marble%23 == 0 {
player := (marble - 1) % players
scores[player] += marble
for i := 0; i < 7; i++ {
current = current.previous
}
scores[player] += current.value
current.previous.next = current.next
current.next.previous = current.previous
current = current.next
continue
}
node := &Node{value: marble, previous: current.next, next: current.next.next}
current.next.next.previous = node
current.next.next = node
current = node
}
maxScore := lib.NewMaxer()
for _, score := range scores {
maxScore.Add(score)
}
return maxScore.Get()
}
type Node struct {
value int
previous *Node
next *Node
}
func (n *Node) print() {
s := strconv.Itoa(n.value)
cur := n.next
for cur != n {
s += "," + strconv.Itoa(cur.value)
cur = cur.next
}
fmt.Println(s)
}