Skip to content

Commit ef0e329

Browse files
committed
2025-day02 optimised
1 parent 0a976ac commit ef0e329

File tree

3 files changed

+46
-14
lines changed

3 files changed

+46
-14
lines changed

2025/day02/.bench

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"Lines":[{"Name":"Part 1","N":43,"NsPerOp":25847627,"AllocedBytesPerOp":0,"AllocsPerOp":0,"MBPerS":0,"Measured":1,"Ord":0},{"Name":"Part 2","N":3,"NsPerOp":452777889,"AllocedBytesPerOp":0,"AllocsPerOp":0,"MBPerS":0,"Measured":1,"Ord":0}],"Measured":1}
1+
{"Lines":[{"Name":"Part 1","N":50,"NsPerOp":23611500,"AllocedBytesPerOp":0,"AllocsPerOp":0,"MBPerS":0,"Measured":1,"Ord":0},{"Name":"Part 2","N":36,"NsPerOp":30616929,"AllocedBytesPerOp":0,"AllocsPerOp":0,"MBPerS":0,"Measured":1,"Ord":0}],"Measured":1}

2025/day02/part1.go

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,23 @@ func doPartOne(input string) int {
1414
fmt.Sscanf(line, "%d-%d", &id1, &id2)
1515
for id := id1; id <= id2; id++ {
1616
idstring := strconv.Itoa(id)
17-
if len(idstring)%2 != 0 {
17+
idlen := len(idstring)
18+
19+
// Must have even length
20+
if idlen&1 != 0 {
1821
continue
1922
}
20-
mid := len(idstring) / 2
21-
if idstring[:mid] == idstring[mid:] {
23+
24+
mid := idlen >> 1
25+
// Compare halves byte by byte for better performance
26+
match := true
27+
for i := 0; i < mid; i++ {
28+
if idstring[i] != idstring[mid+i] {
29+
match = false
30+
break
31+
}
32+
}
33+
if match {
2234
ans += id
2335
}
2436
}

2025/day02/part2.go

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package main
22

33
import (
4-
"aocli/utils"
54
"fmt"
65
"strconv"
76
"strings"
@@ -13,27 +12,48 @@ func doPartTwo(input string) int {
1312
for _, line := range lines {
1413
var id1, id2 int
1514
fmt.Sscanf(line, "%d-%d", &id1, &id2)
16-
nextid:
1715
for id := id1; id <= id2; id++ {
1816
idstring := strconv.Itoa(id)
19-
mid := len(idstring) / 2
20-
for i := 1; i <= mid; i++ {
21-
if len(idstring)%i != 0 {
17+
idlen := len(idstring)
18+
19+
// Single digit always matches
20+
if idlen == 1 {
21+
ans += id
22+
continue
23+
}
24+
25+
// Check if the number can be split into repeating chunks
26+
found := false
27+
for chunkSize := 1; chunkSize <= idlen/2; chunkSize++ {
28+
// Only check divisors of the length
29+
if idlen%chunkSize != 0 {
2230
continue
2331
}
24-
chunks := utils.ChunkSlice([]rune(idstring), i)
32+
33+
// Check if all chunks match the first chunk
2534
match := true
26-
for i := 1; i < len(chunks); i++ {
27-
if string(chunks[i]) != string(chunks[0]) {
28-
match = false
35+
for pos := chunkSize; pos < idlen; pos += chunkSize {
36+
for offset := 0; offset < chunkSize; offset++ {
37+
if idstring[offset] != idstring[pos+offset] {
38+
match = false
39+
break
40+
}
41+
}
42+
if !match {
2943
break
3044
}
3145
}
46+
3247
if match {
3348
ans += id
34-
continue nextid
49+
found = true
50+
break
3551
}
3652
}
53+
54+
if found {
55+
continue
56+
}
3757
}
3858
}
3959
return ans

0 commit comments

Comments
 (0)