]> fbox.kageds.com Git - adventofcode.git/blob - 2023/go/day05/day05.go
day06
[adventofcode.git] / 2023 / go / day05 / day05.go
1 package day05
2
3 import (
4
5 _ "regexp"
6 "strings"
7
8 "fmt"
9
10 "adventofcode2023/utils"
11
12 )
13
14 type Map struct {
15 dest_range_start uint64
16 src_range_start uint64
17 range_len uint64
18 }
19
20 type Almanac struct {
21 seed2soil []Map
22 soil2fert []Map
23 fert2water []Map
24 water2light []Map
25 light2temp []Map
26 temp2humid []Map
27 humid2loc []Map
28 }
29
30 type SeedMap struct {
31 seed uint64
32 range_len uint64
33 }
34
35 func Part1(input string) uint64 {
36 seeds, almanac, _ := parseInput1(input)
37 fmt.Println(seeds)
38 fmt.Println(almanac)
39
40 minLoc := uint64(utils.MaxInt)
41 for _, seed := range seeds {
42 soil := lookup_dest(seed, almanac.seed2soil)
43 fert := lookup_dest(soil, almanac.soil2fert)
44 water := lookup_dest(fert, almanac.fert2water)
45 light := lookup_dest(water, almanac.water2light)
46 temp := lookup_dest(light, almanac.light2temp)
47 humid := lookup_dest(temp, almanac.temp2humid)
48 loc := lookup_dest(humid, almanac.humid2loc)
49 if loc < minLoc {
50 minLoc = loc
51 }
52 fmt.Println(loc)
53 }
54
55 return minLoc
56 }
57
58 func Part2(input string) int {
59 seedsmap, almanac, _ := parseInput2(input)
60
61
62 minLoc := uint64(utils.MaxInt)
63 for _, seedmap := range seedsmap {
64 for i := seedmap.seed;i<seedmap.seed+seedmap.range_len;i++ {
65 soil := lookup_dest(i, almanac.seed2soil)
66 fert := lookup_dest(soil, almanac.soil2fert)
67 water := lookup_dest(fert, almanac.fert2water)
68 light := lookup_dest(water, almanac.water2light)
69 temp := lookup_dest(light, almanac.light2temp)
70 humid := lookup_dest(temp, almanac.temp2humid)
71 loc := lookup_dest(humid, almanac.humid2loc)
72 if loc < minLoc {
73 minLoc = loc
74 }
75 }
76 fmt.Println(minLoc)
77 }
78 //
79 // fmt.Println(minSeedMap)
80 // minLoc = utils.MaxInt
81 // for i:=minSeedMap.seed;i<minSeedMap.seed+minSeedMap.range_len;i++ {
82 // soil := lookup_dest(i, almanac.seed2soil)
83 // fert := lookup_dest(soil, almanac.soil2fert)
84 // water := lookup_dest(fert, almanac.fert2water)
85 // light := lookup_dest(water, almanac.water2light)
86 // temp := lookup_dest(light, almanac.light2temp)
87 // humid := lookup_dest(temp, almanac.temp2humid)
88 // loc := lookup_dest(humid, almanac.humid2loc)
89 // if loc < minLoc {
90 // minLoc = loc
91 // }
92 // }
93 return int(minLoc)
94 }
95
96 func lookup_dest(entity uint64, data []Map) uint64 {
97 for _, dataMap := range data {
98 if entity >= dataMap.src_range_start && entity <= dataMap.src_range_start + dataMap.range_len {
99 return dataMap.dest_range_start + entity - dataMap.src_range_start
100 }
101 }
102 return entity
103 }
104
105 func lookup_src(entity uint64, data []Map) uint64 {
106 for _, dataMap := range data {
107 if entity >= dataMap.dest_range_start && entity <= dataMap.dest_range_start + dataMap.range_len {
108 return dataMap.src_range_start + entity - dataMap.dest_range_start
109 }
110 }
111 return entity
112 }
113
114 func parseInput1(input string) ([]uint64, Almanac, error) {
115
116 var almanac Almanac
117 var seeds []uint64
118
119 lines := strings.Split(input, "\n")
120 seedLine := string(lines[0])
121 tokens := strings.Fields(seedLine)
122 for _, token := range tokens[1:] {
123 seeds = append(seeds, uint64(utils.MustAtoi(token)))
124 }
125
126 blocks := strings.Split(input, "\n\n")
127 for i, block := range blocks {
128 lines := strings.Split(block, "\n")
129 switch i {
130 case 0:
131 continue
132 case 1:
133 almanac.seed2soil = getMap(lines[1:])
134 case 2:
135 almanac.soil2fert = getMap(lines[1:])
136 case 3:
137 almanac.fert2water = getMap(lines[1:])
138 case 4:
139 almanac.water2light = getMap(lines[1:])
140 case 5:
141 almanac.light2temp = getMap(lines[1:])
142 case 6:
143 almanac.temp2humid = getMap(lines[1:])
144 case 7:
145 almanac.humid2loc = getMap(lines[1:])
146 }
147 }
148 return seeds, almanac, nil
149 }
150
151 func parseInput2(input string) ([]SeedMap, Almanac, error) {
152
153 var almanac Almanac
154 var seeds []SeedMap
155
156 lines := strings.Split(input, "\n")
157 seedLine := string(lines[0])
158 tokens := strings.Fields(seedLine)
159 for i:=1;i<len(tokens);i=i+2 {
160 seedStart := uint64(utils.MustAtoi(tokens[i]))
161 seedRange := uint64(utils.MustAtoi(tokens[i+1]))
162 seeds = append(seeds, SeedMap{seedStart, seedRange})
163 }
164
165 blocks := strings.Split(input, "\n\n")
166 for i, block := range blocks {
167 lines := strings.Split(block, "\n")
168 switch i {
169 case 0:
170 continue
171 case 1:
172 almanac.seed2soil = getMap(lines[1:])
173 case 2:
174 almanac.soil2fert = getMap(lines[1:])
175 case 3:
176 almanac.fert2water = getMap(lines[1:])
177 case 4:
178 almanac.water2light = getMap(lines[1:])
179 case 5:
180 almanac.light2temp = getMap(lines[1:])
181 case 6:
182 almanac.temp2humid = getMap(lines[1:])
183 case 7:
184 almanac.humid2loc = getMap(lines[1:])
185 }
186 }
187 return seeds, almanac, nil
188 }
189
190 func getMap(input []string) []Map {
191 var out []Map
192 for _, line := range input {
193 tokens := strings.Fields(line)
194 out = append(out, Map{uint64(utils.MustAtoi(tokens[0])), uint64(utils.MustAtoi(tokens[1])),uint64(utils.MustAtoi(tokens[2]))})
195 }
196 return out
197 }