Skip to content

Instantly share code, notes, and snippets.

@Robert-Wett
Created December 16, 2017 00:06
Show Gist options
  • Save Robert-Wett/7e2cc281f2be89b6d35d06178ed4b6d4 to your computer and use it in GitHub Desktop.
Save Robert-Wett/7e2cc281f2be89b6d35d06178ed4b6d4 to your computer and use it in GitHub Desktop.
day13
package main
import (
"fmt"
"math"
"strconv"
"strings"
"github.com/Robert-Wett/AdventOfCode2017/helpers"
)
func main() {
//partOne(helpers.GetInput("./input.txt"))
//partOne(helpers.GetInput("./sampleInput.txt"))
partTwoForReal(helpers.GetInput("./input.txt"))
//partTwoForReal(helpers.GetInput("./sampleInput.txt"))
//partTwoBrute(helpers.GetInput("./input.txt"))
//partTwo(helpers.GetInput("./input.txt"))
}
func partTwoForReal(input string) {
m := newLayerMap(input)
for i := 0; ; i++ {
m.setCourse(i)
if m.checkIfPassed() {
fmt.Println("YAY!!!! ", i)
return
}
}
}
func partTwo(input string) {
m := newLayerMap(input)
max := m.getMax()
var found bool
for preTicks := 0; preTicks < math.MaxInt32; preTicks++ {
for i := 1; i < max; i++ {
if layer, ok := (*m)[i]; ok {
caught := isCaught(layer.depth, i+preTicks)
if caught {
break
}
}
fmt.Println("FOUND AT: ", preTicks)
}
if found {
break
}
}
}
func isCaught(depth, steps int) bool {
pos := steps
var idx int
if pos < depth {
idx = pos
} else if (pos/depth)%2 == 0 {
idx = depth - (-pos % depth) - 1
} else {
idx = (depth - (pos % depth)) - 1
}
return idx == 0
}
func partTwoBrute(input string) {
var i int
m := newLayerMap(input)
for true {
m.zeroMap()
p := packet{}
if attemptPassWithWait(m, &p, i) {
fmt.Println(fmt.Sprintf("You had to wait %d picoseconds before crossing successfuly", i))
break
}
i++
}
}
func attemptPassWithWait(m *layerMap, p *packet, numPreTicks int) bool {
m.tick(numPreTicks)
max := m.getMax()
for i := 0; i < max; i++ {
p.tick(m)
m.tick(1)
}
return len(p.caught) == 0
}
func partOne(input string) {
m := newLayerMap(input)
//p := packet{}
//attemptPass(m, &p)
m.setCourse(0)
m.checkForStats()
}
func (l *layerMap) setCourse(steps int) {
l.zeroMap()
max := l.getMax()
for i := 0; i < max; i++ {
if curLayer, ok := (*l)[i]; ok {
curLayer.tick(i + steps)
}
}
}
func (l *layerMap) checkIfPassed() bool {
for _, layer := range *l {
if layer.idx == 0 {
return false
}
}
return true
}
func (l *layerMap) checkForStats() {
var score int
for _, layer := range *l {
if layer.idx == 0 {
score += layer.pos * layer.depth
}
}
fmt.Println(score)
}
func attemptPass(m *layerMap, p *packet) {
max := m.getMax()
for i := 0; i < max; i++ {
p.tick(m)
m.tick(1)
}
severity := p.caught.calculateSeverity()
if severity > 0 {
fmt.Println(fmt.Sprintf("You were caught %d times, with a severity of %d", len(p.caught), severity))
}
}
type packet struct {
idx int
caught layers
}
func (p *packet) tick(l *layerMap) {
// If a layer exists at this index
if curLayer, ok := (*l)[p.idx]; ok {
// If the layer's scanner is at the top
if curLayer.idx == 0 {
fmt.Println("Caught at layer: ", curLayer.pos)
p.caught = append(p.caught, curLayer)
}
}
p.idx++
}
type layerMap map[int]*layer
func newLayerMap(input string) *layerMap {
lm := make(layerMap)
for _, line := range strings.Split(input, "\n") {
p, d := parseLine(line)
lm[p] = &layer{pos: p, depth: d}
}
return &lm
}
func (l *layerMap) zeroMap() {
for _, layer := range *l {
layer.idx = 0
layer.dir = 0
}
}
func (l *layerMap) tick(num int) {
if num <= 0 {
return
}
for _, layer := range *l {
(*layer).tick(num)
}
}
func (l *layerMap) getMax() int {
var highest int
for k := range *l {
if k > highest {
highest = k
}
}
return highest + 1
}
type layers []*layer
func (l *layers) calculateSeverity() int {
var total int
for _, layer := range *l {
total += layer.pos * layer.depth
}
return total
}
type layer struct {
idx int
depth int
pos int
dir int
}
func (l *layer) tick(num int) {
for i := 0; i < num; i++ {
// Zero or Single lengthed layers don't change state
if l.depth-1 <= 0 {
return
}
if l.dir == 0 { // Down
if l.idx+1 > l.depth-1 {
// Change direction
l.dir = 1
l.idx--
} else {
l.idx++
}
} else { // Up
if l.idx-1 < 0 {
// Change direction
l.dir = 0
l.idx++
} else {
l.idx--
}
}
}
}
func parseLine(line string) (int, int) {
layer := strings.Split(line, ": ")
pos, _ := strconv.Atoi(layer[0])
depth, _ := strconv.Atoi(layer[1])
return pos, depth
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment