-
Notifications
You must be signed in to change notification settings - Fork 0
/
day07.go
102 lines (91 loc) · 1.49 KB
/
day07.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
package main
import (
"flag"
"fmt"
"io/ioutil"
"log"
"math"
"strconv"
"strings"
)
var inputFile = flag.String("inputFile", "inputs/day07.input", "Relative file path to use as input.")
func main() {
flag.Parse()
input, lowest, highest := parseInput()
p1(input, lowest, highest)
p2(input, lowest, highest)
}
type CrabGroup map[int]int
func p1(cg CrabGroup, lo, hi int) {
tc := math.MaxInt
for i := lo; i < hi; i++ {
c := cost(cg, i)
if tc > c {
tc = c
} else {
break
}
}
fmt.Println(tc)
}
func cost(cg CrabGroup, pos int) int {
fuel := 0
for k, v := range cg {
fuel += abs(k-pos) * v
}
return fuel
}
func p2(cg CrabGroup, lo, hi int) {
tc := math.MaxInt
for i := lo; i < hi; i++ {
c := cost1(cg, i)
if tc > c {
tc = c
} else {
break
}
}
fmt.Println(tc)
}
func cost1(cg CrabGroup, pos int) int {
fuel := 0
for k, v := range cg {
// 1+2+3...+n = n(n+1)/2
if k > pos {
fuel += v * (k - pos) * (k - pos + 1) / 2
} else {
fuel += v * (pos - k) * (pos - k + 1) / 2
}
}
return fuel
}
func abs(a int) int {
if a < 0 {
return -a
}
return a
}
func parseInput() (CrabGroup, int, int) {
b, err := ioutil.ReadFile(*inputFile)
if err != nil {
log.Fatal(err)
}
lo := math.MaxInt
hi := math.MinInt
si := strings.Split(strings.TrimSpace(string(b)), ",")
cg := make(CrabGroup)
for _, v := range si {
if v == "" {
continue
}
vi, _ := strconv.Atoi(v)
if vi > hi {
hi = vi
}
if vi < lo {
lo = vi
}
cg[vi]++
}
return cg, lo, hi
}