Skip to content

Commit

Permalink
day 05 solutions
Browse files Browse the repository at this point in the history
  • Loading branch information
kylehoehns committed Dec 5, 2023
1 parent 182cf91 commit 743ef53
Show file tree
Hide file tree
Showing 4 changed files with 207 additions and 0 deletions.
10 changes: 10 additions & 0 deletions pkg/ints/ints.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,13 @@ func FromStringSlice(input []string) []int {
}
return output
}

func Min(numbers []int) int {
m := numbers[0]
for _, num := range numbers {
if num < m {
m = num
}
}
return m
}
137 changes: 137 additions & 0 deletions puzzles/day05/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
package main

import (
"fmt"
"github.com/kylehoehns/aoc-2023-go/pkg/files"
"github.com/kylehoehns/aoc-2023-go/pkg/ints"
"strings"
)

func main() {
fmt.Println("Part 1: ", part1("input.txt"))
fmt.Println("Part 2: ", part2("input.txt"))
}

type Almanac struct {
seeds []int
seedToSoil Mappings
soilToFertilizer Mappings
fertilizerToWater Mappings
waterToLight Mappings
lightToTemperature Mappings
temperatureToHumidity Mappings
humidityToLocation Mappings
}

type Mappings struct {
name string
mappings []Mapping
}

func (m *Mappings) determineDestination(s int) int {
for _, mapping := range m.mappings {
if s >= mapping.sourceStart && s < mapping.sourceStart+mapping.rangeLength {
return mapping.destinationStart + (s - mapping.sourceStart)
}
}
return s
}

type Mapping struct {
destinationStart int
sourceStart int
rangeLength int
}

func part1(name string) int {
paragraphs := files.ReadParagraphs(name)

seeds := parseSeedsPart1(paragraphs)
a := parseAlmanac(paragraphs, seeds)

return determineSmallestLocationPart1(a)
}

func part2(name string) int {
paragraphs := files.ReadParagraphs(name)

seeds := parseSeedsPart1(paragraphs)
a := parseAlmanac(paragraphs, seeds)

return determineSmallestLocationPart2(a)
}

func parseAlmanac(paragraphs [][]string, seeds []int) Almanac {
return Almanac{
seeds: seeds,
seedToSoil: parseMappings("seedToSoil", paragraphs[1]),
soilToFertilizer: parseMappings("soilToFertilizer", paragraphs[2]),
fertilizerToWater: parseMappings("fertilizerToWater", paragraphs[3]),
waterToLight: parseMappings("waterToLight", paragraphs[4]),
lightToTemperature: parseMappings("lightToTemperature", paragraphs[5]),
temperatureToHumidity: parseMappings("temperatureToHumidity", paragraphs[6]),
humidityToLocation: parseMappings("humidityToLocation", paragraphs[7]),
}
}

func parseMappings(name string, paragraph []string) Mappings {
m := make([]Mapping, 0)
for _, line := range paragraph[1:] {
parts := strings.Split(line, " ")

m = append(m, Mapping{
sourceStart: ints.FromString(parts[1]),
destinationStart: ints.FromString(parts[0]),
rangeLength: ints.FromString(parts[2]),
})
}
return Mappings{
name: name,
mappings: m,
}
}

func parseSeedsPart1(paragraphs [][]string) []int {
// parse "seeds: 79 14 55 13" into an array of ints
seeds := make([]int, 0)
// seeds is always the first paragraph and only has a single line
seedLine := paragraphs[0][0][7:]
seedLineParts := strings.Split(seedLine, " ")
for _, seedPart := range seedLineParts {
seeds = append(seeds, ints.FromString(seedPart))
}
return seeds
}

func determineSmallestLocationPart1(a Almanac) int {
locations := make([]int, 0)
for _, seed := range a.seeds {
locations = append(locations, determineSeedLocation(seed, a))
}

return ints.Min(locations)
}

func determineSmallestLocationPart2(a Almanac) int {
locations := make([]int, 0)
for i := 0; i < len(a.seeds); i += 2 {
seedStart := a.seeds[i]
seedEnd := seedStart + a.seeds[i+1]
for j := seedStart; j < seedEnd; j++ {
locations = append(locations, determineSeedLocation(j, a))
}
}

return ints.Min(locations)
}

func determineSeedLocation(seed int, a Almanac) int {
soil := a.seedToSoil.determineDestination(seed)
fertilizer := a.soilToFertilizer.determineDestination(soil)
water := a.fertilizerToWater.determineDestination(fertilizer)
light := a.waterToLight.determineDestination(water)
temperature := a.lightToTemperature.determineDestination(light)
humidity := a.temperatureToHumidity.determineDestination(temperature)
location := a.humidityToLocation.determineDestination(humidity)
return location
}
27 changes: 27 additions & 0 deletions puzzles/day05/main_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
package main

import (
"testing"

"github.com/stretchr/testify/assert"
)

func TestPart1(t *testing.T) {

t.Run("Part 1", func(t *testing.T) {
expected := 35
actual := part1("test-input.txt")
assert.Equal(t, expected, actual)
})

}

func TestPart2(t *testing.T) {

t.Run("Part 2", func(t *testing.T) {
expected := 46
actual := part2("test-input.txt")
assert.Equal(t, expected, actual)
})

}
33 changes: 33 additions & 0 deletions puzzles/day05/test-input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
seeds: 79 14 55 13

seed-to-soil map:
50 98 2
52 50 48

soil-to-fertilizer map:
0 15 37
37 52 2
39 0 15

fertilizer-to-water map:
49 53 8
0 11 42
42 0 7
57 7 4

water-to-light map:
88 18 7
18 25 70

light-to-temperature map:
45 77 23
81 45 19
68 64 13

temperature-to-humidity map:
0 69 1
1 0 69

humidity-to-location map:
60 56 37
56 93 4

0 comments on commit 743ef53

Please sign in to comment.