@@ -2,9 +2,11 @@ package main
2
2
3
3
import (
4
4
"bufio"
5
+ "container/list"
5
6
"fmt"
6
7
"log"
7
8
"os"
9
+ "runtime/pprof"
8
10
"time"
9
11
)
10
12
@@ -14,6 +16,26 @@ type diskstruct struct {
14
16
pos int
15
17
}
16
18
19
+ func visualize (spans * list.List ) {
20
+ fmt .Println ("\n ------------------" )
21
+ for e := spans .Front (); e != nil ; e = e .Next () {
22
+ v := e .Value .(* diskstruct )
23
+ fmt .Print ("(" , v .id , ":" , v .len , ") " )
24
+ }
25
+ fmt .Println ("\n " )
26
+ for e := spans .Front (); e != nil ; e = e .Next () {
27
+ v := e .Value .(* diskstruct )
28
+ for range v .len {
29
+ if v .id == - 1 {
30
+ fmt .Print ("." )
31
+ } else {
32
+ fmt .Print (v .id )
33
+ }
34
+ }
35
+ }
36
+ fmt .Println ()
37
+ }
38
+
17
39
func day9 (file string ) (part1 , part2 int ) {
18
40
f , err := os .Open (file )
19
41
if err != nil {
@@ -22,69 +44,101 @@ func day9(file string) (part1, part2 int) {
22
44
defer f .Close ()
23
45
scanner := bufio .NewScanner (f )
24
46
25
- spans := []diskstruct {}
47
+ spans := list .New ()
48
+ spans2 := make ([]* diskstruct , 0 , 100 )
49
+
26
50
files := 0
51
+
52
+ id := 0
27
53
for scanner .Scan () {
28
54
t := scanner .Text ()
29
- id := 0
30
55
for i := 0 ; i < len (t ); i ++ {
31
- s := diskstruct {
32
- id : id ,
33
- len : int (t [i ] - '0' ),
56
+ l := int (t [i ] - '0' )
57
+ if l > 0 {
58
+ s := & diskstruct {
59
+ id : id ,
60
+ len : l ,
61
+ }
62
+ s2 := * s
63
+ spans .PushBack (s )
64
+ spans2 = append (spans2 , & s2 )
34
65
}
35
- spans = append (spans , s )
36
66
i ++
67
+
37
68
if i < len (t ) {
38
- s := diskstruct {
39
- id : - 1 ,
40
- len : int (t [i ] - '0' ),
69
+ l = int (t [i ] - '0' )
70
+ if l > 0 {
71
+ s := & diskstruct {
72
+ id : - 1 ,
73
+ len : l ,
74
+ }
75
+ s2 := * s
76
+ spans .PushBack (s )
77
+ spans2 = append (spans2 , & s2 )
41
78
}
42
- spans = append (spans , s )
43
79
}
44
80
id ++
45
81
}
46
82
files = id
47
83
}
48
- spans2 := make ([]diskstruct , len (spans ))
49
- copy (spans2 , spans )
84
+ // spans2 := make([]diskstruct, spans.Len())
85
+ // for e := spans.Front(); e != nil; e = e.Next() {
86
+ // v := e.Value.(*diskstruct)
87
+ // fmt.Print("(", v.id, ":", v.len, ") ")
88
+ // }
89
+ // fmt.Println()
50
90
51
91
for {
52
- l , r := 0 , len (spans )- 1
53
- for ; l < r && spans [l ].id != - 1 ; l ++ {
92
+ l , r := spans .Front (), spans .Back ()
93
+
94
+ i := 0
95
+ for ; l != nil && l .Value .(* diskstruct ).id != - 1 ; l = l .Next () {
96
+ i ++
54
97
}
55
- for ; l < r && spans [r ].id == - 1 ; r -- {
98
+ j := spans .Len ()
99
+ for ; r != nil && r .Value .(* diskstruct ).id == - 1 ; r = r .Prev () {
100
+ j --
56
101
}
57
- if l >= r {
102
+ if i >= j {
58
103
break
59
104
}
60
105
61
- spans [l ].id = spans [r ].id
62
- if spans [l ].len > spans [r ].len {
63
- spaceleft := spans [l ].len - spans [r ].len
64
- spans [l ].len = spans [r ].len
65
- spans = append (spans [:l + 1 ], append ([]diskstruct {{id : - 1 , len : spaceleft }}, spans [l + 1 :]... )... )
66
- spans = append (spans [:r + 1 ], spans [r + 2 :]... )
67
- } else if spans [l ].len < spans [r ].len {
68
- spans [r ].len -= spans [l ].len
106
+ lv := l .Value .(* diskstruct )
107
+ rv := r .Value .(* diskstruct )
108
+ lv .id = rv .id
109
+ if lv .len > rv .len {
110
+ spaceleft := lv .len - rv .len
111
+ lv .len = rv .len
112
+ spaceleftStruct := & diskstruct {id : - 1 , len : spaceleft }
113
+ spans .InsertAfter (spaceleftStruct , l )
114
+ spans .Remove (r )
115
+ } else if lv .len < rv .len {
116
+ rv .len -= lv .len
69
117
} else {
70
- spans = append ( spans [: r ], spans [ r + 1 :] ... )
118
+ spans . Remove ( r )
71
119
}
72
- if spans [len (spans )- 1 ].id == - 1 {
73
- spans = spans [:len (spans )- 1 ]
120
+
121
+ last := spans .Back ()
122
+ if last .Value .(* diskstruct ).id == - 1 {
123
+ spans .Remove (last )
74
124
}
125
+
126
+ // visualize(spans)
75
127
}
76
128
77
129
// fmt.Println(spans)
78
130
blockn := 0
79
- for _ , v := range spans {
131
+ for e := spans .Front (); e != nil ; e = e .Next () {
132
+ v := e .Value .(* diskstruct )
80
133
for range v .len {
81
134
part1 += blockn * v .id
82
135
blockn ++
83
136
}
84
137
}
85
138
86
- idx := make (map [int ]* diskstruct )
87
- fsm := []diskstruct {}
139
+ // idx := make(map[int]*diskstruct)
140
+ idx := make ([]* diskstruct , id )
141
+ fsm := []* diskstruct {}
88
142
blockn = 0
89
143
for _ , v := range spans2 {
90
144
v .pos = blockn
@@ -93,8 +147,9 @@ func day9(file string) (part1, part2 int) {
93
147
fsm = append (fsm , v )
94
148
} else {
95
149
v2 := v
96
- idx [v .id ] = & v2
150
+ idx [v .id ] = v2
97
151
}
152
+ // visualize(spans2)
98
153
}
99
154
100
155
for i := files - 1 ; i >= 0 ; i -- {
@@ -121,12 +176,25 @@ func day9(file string) (part1, part2 int) {
121
176
122
177
func main () {
123
178
log .SetFlags (log .Lshortfile | log .LstdFlags )
179
+ logperf := false
180
+ if logperf {
181
+ pf , _ := os .Create ("default.pgo" )
182
+ err := pprof .StartCPUProfile (pf )
183
+ if err != nil {
184
+ log .Fatal (err )
185
+ }
186
+ defer pf .Close ()
187
+ }
124
188
t1 := time .Now ()
125
189
part1 , part2 := day9 ("test.txt" )
126
190
fmt .Println (part1 , part2 )
127
191
if part1 != 1928 || part2 != 2858 {
128
192
log .Fatal ("Test failed " , part1 , part2 )
129
193
}
130
194
fmt .Println (day9 ("input.txt" ))
195
+ if logperf {
196
+ pprof .StopCPUProfile ()
197
+ }
198
+
131
199
fmt .Println ("Elapsed time:" , time .Since (t1 ))
132
200
}
0 commit comments