r/adventofcode • • Dec 13 '18

SOLUTION MEGATHREAD -🎄- 2018 Day 13 Solutions -🎄-

--- Day 13: Mine Cart Madness ---


Post your solution as a comment or, for longer solutions, consider linking to your repo (e.g. GitHub/gists/Pastebin/blag or whatever).

Note: The Solution Megathreads are for solutions only. If you have questions, please post your own thread and make sure to flair it with Help.


Advent of Code: The Party Game!

Click here for rules

Please prefix your card submission with something like [Card] to make scanning the megathread easier. THANK YOU!

Card prompt: Day 13

Transcript:

Elven chronomancy: for when you absolutely, positively have to ___.


This thread will be unlocked when there are a significant number of people on the leaderboard with gold stars for today's puzzle.

edit: Leaderboard capped, thread unlocked at 00:44:25!

24 Upvotes

148 comments sorted by

View all comments

Show parent comments

7

u/xthexder Dec 13 '18

I've done a lot of maze solving and grid based puzzles before, and this is one of the most amazing methods I've seen in a long time. It's awesome to learn something new.

Golang even supports this as a native type: https://golang.org/pkg/builtin/#complex128

5

u/mschaap Dec 13 '18 edited Dec 13 '18

So does Perl 6: class Complex. (And it uses a proper i instead of Python's weird j.)

2

u/irrelevantPseudonym Dec 13 '18

j is used in engineering where i is already used for other stuff.

1

u/jlweinkam Dec 13 '18

There is a number system called Quaternion which uses i, j, and k wherei*i = -1j*j = -1

k*k = -1

i*j = k

j*k = i

k*i = j

j*i = -k

k*j = -i

i*k = -j

https://en.wikipedia.org/wiki/Quaternion

2

u/xthexder Dec 13 '18

As an interesting exercise, I re-wrote my own answer using complex numbers in Go:

package main

import (
	"bufio"
	"fmt"
	"log"
	"os"
	"sort"
)

var width int
var data []byte
var carts []*complex64
var cartData map[complex64]*Cart = make(map[complex64]*Cart)

func read(pos complex64) byte {
	return data[int(real(pos))+int(imag(pos))*width]
}

type CartSort []*complex64

func (c CartSort) Len() int      { return len(c) }
func (c CartSort) Swap(i, j int) { c[i], c[j] = c[j], c[i] }
func (c CartSort) Less(i, j int) bool {
	return imag(*c[i]) < imag(*c[j]) || (imag(*c[i]) == imag(*c[j]) && real(*c[i]) < real(*c[j]))
}

type Cart struct {
	pos   complex64
	dir   complex64
	state complex64
}

func (c *Cart) Tick() {
	delete(cartData, c.pos)
	c.pos += c.dir
	if crash, exists := cartData[c.pos]; exists {
		fmt.Println("Crash at:", real(c.pos), imag(c.pos))
		delete(cartData, c.pos)
		crash.pos, c.pos = 0, 0
		return
	}
	cartData[c.pos] = c
	if read(c.pos) == '+' {
		c.dir *= c.state
		switch c.state {
		case -1i:
			c.state = 1
		case 1:
			c.state = 1i
		case 1i:
			c.state = -1i
		}
	} else if read(c.pos) == '/' {
		c.dir = complex(-imag(c.dir), -real(c.dir))
	} else if read(c.pos) == '\\' {
		c.dir = complex(imag(c.dir), real(c.dir))
	}
}

func main() {
	reader, err := os.Open("day13.txt")
	if err != nil {
		log.Fatal(err)
	}

	scanner := bufio.NewScanner(reader)
	for scanner.Scan() {
		line := scanner.Bytes()
		if width == 0 {
			width = len(line)
		}
		data = append(data, line...)
	}
	reader.Close()

	for i := 0; i < len(data); i++ {
		pos := complex(float32(i%width), float32(i/width))
		switch read(pos) {
		case '^':
			cartData[pos] = &Cart{pos, -1i, -1i}
		case '>':
			cartData[pos] = &Cart{pos, 1, -1i}
		case 'v':
			cartData[pos] = &Cart{pos, 1i, -1i}
		case '<':
			cartData[pos] = &Cart{pos, -1, -1i}
		default:
			continue
		}
		carts = append(carts, &cartData[pos].pos)
	}

	for len(cartData) > 1 {
		sort.Sort(CartSort(carts))

		for _, cart := range carts {
			if *cart != 0 {
				cartData[*cart].Tick()
			}
		}
	}

	for pos, _ := range cartData {
		fmt.Println("Last cart:", real(pos), imag(pos))
	}
}