@@ -12,12 +12,18 @@ const (
12
12
fnum rune = '0'
13
13
lnum rune = '9'
14
14
period rune = '.'
15
+ star rune = '*'
15
16
)
16
17
17
18
type Slice struct {
18
19
first , last int
19
20
}
20
21
22
+ type SliceContext struct {
23
+ slice Slice
24
+ line int
25
+ }
26
+
21
27
func getNumbers (line []rune ) []Slice {
22
28
var slices []Slice
23
29
cur := Slice {first : - 1 , last : - 1 }
@@ -42,10 +48,41 @@ func getNumbers(line []rune) []Slice {
42
48
}
43
49
}
44
50
}
51
+ if cur .first > - 1 && cur .last > - 1 {
52
+ tmp := Slice {first : cur .first , last : cur .last }
53
+ slices = append (slices , tmp )
54
+ } else if cur .first > - 1 {
55
+ tmp := Slice {first : cur .first , last : cur .first }
56
+ slices = append (slices , tmp )
57
+ }
45
58
return slices
46
59
47
60
}
48
61
62
+ func getNumber (line []rune , pos int ) Slice {
63
+ var lrange , rrange int
64
+ for i := pos ; i >= 0 ; i -- {
65
+ if line [i ] <= lnum && line [i ] >= fnum {
66
+ lrange = i
67
+ } else {
68
+ break
69
+ }
70
+ }
71
+ for i := pos ; i < len (line ); i ++ {
72
+ if line [i ] <= lnum && line [i ] >= fnum {
73
+ rrange = i
74
+ } else {
75
+ break
76
+ }
77
+ }
78
+ return Slice {first : lrange , last : rrange }
79
+ }
80
+
81
+ func getNumberInt (line []rune , pos int ) int {
82
+ sliced := getNumber (line , pos )
83
+ return stringToInt (string (line [sliced .first : sliced .last + 1 ]))
84
+ }
85
+
49
86
func stringToInt (slice string ) int {
50
87
res , err := strconv .Atoi (slice )
51
88
if err != nil {
@@ -67,6 +104,7 @@ func isPartNumber(num Slice, curline []rune, preline []rune, nexline []rune) int
67
104
} else {
68
105
rrange = num .last
69
106
}
107
+
70
108
if preline != nil {
71
109
for i := lrange ; i <= rrange ; i ++ {
72
110
if (preline [i ] > lnum || preline [i ] < fnum ) && (preline [i ] != period ) {
@@ -90,22 +128,22 @@ func isPartNumber(num Slice, curline []rune, preline []rune, nexline []rune) int
90
128
}
91
129
}
92
130
if lrange != num .first && rrange != num .last {
93
- if (( curline [lrange ] > lnum || curline [ num . first - lrange ] < fnum ) && ( curline [ lrange ] != period )) || (( curline [rrange ] > lnum || curline [ rrange ] < fnum ) && ( curline [ rrange ] != period ) ) {
131
+ if (curline [lrange ] != period ) || (curline [rrange ] != period ) {
94
132
if num .first == num .last {
95
133
return stringToInt (string (curline [num .first ]))
96
134
}
97
135
return stringToInt (string (curline [num .first : num .last + 1 ]))
98
136
}
99
137
100
138
} else if num .first == lrange && num .last != rrange {
101
- if ( curline [rrange ] > lnum || curline [ rrange ] < fnum ) && ( curline [ rrange ] != period ) {
139
+ if curline [rrange ] != period {
102
140
if num .first == num .last {
103
141
return stringToInt (string (curline [num .first ]))
104
142
}
105
143
return stringToInt (string (curline [num .first : num .last + 1 ]))
106
144
}
107
145
} else if num .last == rrange && num .first != lrange {
108
- if ( curline [lrange ] > lnum || curline [ lrange ] < fnum ) && ( curline [ lrange ] != period ) {
146
+ if curline [lrange ] != period {
109
147
if num .first == num .last {
110
148
return stringToInt (string (curline [num .first ]))
111
149
}
@@ -118,46 +156,132 @@ func isPartNumber(num Slice, curline []rune, preline []rune, nexline []rune) int
118
156
func Exercise1 (input [][]rune ) {
119
157
fmt .Println ("Exercise 1" )
120
158
var sum , cur int
121
- reader := bufio .NewReader (os .Stdin )
122
159
for idx , line := range input {
123
- // fmt.Printf("Line %d:", idx)
124
160
slices := getNumbers (line )
125
- fmt .Printf ("Line %d: " , idx )
126
161
for _ , slice := range slices {
127
- // if slice.last != -1 {
128
- // fmt.Printf("%s, ", string(line[slice.first:slice.last+1]))
129
- // } else {
130
- // fmt.Printf("%s, ", string(line[slice.first]))
131
- // }
162
+
132
163
if idx == 0 && len (input ) > idx + 1 {
133
164
cur = isPartNumber (slice , line , nil , input [idx + 1 ])
134
165
} else if idx == len (input )- 1 {
135
166
cur = isPartNumber (slice , line , input [idx - 1 ], nil )
136
167
} else {
137
168
cur = isPartNumber (slice , line , input [idx - 1 ], input [idx + 1 ])
138
169
}
139
- fmt .Printf ("%d, " , cur )
140
- sum += cur
170
+ if cur != 0 {
171
+ sum += cur
172
+ }
141
173
}
142
174
143
- if idx > 0 {
144
- fmt .Printf ("\n %s" , string (input [idx - 1 ]))
175
+ }
176
+ fmt .Println ("Sum: " , sum )
177
+ }
178
+
179
+ func IsDigit (char rune ) bool {
180
+ return char >= fnum && char <= lnum
181
+ }
182
+
183
+ func isGearStar (spos int , curline []rune , preline []rune , nexline []rune ) int {
184
+ var lrange , rrange int
185
+ if spos >= 1 {
186
+ lrange = spos - 1
187
+ } else {
188
+ lrange = 0
189
+ }
190
+ if spos < len (curline )- 1 {
191
+ rrange = spos + 1
192
+ } else {
193
+ rrange = spos
194
+ }
195
+ nums := make ([]int , 0 )
196
+ if preline != nil {
197
+ for i := lrange ; i <= rrange ; i ++ {
198
+ if IsDigit (preline [i ]) {
199
+ sliced := getNumber (preline , i )
200
+ nums = append (nums , stringToInt (string (preline [sliced .first :sliced .last + 1 ])))
201
+ if sliced .first <= spos && sliced .last >= spos {
202
+ break
203
+ }
204
+ }
145
205
}
146
- fmt .Printf ("\n %s" , string (line ))
147
- if idx < len (input )- 1 {
148
- fmt .Printf ("\n %s" , string (input [idx + 1 ]))
206
+ }
207
+ if nexline != nil {
208
+ for i := lrange ; i <= rrange ; i ++ {
209
+ if IsDigit (nexline [i ]) {
210
+ sliced := getNumber (nexline , i )
211
+ nums = append (nums , stringToInt (string (nexline [sliced .first :sliced .last + 1 ])))
212
+ if sliced .first <= spos && sliced .last >= spos {
213
+ break
214
+ }
215
+ }
149
216
}
150
- fmt .Println ("\n Check line above: " )
151
- _ , _ = reader .ReadString ('\n' )
152
217
}
153
- fmt .Println ("Sum: " , sum )
218
+ if lrange != spos && rrange != spos {
219
+ if IsDigit (curline [lrange ]) {
220
+ nums = append (nums , getNumberInt (curline , lrange ))
221
+ }
222
+ if IsDigit (curline [rrange ]) {
223
+ nums = append (nums , getNumberInt (curline , rrange ))
224
+ }
225
+
226
+ } else if spos == lrange && spos != rrange {
227
+ if IsDigit (curline [rrange ]) {
228
+ nums = append (nums , getNumberInt (curline , rrange ))
229
+ }
230
+ } else if spos == rrange && spos != lrange {
231
+ if IsDigit (curline [lrange ]) {
232
+ nums = append (nums , getNumberInt (curline , lrange ))
233
+ }
234
+ }
235
+ if len (nums ) == 2 {
236
+ // fmt.Println("Gear: ", nums, " = ", nums[0]*nums[1])
237
+ return nums [0 ] * nums [1 ]
238
+ }
239
+ return 0
240
+ }
241
+
242
+ func Exercise2 (input [][]rune ) {
243
+ fmt .Println ("Exercise 2" )
244
+ var sum , mygear int
245
+ for idx , line := range input {
246
+ for index , myrune := range line {
247
+ if myrune != star {
248
+ continue
249
+ }
250
+ var lrange , rrange int
251
+ if index >= 1 {
252
+ lrange = index - 1
253
+ } else {
254
+ lrange = 0
255
+ }
256
+ if index < len (line )- 1 {
257
+ rrange = index + 1
258
+ } else {
259
+ rrange = index
260
+ }
261
+ if idx == 0 && len (input ) > idx + 1 {
262
+ fmt .Printf ("Selected at index %d: \n \t [%d:%d]=%s\n \t %s\n " , index , lrange , rrange + 1 , string (line [lrange :rrange + 1 ]), string (input [idx + 1 ][lrange :rrange + 1 ]))
263
+ // mygear = isGearStar(index, line, nil, input[idx+1])
264
+ } else if idx == len (input )- 1 {
265
+ mygear = isGearStar (index , line , input [idx - 1 ], nil )
266
+ // fmt.Printf("Selected at index %d: \n\t%s\n\t%s\n", index, string(input[idx-1][lrange:rrange+1]), string(line[lrange:rrange+1]))
267
+ } else {
268
+ mygear = isGearStar (index , line , input [idx - 1 ], input [idx + 1 ])
269
+ // fmt.Printf("Selected at index %d: \n\t%s\n\t[%d:%d]=%s\n\t%s\n", index, string(input[idx-1][lrange:rrange+1]), lrange, rrange+1, string(line[lrange:rrange+1]), string(input[idx+1][lrange:rrange+1]))
270
+ }
271
+ if mygear > 0 {
272
+ sum += mygear
273
+ }
274
+ }
275
+ }
276
+ fmt .Println ("Gear Sum: " , sum )
277
+
154
278
}
155
279
156
280
func main () {
157
281
var inputfile string
158
282
var exercise1 bool
159
283
flag .StringVar (& inputfile , "input" , "input.txt" , "Input file" )
160
- flag .BoolVar (& exercise1 , "exercise1" , true , "Exercise 1 is True, Exercise 2 is False" )
284
+ flag .BoolVar (& exercise1 , "exercise1" , false , "Exercise 1 is True, Exercise 2 is False" )
161
285
flag .Parse ()
162
286
163
287
file , err := os .Open (inputfile )
@@ -172,7 +296,8 @@ func main() {
172
296
height , width := 0 , 0
173
297
for scanner .Scan () {
174
298
height ++
175
- if charlong := scanner .Text (); width != 0 && width < len (charlong ) {
299
+ charlong := scanner .Text ()
300
+ if width != 0 && width < len (charlong ) {
176
301
width = len (charlong )
177
302
} else if width == 0 {
178
303
width = len (charlong )
@@ -197,6 +322,6 @@ func main() {
197
322
if exercise1 {
198
323
Exercise1 (myrune )
199
324
} else {
200
- fmt . Println ( "Exercise 2" )
325
+ Exercise2 ( myrune )
201
326
}
202
327
}
0 commit comments