Skip to content

Commit 7a0d0d3

Browse files
committed
refac(angch/2024-09): Better structures
1 parent 5769ead commit 7a0d0d3

File tree

3 files changed

+231
-31
lines changed

3 files changed

+231
-31
lines changed

angch/2024-09/default.pgo

970 Bytes
Binary file not shown.

angch/2024-09/main.go

Lines changed: 99 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,11 @@ package main
22

33
import (
44
"bufio"
5+
"container/list"
56
"fmt"
67
"log"
78
"os"
9+
"runtime/pprof"
810
"time"
911
)
1012

@@ -14,6 +16,26 @@ type diskstruct struct {
1416
pos int
1517
}
1618

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+
1739
func day9(file string) (part1, part2 int) {
1840
f, err := os.Open(file)
1941
if err != nil {
@@ -22,69 +44,101 @@ func day9(file string) (part1, part2 int) {
2244
defer f.Close()
2345
scanner := bufio.NewScanner(f)
2446

25-
spans := []diskstruct{}
47+
spans := list.New()
48+
spans2 := make([]*diskstruct, 0, 100)
49+
2650
files := 0
51+
52+
id := 0
2753
for scanner.Scan() {
2854
t := scanner.Text()
29-
id := 0
3055
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)
3465
}
35-
spans = append(spans, s)
3666
i++
67+
3768
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)
4178
}
42-
spans = append(spans, s)
4379
}
4480
id++
4581
}
4682
files = id
4783
}
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()
5090

5191
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++
5497
}
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--
56101
}
57-
if l >= r {
102+
if i >= j {
58103
break
59104
}
60105

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
69117
} else {
70-
spans = append(spans[:r], spans[r+1:]...)
118+
spans.Remove(r)
71119
}
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)
74124
}
125+
126+
// visualize(spans)
75127
}
76128

77129
// fmt.Println(spans)
78130
blockn := 0
79-
for _, v := range spans {
131+
for e := spans.Front(); e != nil; e = e.Next() {
132+
v := e.Value.(*diskstruct)
80133
for range v.len {
81134
part1 += blockn * v.id
82135
blockn++
83136
}
84137
}
85138

86-
idx := make(map[int]*diskstruct)
87-
fsm := []diskstruct{}
139+
// idx := make(map[int]*diskstruct)
140+
idx := make([]*diskstruct, id)
141+
fsm := []*diskstruct{}
88142
blockn = 0
89143
for _, v := range spans2 {
90144
v.pos = blockn
@@ -93,8 +147,9 @@ func day9(file string) (part1, part2 int) {
93147
fsm = append(fsm, v)
94148
} else {
95149
v2 := v
96-
idx[v.id] = &v2
150+
idx[v.id] = v2
97151
}
152+
// visualize(spans2)
98153
}
99154

100155
for i := files - 1; i >= 0; i-- {
@@ -121,12 +176,25 @@ func day9(file string) (part1, part2 int) {
121176

122177
func main() {
123178
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+
}
124188
t1 := time.Now()
125189
part1, part2 := day9("test.txt")
126190
fmt.Println(part1, part2)
127191
if part1 != 1928 || part2 != 2858 {
128192
log.Fatal("Test failed ", part1, part2)
129193
}
130194
fmt.Println(day9("input.txt"))
195+
if logperf {
196+
pprof.StopCPUProfile()
197+
}
198+
131199
fmt.Println("Elapsed time:", time.Since(t1))
132200
}

angch/2024-09/old/main.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
package main
2+
3+
import (
4+
"bufio"
5+
"fmt"
6+
"log"
7+
"os"
8+
"time"
9+
)
10+
11+
type diskstruct struct {
12+
id int
13+
len int
14+
pos int
15+
}
16+
17+
func day9(file string) (part1, part2 int) {
18+
f, err := os.Open(file)
19+
if err != nil {
20+
log.Fatal(err)
21+
}
22+
defer f.Close()
23+
scanner := bufio.NewScanner(f)
24+
25+
spans := []diskstruct{}
26+
files := 0
27+
for scanner.Scan() {
28+
t := scanner.Text()
29+
id := 0
30+
for i := 0; i < len(t); i++ {
31+
s := diskstruct{
32+
id: id,
33+
len: int(t[i] - '0'),
34+
}
35+
spans = append(spans, s)
36+
i++
37+
if i < len(t) {
38+
s := diskstruct{
39+
id: -1,
40+
len: int(t[i] - '0'),
41+
}
42+
spans = append(spans, s)
43+
}
44+
id++
45+
}
46+
files = id
47+
}
48+
spans2 := make([]diskstruct, len(spans))
49+
copy(spans2, spans)
50+
51+
for {
52+
l, r := 0, len(spans)-1
53+
for ; l < r && spans[l].id != -1; l++ {
54+
}
55+
for ; l < r && spans[r].id == -1; r-- {
56+
}
57+
if l >= r {
58+
break
59+
}
60+
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
69+
} else {
70+
spans = append(spans[:r], spans[r+1:]...)
71+
}
72+
if spans[len(spans)-1].id == -1 {
73+
spans = spans[:len(spans)-1]
74+
}
75+
}
76+
77+
// fmt.Println(spans)
78+
blockn := 0
79+
for _, v := range spans {
80+
for range v.len {
81+
part1 += blockn * v.id
82+
blockn++
83+
}
84+
}
85+
86+
idx := make(map[int]*diskstruct)
87+
fsm := []diskstruct{}
88+
blockn = 0
89+
for _, v := range spans2 {
90+
v.pos = blockn
91+
blockn += v.len
92+
if v.id == -1 {
93+
fsm = append(fsm, v)
94+
} else {
95+
v2 := v
96+
idx[v.id] = &v2
97+
}
98+
}
99+
100+
for i := files - 1; i >= 0; i-- {
101+
for j := 0; j < len(fsm); j++ {
102+
if idx[i].len <= fsm[j].len && idx[i].pos > fsm[j].pos {
103+
idx[i].pos = fsm[j].pos
104+
fsm[j].pos += idx[i].len
105+
fsm[j].len -= idx[i].len
106+
break
107+
}
108+
}
109+
}
110+
111+
for _, v := range idx {
112+
pos := v.pos
113+
for range v.len {
114+
part2 += pos * v.id
115+
pos++
116+
}
117+
}
118+
119+
return
120+
}
121+
122+
func main() {
123+
log.SetFlags(log.Lshortfile | log.LstdFlags)
124+
t1 := time.Now()
125+
part1, part2 := day9("test.txt")
126+
fmt.Println(part1, part2)
127+
if part1 != 1928 || part2 != 2858 {
128+
log.Fatal("Test failed ", part1, part2)
129+
}
130+
fmt.Println(day9("input.txt"))
131+
fmt.Println("Elapsed time:", time.Since(t1))
132+
}

0 commit comments

Comments
 (0)