2022 day 11: Bash parts 1 & 2, before cleaning
This commit is contained in:
111
2022/day11/Makefile
Normal file
111
2022/day11/Makefile
Normal file
@@ -0,0 +1,111 @@
|
|||||||
|
# AOC daily Makefile - GNU make only.
|
||||||
|
#
|
||||||
|
# Copyright (C) 2021-2022 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
#
|
||||||
|
|
||||||
|
INPUT := input/input.txt
|
||||||
|
SHELL := /bin/bash
|
||||||
|
|
||||||
|
CC := gcc
|
||||||
|
BEAR := bear
|
||||||
|
CCLSFILE:= compile_commands.json
|
||||||
|
|
||||||
|
LIB := aoc_$(shell uname -m)
|
||||||
|
INCDIR := ../include
|
||||||
|
LIBDIR := ../lib
|
||||||
|
LDFLAGS := -L$(LIBDIR)
|
||||||
|
#LDLIB := -l$(LIB) -lm
|
||||||
|
LDLIB := -l$(LIB)
|
||||||
|
|
||||||
|
export LD_LIBRARY_PATH = $(LIBDIR)
|
||||||
|
|
||||||
|
CFLAGS += -std=gnu11
|
||||||
|
CFLAGS += -O2
|
||||||
|
CFLAGS += -g
|
||||||
|
# for gprof
|
||||||
|
# CFLAGS += -pg
|
||||||
|
CFLAGS += -Wall
|
||||||
|
CFLAGS += -Wextra
|
||||||
|
CFLAGS += -march=native
|
||||||
|
# Next one may be useful for valgrind (some invalid instructions)
|
||||||
|
# CFLAGS += -mno-tbm
|
||||||
|
CFLAGS += -Wmissing-declarations
|
||||||
|
CFLAGS += -Wno-unused-result
|
||||||
|
|
||||||
|
CFLAGS += -DDEBUG_DEBUG # activate general debug (debug.c)
|
||||||
|
CFLAGS += -DDEBUG_POOL # memory pools management
|
||||||
|
|
||||||
|
VALGRIND := valgrind
|
||||||
|
VALGRINDFLAGS := --leak-check=full --show-leak-kinds=all --track-origins=yes \
|
||||||
|
--sigill-diagnostics=yes --quiet --show-error-list=yes
|
||||||
|
|
||||||
|
|
||||||
|
TIME := \time -f "\ttime: %E real, %U user, %S sys\n\tcontext-switch:\t%c+%w, page-faults: %F+%R\n"
|
||||||
|
export PATH := .:$(PATH)
|
||||||
|
|
||||||
|
.PHONY: clean all compile assembly memcheck memcheck1 memcheck2 part1 part2 ccls bear org
|
||||||
|
|
||||||
|
all: README.org ccls part1 part2
|
||||||
|
|
||||||
|
memcheck: memcheck1 memcheck2
|
||||||
|
|
||||||
|
memcheck1: aoc-c
|
||||||
|
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 1 < $(INPUT)
|
||||||
|
|
||||||
|
memcheck2: aoc-c
|
||||||
|
@$(VALGRIND) $(VALGRINDFLAGS) aoc-c -p 2 < $(INPUT)
|
||||||
|
@#@valgrind -s --track-origins=yes aoc-c -p 2 < $(INPUT)
|
||||||
|
|
||||||
|
compile: aoc-c
|
||||||
|
|
||||||
|
cpp: aoc-c.i
|
||||||
|
|
||||||
|
assembly: aoc-c.s
|
||||||
|
|
||||||
|
part1: aoc-c
|
||||||
|
@$(TIME) aoc.bash -p 1 < $(INPUT) 2>&1
|
||||||
|
@#$(TIME) aoc-c -p 1 < $(INPUT)
|
||||||
|
|
||||||
|
part2: aoc-c
|
||||||
|
@#$(TIME) aoc.bash -p 2 < $(INPUT) 2>&1
|
||||||
|
@#$(TIME) aoc-c -p 2 < $(INPUT)
|
||||||
|
|
||||||
|
ccls: $(CCLSFILE)
|
||||||
|
|
||||||
|
clean:
|
||||||
|
@rm -f aoc-c core* vgcore* gmon.out aoc-c.s aoc-c.i README.html compile_commands.json
|
||||||
|
|
||||||
|
aoc-c: aoc-c.c common.c
|
||||||
|
@echo compiling $<
|
||||||
|
$(CC) $(CFLAGS) $(LDFLAGS) -I $(INCDIR) $^ $(LDLIB) -o $@
|
||||||
|
|
||||||
|
# generate pre-processed file (.i) and assembler (.s)
|
||||||
|
%.i: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -E $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
%.s: %.c
|
||||||
|
@echo generating $@
|
||||||
|
@$(CC) -S -fverbose-asm $(CFLAGS) -I $(INCDIR) $< -o $@
|
||||||
|
|
||||||
|
# generate README.org from README.html (must cleanup !)
|
||||||
|
org: README.org
|
||||||
|
|
||||||
|
%.org: %.html
|
||||||
|
@echo generating $@. Cleanup before commit !
|
||||||
|
@pandoc $< -o $@
|
||||||
|
|
||||||
|
# generate compile_commands.json
|
||||||
|
$(CCLSFILE): aoc-c.c Makefile
|
||||||
|
$(BEAR) -- make clean compile
|
||||||
|
|
||||||
|
bear: clean
|
||||||
|
@touch .ccls-root
|
||||||
|
@$(BEAR) -- make compile
|
364
2022/day11/README.org
Normal file
364
2022/day11/README.org
Normal file
@@ -0,0 +1,364 @@
|
|||||||
|
** --- Day 11: Monkey in the Middle ---
|
||||||
|
As you finally start making your way upriver, you realize your pack is
|
||||||
|
much lighter than you remember. Just then, one of the items from your
|
||||||
|
pack goes flying overhead. Monkeys are playing
|
||||||
|
[[https://en.wikipedia.org/wiki/Keep_away][Keep Away]] with your missing
|
||||||
|
things!
|
||||||
|
|
||||||
|
To get your stuff back, you need to be able to predict where the monkeys
|
||||||
|
will throw your items. After some careful observation, you realize the
|
||||||
|
monkeys operate based on /how worried you are about each item/.
|
||||||
|
|
||||||
|
You take some notes (your puzzle input) on the items each monkey
|
||||||
|
currently has, how worried you are about those items, and how the monkey
|
||||||
|
makes decisions based on your worry level. For example:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
Monkey 0:
|
||||||
|
Starting items: 79, 98
|
||||||
|
Operation: new = old * 19
|
||||||
|
Test: divisible by 23
|
||||||
|
If true: throw to monkey 2
|
||||||
|
If false: throw to monkey 3
|
||||||
|
|
||||||
|
Monkey 1:
|
||||||
|
Starting items: 54, 65, 75, 74
|
||||||
|
Operation: new = old + 6
|
||||||
|
Test: divisible by 19
|
||||||
|
If true: throw to monkey 2
|
||||||
|
If false: throw to monkey 0
|
||||||
|
|
||||||
|
Monkey 2:
|
||||||
|
Starting items: 79, 60, 97
|
||||||
|
Operation: new = old * old
|
||||||
|
Test: divisible by 13
|
||||||
|
If true: throw to monkey 1
|
||||||
|
If false: throw to monkey 3
|
||||||
|
|
||||||
|
Monkey 3:
|
||||||
|
Starting items: 74
|
||||||
|
Operation: new = old + 3
|
||||||
|
Test: divisible by 17
|
||||||
|
If true: throw to monkey 0
|
||||||
|
If false: throw to monkey 1
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
Each monkey has several attributes:
|
||||||
|
|
||||||
|
- =Starting items= lists your /worry level/ for each item the monkey is
|
||||||
|
currently holding in the order they will be inspected.
|
||||||
|
- =Operation= shows how your worry level changes as that monkey inspects
|
||||||
|
an item. (An operation like =new = old * 5= means that your worry
|
||||||
|
level after the monkey inspected the item is five times whatever your
|
||||||
|
worry level was before inspection.)
|
||||||
|
- =Test= shows how the monkey uses your worry level to decide where to
|
||||||
|
throw an item next.
|
||||||
|
- =If true= shows what happens with an item if the =Test= was true.
|
||||||
|
- =If false= shows what happens with an item if the =Test= was false.
|
||||||
|
|
||||||
|
After each monkey inspects an item but before it tests your worry level,
|
||||||
|
your relief that the monkey's inspection didn't damage the item causes
|
||||||
|
your worry level to be /divided by three/ and rounded down to the
|
||||||
|
nearest integer.
|
||||||
|
|
||||||
|
The monkeys take turns inspecting and throwing items. On a single
|
||||||
|
monkey's /turn/, it inspects and throws all of the items it is holding
|
||||||
|
one at a time and in the order listed. Monkey =0= goes first, then
|
||||||
|
monkey =1=, and so on until each monkey has had one turn. The process of
|
||||||
|
each monkey taking a single turn is called a /round/.
|
||||||
|
|
||||||
|
When a monkey throws an item to another monkey, the item goes on the
|
||||||
|
/end/ of the recipient monkey's list. A monkey that starts a round with
|
||||||
|
no items could end up inspecting and throwing many items by the time its
|
||||||
|
turn comes around. If a monkey is holding no items at the start of its
|
||||||
|
turn, its turn ends.
|
||||||
|
|
||||||
|
In the above example, the first round proceeds as follows:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
Monkey 0:
|
||||||
|
Monkey inspects an item with a worry level of 79.
|
||||||
|
Worry level is multiplied by 19 to 1501.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 500.
|
||||||
|
Current worry level is not divisible by 23.
|
||||||
|
Item with worry level 500 is thrown to monkey 3.
|
||||||
|
Monkey inspects an item with a worry level of 98.
|
||||||
|
Worry level is multiplied by 19 to 1862.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 620.
|
||||||
|
Current worry level is not divisible by 23.
|
||||||
|
Item with worry level 620 is thrown to monkey 3.
|
||||||
|
Monkey 1:
|
||||||
|
Monkey inspects an item with a worry level of 54.
|
||||||
|
Worry level increases by 6 to 60.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 20.
|
||||||
|
Current worry level is not divisible by 19.
|
||||||
|
Item with worry level 20 is thrown to monkey 0.
|
||||||
|
Monkey inspects an item with a worry level of 65.
|
||||||
|
Worry level increases by 6 to 71.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 23.
|
||||||
|
Current worry level is not divisible by 19.
|
||||||
|
Item with worry level 23 is thrown to monkey 0.
|
||||||
|
Monkey inspects an item with a worry level of 75.
|
||||||
|
Worry level increases by 6 to 81.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 27.
|
||||||
|
Current worry level is not divisible by 19.
|
||||||
|
Item with worry level 27 is thrown to monkey 0.
|
||||||
|
Monkey inspects an item with a worry level of 74.
|
||||||
|
Worry level increases by 6 to 80.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 26.
|
||||||
|
Current worry level is not divisible by 19.
|
||||||
|
Item with worry level 26 is thrown to monkey 0.
|
||||||
|
Monkey 2:
|
||||||
|
Monkey inspects an item with a worry level of 79.
|
||||||
|
Worry level is multiplied by itself to 6241.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 2080.
|
||||||
|
Current worry level is divisible by 13.
|
||||||
|
Item with worry level 2080 is thrown to monkey 1.
|
||||||
|
Monkey inspects an item with a worry level of 60.
|
||||||
|
Worry level is multiplied by itself to 3600.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 1200.
|
||||||
|
Current worry level is not divisible by 13.
|
||||||
|
Item with worry level 1200 is thrown to monkey 3.
|
||||||
|
Monkey inspects an item with a worry level of 97.
|
||||||
|
Worry level is multiplied by itself to 9409.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 3136.
|
||||||
|
Current worry level is not divisible by 13.
|
||||||
|
Item with worry level 3136 is thrown to monkey 3.
|
||||||
|
Monkey 3:
|
||||||
|
Monkey inspects an item with a worry level of 74.
|
||||||
|
Worry level increases by 3 to 77.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 25.
|
||||||
|
Current worry level is not divisible by 17.
|
||||||
|
Item with worry level 25 is thrown to monkey 1.
|
||||||
|
Monkey inspects an item with a worry level of 500.
|
||||||
|
Worry level increases by 3 to 503.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 167.
|
||||||
|
Current worry level is not divisible by 17.
|
||||||
|
Item with worry level 167 is thrown to monkey 1.
|
||||||
|
Monkey inspects an item with a worry level of 620.
|
||||||
|
Worry level increases by 3 to 623.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 207.
|
||||||
|
Current worry level is not divisible by 17.
|
||||||
|
Item with worry level 207 is thrown to monkey 1.
|
||||||
|
Monkey inspects an item with a worry level of 1200.
|
||||||
|
Worry level increases by 3 to 1203.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 401.
|
||||||
|
Current worry level is not divisible by 17.
|
||||||
|
Item with worry level 401 is thrown to monkey 1.
|
||||||
|
Monkey inspects an item with a worry level of 3136.
|
||||||
|
Worry level increases by 3 to 3139.
|
||||||
|
Monkey gets bored with item. Worry level is divided by 3 to 1046.
|
||||||
|
Current worry level is not divisible by 17.
|
||||||
|
Item with worry level 1046 is thrown to monkey 1.
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
After round 1, the monkeys are holding items with these worry levels:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
Monkey 0: 20, 23, 27, 26
|
||||||
|
Monkey 1: 2080, 25, 167, 207, 401, 1046
|
||||||
|
Monkey 2:
|
||||||
|
Monkey 3:
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
Monkeys 2 and 3 aren't holding any items at the end of the round; they
|
||||||
|
both inspected items during the round and threw them all before the
|
||||||
|
round ended.
|
||||||
|
|
||||||
|
This process continues for a few more rounds:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
After round 2, the monkeys are holding items with these worry levels:
|
||||||
|
Monkey 0: 695, 10, 71, 135, 350
|
||||||
|
Monkey 1: 43, 49, 58, 55, 362
|
||||||
|
Monkey 2:
|
||||||
|
Monkey 3:
|
||||||
|
|
||||||
|
After round 3, the monkeys are holding items with these worry levels:
|
||||||
|
Monkey 0: 16, 18, 21, 20, 122
|
||||||
|
Monkey 1: 1468, 22, 150, 286, 739
|
||||||
|
Monkey 2:
|
||||||
|
Monkey 3:
|
||||||
|
|
||||||
|
After round 4, the monkeys are holding items with these worry levels:
|
||||||
|
Monkey 0: 491, 9, 52, 97, 248, 34
|
||||||
|
Monkey 1: 39, 45, 43, 258
|
||||||
|
Monkey 2:
|
||||||
|
Monkey 3:
|
||||||
|
|
||||||
|
After round 5, the monkeys are holding items with these worry levels:
|
||||||
|
Monkey 0: 15, 17, 16, 88, 1037
|
||||||
|
Monkey 1: 20, 110, 205, 524, 72
|
||||||
|
Monkey 2:
|
||||||
|
Monkey 3:
|
||||||
|
|
||||||
|
After round 6, the monkeys are holding items with these worry levels:
|
||||||
|
Monkey 0: 8, 70, 176, 26, 34
|
||||||
|
Monkey 1: 481, 32, 36, 186, 2190
|
||||||
|
Monkey 2:
|
||||||
|
Monkey 3:
|
||||||
|
|
||||||
|
After round 7, the monkeys are holding items with these worry levels:
|
||||||
|
Monkey 0: 162, 12, 14, 64, 732, 17
|
||||||
|
Monkey 1: 148, 372, 55, 72
|
||||||
|
Monkey 2:
|
||||||
|
Monkey 3:
|
||||||
|
|
||||||
|
After round 8, the monkeys are holding items with these worry levels:
|
||||||
|
Monkey 0: 51, 126, 20, 26, 136
|
||||||
|
Monkey 1: 343, 26, 30, 1546, 36
|
||||||
|
Monkey 2:
|
||||||
|
Monkey 3:
|
||||||
|
|
||||||
|
After round 9, the monkeys are holding items with these worry levels:
|
||||||
|
Monkey 0: 116, 10, 12, 517, 14
|
||||||
|
Monkey 1: 108, 267, 43, 55, 288
|
||||||
|
Monkey 2:
|
||||||
|
Monkey 3:
|
||||||
|
|
||||||
|
After round 10, the monkeys are holding items with these worry levels:
|
||||||
|
Monkey 0: 91, 16, 20, 98
|
||||||
|
Monkey 1: 481, 245, 22, 26, 1092, 30
|
||||||
|
Monkey 2:
|
||||||
|
Monkey 3:
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
After round 15, the monkeys are holding items with these worry levels:
|
||||||
|
Monkey 0: 83, 44, 8, 184, 9, 20, 26, 102
|
||||||
|
Monkey 1: 110, 36
|
||||||
|
Monkey 2:
|
||||||
|
Monkey 3:
|
||||||
|
|
||||||
|
...
|
||||||
|
|
||||||
|
After round 20, the monkeys are holding items with these worry levels:
|
||||||
|
Monkey 0: 10, 12, 14, 26, 34
|
||||||
|
Monkey 1: 245, 93, 53, 199, 115
|
||||||
|
Monkey 2:
|
||||||
|
Monkey 3:
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
Chasing all of the monkeys at once is impossible; you're going to have
|
||||||
|
to focus on the /two most active/ monkeys if you want any hope of
|
||||||
|
getting your stuff back. Count the /total number of times each monkey
|
||||||
|
inspects items/ over 20 rounds:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
Monkey 0 inspected items 101 times.
|
||||||
|
Monkey 1 inspected items 95 times.
|
||||||
|
Monkey 2 inspected items 7 times.
|
||||||
|
Monkey 3 inspected items 105 times.
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
In this example, the two most active monkeys inspected items 101 and 105
|
||||||
|
times. The level of /monkey business/ in this situation can be found by
|
||||||
|
multiplying these together: =10605=.
|
||||||
|
|
||||||
|
Figure out which monkeys to chase by counting how many items they
|
||||||
|
inspect over 20 rounds. /What is the level of monkey business after 20
|
||||||
|
rounds of stuff-slinging simian shenanigans?/
|
||||||
|
|
||||||
|
Your puzzle answer was =54253=.
|
||||||
|
|
||||||
|
** --- Part Two ---
|
||||||
|
You're worried you might not ever get your items back. So worried, in
|
||||||
|
fact, that your relief that a monkey's inspection didn't damage an item
|
||||||
|
/no longer causes your worry level to be divided by three/.
|
||||||
|
|
||||||
|
Unfortunately, that relief was all that was keeping your worry levels
|
||||||
|
from reaching /ridiculous levels/. You'll need to /find another way to
|
||||||
|
keep your worry levels manageable/.
|
||||||
|
|
||||||
|
At this rate, you might be putting up with these monkeys for a /very
|
||||||
|
long time/ - possibly /=10000= rounds/!
|
||||||
|
|
||||||
|
With these new rules, you can still figure out the monkey business after
|
||||||
|
10000 rounds. Using the same example above:
|
||||||
|
|
||||||
|
#+begin_example
|
||||||
|
== After round 1 ==
|
||||||
|
Monkey 0 inspected items 2 times.
|
||||||
|
Monkey 1 inspected items 4 times.
|
||||||
|
Monkey 2 inspected items 3 times.
|
||||||
|
Monkey 3 inspected items 6 times.
|
||||||
|
|
||||||
|
== After round 20 ==
|
||||||
|
Monkey 0 inspected items 99 times.
|
||||||
|
Monkey 1 inspected items 97 times.
|
||||||
|
Monkey 2 inspected items 8 times.
|
||||||
|
Monkey 3 inspected items 103 times.
|
||||||
|
|
||||||
|
== After round 1000 ==
|
||||||
|
Monkey 0 inspected items 5204 times.
|
||||||
|
Monkey 1 inspected items 4792 times.
|
||||||
|
Monkey 2 inspected items 199 times.
|
||||||
|
Monkey 3 inspected items 5192 times.
|
||||||
|
|
||||||
|
== After round 2000 ==
|
||||||
|
Monkey 0 inspected items 10419 times.
|
||||||
|
Monkey 1 inspected items 9577 times.
|
||||||
|
Monkey 2 inspected items 392 times.
|
||||||
|
Monkey 3 inspected items 10391 times.
|
||||||
|
|
||||||
|
== After round 3000 ==
|
||||||
|
Monkey 0 inspected items 15638 times.
|
||||||
|
Monkey 1 inspected items 14358 times.
|
||||||
|
Monkey 2 inspected items 587 times.
|
||||||
|
Monkey 3 inspected items 15593 times.
|
||||||
|
|
||||||
|
== After round 4000 ==
|
||||||
|
Monkey 0 inspected items 20858 times.
|
||||||
|
Monkey 1 inspected items 19138 times.
|
||||||
|
Monkey 2 inspected items 780 times.
|
||||||
|
Monkey 3 inspected items 20797 times.
|
||||||
|
|
||||||
|
== After round 5000 ==
|
||||||
|
Monkey 0 inspected items 26075 times.
|
||||||
|
Monkey 1 inspected items 23921 times.
|
||||||
|
Monkey 2 inspected items 974 times.
|
||||||
|
Monkey 3 inspected items 26000 times.
|
||||||
|
|
||||||
|
== After round 6000 ==
|
||||||
|
Monkey 0 inspected items 31294 times.
|
||||||
|
Monkey 1 inspected items 28702 times.
|
||||||
|
Monkey 2 inspected items 1165 times.
|
||||||
|
Monkey 3 inspected items 31204 times.
|
||||||
|
|
||||||
|
== After round 7000 ==
|
||||||
|
Monkey 0 inspected items 36508 times.
|
||||||
|
Monkey 1 inspected items 33488 times.
|
||||||
|
Monkey 2 inspected items 1360 times.
|
||||||
|
Monkey 3 inspected items 36400 times.
|
||||||
|
|
||||||
|
== After round 8000 ==
|
||||||
|
Monkey 0 inspected items 41728 times.
|
||||||
|
Monkey 1 inspected items 38268 times.
|
||||||
|
Monkey 2 inspected items 1553 times.
|
||||||
|
Monkey 3 inspected items 41606 times.
|
||||||
|
|
||||||
|
== After round 9000 ==
|
||||||
|
Monkey 0 inspected items 46945 times.
|
||||||
|
Monkey 1 inspected items 43051 times.
|
||||||
|
Monkey 2 inspected items 1746 times.
|
||||||
|
Monkey 3 inspected items 46807 times.
|
||||||
|
|
||||||
|
== After round 10000 ==
|
||||||
|
Monkey 0 inspected items 52166 times.
|
||||||
|
Monkey 1 inspected items 47830 times.
|
||||||
|
Monkey 2 inspected items 1938 times.
|
||||||
|
Monkey 3 inspected items 52013 times.
|
||||||
|
#+end_example
|
||||||
|
|
||||||
|
After 10000 rounds, the two most active monkeys inspected items 52166
|
||||||
|
and 52013 times. Multiplying these together, the level of /monkey
|
||||||
|
business/ in this situation is now =2713310158=.
|
||||||
|
|
||||||
|
Worry levels are no longer divided by three after each item is
|
||||||
|
inspected; you'll need to find another way to keep your worry levels
|
||||||
|
manageable. Starting again from the initial state in your puzzle input,
|
||||||
|
/what is the level of monkey business after 10000 rounds?/
|
||||||
|
|
||||||
|
Your puzzle answer was =13119526120=.
|
||||||
|
|
||||||
|
Both parts of this puzzle are complete! They provide two gold stars: **
|
119
2022/day11/aoc.bash
Executable file
119
2022/day11/aoc.bash
Executable file
@@ -0,0 +1,119 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# aoc.bash: Advent of Code 2022, day 11
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
|
||||||
|
. common.bash
|
||||||
|
|
||||||
|
declare -ai div ttrue tfalse inspect
|
||||||
|
declare -a items # (1 2) is "1 2"
|
||||||
|
declare -a op1 op op2
|
||||||
|
declare -i reduce=1
|
||||||
|
|
||||||
|
print() {
|
||||||
|
for i in "${!items[@]}"; do
|
||||||
|
printf "Monkey %d: %s\n" "$i" "${items[$i]}"
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
calc1() {
|
||||||
|
local -i m1=0 m2=0 i
|
||||||
|
local -n _res="$1"
|
||||||
|
for i in "${inspect[@]}"; do
|
||||||
|
if ((i > m1)); then
|
||||||
|
((m2 = m1, m1 = i))
|
||||||
|
elif ((i > m2)); then
|
||||||
|
((m2 = i))
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
echo "m1=$m1 m2=$m2"
|
||||||
|
(( _res = m1 * m2 ))
|
||||||
|
}
|
||||||
|
|
||||||
|
inspect() {
|
||||||
|
local -i _part="$1" monkey="$2" item _tmp
|
||||||
|
local -i _op1=${op1[$monkey]} _op2=${op2[$monkey]}
|
||||||
|
local -a _items
|
||||||
|
read -ra _items <<< "${items[$monkey]}"
|
||||||
|
printf "ITEMS [%s] %d:(%s)\n" "${items[$monkey]}" "${#_items[@]}" "${_items[*]}"
|
||||||
|
for item in "${_items[@]}"; do
|
||||||
|
(( inspect[monkey]++ ))
|
||||||
|
echo "M=$monkey items=(${items[$monkey]})/$item"
|
||||||
|
[[ -v op1[$monkey] ]] || _op1=$item
|
||||||
|
[[ -v op2[$monkey] ]] || _op2=$item
|
||||||
|
echo "old=$item/op1=$_op1 op2=$_op2"
|
||||||
|
case "${op[$monkey]}" in
|
||||||
|
\+)
|
||||||
|
(( _tmp = _op1 + _op2 ))
|
||||||
|
printf "%d + %d = %d " "$_op1" "$_op2" "$_tmp"
|
||||||
|
;;
|
||||||
|
\*)
|
||||||
|
(( _tmp = _op1 * _op2 ))
|
||||||
|
printf "%d * %d = %d " "$_op1" "$_op2" "$_tmp"
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
((_part == 1)) && (( _tmp /= 3 ))
|
||||||
|
(( _tmp %= reduce ))
|
||||||
|
if ! (( _tmp % div[monkey] )); then
|
||||||
|
items[${ttrue[$monkey]}]+=" $_tmp"
|
||||||
|
else
|
||||||
|
items[${tfalse[$monkey]}]+=" $_tmp"
|
||||||
|
fi
|
||||||
|
printf "/3 = %d\n" "$_tmp"
|
||||||
|
printf "M=%d new=%d\n" "$monkey" "$_tmp"
|
||||||
|
done
|
||||||
|
items[$monkey]=""
|
||||||
|
print
|
||||||
|
echo
|
||||||
|
}
|
||||||
|
|
||||||
|
parse() {
|
||||||
|
local -i monkey=0
|
||||||
|
local -a _items
|
||||||
|
|
||||||
|
while read -r; do # ignore Monkey number
|
||||||
|
#echo -n "monkey=$monkey "
|
||||||
|
IFS=" :," read -ra _items # starting items
|
||||||
|
|
||||||
|
items[$monkey]="${_items[*]:2}"
|
||||||
|
echo -n "items[$monkey]=${items[$monkey]} "
|
||||||
|
IFS=" :=" read -r _ _ op1[$monkey] op[$monkey] op2[$monkey] # operator and operand
|
||||||
|
[[ ${op1[$monkey]} == old ]] && unset "op1[$monkey]"
|
||||||
|
[[ ${op2[$monkey]} == old ]] && unset "op2[$monkey]"
|
||||||
|
echo -n "op=${op[$monkey]} ops=${op1[$monkey]}/${op2[$monkey]} "
|
||||||
|
IFS=" :=" read -r _ _ _ div[$monkey] # divisor
|
||||||
|
(( reduce *= div[monkey] ))
|
||||||
|
echo -n "div=${div[$monkey]} "
|
||||||
|
read -r _ _ _ _ _ ttrue[$monkey] # throw if true
|
||||||
|
read -r _ _ _ _ _ tfalse[$monkey]
|
||||||
|
echo "T=${ttrue[$monkey]} F=${tfalse[$monkey]}"
|
||||||
|
read -r
|
||||||
|
(( monkey++ ))
|
||||||
|
#break
|
||||||
|
done
|
||||||
|
}
|
||||||
|
|
||||||
|
solve() {
|
||||||
|
local -i _loops=20
|
||||||
|
(( part == 2 )) && (( _loops = 10000 ))
|
||||||
|
for ((round = 0; round < _loops; ++round)); do
|
||||||
|
for ((monkey = 0; monkey < ${#div[@]}; ++monkey)); do
|
||||||
|
inspect "$part" "$monkey"
|
||||||
|
done
|
||||||
|
done
|
||||||
|
printf "inspect=%s\n" "${inspect[*]}"
|
||||||
|
# remove last '\n', add starting '\n'
|
||||||
|
calc1 res
|
||||||
|
#(( part == 2 )) && res=$'\n'${res::-1}
|
||||||
|
}
|
||||||
|
|
||||||
|
main "$@"
|
||||||
|
exit 0
|
17
2022/day11/aoc.h
Normal file
17
2022/day11/aoc.h
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
/* aoc.c: Advent of Code 2022
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
#ifndef _AOC_H_
|
||||||
|
#define _AOC_H_
|
||||||
|
|
||||||
|
extern int parseargs(int ac, char**av);
|
||||||
|
|
||||||
|
#endif /* _AOC_H_ */
|
68
2022/day11/common.bash
Executable file
68
2022/day11/common.bash
Executable file
@@ -0,0 +1,68 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
#
|
||||||
|
# common.bash: Advent of Code 2022, common bash functions
|
||||||
|
#
|
||||||
|
# Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
# Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
# Some rights reserved. See COPYING.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License along with this
|
||||||
|
# program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
#
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
|
||||||
|
# shellcheck disable=2034
|
||||||
|
export cmdname=${0##*/}
|
||||||
|
export debug=0
|
||||||
|
export res
|
||||||
|
export LANG=C
|
||||||
|
|
||||||
|
shopt -s extglob
|
||||||
|
set -o noglob
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
printf "usage: %s [-d DEBUG] [-p PART]\n" "$cmdname"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
checkargs() {
|
||||||
|
local part=1
|
||||||
|
while getopts p:d: todo; do
|
||||||
|
case "$todo" in
|
||||||
|
d)
|
||||||
|
if [[ "$OPTARG" =~ ^[[:digit:]+]$ ]]; then
|
||||||
|
debug="$OPTARG"
|
||||||
|
else
|
||||||
|
printf "%s: illegal [%s] debug level.\n" "$CMD" "$OPTARG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
p)
|
||||||
|
if [[ "$OPTARG" =~ ^[12]$ ]]; then
|
||||||
|
part="$OPTARG"
|
||||||
|
else
|
||||||
|
printf "%s: illegal [%s] part.\n" "$CMD" "$OPTARG"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
usage
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
# Now check remaining argument (backup directory)
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
|
||||||
|
(( $# > 1 )) && usage
|
||||||
|
return "$part"
|
||||||
|
}
|
||||||
|
|
||||||
|
main() {
|
||||||
|
local -i part
|
||||||
|
|
||||||
|
checkargs "$@"
|
||||||
|
part=$?
|
||||||
|
parse "$part"
|
||||||
|
solve "$part"
|
||||||
|
printf "%s: res=%s\n" "$cmdname" "$res"
|
||||||
|
}
|
49
2022/day11/common.c
Normal file
49
2022/day11/common.c
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
/* common.c: Advent of Code 2022, common functions
|
||||||
|
*
|
||||||
|
* Copyright (C) 2022 Bruno Raoult ("br")
|
||||||
|
* Licensed under the GNU General Public License v3.0 or later.
|
||||||
|
* Some rights reserved. See COPYING.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with this
|
||||||
|
* program. If not, see <https://www.gnu.org/licenses/gpl-3.0-standalone.html>.
|
||||||
|
*
|
||||||
|
* SPDX-License-Identifier: GPL-3.0-or-later <https://spdx.org/licenses/GPL-3.0-or-later.html>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
#include "aoc.h"
|
||||||
|
#include "debug.h"
|
||||||
|
|
||||||
|
static int usage(char *prg)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "Usage: %s [-d debug_level] [-p part] [-i input]\n", prg);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int parseargs(int ac, char **av)
|
||||||
|
{
|
||||||
|
int opt, part = 1;
|
||||||
|
|
||||||
|
while ((opt = getopt(ac, av, "d:p:")) != -1) {
|
||||||
|
switch (opt) {
|
||||||
|
case 'd':
|
||||||
|
debug_level_set(atoi(optarg));
|
||||||
|
break;
|
||||||
|
case 'p': /* 1 or 2 */
|
||||||
|
part = atoi(optarg);
|
||||||
|
if (part < 1 || part > 2)
|
||||||
|
return usage(*av);
|
||||||
|
break;
|
||||||
|
case 'i':
|
||||||
|
|
||||||
|
default:
|
||||||
|
return usage(*av);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (optind < ac)
|
||||||
|
return usage(*av);
|
||||||
|
return part;
|
||||||
|
}
|
27
2022/day11/input/example.txt
Normal file
27
2022/day11/input/example.txt
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
Monkey 0:
|
||||||
|
Starting items: 79, 98
|
||||||
|
Operation: new = old * 19
|
||||||
|
Test: divisible by 23
|
||||||
|
If true: throw to monkey 2
|
||||||
|
If false: throw to monkey 3
|
||||||
|
|
||||||
|
Monkey 1:
|
||||||
|
Starting items: 54, 65, 75, 74
|
||||||
|
Operation: new = old + 6
|
||||||
|
Test: divisible by 19
|
||||||
|
If true: throw to monkey 2
|
||||||
|
If false: throw to monkey 0
|
||||||
|
|
||||||
|
Monkey 2:
|
||||||
|
Starting items: 79, 60, 97
|
||||||
|
Operation: new = old * old
|
||||||
|
Test: divisible by 13
|
||||||
|
If true: throw to monkey 1
|
||||||
|
If false: throw to monkey 3
|
||||||
|
|
||||||
|
Monkey 3:
|
||||||
|
Starting items: 74
|
||||||
|
Operation: new = old + 3
|
||||||
|
Test: divisible by 17
|
||||||
|
If true: throw to monkey 0
|
||||||
|
If false: throw to monkey 1
|
55
2022/day11/input/input.txt
Normal file
55
2022/day11/input/input.txt
Normal file
@@ -0,0 +1,55 @@
|
|||||||
|
Monkey 0:
|
||||||
|
Starting items: 98, 70, 75, 80, 84, 89, 55, 98
|
||||||
|
Operation: new = old * 2
|
||||||
|
Test: divisible by 11
|
||||||
|
If true: throw to monkey 1
|
||||||
|
If false: throw to monkey 4
|
||||||
|
|
||||||
|
Monkey 1:
|
||||||
|
Starting items: 59
|
||||||
|
Operation: new = old * old
|
||||||
|
Test: divisible by 19
|
||||||
|
If true: throw to monkey 7
|
||||||
|
If false: throw to monkey 3
|
||||||
|
|
||||||
|
Monkey 2:
|
||||||
|
Starting items: 77, 95, 54, 65, 89
|
||||||
|
Operation: new = old + 6
|
||||||
|
Test: divisible by 7
|
||||||
|
If true: throw to monkey 0
|
||||||
|
If false: throw to monkey 5
|
||||||
|
|
||||||
|
Monkey 3:
|
||||||
|
Starting items: 71, 64, 75
|
||||||
|
Operation: new = old + 2
|
||||||
|
Test: divisible by 17
|
||||||
|
If true: throw to monkey 6
|
||||||
|
If false: throw to monkey 2
|
||||||
|
|
||||||
|
Monkey 4:
|
||||||
|
Starting items: 74, 55, 87, 98
|
||||||
|
Operation: new = old * 11
|
||||||
|
Test: divisible by 3
|
||||||
|
If true: throw to monkey 1
|
||||||
|
If false: throw to monkey 7
|
||||||
|
|
||||||
|
Monkey 5:
|
||||||
|
Starting items: 90, 98, 85, 52, 91, 60
|
||||||
|
Operation: new = old + 7
|
||||||
|
Test: divisible by 5
|
||||||
|
If true: throw to monkey 0
|
||||||
|
If false: throw to monkey 4
|
||||||
|
|
||||||
|
Monkey 6:
|
||||||
|
Starting items: 99, 51
|
||||||
|
Operation: new = old + 1
|
||||||
|
Test: divisible by 13
|
||||||
|
If true: throw to monkey 5
|
||||||
|
If false: throw to monkey 2
|
||||||
|
|
||||||
|
Monkey 7:
|
||||||
|
Starting items: 98, 94, 59, 76, 51, 65, 75
|
||||||
|
Operation: new = old + 5
|
||||||
|
Test: divisible by 2
|
||||||
|
If true: throw to monkey 3
|
||||||
|
If false: throw to monkey 6
|
Reference in New Issue
Block a user