Skip to content

Commit

Permalink
Merge pull request #128 from asphaltbuffet/2024-02
Browse files Browse the repository at this point in the history
2024 02
  • Loading branch information
asphaltbuffet authored Dec 12, 2024
2 parents 85ad5c8 + f5b9998 commit 7750c29
Show file tree
Hide file tree
Showing 6 changed files with 302 additions and 2 deletions.
37 changes: 37 additions & 0 deletions exercises/2024/02-red-NosedReports/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# [Day 2: Red-Nosed Reports](https://adventofcode.com/2024/day/2)

<!-- These are helper text to make formatting the yearly readme consistent and easier...
[Day 2: Red-Nosed Reports][rm2]
[Go][go2]
[Python][py2]
[rm2]: 02-red-NosedReports/README.md
[go2]: 02-red-NosedReports/go
[py2]: 02-red-NosedReports/py
-->

## Go

```text
──────────────────────────────────────────
ADVENT OF CODE 2024
Day 2: Red-Nosed Reports
──────────────────────────────────────────
Solving (Go)...
1.1: PASS 478µs
⤷ 549
2.1: PASS 707µs
⤷ 589
```

## Python

```text
< section intentionally left blank >
```

## 2024 Run Times

![2024 exercise run-time graphs](../run-times.png)
54 changes: 54 additions & 0 deletions exercises/2024/02-red-NosedReports/go/exercise.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package exercises

import (
"github.com/asphaltbuffet/advent-of-code/internal/common"
)

// Exercise for Advent of Code 2024 day 2.
type Exercise struct {
common.BaseExercise
}

// One returns the answer to the first part of the exercise.
func (e Exercise) One(instr string) (any, error) {
reports, err := parse(instr)
if err != nil {
return nil, err
}

var count int
for _, r := range reports {
if ok := r.isSafe(); ok {
count++
}
}

return count, nil
}

// Two returns the answer to the second part of the exercise.
func (e Exercise) Two(instr string) (any, error) {
reports, err := parse(instr)
if err != nil {
return nil, err
}

var count int
for _, r := range reports {
r := r
if ok := r.isSafe(); ok {
count++
} else {
for i := 0; i < len(r.values); i++ {
tmp := Report{values: removeAt(r.values, i)}

if altOk := tmp.isSafe(); altOk {
count++
break
}
}
}
}

return count, nil
}
72 changes: 72 additions & 0 deletions exercises/2024/02-red-NosedReports/go/reports.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package exercises

import (
"fmt"
"strconv"
"strings"
)

type Report struct {
values []int
}

func parse(s string) ([]Report, error) {
var reports []Report

for _, line := range strings.Split(s, "\n") {
vals := strings.Fields(line)
r := Report{
values: make([]int, 0, len(vals)),
}

for i, level := range vals {
v, err := strconv.Atoi(level)
if err != nil {
return nil, fmt.Errorf("failed to parse line %d: %w", i, err)
}

r.values = append(r.values, v)
}
reports = append(reports, r)

}

return reports, nil
}

func (r *Report) isSafe() bool {
if r.values[0] < r.values[1] {
for i, j := 0, 1; j < len(r.values); i, j = i+1, j+1 {
if r.values[j]-r.values[i] < 1 || r.values[j]-r.values[i] > 3 {
return false
}
}
} else {
for i, j := 0, 1; j < len(r.values); i, j = i+1, j+1 {
if r.values[i]-r.values[j] < 1 || r.values[i]-r.values[j] > 3 {
return false
}
}
}

return true
}

func makeSafe(r *Report, idx int) (int, bool) {
fmt.Println(r.values)
for i := 0; i < len(r.values); i++ {
tmp := make([]int, 0, len(r.values)-1)
tmp = append(tmp, r.values[:i]...)
tmp = append(tmp, r.values[i+1:]...)

fmt.Println(tmp)
}
return -1, true
}

func removeAt(r []int, idx int) []int {
tmp := make([]int, len(r))
copy(tmp, r)
tmp = append(tmp[:idx], tmp[idx+1:]...)
return tmp
}
107 changes: 107 additions & 0 deletions exercises/2024/02-red-NosedReports/go/reports_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
package exercises

import (
"testing"

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

func TestReport_isSafe(t *testing.T) {
tests := []struct {
name string
values []int
assertion assert.BoolAssertionFunc
}{
{"example 1", []int{7, 6, 4, 2, 1}, assert.True},
{"example 2", []int{1, 2, 7, 8, 9}, assert.False},
{"example 3", []int{9, 7, 6, 2, 1}, assert.False},
{"example 4", []int{1, 3, 2, 4, 5}, assert.False},
{"example 5", []int{8, 6, 4, 4, 1}, assert.False},
{"example 6", []int{1, 3, 6, 7, 9}, assert.True},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
r := &Report{values: tt.values}

tt.assertion(t, r.isSafe())
})
}
}

func Test_parse(t *testing.T) {
tests := []struct {
name string
s string
want []Report
assertion assert.ErrorAssertionFunc
}{
{
name: "example all",
s: "7 6 4 2 1\n1 2 7 8 9\n9 7 6 2 1\n1 3 2 4 5\n8 6 4 4 1\n1 3 6 7 9",
want: []Report{
{
values: []int{7, 6, 4, 2, 1},
},
{
values: []int{1, 2, 7, 8, 9},
},
{
values: []int{9, 7, 6, 2, 1},
},
{
values: []int{1, 3, 2, 4, 5},
},
{
values: []int{8, 6, 4, 4, 1},
},
{
values: []int{1, 3, 6, 7, 9},
},
},
assertion: assert.NoError,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := parse(tt.s)
tt.assertion(t, err)
assert.Equal(t, tt.want, got)
})
}
}

func Test_removeAt(t *testing.T) {
type args struct {
r []int
idx int
}
tests := []struct {
name string
args args
want []int
}{
{
name: "first",
args: args{
r: []int{1, 2, 3},
idx: 0,
},
want: []int{2, 3},
},
{
name: "last",
args: args{
r: []int{1, 2, 3},
idx: 2,
},
want: []int{1, 2},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := removeAt(tt.args.r, tt.args.idx)
assert.Len(t, got, len(tt.want))
// assert.Equal(t, tt.want, removeAt(tt.args.r, tt.args.idx))
})
}
}
28 changes: 28 additions & 0 deletions exercises/2024/02-red-NosedReports/info.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"id": "2024-02",
"title": "Red-Nosed Reports",
"year": 2024,
"day": 2,
"url": "https://adventofcode.com/2024/day/2",
"data": {
"inputFile": "input.txt",
"testCases": {
"one": [
{
"input": "7 6 4 2 1\n1 2 7 8 9\n9 7 6 2 1\n1 3 2 4 5\n8 6 4 4 1\n1 3 6 7 9",
"expected": "2"
}
],
"two": [
{
"input": "7 6 4 2 1\n1 2 7 8 9\n9 7 6 2 1\n1 3 2 4 5\n8 6 4 4 1\n1 3 6 7 9",
"expected": "4"
}
]
},
"answers": {
"a": "549",
"b": "589"
}
}
}
6 changes: 4 additions & 2 deletions exercises/2024/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@

| Title | Stars | Solutions |
| -------------------------------- | :---: | --------- |
| [Day 1: Historian Hysteria][rm1] | ★★ | [Go][go1] |
| Day 2 | ☆☆ | |
| [Day 1: Historian Hysteria][rm1] | ⭐⭐ | [Go][go1] |
| [Day 2: Red-Nosed Reports][rm2] | ⭐⭐ | [Go][go2] |
| Day 3 | ☆☆ | |
| Day 4 | ☆☆ | |
| Day 5 | ☆☆ | |
Expand Down Expand Up @@ -46,3 +46,5 @@ TODO

[rm1]: 01-historianHysteria/README.md
[go1]: 01-historianHysteria/go
[rm2]: 02-red-NosedReports/README.md
[go2]: 02-red-NosedReports/go

0 comments on commit 7750c29

Please sign in to comment.