Created
December 16, 2017 00:06
-
-
Save Robert-Wett/7e2cc281f2be89b6d35d06178ed4b6d4 to your computer and use it in GitHub Desktop.
day13
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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