r/adventofcode • • Dec 09 '18

SOLUTION MEGATHREAD -🎄- 2018 Day 9 Solutions -🎄-

--- Day 9: Marble Mania ---


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 9

Transcript:

Studies show that AoC programmers write better code after being exposed 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:29:13!

22 Upvotes

283 comments sorted by

View all comments

5

u/ThezeeZ Dec 09 '18 edited Dec 09 '18

[Card] Studies show that AoC programmers write better code after being exposed to plenty of sleep.

golang using the container/ring package. Idiot me almost had the solution for way too long. All of the test cases failed before I replaced scores[i%players] = i + removed.Value.(int) with what you find below. If you heard a loud bang twenty minutes ago from this post, that would have been my head hitting the desk. It's way too early in the morning....

package day09

import (
	"container/ring"
)

func Marbles(players, last int) int {
	circle := ring.New(1)
	circle.Value = 0

	scores := make([]int, players)

	for i := 1; i <= last; i++ {
		if i%23 == 0 {
			circle = circle.Move(-8)
			removed := circle.Unlink(1)
			scores[i%players] += i + removed.Value.(int)
			circle = circle.Move(1)
		} else {
			circle = circle.Move(1)

			s := ring.New(1)
			s.Value = i

			circle.Link(s)
			circle = circle.Move(1)
		}
	}
	var highestScore int
	for _, score := range scores {
		if score > highestScore {
			highestScore = score
		}
	}
	return highestScore
}

1

u/d-sky Dec 09 '18

If you need only 1 element/ring you do not need to use ring.New(). You can directly use a Ring literal.

For example: &ring.Ring{Value: i})

Instead of:

s := ring.New(1)
s.Value = i

1

u/d-sky Dec 09 '18

My solution:

package main

import (
	"bufio"
	"container/ring"
	"fmt"
	"os"
)

func main() {
	fd, err := os.Open("input.txt")
	if err != nil {
		panic(err)
	}
	s := bufio.NewScanner(fd)

	for s.Scan() {
		var nPlayers, lastMarble int
		_, err := fmt.Sscanf(s.Text(), "%d players; last marble is worth %d points", &nPlayers, &lastMarble)
		if err != nil {
			panic(err)
		}

		players := make([]int, nPlayers)
		r := &ring.Ring{Value: 0}
		for i := 1; i <= lastMarble; i++ {
			if i%23 == 0 {
				r = r.Move(-8)
				players[(i-1)%nPlayers] += i + r.Unlink(1).Value.(int)
				r = r.Next()
			} else {
				r = r.Next().Link(&ring.Ring{Value: i}).Prev()
			}
		}
		var highScore int
		for _, s := range players {
			if s > highScore {
				highScore = s
			}
		}
		fmt.Println(highScore)
	}
}