]> fbox.kageds.com Git - adventofcode.git/blob - 2023/go/day05/day05.go
202bfaa3c7231828c96ac5b48d30d7c8cfea5555
[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 for i:=0;i<utils.MaxInt;i++{
62 humid := lookup_src(uint64(i), almanac.humid2loc)
63 temp := lookup_src(humid, almanac.temp2humid)
64 light := lookup_src(temp, almanac.light2temp)
65 water := lookup_src(light, almanac.water2light)
66 fert := lookup_src(water, almanac.fert2water)
67 soil := lookup_src(fert, almanac.soil2fert)
68 seed := lookup_src(soil, almanac.seed2soil)
69
70 for _, seedmap := range seedsmap {
71 if seed >= seedmap.seed && seed < seedmap.seed+seedmap.range_len {
72 return i
73 }
74 }
75 }
76 return -1
77 }
78
79 func lookup_dest(entity uint64, data []Map) uint64 {
80 for _, dataMap := range data {
81 if entity >= dataMap.src_range_start && entity <= dataMap.src_range_start + dataMap.range_len {
82 return dataMap.dest_range_start + entity - dataMap.src_range_start
83 }
84 }
85 return entity
86 }
87
88 func lookup_src(entity uint64, data []Map) uint64 {
89 for _, dataMap := range data {
90 if entity >= dataMap.dest_range_start && entity <= dataMap.dest_range_start + dataMap.range_len {
91 return dataMap.src_range_start + entity - dataMap.dest_range_start
92 }
93 }
94 return entity
95 }
96
97 func parseInput1(input string) ([]uint64, Almanac, error) {
98
99 var almanac Almanac
100 var seeds []uint64
101
102 lines := strings.Split(input, "\n")
103 seedLine := string(lines[0])
104 tokens := strings.Fields(seedLine)
105 for _, token := range tokens[1:] {
106 seeds = append(seeds, uint64(utils.MustAtoi(token)))
107 }
108
109 blocks := strings.Split(input, "\n\n")
110 for i, block := range blocks {
111 lines := strings.Split(block, "\n")
112 switch i {
113 case 0:
114 continue
115 case 1:
116 almanac.seed2soil = getMap(lines[1:])
117 case 2:
118 almanac.soil2fert = getMap(lines[1:])
119 case 3:
120 almanac.fert2water = getMap(lines[1:])
121 case 4:
122 almanac.water2light = getMap(lines[1:])
123 case 5:
124 almanac.light2temp = getMap(lines[1:])
125 case 6:
126 almanac.temp2humid = getMap(lines[1:])
127 case 7:
128 almanac.humid2loc = getMap(lines[1:])
129 }
130 }
131 return seeds, almanac, nil
132 }
133
134 func parseInput2(input string) ([]SeedMap, Almanac, error) {
135
136 var almanac Almanac
137 var seeds []SeedMap
138
139 lines := strings.Split(input, "\n")
140 seedLine := string(lines[0])
141 tokens := strings.Fields(seedLine)
142 for i:=1;i<len(tokens);i=i+2 {
143 seedStart := uint64(utils.MustAtoi(tokens[i]))
144 seedRange := uint64(utils.MustAtoi(tokens[i+1]))
145 seeds = append(seeds, SeedMap{seedStart, seedRange})
146 }
147
148 blocks := strings.Split(input, "\n\n")
149 for i, block := range blocks {
150 lines := strings.Split(block, "\n")
151 switch i {
152 case 0:
153 continue
154 case 1:
155 almanac.seed2soil = getMap(lines[1:])
156 case 2:
157 almanac.soil2fert = getMap(lines[1:])
158 case 3:
159 almanac.fert2water = getMap(lines[1:])
160 case 4:
161 almanac.water2light = getMap(lines[1:])
162 case 5:
163 almanac.light2temp = getMap(lines[1:])
164 case 6:
165 almanac.temp2humid = getMap(lines[1:])
166 case 7:
167 almanac.humid2loc = getMap(lines[1:])
168 }
169 }
170 return seeds, almanac, nil
171 }
172
173 func getMap(input []string) []Map {
174 var out []Map
175 for _, line := range input {
176 tokens := strings.Fields(line)
177 out = append(out, Map{uint64(utils.MustAtoi(tokens[0])), uint64(utils.MustAtoi(tokens[1])),uint64(utils.MustAtoi(tokens[2]))})
178 }
179 return out
180 }