Skip to content

Commit 1a940e3

Browse files
committed
2025 day 2
1 parent 0a33111 commit 1a940e3

File tree

4 files changed

+168
-0
lines changed

4 files changed

+168
-0
lines changed

2025/2/Makefile

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
input:
2+
http "https://adventofcode.com/2025/day/2/input" "Cookie:session=${AOC_SESSION};" >input
3+
4+
main1:
5+
go build -o main1 main1.go common.go
6+
7+
main2:
8+
go build -o main2 main2.go common.go
9+
10+
.PHONY: run1 run2 clean
11+
12+
run1: main1 input
13+
./main1 <input
14+
15+
run2: main2 input
16+
./main2 <input
17+
18+
clean:
19+
rm -f main1 main2 input
20+

2025/2/common.go

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"os"
6+
"strconv"
7+
"strings"
8+
)
9+
10+
type Range struct {
11+
start, stop, digits int
12+
}
13+
14+
func (r Range) InvalidIDs(chunkLen int) map[int]struct{} {
15+
repeat := r.digits / chunkLen
16+
17+
invalids := make(map[int]struct{})
18+
19+
for i := r.start / pow10(r.digits-chunkLen); i <= r.stop/(pow10(r.digits-chunkLen)+1); i++ {
20+
id := buildID(i, repeat)
21+
if id < r.start {
22+
continue
23+
}
24+
if id > r.stop {
25+
break
26+
}
27+
invalids[id] = struct{}{}
28+
}
29+
30+
return invalids
31+
}
32+
33+
func parseInput() []Range {
34+
scanner := bufio.NewScanner(os.Stdin)
35+
scanner.Scan()
36+
var list []Range
37+
for _, r := range strings.Split(scanner.Text(), ",") {
38+
limits := strings.Split(r, "-")
39+
start, _ := strconv.Atoi(limits[0])
40+
stop, _ := strconv.Atoi(limits[1])
41+
startDigits, stopDigits := digits(start), digits(stop)
42+
43+
// split the range into two ranges
44+
// e.g., start->999 and 1000->stop
45+
// to work on single digits range later
46+
if startDigits == stopDigits {
47+
list = append(list, Range{start, stop, startDigits})
48+
} else {
49+
list = append(list, Range{start, pow10(stopDigits-1) - 1, startDigits})
50+
list = append(list, Range{pow10(startDigits), stop, stopDigits})
51+
}
52+
}
53+
return list
54+
}
55+
56+
// faster than
57+
// int(math.Pow10(exp))
58+
func pow10(exp int) int {
59+
base := 10
60+
result := 1
61+
for {
62+
if exp&1 == 1 {
63+
result *= base
64+
}
65+
exp >>= 1
66+
if exp == 0 {
67+
break
68+
}
69+
base *= base
70+
}
71+
return result
72+
}
73+
74+
// faster than
75+
// len(strconv.Itoa(i))
76+
func digits(i int) int {
77+
if i == 0 {
78+
return 1
79+
}
80+
count := 0
81+
for i != 0 {
82+
i /= 10
83+
count++
84+
}
85+
return count
86+
}
87+
88+
// faster than
89+
// strconv.Atoi(strings.Repeat(strconv.Itoa(chunk), repeat))
90+
func buildID(chunk, repeat int) int {
91+
n := chunk
92+
for i := 1; i < repeat; i++ {
93+
n = n*pow10(digits(chunk)) + chunk
94+
}
95+
return n
96+
}

2025/2/main1.go

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package main
2+
3+
import "fmt"
4+
5+
func main() {
6+
ranges := parseInput()
7+
8+
sum := 0
9+
for _, r := range ranges {
10+
11+
// only even digits
12+
if r.digits%2 != 0 {
13+
continue
14+
}
15+
16+
for n := range r.InvalidIDs(r.digits / 2) {
17+
sum += n
18+
}
19+
}
20+
21+
fmt.Println(sum)
22+
}

2025/2/main2.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package main
2+
3+
import (
4+
"fmt"
5+
"maps"
6+
)
7+
8+
func main() {
9+
ranges := parseInput()
10+
11+
invalids := map[int]struct{}{}
12+
13+
for _, r := range ranges {
14+
for chunkLen := 1; chunkLen <= r.digits/2; chunkLen++ {
15+
16+
// only divisors
17+
if r.digits%chunkLen != 0 {
18+
continue
19+
}
20+
21+
maps.Copy(invalids, r.InvalidIDs(chunkLen))
22+
}
23+
}
24+
25+
sum := 0
26+
for n := range invalids {
27+
sum += n
28+
}
29+
fmt.Println(sum)
30+
}

0 commit comments

Comments
 (0)