Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: Implement solution for 2024 day 1
Browse files Browse the repository at this point in the history
obalunenko committed Dec 16, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 2715e9a commit 6a362c2
Showing 5 changed files with 500 additions and 5 deletions.
100 changes: 98 additions & 2 deletions internal/puzzles/solutions/2024/day01/solution.go
Original file line number Diff line number Diff line change
@@ -2,7 +2,12 @@
package day01

import (
"bufio"
"fmt"
"io"
"slices"
"strconv"
"strings"

"github.com/obalunenko/advent-of-code/internal/puzzles"
)
@@ -22,9 +27,100 @@ func (s solution) Day() string {
}

func (s solution) Part1(input io.Reader) (string, error) {
return "", puzzles.ErrNotImplemented
l, err := parseInput(input)
if err != nil {
return "", fmt.Errorf("failed to parse input: %w", err)
}

slices.Sort(l.itemsA)
slices.Sort(l.itemsB)

var sum int

for i := 0; i < len(l.itemsA); i++ {
d := l.itemsA[i] - l.itemsB[i]
if d < 0 {
d = -d
}

sum += d
}

return strconv.Itoa(sum), nil
}

func (s solution) Part2(input io.Reader) (string, error) {
return "", puzzles.ErrNotImplemented
l, err := parseInput(input)
if err != nil {
return "", fmt.Errorf("failed to parse input: %w", err)
}

seenA := make(map[int]int)

for _, a := range l.itemsA {
seenA[a] = 0

for _, b := range l.itemsB {
if a == b {
seenA[a]++
}
}
}

var sum int

for _, a := range l.itemsA {
sum += a * seenA[a]
}

return strconv.Itoa(sum), nil
}

type lists struct {
itemsA []int
itemsB []int
}

func parseInput(input io.Reader) (lists, error) {
const (
listsNum = 2
listAIdx = 0
listBIdx = 1
)

l := lists{
itemsA: make([]int, 0),
itemsB: make([]int, 0),
}

scanner := bufio.NewScanner(input)
for scanner.Scan() {
line := scanner.Text()

parts := strings.Split(line, " ")
if len(parts) != listsNum {
return lists{}, fmt.Errorf("invalid input line: %s", line)
}

// Parse parts[0] and parts[1] to integers and append them to l.itemsA and l.itemsB respectively.
a, err := strconv.Atoi(parts[listAIdx])
if err != nil {
return lists{}, fmt.Errorf("failed to parse int: %w", err)
}

b, err := strconv.Atoi(parts[listBIdx])
if err != nil {
return lists{}, fmt.Errorf("failed to parse int: %w", err)
}

l.itemsA = append(l.itemsA, a)

l.itemsB = append(l.itemsB, b)
}

if scanner.Err() != nil {
return lists{}, fmt.Errorf("scanner error: %w", scanner.Err())
}

return l, nil
}
4 changes: 2 additions & 2 deletions internal/puzzles/solutions/2024/day01/solution_test.go
Original file line number Diff line number Diff line change
@@ -87,11 +87,11 @@ func Test_solution_Part2(t *testing.T) {
wantErr assert.ErrorAssertionFunc
}{
{
name: "",
name: "test example from description",
args: args{
input: utils.ReaderFromFile(t, filepath.Join("testdata", "input.txt")),
},
want: "",
want: "31",
wantErr: assert.NoError,
},
{
36 changes: 35 additions & 1 deletion internal/puzzles/solutions/2024/day01/spec.md
Original file line number Diff line number Diff line change
@@ -66,5 +66,39 @@ Your actual left and right lists contain many location IDs. What is the total di

## --- Part Two ---

<!--- Pass here the description for part two --->
Your analysis only confirmed what everyone feared: the two lists of location IDs are indeed very different.

Or are they?

The Historians can't agree on which group made the mistakes or how to read most of the Chief's handwriting,
but in the commotion you notice an interesting detail: a lot of location IDs appear in both lists! Maybe the other
numbers aren't location IDs at all but rather misinterpreted handwriting.

This time, you'll need to figure out exactly how often each number from the left list appears in the right list.
Calculate a total similarity score by adding up each number in the left list after multiplying it by the number of
times that number appears in the right list.

Here are the same example lists again:

```text
3 4
4 3
2 5
1 3
3 9
3 3
```

For these example lists, here is the process of finding the similarity score:

- The first number in the left list is 3. It appears in the right list three times, so the similarity score increases by 3 * 3 = 9.
- The second number in the left list is 4. It appears in the right list once, so the similarity score increases by 4 * 1 = 4.
- The third number in the left list is 2. It does not appear in the right list, so the similarity score does not increase (2 * 0 = 0).
- The fourth number, 1, also does not appear in the right list.
- The fifth number, 3, appears in the right list three times; the similarity score increases by 9.
- The last number, 3, appears in the right list three times; the similarity score again increases by 9.

So, for these example lists, the similarity score at the end of this process is `31` `(9 + 4 + 0 + 0 + 9 + 9)`.

Once again consider your left and right lists. What is their similarity score?

Loading

0 comments on commit 6a362c2

Please sign in to comment.