11package day9
22
33import (
4- "strconv "
4+ "math "
55)
66
77const ZERO_RUNE = '0'
88const EMPTY_RUNE = '.'
9- const EMPTY_STRING = string (EMPTY_RUNE )
109
11- func Solve (input string ) int {
10+ type file struct {
11+ empty bool
12+ digit uint
13+ }
14+
15+ func Solve (input string ) uint64 {
1216 return checksum (compress (expand (input )))
1317}
1418
15- func expand (input string ) string {
16- var result string
19+ func expand (input string ) [] file {
20+ result := make ([] file , 0 )
1721 blankSpace := false
18- id : = 0
22+ var id uint = 0
1923 for _ , fileSize := range input {
2024 for i := 0 ; i < runeToInt (fileSize ); i ++ {
21- if blankSpace {
22- result += EMPTY_STRING
23- } else {
24- result += strconv .Itoa (id )
25- }
25+ result = append (result , file {empty : blankSpace , digit : id })
2626 }
2727 if ! blankSpace {
2828 id += 1
@@ -32,11 +32,15 @@ func expand(input string) string {
3232 return result
3333}
3434
35- func compress (input string ) string {
36- result := []byte (input )
35+ func runeToInt (r rune ) int {
36+ return int (r - ZERO_RUNE )
37+ }
38+
39+ func compress (input []file ) []file {
40+ result := input
3741 ptr , tailPtr := 0 , len (input )- 1
3842 for {
39- if result [tailPtr ] != EMPTY_RUNE || tailPtr <= 0 {
43+ if ! result [tailPtr ]. empty || tailPtr <= 0 {
4044 break
4145 }
4246 tailPtr --
@@ -46,34 +50,34 @@ func compress(input string) string {
4650 if ptr >= tailPtr {
4751 break
4852 }
49- if result [ptr ] != EMPTY_RUNE {
53+ if ! result [ptr ]. empty {
5054 ptr ++
5155 continue
5256 }
5357 result [ptr ] = result [tailPtr ]
54- result [tailPtr ] = EMPTY_RUNE
58+ result [tailPtr ] = file { empty : true }
5559 ptr ++
5660 for {
5761 tailPtr --
58- if result [tailPtr ] != EMPTY_RUNE {
62+ if ! result [tailPtr ]. empty {
5963 break
6064 }
6165 }
6266 }
63- return string ( result )
67+ return result
6468}
6569
66- func checksum (input string ) int {
67- result := 0
70+ func checksum (input [] file ) uint64 {
71+ result := uint64 ( 0 )
6872 for i , d := range input {
69- if d == EMPTY_RUNE {
73+ if d . empty {
7074 break
7175 }
72- result += i * runeToInt (d )
76+ val := uint64 (i * int (d .digit ))
77+ if math .MaxUint64 - val < result {
78+ panic ("overflow" )
79+ }
80+ result += val
7381 }
7482 return result
7583}
76-
77- func runeToInt (r rune ) int {
78- return int (r - ZERO_RUNE )
79- }
0 commit comments