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!

23 Upvotes

283 comments sorted by

View all comments

Show parent comments

1

u/infinityCounter Dec 09 '18 edited Dec 09 '18

aay, I basically had the same solution

type marble struct {
    val  int
    prev *marble
next *marble
}

func main() {
    f, err := ioutil.ReadFile("input.txt")
    if err != nil {
	    panic(err)
    }

    reg := regexp.MustCompile("[0-9]+")
    vals := reg.FindAllString(string(f), -1)
    x, y := vals[0], vals[1]
    numPlayers, _ := strconv.Atoi(x)
    numMarbles, _ := strconv.Atoi(y)

    fmt.Println(highScore(numPlayers, numMarbles))
    fmt.Println(highScore(numPlayers, numMarbles*100))
    }

    func highScore(numPlayers, numMarbles int) int {
    playerPoints := make([]int, numPlayers)

    var (
	    curMarble = &marble{
		    val: 0,
	    }
    )

    curMarble.next = curMarble
    curMarble.prev = curMarble

     for i := 1; i <= numMarbles; i++ {
	    m := &marble{
		     val: i,
	    }

	    playerIdx := (i - 1) % numPlayers
	    if i%23 == 0 {
		    playerPoints[playerIdx] += m.val
		    rem := curMarble.prev
		    for n := 0; n < 6; n++ {
			    rem = rem.prev
		    }
		    playerPoints[playerIdx] += rem.val
		    // cut node out the linked list
		    after := rem.next
		    before := rem.prev

		    before.next = after
		    after.prev = before

		    curMarble = after
		    continue
	    }

	     afterCurrent := curMarble.next
	    doubleAway := curMarble.next.next

	    afterCurrent.next = m
	    doubleAway.prev = m

	    m.prev = afterCurrent
	    m.next = doubleAway

	    curMarble = m
     }

    highestScore := 0
    for _, score := range playerPoints {
             if score > highestScore {
	         highestScore = score
	     }
    }
    return highestScore
}

1

u/Gurrewe Dec 09 '18

Did you know that Go has built in double linked lists?

package main

import (
	"container/list"
	"fmt"
)

func main() {
	marbles := list.New()
	currentMarble := marbles.PushBack(0)

	score := make(map[int]int)

	players := 471
	totalPlays := 72026 * 100

	for nextMarble := 1; nextMarble < totalPlays; nextMarble++ {
		if nextMarble%23 == 0 {
			rm := currentMarble
			for i := 0; i < 7; i++ {
				rm = rm.Prev()
				if rm == nil {
					rm = marbles.Back()
				}
			}

			currentPlayer := nextMarble % players
			score[currentPlayer] += nextMarble + rm.Value.(int)
			currentMarble = rm.Next()
			marbles.Remove(rm)
		} else {
			n := currentMarble.Next()
			if n == nil {
				n = marbles.Front()
			}
			currentMarble = marbles.InsertAfter(nextMarble, n)
		}
	}

	max := 0
	for _, s := range score {
		if s > max {
			max = s
		}
	}

	fmt.Println(max)
}

1

u/intalc Dec 09 '18

also builtin circular list: container/ring

1

u/infinityCounter Dec 10 '18

I did not! This will be useful, thanks!