Skip to content

Commit

Permalink
Implementations for day 10
Browse files Browse the repository at this point in the history
  • Loading branch information
nlowe committed Dec 11, 2018
1 parent 2e830f3 commit b0cf811
Show file tree
Hide file tree
Showing 4 changed files with 544 additions and 0 deletions.
2 changes: 2 additions & 0 deletions aoc2018.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package main

import (
"fmt"
"github.com/nlowe/aoc2018/day10"
"github.com/nlowe/aoc2018/day9"
"os"
"time"
Expand Down Expand Up @@ -57,6 +58,7 @@ func main() {
day7.A, day7.B,
day8.A, day8.B,
day9.A, day9.B,
day10.A,
)

flags := rootCmd.PersistentFlags()
Expand Down
158 changes: 158 additions & 0 deletions day10/day10.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
package day10

import (
"fmt"
"github.com/nlowe/aoc2018/util"
"github.com/spf13/cobra"
"strconv"
"strings"
)

// We calculate the solution for 10b during 10a anyways. Since most of the code is re-used,
// they're just setup as aliases of eachOther
var A = &cobra.Command{
Use: "10a",
Aliases: []string{"10b"},
Short: "Day 10, Problem A",
Run: func(_ *cobra.Command, _ []string) {
fmt.Printf("Answer: \n\n%s\n", a(util.ReadInput(), SolutionLetterHeight))
},
}

const TestLetterHeight = 8
const SolutionLetterHeight = 10

type point struct {
x int
y int
vx int
vy int
}

type bitmap struct {
pixels map[int]map[int] bool
minX int
minY int
maxX int
maxY int
}

func parsePoint(line string) *point {
components := strings.Split(line, "> velocity=<")
p := strings.Split(strings.TrimRight(components[0][10:], ">"), ",")
v := strings.Split(strings.TrimRight(components[1], ">"), ",")

result := &point{}

if x, err := strconv.Atoi(strings.TrimSpace(p[0])); err != nil {
panic(err)
} else {
result.x = x
}

if y, err := strconv.Atoi(strings.TrimSpace(p[1])); err != nil {
panic(err)
} else {
result.y = y
}

if vx, err := strconv.Atoi(strings.TrimSpace(v[0])); err != nil {
panic(err)
} else {
result.vx = vx
}

if vy, err := strconv.Atoi(strings.TrimSpace(v[1])); err != nil {
panic(err)
} else {
result.vy = vy
}

return result
}

// This is the best test I could come up with that works for tests and real inputs
// TODO: Figure out a better test
func isProbableSolution(height int, points []*point) bool {
bitmap := mapIt(points)

return bitmap.maxY - bitmap.minY == height - 1
}

func mapIt(points []*point) *bitmap {
minX := points[0].x
minY := points[0].y
maxX := points[0].x
maxY := points[0].y

pixels := map[int]map[int]bool{}

for _, p := range points {
if _, found := pixels[p.x]; !found {
pixels[p.x] = map[int]bool{}
}

pixels[p.x][p.y] = true

if p.x < minX {
minX = p.x
}

if p.x > maxX {
maxX = p.x
}

if p.y < minY {
minY = p.y
}

if p.y > maxY {
maxY = p.y
}
}

return &bitmap{pixels:pixels, minX: minX, minY: minY, maxX: maxX, maxY: maxY}
}

func prettyPrint(points []*point) string {
bitmap := mapIt(points)


builder := strings.Builder{}
for y := bitmap.minY; y <= bitmap.maxY; y++ {
line := strings.Builder{}

for x := bitmap.minX; x <= bitmap.maxX; x++ {
if _, found := bitmap.pixels[x]; found && bitmap.pixels[x][y] {
line.WriteRune('#')
} else {
line.WriteRune('.')
}
}

builder.WriteString(line.String())
builder.WriteRune('\n')
}

return strings.TrimSpace(builder.String())
}

func a(input *util.ChallengeInput, targetHeight int) string {
var points []*point
for line := range input.Lines() {
points = append(points, parsePoint(line))
}

steps := 0
for !isProbableSolution(targetHeight, points) {
steps += 1
for _, p := range points {
p.x += p.vx
p.y += p.vy
}
}

fmt.Printf("Solution found after %d steps\n", steps)

return prettyPrint(points)
}
52 changes: 52 additions & 0 deletions day10/day10_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
package day10

import (
"github.com/nlowe/aoc2018/util"
"github.com/stretchr/testify/require"
"testing"
)

func TestA(t *testing.T) {
input := util.TestInput(`position=< 9, 1> velocity=< 0, 2>
position=< 7, 0> velocity=<-1, 0>
position=< 3, -2> velocity=<-1, 1>
position=< 6, 10> velocity=<-2, -1>
position=< 2, -4> velocity=< 2, 2>
position=<-6, 10> velocity=< 2, -2>
position=< 1, 8> velocity=< 1, -1>
position=< 1, 7> velocity=< 1, 0>
position=<-3, 11> velocity=< 1, -2>
position=< 7, 6> velocity=<-1, -1>
position=<-2, 3> velocity=< 1, 0>
position=<-4, 3> velocity=< 2, 0>
position=<10, -3> velocity=<-1, 1>
position=< 5, 11> velocity=< 1, -2>
position=< 4, 7> velocity=< 0, -1>
position=< 8, -2> velocity=< 0, 1>
position=<15, 0> velocity=<-2, 0>
position=< 1, 6> velocity=< 1, 0>
position=< 8, 9> velocity=< 0, -1>
position=< 3, 3> velocity=<-1, 1>
position=< 0, 5> velocity=< 0, -1>
position=<-2, 2> velocity=< 2, 0>
position=< 5, -2> velocity=< 1, 2>
position=< 1, 4> velocity=< 2, 1>
position=<-2, 7> velocity=< 2, -2>
position=< 3, 6> velocity=<-1, -1>
position=< 5, 0> velocity=< 1, 0>
position=<-6, 0> velocity=< 2, 0>
position=< 5, 9> velocity=< 1, -2>
position=<14, 7> velocity=<-2, 0>
position=<-3, 6> velocity=< 2, -1>`)

expected := `#...#..###
#...#...#.
#...#...#.
#####...#.
#...#...#.
#...#...#.
#...#...#.
#...#..###`

require.Equal(t, expected, a(input, TestLetterHeight))
}
Loading

0 comments on commit b0cf811

Please sign in to comment.