56 lines
1.5 KiB
Go
56 lines
1.5 KiB
Go
package day09
|
|
|
|
type Marble struct {
|
|
Number int
|
|
CW *Marble
|
|
CCW *Marble
|
|
}
|
|
|
|
// Returns the new current marble and the score to add.
|
|
func (m *Marble) PlaceNewMarble(number int) (*Marble, int) {
|
|
// if the marble that is about to be placed has a number which is a multiple
|
|
// of 23, the current player keeps the marble they would have placed, adding
|
|
// it to their score. In addition, the marble 7 marbles counter-clockwise
|
|
// from the current marble is removed from the circle and also added to the
|
|
// current player's score. The marble located immediately clockwise of the
|
|
// marble that was removed becomes the new current marble.
|
|
if number%23 == 0 {
|
|
score := number
|
|
cursor := m
|
|
for i := 0; i < 7; i++ {
|
|
cursor = cursor.CCW
|
|
}
|
|
score += cursor.Number
|
|
cursor = cursor.Remove()
|
|
return cursor, score
|
|
}
|
|
|
|
// [Insert the marble] between the marbles that are 1 and 2
|
|
// marbles clockwise of the current marble.
|
|
// The marble that was just placed then becomes the current marble.
|
|
|
|
// first create the marble and populate its fields correctly
|
|
newMarble := &Marble{Number: number}
|
|
cursor := m.CW
|
|
newMarble.CCW = cursor
|
|
newMarble.CW = cursor.CW
|
|
|
|
// now sync up the pointers in the adjacent marbles
|
|
newMarble.CCW.CW = newMarble
|
|
newMarble.CW.CCW = newMarble
|
|
return newMarble, 0
|
|
}
|
|
|
|
func (m *Marble) Remove() *Marble {
|
|
// removes the marble from the list, repairing links. Returns the
|
|
// marble immediately CW of this one.
|
|
|
|
// link the two newly-adjacent marbles.
|
|
ccw := m.CCW
|
|
cw := m.CW
|
|
ccw.CW = cw
|
|
cw.CCW = ccw
|
|
|
|
return cw
|
|
}
|