github.com/cycloss/advent-of-code@v0.0.0-20221210145555-15039b95faa6/2021/day6/day6.go (about)

     1  package main
     2  
     3  import (
     4  	"bufio"
     5  	"fmt"
     6  	"log"
     7  	"math/big"
     8  	"os"
     9  	"strconv"
    10  	"strings"
    11  )
    12  
    13  func main() {
    14  	var file, err = os.Open("day6.txt")
    15  	if err != nil {
    16  		log.Fatalf("failed to open file: %v\n", err)
    17  	}
    18  	defer file.Close()
    19  	solve(file)
    20  }
    21  
    22  func solve(file *os.File) {
    23  	var buff = bufio.NewScanner(file)
    24  	var fishes = createStartingFish(buff)
    25  	var part1 = simulate(fishes, 80)
    26  	var part2 = simulate(fishes, 256)
    27  	fmt.Printf("Part 1 Solution: %d\n", part1)
    28  	fmt.Printf("Part 2 Solution: %d\n", part2)
    29  
    30  }
    31  
    32  func createStartingFish(buff *bufio.Scanner) []int {
    33  	var fishes = make([]int, breedingCycle)
    34  
    35  	for buff.Scan() {
    36  		var line = buff.Text()
    37  		var rawNums = strings.Split(line, ",")
    38  		for _, v := range rawNums {
    39  			var num, err = strconv.Atoi(v)
    40  			if err != nil {
    41  				log.Fatal(v)
    42  			}
    43  			fishes[num]++
    44  		}
    45  	}
    46  	return fishes
    47  }
    48  
    49  const breedingCycle = 7
    50  const juvenileStage = 2
    51  
    52  func simulate(fish []int, days int) *big.Int {
    53  	var adults = convertToBigIntArr(fish)
    54  	var breedingP = 0
    55  	var juveniles = createJuveniles()
    56  	var juvenileP = 0
    57  	for i := 0; i < days; i++ {
    58  		var fishesToBreed = adults[breedingP]
    59  		var newFish = big.NewInt(0)
    60  		// breed new fish
    61  		newFish.Set(fishesToBreed)
    62  		// move oldest juveniles to group that just bred
    63  		var juvenilesToMove = juveniles[juvenileP]
    64  		fishesToBreed.Add(fishesToBreed, juvenilesToMove)
    65  		// set oldest juveniles group to new fish
    66  		juvenilesToMove.Set(newFish)
    67  		breedingP = (breedingP + 1) % breedingCycle
    68  		juvenileP = (juvenileP + 1) % juvenileStage
    69  
    70  	}
    71  	var adultTotal = totalFishBig(adults)
    72  	return adultTotal.Add(adultTotal, totalFishBig(juveniles))
    73  }
    74  
    75  func convertToBigIntArr(fishes []int) []*big.Int {
    76  	var fishesBig = make([]*big.Int, len(fishes))
    77  	for i, v := range fishes {
    78  		fishesBig[i] = big.NewInt(int64(v))
    79  	}
    80  	return fishesBig
    81  }
    82  
    83  func createJuveniles() []*big.Int {
    84  	var juv = make([]int, juvenileStage)
    85  	return convertToBigIntArr(juv)
    86  }
    87  
    88  func totalFishBig(fish []*big.Int) *big.Int {
    89  	var total = big.NewInt(0)
    90  	for _, v := range fish {
    91  		total.Add(total, v)
    92  	}
    93  	return total
    94  }