Skip to content

Commit

Permalink
Refactor input parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
gdejong committed Dec 5, 2024
1 parent 314dac2 commit ec24973
Show file tree
Hide file tree
Showing 7 changed files with 80 additions and 91 deletions.
85 changes: 35 additions & 50 deletions cmd/day1/main.go
Original file line number Diff line number Diff line change
@@ -1,100 +1,85 @@
package main

import (
"bufio"
"fmt"
"github.com/gdejong/advent-of-code-2024/internal/input"
"github.com/gdejong/advent-of-code-2024/internal/must"
"io"
"os"
"slices"
)

func main() {
f := must.NoError(os.Open("cmd/day1/real_input.txt"))
lines := input.Content("cmd/day1/real_input.txt")

part1answer := part1(f)
fmt.Println(part1answer)
fmt.Println(part1(lines))

// Reset the file so we can it again for part 2
must.NoError(f.Seek(0, io.SeekStart))

part2answer := part2(f)
fmt.Println(part2answer)
fmt.Println(part2(lines))
}

func part2(f *os.File) int {
s := bufio.NewScanner(f)

func part1(lines []string) int {
var leftList []int
var rightList []int

for s.Scan() {
line := s.Text()

for _, line := range lines {
var leftNumber int
var rightNumber int
must.NoError(fmt.Sscanf(line, "%d %d", &leftNumber, &rightNumber))
leftList = append(leftList, leftNumber)
rightList = append(rightList, rightNumber)
}

counterMap := make(map[int]int)
slices.Sort(leftList)
slices.Sort(rightList)

for _, value := range rightList {
if _, ok := counterMap[value]; ok {
counterMap[value]++
} else {
counterMap[value] = 1
}
if len(leftList) != len(rightList) {
panic("expected same length")
}

similarityScore := 0
for _, value := range leftList {
counterMapValue, ok := counterMap[value]
if !ok {
continue
distanceSum := 0
for i := 0; i < len(leftList); i++ {
distance := leftList[i] - rightList[i]

// Take the absolute value
if distance < 0 {
distance = distance * -1
}

similarityScore += value * counterMapValue
distanceSum += distance
}

return similarityScore
return distanceSum
}

func part1(f *os.File) int {
s := bufio.NewScanner(f)

func part2(lines []string) int {
var leftList []int
var rightList []int

for s.Scan() {
line := s.Text()

for _, line := range lines {
var leftNumber int
var rightNumber int
must.NoError(fmt.Sscanf(line, "%d %d", &leftNumber, &rightNumber))
leftList = append(leftList, leftNumber)
rightList = append(rightList, rightNumber)
}

slices.Sort(leftList)
slices.Sort(rightList)
counterMap := make(map[int]int)

if len(leftList) != len(rightList) {
panic("expected same length")
for _, value := range rightList {
if _, ok := counterMap[value]; ok {
counterMap[value]++
} else {
counterMap[value] = 1
}
}

distanceSum := 0
for i := 0; i < len(leftList); i++ {
distance := leftList[i] - rightList[i]

// Take the absolute value
if distance < 0 {
distance = distance * -1
similarityScore := 0
for _, value := range leftList {
counterMapValue, ok := counterMap[value]
if !ok {
continue
}

distanceSum += distance
similarityScore += value * counterMapValue
}

return distanceSum
return similarityScore
}
11 changes: 5 additions & 6 deletions cmd/day1/main_test.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
package main

import (
"github.com/gdejong/advent-of-code-2024/internal/must"
"os"
"github.com/gdejong/advent-of-code-2024/internal/input"
"testing"
)

func TestPart1(t *testing.T) {
f := must.NoError(os.Open("test_input.txt"))
lines := input.Content("test_input.txt")

answer := part1(f)
answer := part1(lines)

if answer != 11 {
t.Errorf("wrong answer, got: %d", answer)
}
}

func TestPart2(t *testing.T) {
f := must.NoError(os.Open("test_input.txt"))
lines := input.Content("test_input.txt")

answer := part2(f)
answer := part2(lines)

if answer != 31 {
t.Errorf("wrong answer, got: %d", answer)
Expand Down
37 changes: 8 additions & 29 deletions cmd/day2/main.go
Original file line number Diff line number Diff line change
@@ -1,35 +1,24 @@
package main

import (
"bufio"
"fmt"
"github.com/gdejong/advent-of-code-2024/internal/input"
"github.com/gdejong/advent-of-code-2024/internal/math"
"github.com/gdejong/advent-of-code-2024/internal/must"
"github.com/gdejong/advent-of-code-2024/internal/slices"
"io"
"os"
"strings"
)

func main() {
f := must.NoError(os.Open("cmd/day2/real_input.txt"))
lines := input.Content("cmd/day2/real_input.txt")

fmt.Println(part1(f))
fmt.Println(part1(lines))

// Reset the file so we can it again for part 2
must.NoError(f.Seek(0, io.SeekStart))

fmt.Println(part2(f))
fmt.Println(part2(lines))
}

func part1(f *os.File) int {
s := bufio.NewScanner(f)

func part1(lines []string) int {
safeCounter := 0
for s.Scan() {
line := s.Text()

for _, line := range lines {
report := input.ToIntegers(strings.Fields(line))

if isSafeReport(report) {
Expand All @@ -40,20 +29,16 @@ func part1(f *os.File) int {
return safeCounter
}

func part2(f *os.File) int {
s := bufio.NewScanner(f)

func part2(lines []string) int {
safeCounter := 0
for s.Scan() {
line := s.Text()

for _, line := range lines {
report := input.ToIntegers(strings.Fields(line))

// Create all possible options by continually removing one level
var reportsToCheck [][]int
reportsToCheck = append(reportsToCheck, report)
for index := range len(report) {
reportsToCheck = append(reportsToCheck, remove(report, index))
reportsToCheck = append(reportsToCheck, slices.CopyAndRemoveIndex(report, index))
}

for _, r := range reportsToCheck {
Expand All @@ -67,12 +52,6 @@ func part2(f *os.File) int {
return safeCounter
}

func remove(slice []int, s int) []int {
s2 := make([]int, len(slice))
copy(s2, slice)
return append(s2[:s], s2[s+1:]...)
}

func isSafeReport(levels []int) bool {
// Calculate the differences
diffs := make([]int, len(levels)-1)
Expand Down
11 changes: 5 additions & 6 deletions cmd/day2/main_test.go
Original file line number Diff line number Diff line change
@@ -1,25 +1,24 @@
package main

import (
"github.com/gdejong/advent-of-code-2024/internal/must"
"os"
"github.com/gdejong/advent-of-code-2024/internal/input"
"testing"
)

func TestPart1(t *testing.T) {
f := must.NoError(os.Open("test_input.txt"))
lines := input.Content("test_input.txt")

answer := part1(f)
answer := part1(lines)

if answer != 2 {
t.Errorf("wrong answer, got: %d", answer)
}
}

func TestPart2(t *testing.T) {
f := must.NoError(os.Open("test_input.txt"))
lines := input.Content("test_input.txt")

answer := part2(f)
answer := part2(lines)

if answer != 4 {
t.Errorf("wrong answer, got: %d", answer)
Expand Down
18 changes: 18 additions & 0 deletions internal/input/input.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,28 @@
package input

import (
"bufio"
"github.com/gdejong/advent-of-code-2024/internal/must"
"os"
"strconv"
)

func Content(file string) []string {
f, err := os.Open(file)
if err != nil {
panic(err)
}
defer f.Close()
s := bufio.NewScanner(f)

lines := make([]string, 0)
for s.Scan() {
lines = append(lines, s.Text())
}

return lines
}

func ToIntegers(input []string) []int {
integers := make([]int, len(input))

Expand Down
1 change: 1 addition & 0 deletions internal/math/math.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package math

// Abs returns the absolute value of value.
func Abs(value int) int {
if value < 0 {
value = value * -1
Expand Down
8 changes: 8 additions & 0 deletions internal/slices/slices.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,11 @@ func All[T any](ts []T, pred func(T) bool) bool {
}
return true
}

// CopyAndRemoveIndex returns a new slice with the given i element removed.
func CopyAndRemoveIndex(slice []int, i int) []int {
newSlice := make([]int, len(slice))
copy(newSlice, slice) // make a copy so we do not alter the original slice

return append(newSlice[:i], newSlice[i+1:]...)
}

0 comments on commit ec24973

Please sign in to comment.