-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmain.go
104 lines (85 loc) · 1.4 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
package main
func fs1(elves int) int {
root := &Elf{
id: 1,
presents: 1,
}
previous := root
for i := 2; i <= elves; i++ {
elf := &Elf{
id: i,
presents: 1,
}
previous.left = elf
previous = elf
if i == elves {
elf.left = root
}
}
cur := root
for {
if cur.isOver(elves) {
return cur.id
}
cur.stealLeft()
cur = cur.left
}
}
type Elf struct {
id int
presents int
left *Elf
}
func (e *Elf) isOver(elves int) bool {
return e.presents == elves
}
func (e *Elf) stealLeft() {
if e.presents == 0 {
return
}
e.presents += e.left.presents
e.left = e.left.left
}
func (e *Elf) stealMiddle(remaining int) {
moves := 0
if remaining%2 == 1 {
moves = remaining / 2
} else {
moves = remaining/2 - 1
}
var previous *Elf
target := e
for i := 0; i < moves; i++ {
previous = target
target = target.left
}
e.presents += target.presents
previous.left = target.left
}
func fs2(elves int) int {
circle := make([]int, elves)
for i := 0; i < elves; i++ {
circle[i] = i + 1
}
for i := 0; ; {
if elves == 2 {
return circle[i]
}
next := 0
next = elves / 2
next = (i + next) % elves
if next == 0 {
circle = circle[1:]
} else if next == elves-1 {
circle = circle[:elves-1]
} else {
circle = append(circle[:next], circle[next+1:]...)
}
elves--
if next < i {
i = i % elves
} else {
i = (i + 1) % elves
}
}
}