package main import ( "AOC2022/helper" "fmt" "os" "sort" "strconv" "strings" ) type Monkey struct { items []int newOperation func(item int) int test func(item int) int inspections int } func main() { args := os.Args[1:] lines := helper.ReadTextFile(args[0]) runSimulation(lines, 20, true) runSimulation(lines, 10000, false) } func runSimulation(lines []string, turns int, part1 bool) { monkeys, worryLimiter := getMonkeys(lines, part1) for i := 0; i < turns; i++ { for i := 0; i < len(monkeys); i++ { monkey := &monkeys[i] for _, item := range monkey.items { monkey.inspections++ item = monkey.newOperation(item) % worryLimiter throwTo := monkey.test(item) monkeys[throwTo].items = append(monkeys[throwTo].items, item) } monkey.items = []int{} } } sort.Slice(monkeys, func(i, j int) bool { return monkeys[i].inspections > monkeys[j].inspections }) fmt.Println(monkeys[0].inspections * monkeys[1].inspections) } func getMonkeys(lines []string, part1 bool) ([]Monkey, int) { var monkeys []Monkey worryLimiter := 1 for i := 0; i < len(lines); i += 7 { monkey := Monkey{} startingItemsString := lines[i+1][18:] for _, item := range strings.Split(startingItemsString, ", ") { monkey.items = append(monkey.items, helper.RemoveError(strconv.Atoi(item))) } worryLimiter *= getTest(lines, i, &monkey) getOperation(lines, i, &monkey, part1) monkeys = append(monkeys, monkey) } return monkeys, worryLimiter } func getTest(lines []string, i int, monkey *Monkey) int { divisbleby := helper.RemoveError(strconv.Atoi(lines[i+3][21:])) returnTrue := helper.RemoveError(strconv.Atoi(lines[i+4][29:])) returnFalse := helper.RemoveError(strconv.Atoi(lines[i+5][30:])) monkey.test = func(item int) int { if item%divisbleby == 0 { return returnTrue } return returnFalse } return divisbleby } func getOperation(lines []string, i int, monkey *Monkey, part1 bool) { opertionString := lines[i+2][23:] value, err := strconv.Atoi(opertionString[2:]) if err == nil { if opertionString[0] == '+' { monkey.newOperation = func(item int) (returnVal int) { returnVal = (item + value) if part1 { returnVal /= 3 } return } } if opertionString[0] == '*' { monkey.newOperation = func(item int) (returnVal int) { returnVal = (item * value) if part1 { returnVal /= 3 } return } } } else { if opertionString[0] == '+' { monkey.newOperation = func(item int) (returnVal int) { returnVal = item + item if part1 { returnVal /= 3 } return } } if opertionString[0] == '*' { monkey.newOperation = func(item int) (returnVal int) { returnVal = item * item if part1 { returnVal /= 3 } return } } } }