-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
301 lines (255 loc) · 6.09 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
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
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
package main
import (
"bufio"
"flag"
"fmt"
"os"
"strconv"
"strings"
)
var (
methodP *string
)
func init() {
// Use Flags to run a part
methodP = flag.String("method", "p2", "The method/part that should be run, valid are p1,p2 and test")
flag.Parse()
}
func main() {
switch *methodP {
case "p1":
PartOne()
break
case "p2":
PartTwo()
break
case "test":
break
}
}
func PartOne() {
input := readInput()
// Count number of times 1,4,7,8 appear in output values
// 1 = len(2)
// 4 = len(4)
// 7 = len(3)
// 8 = len(7)
sum := 0
for _, v := range input {
output := strings.SplitAfter(v, "|")
outputs := strings.Split(strings.Trim(output[1], " "), " ")
for _, num := range outputs {
//output nums
if len(num) == 2 || len(num) == 3 || len(num) == 4 || len(num) == 7 {
sum++
}
}
}
fmt.Println(sum)
}
func PartTwo() {
input := readInput()
total := 0
// Count number of times 1,4,7,8 appear in output values
// 1 = len(2)
// 4 = len(4)
// 7 = len(3)
// 8 = len(7)
for _, v := range input {
var number1 string
var number4 string
var number7 string
var number8 string
var rest []string
output := strings.SplitAfter(v, "|")
outputs := strings.Split(strings.Trim(output[0], " "), " ")
// First the easy solves
for _, num := range outputs {
//output nums
switch len(num) {
case 2:
number1 = num
case 3:
number7 = num
case 4:
number4 = num
case 7:
number8 = num
default:
rest = append(rest, num)
}
}
a := "a"
b := "b"
c := "c"
d := "d"
e := "e"
f := "f"
g := "g"
// Now solve for rest
// try and work out what each character is
// a is the character missing between one and seven
a = strings.Replace(number7, string(number1[0]), "", -1)
a = strings.Replace(a, string(number1[1]), "", -1)
// c appears 8 times overall and also in 1 (appears 4 times in rest)
// f appears 9 times overall and also in 1 (appears 5 times in rest)
// count number1[0] and number1[1] and put them in above
sumcf := 0
if strings.Contains(rest[0], string(number1[0])) {
sumcf++
}
if strings.Contains(rest[1], string(number1[0])) {
sumcf++
}
if strings.Contains(rest[2], string(number1[0])) {
sumcf++
}
if strings.Contains(rest[3], string(number1[0])) {
sumcf++
}
if strings.Contains(rest[4], string(number1[0])) {
sumcf++
}
if strings.Contains(rest[5], string(number1[0])) {
sumcf++
}
if sumcf == 4 {
c = string(number1[0])
f = string(number1[1])
} else {
c = string(number1[1])
f = string(number1[0])
}
// Now do same for b and d
// b and d are in 4 (-c and f)
bd := strings.Replace(number4, c, "", -1)
bd = strings.Replace(bd, f, "", -1)
// b appears 4 times in rest and also in bd
// d appears 5 times in rest and also in bd
// count bd and put them in above
sumbd := 0
if strings.Contains(rest[0], string(bd[0])) {
sumbd++
}
if strings.Contains(rest[1], string(bd[0])) {
sumbd++
}
if strings.Contains(rest[2], string(bd[0])) {
sumbd++
}
if strings.Contains(rest[3], string(bd[0])) {
sumbd++
}
if strings.Contains(rest[4], string(bd[0])) {
sumbd++
}
if strings.Contains(rest[5], string(bd[0])) {
sumbd++
}
if sumbd == 4 {
b = string(bd[0])
d = string(bd[1])
} else {
b = string(bd[1])
d = string(bd[0])
}
// Do eg now
// e and g are in 8 (-abcdf)
eg := strings.ReplaceAll(number8, a, "")
eg = strings.ReplaceAll(eg, b, "")
eg = strings.ReplaceAll(eg, c, "")
eg = strings.ReplaceAll(eg, d, "")
eg = strings.ReplaceAll(eg, f, "")
// e appears 3 times in rest and also in eg
// g appears 6 times in rest and also in ge
// count bd and put them in above
sumeg := 0
if strings.Contains(rest[0], string(eg[0])) {
sumeg++
}
if strings.Contains(rest[1], string(eg[0])) {
sumeg++
}
if strings.Contains(rest[2], string(eg[0])) {
sumeg++
}
if strings.Contains(rest[3], string(eg[0])) {
sumeg++
}
if strings.Contains(rest[4], string(eg[0])) {
sumeg++
}
if strings.Contains(rest[5], string(eg[0])) {
sumeg++
}
if sumeg == 3 {
e = string(eg[0])
g = string(eg[1])
} else {
e = string(eg[1])
g = string(eg[0])
}
//fmt.Println(a + b + c + d + e + f + g)
// now that we have all characters, we should be able to work out the outputs
checks := strings.Split(strings.Trim(output[1], " "), " ")
numString := ""
for _, checkNumber := range checks {
numString += strconv.Itoa(checkNum(a, b, c, d, e, f, g, checkNumber))
//fmt.Println(checkNumber, "=", checkNum(a, b, c, d, e, f, g, checkNumber))
}
backtoInt, _ := strconv.Atoi(numString)
total += backtoInt
//fmt.Println(backtoInt)
}
fmt.Println(total)
}
// Given a set of input values and a checkNum, work out what this number is
func checkNum(a, b, c, d, e, f, g string, checkNum string) int {
hasa := strings.ContainsAny(checkNum, a)
hasb := strings.ContainsAny(checkNum, b)
hasc := strings.ContainsAny(checkNum, c)
hasd := strings.ContainsAny(checkNum, d)
hase := strings.ContainsAny(checkNum, e)
hasf := strings.ContainsAny(checkNum, f)
hasg := strings.ContainsAny(checkNum, g)
// Check each number
if hasa && hasb && hasc && hase && hasf && hasg && len(checkNum) == 6 {
return 0
}
if hasc && hasf && len(checkNum) == 2 {
return 1
}
if hasa && hasc && hasd && hase && hasg && len(checkNum) == 5 {
return 2
}
if hasa && hasc && hasd && hasf && hasg && len(checkNum) == 5 {
return 3
}
if hasb && hasc && hasd && hasf && len(checkNum) == 4 {
return 4
}
if hasa && hasb && hasd && hasf && hasg && len(checkNum) == 5 {
return 5
}
if hasa && hasb && hasd && hase && hasf && hasg && len(checkNum) == 6 {
return 6
}
if hasa && hasc && hasf && len(checkNum) == 3 {
return 7
}
if hasa && hasb && hasc && hasd && hase && hasf && hasg && len(checkNum) == 7 {
return 8
}
return 9
}
// Read data from input.txt
// Return the string, so that we can deal with it however
func readInput() []string {
var input []string
f, _ := os.Open("input.txt")
scanner := bufio.NewScanner(f)
for scanner.Scan() {
input = append(input, scanner.Text())
}
return input
}