Skip to content

Commit

Permalink
day 5 part 1
Browse files Browse the repository at this point in the history
  • Loading branch information
angristan committed Dec 5, 2023
1 parent b8bb188 commit 25be763
Show file tree
Hide file tree
Showing 3 changed files with 544 additions and 0 deletions.
125 changes: 125 additions & 0 deletions 05/05.go
@@ -0,0 +1,125 @@
package main

import (
"fmt"
"regexp"
"slices"
"strconv"
"strings"

"github.com/angristan/advent-of-code-2023/utils"
)

func main() {
input := utils.ParseInput("input.txt")

cards := ConvertInputToAlmanac(input)
part1Score := cards.GetLowestLocationNumber()
fmt.Printf("Part 1: %d\n", part1Score)

}

type Range struct {
DestinationIndex int
SourceIndex int
RangeLength int
}

type Map struct {
Ranges []Range
}

type Seed int

type Almanac struct {
Maps []Map
Seeds []Seed
}

var numberRegex = regexp.MustCompile(`\d+`)

func ConvertInputToAlmanac(input []string) Almanac {
seeds := []Seed{}

seedsString := numberRegex.FindAllString(input[0], -1)

for _, seedString := range seedsString {
seed, err := strconv.Atoi(seedString)
if err != nil {
panic(err)
}

seeds = append(seeds, Seed(seed))
}

maps := []Map{}

currentMap := Map{}
for _, line := range input[2:] {
if strings.Contains(line, "map") || line == "" {
if len(currentMap.Ranges) > 0 {
maps = append(maps, currentMap)
currentMap = Map{}
}
continue
}

indices := numberRegex.FindAllString(line, -1)
destinationIndex, err := strconv.Atoi(indices[0])
if err != nil {
panic(err)
}

sourceIndex, err := strconv.Atoi(indices[1])
if err != nil {
panic(err)
}

rangeLength, err := strconv.Atoi(indices[2])
if err != nil {
panic(err)
}

currentMap.Ranges = append(currentMap.Ranges, Range{
DestinationIndex: destinationIndex,
SourceIndex: sourceIndex,
RangeLength: rangeLength,
})
}

maps = append(maps, currentMap)

return Almanac{
Maps: maps,
Seeds: seeds,
}
}

func (almanac Almanac) GetSeedsLocations() []int {
locations := make([]int, 0)

for _, seed := range almanac.Seeds {
nextIndex := int(seed)
nextMap:
for _, m := range almanac.Maps {
for _, r := range m.Ranges {
if nextIndex >= r.SourceIndex && nextIndex < r.SourceIndex+r.RangeLength {
nextIndex = r.DestinationIndex + int(nextIndex) - r.SourceIndex
continue nextMap
}
}
}

location := nextIndex
locations = append(locations, location)
}

return locations
}

func (almanac Almanac) GetLowestLocationNumber() int {
locations := almanac.GetSeedsLocations()
slices.Sort(locations)

return locations[0]
}
175 changes: 175 additions & 0 deletions 05/05_test.go
@@ -0,0 +1,175 @@
package main

import (
"testing"

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

func TestConvertInputToAlmanac(t *testing.T) {
input := []string{
"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",
}

want := Almanac{
Seeds: []Seed{79, 14, 55, 13},
Maps: []Map{
{Ranges: []Range{
{DestinationIndex: 50, SourceIndex: 98, RangeLength: 2},
{DestinationIndex: 52, SourceIndex: 50, RangeLength: 48}},
},
{Ranges: []Range{
{DestinationIndex: 0, SourceIndex: 15, RangeLength: 37},
{DestinationIndex: 37, SourceIndex: 52, RangeLength: 2},
{DestinationIndex: 39, SourceIndex: 0, RangeLength: 15}},
},
{Ranges: []Range{
{DestinationIndex: 49, SourceIndex: 53, RangeLength: 8},
{DestinationIndex: 0, SourceIndex: 11, RangeLength: 42},
{DestinationIndex: 42, SourceIndex: 0, RangeLength: 7},
{DestinationIndex: 57, SourceIndex: 7, RangeLength: 4}},
},
{Ranges: []Range{
{DestinationIndex: 88, SourceIndex: 18, RangeLength: 7},
{DestinationIndex: 18, SourceIndex: 25, RangeLength: 70}},
},
{Ranges: []Range{
{DestinationIndex: 45, SourceIndex: 77, RangeLength: 23},
{DestinationIndex: 81, SourceIndex: 45, RangeLength: 19},
{DestinationIndex: 68, SourceIndex: 64, RangeLength: 13}},
},
{Ranges: []Range{
{DestinationIndex: 0, SourceIndex: 69, RangeLength: 1},
{DestinationIndex: 1, SourceIndex: 0, RangeLength: 69}},
},
{Ranges: []Range{
{DestinationIndex: 60, SourceIndex: 56, RangeLength: 37},
{DestinationIndex: 56, SourceIndex: 93, RangeLength: 4}},
},
},
}

almanac := ConvertInputToAlmanac(input)

assert.Equal(t, want, almanac)
}

func TestGetSeedsLocations(t *testing.T) {
alamanac := Almanac{
Seeds: []Seed{79, 14, 55, 13},
Maps: []Map{
{Ranges: []Range{
{DestinationIndex: 50, SourceIndex: 98, RangeLength: 2},
{DestinationIndex: 52, SourceIndex: 50, RangeLength: 48}},
},
{Ranges: []Range{
{DestinationIndex: 0, SourceIndex: 15, RangeLength: 37},
{DestinationIndex: 37, SourceIndex: 52, RangeLength: 2},
{DestinationIndex: 39, SourceIndex: 0, RangeLength: 15}},
},
{Ranges: []Range{
{DestinationIndex: 49, SourceIndex: 53, RangeLength: 8},
{DestinationIndex: 0, SourceIndex: 11, RangeLength: 42},
{DestinationIndex: 42, SourceIndex: 0, RangeLength: 7},
{DestinationIndex: 57, SourceIndex: 7, RangeLength: 4}},
},
{Ranges: []Range{
{DestinationIndex: 88, SourceIndex: 18, RangeLength: 7},
{DestinationIndex: 18, SourceIndex: 25, RangeLength: 70}},
},
{Ranges: []Range{
{DestinationIndex: 45, SourceIndex: 77, RangeLength: 23},
{DestinationIndex: 81, SourceIndex: 45, RangeLength: 19},
{DestinationIndex: 68, SourceIndex: 64, RangeLength: 13}},
},
{Ranges: []Range{
{DestinationIndex: 0, SourceIndex: 69, RangeLength: 1},
{DestinationIndex: 1, SourceIndex: 0, RangeLength: 69}},
},
{Ranges: []Range{
{DestinationIndex: 60, SourceIndex: 56, RangeLength: 37},
{DestinationIndex: 56, SourceIndex: 93, RangeLength: 4}},
},
},
}

expectedLocations := []int{82, 43, 86, 35}

assert.Equal(t, alamanac.GetSeedsLocations(), expectedLocations)
}

func TestGetLowestLocationNumber(t *testing.T) {
alamanac := Almanac{
Seeds: []Seed{79, 14, 55, 13},
Maps: []Map{
{Ranges: []Range{
{DestinationIndex: 50, SourceIndex: 98, RangeLength: 2},
{DestinationIndex: 52, SourceIndex: 50, RangeLength: 48}},
},
{Ranges: []Range{
{DestinationIndex: 0, SourceIndex: 15, RangeLength: 37},
{DestinationIndex: 37, SourceIndex: 52, RangeLength: 2},
{DestinationIndex: 39, SourceIndex: 0, RangeLength: 15}},
},
{Ranges: []Range{
{DestinationIndex: 49, SourceIndex: 53, RangeLength: 8},
{DestinationIndex: 0, SourceIndex: 11, RangeLength: 42},
{DestinationIndex: 42, SourceIndex: 0, RangeLength: 7},
{DestinationIndex: 57, SourceIndex: 7, RangeLength: 4}},
},
{Ranges: []Range{
{DestinationIndex: 88, SourceIndex: 18, RangeLength: 7},
{DestinationIndex: 18, SourceIndex: 25, RangeLength: 70}},
},
{Ranges: []Range{
{DestinationIndex: 45, SourceIndex: 77, RangeLength: 23},
{DestinationIndex: 81, SourceIndex: 45, RangeLength: 19},
{DestinationIndex: 68, SourceIndex: 64, RangeLength: 13}},
},
{Ranges: []Range{
{DestinationIndex: 0, SourceIndex: 69, RangeLength: 1},
{DestinationIndex: 1, SourceIndex: 0, RangeLength: 69}},
},
{Ranges: []Range{
{DestinationIndex: 60, SourceIndex: 56, RangeLength: 37},
{DestinationIndex: 56, SourceIndex: 93, RangeLength: 4}},
},
},
}

expectedLowestLocationNumber := 35

assert.Equal(t, alamanac.GetLowestLocationNumber(), expectedLowestLocationNumber)
}

0 comments on commit 25be763

Please sign in to comment.