Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
A
Advent of Coding
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package registry
Container registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
Christopher Bohn
Advent of Coding
Commits
ea526372
Commit
ea526372
authored
2 years ago
by
Christopher Bohn
Browse files
Options
Downloads
Patches
Plain Diff
Completed Year 2022 Day 11 part 1. Still working on part 2.
parent
88dc41c1
No related branches found
No related tags found
No related merge requests found
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
2022/README.md
+67
-0
67 additions, 0 deletions
2022/README.md
2022/src/main/java/edu/unl/cse/bohn/year2022/Day11.java
+242
-0
242 additions, 0 deletions
2022/src/main/java/edu/unl/cse/bohn/year2022/Day11.java
with
309 additions
and
0 deletions
2022/README.md
+
67
−
0
View file @
ea526372
...
...
@@ -333,5 +333,72 @@ I'm revisiting the signal strength code.
## Day 11
-
[
The problem
](
https://adventofcode.com/2022/day/11
)
-
[
The solution
](
src/main/java/edu/unl/cse/bohn/year2022/Day11.java
)
Oof. This is a long description. Probably because the input is so verbose, and then you have the exmaple.
### Part 1
The subproblems are
-
Parse the input to obtain, for each monkey, its
-
starting items -- not only the value (worry level), but also the order
-
relationship between the new and old worry levels
-
after examining the input, all operations appear to be addition or multiplication, and the first operand is
always the old value
-
test operation and the true/false target monkeys
-
after examining the input, all tests are whether the worry level is divisible by some integer
-
-
Determine which monkey will throw an item next
-
Reduce an item's worry level immediately before it is thrown
-
Track how many (probably non-unique) items a monkey inspects across the many rounds
-
Determine the two most active monkeys after 20 rounds
### Part 2
The part 2 description seems to be forecasting that the
`Monkey`
class will be used and modified again in the coming
day(s).
If that happens, then I'll move
`Monkey`
to be an outer class instead of an inner class.
For now, I just need to modify it so that the boredom modification is optional.
### Refactoring
Since parts 1 & 2 differ only in whether to use the boredom modification and the number of rounds,
I can create a parameterized method.
### Possible misinterpretation
It looks like part 2 isn't saying to abandon the divisor
*now*
to replace the modifier later;
I guess we're supposed to figure out the new modifier for of part 2.
That is more interesting, to say the least.
Both the description and my code (without a boredom modifier) agree that after 1 round:
```
Monkey 0 inspected items 2 times.
Monkey 1 inspected items 4 times.
Monkey 2 inspected items 3 times.
Monkey 3 inspected items 6 times.
```
but after 20, the description says
```
Monkey 0 inspected items 99 times.
Monkey 1 inspected items 97 times.
Monkey 2 inspected items 8 times.
Monkey 3 inspected items 103 times.
```
but my code (without a boredom modifier) says
```
Monkey 0 inspected items 96 times.
Monkey 1 inspected items 100 times.
Monkey 2 inspected items 7 times.
Monkey 3 inspected items 103 times.
```
I wonder if this suggests the final pre-throw modifier is history based; that is, no modifier on the first inspection,
but then the monkey gets a little bored at something it's seen before.
## Day 12
(coming soon)
This diff is collapsed.
Click to expand it.
2022/src/main/java/edu/unl/cse/bohn/year2022/Day11.java
0 → 100644
+
242
−
0
View file @
ea526372
package
edu.unl.cse.bohn.year2022
;
import
edu.unl.cse.bohn.Puzzle
;
import
java.util.*
;
import
java.util.function.UnaryOperator
;
import
java.util.stream.Collectors
;
@SuppressWarnings
(
"unused"
)
public
class
Day11
extends
Puzzle
{
public
Day11
(
boolean
isProductionReady
)
{
super
(
isProductionReady
);
sampleData
=
"""
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"""
;
}
@Override
public
long
computePart1
(
List
<
String
>
data
)
{
//noinspection MagicNumber
return
measureMonkeyBusiness
(
data
,
20
,
true
);
}
@Override
public
long
computePart2
(
List
<
String
>
data
)
{
measureMonkeyBusiness
(
data
,
1
,
false
);
System
.
out
.
println
();
//noinspection MagicNumber
return
measureMonkeyBusiness
(
data
,
20
,
false
);
}
private
static
long
measureMonkeyBusiness
(
List
<
String
>
data
,
int
numberOfRounds
,
boolean
useBoredomModifier
)
{
List
<
Monkey
>
monkeys
=
new
LinkedList
<>();
Monkey
.
clearMonkeys
();
Monkey
.
setTerse
();
if
(
useBoredomModifier
)
{
Monkey
.
setBoredomModification
();
}
else
{
Monkey
.
clearBoredomModification
();
}
int
monkeyNumber
=
0
;
while
(
monkeyNumber
*
7
<
data
.
size
())
{
monkeys
.
add
(
Monkey
.
createMonkey
(
data
.
subList
(
monkeyNumber
*
7
,
monkeyNumber
*
7
+
6
)));
monkeyNumber
++;
}
for
(
int
i
=
0
;
i
<
numberOfRounds
;
i
++)
{
for
(
Monkey
monkey
:
monkeys
)
{
monkey
.
throwItems
();
}
}
// Monkey.printMonkeys();
Monkey
.
setVerbose
();
LinkedList
<
Integer
>
inspectionCounts
=
new
LinkedList
<>();
for
(
Monkey
monkey:
monkeys
)
{
inspectionCounts
.
add
(
monkey
.
getNumberOfInspections
());
}
inspectionCounts
.
sort
(
Integer:
:
compareTo
);
return
(
long
)
inspectionCounts
.
removeLast
()
*
(
long
)
inspectionCounts
.
removeLast
();
}
private
static
class
Monkey
{
public
static
final
int
BOREDOM_DIVISOR
=
3
;
private
static
boolean
useBoredomModifier
=
true
;
private
static
boolean
verbose
=
false
;
private
static
final
List
<
Monkey
>
monkeys
=
new
LinkedList
<>();
private
final
int
monkeyNumber
;
private
final
List
<
Integer
>
items
;
private
final
UnaryOperator
<
Integer
>
worryLevelModifier
;
private
final
int
testDivisor
;
private
final
Map
<
Boolean
,
Integer
>
targetMonkeys
;
private
int
inspectionCount
;
public
static
void
setVerbose
()
{
verbose
=
true
;
}
public
static
void
setTerse
()
{
verbose
=
false
;
}
public
static
void
setBoredomModification
()
{
useBoredomModifier
=
true
;
}
public
static
void
clearBoredomModification
()
{
useBoredomModifier
=
false
;
}
public
static
void
printMonkeys
()
{
for
(
Monkey
monkey
:
monkeys
)
{
System
.
out
.
println
(
"Monkey "
+
monkey
.
getMonkeyNumber
()
+
": "
+
monkey
.
getItems
());
}
}
public
static
Monkey
createMonkey
(
List
<
String
>
description
)
{
// >Monkey 0:
int
intendedMonkeyNumber
=
Integer
.
parseInt
(
description
.
get
(
0
).
strip
().
split
(
" "
)[
1
].
split
(
":"
)[
0
]);
// > Starting items: 79, 98
String
[]
itemStrings
=
description
.
get
(
1
).
split
(
":"
)[
1
].
strip
().
split
(
", "
);
List
<
Integer
>
items
=
Arrays
.
stream
(
itemStrings
)
.
map
(
Integer:
:
parseInt
)
.
collect
(
Collectors
.
toCollection
(
LinkedList:
:
new
));
// > Operation: new = old * 19
String
operator
=
description
.
get
(
2
).
strip
().
split
(
" "
)[
4
];
String
operand
=
description
.
get
(
2
).
strip
().
split
(
" "
)[
5
];
UnaryOperator
<
Integer
>
worryLevelModifier
=
switch
(
operator
)
{
case
"+"
->
operand
.
equals
(
"old"
)
?
(
n
->
n
+
n
)
:
(
n
->
n
+
Integer
.
parseInt
(
operand
));
case
"*"
->
operand
.
equals
(
"old"
)
?
(
n
->
n
*
n
)
:
(
n
->
n
*
Integer
.
parseInt
(
operand
));
default
->
throw
new
UnsupportedOperationException
(
"Unhandled operator: "
+
operator
);
};
// > Test: divisible by 23
int
testDivisor
=
Integer
.
parseInt
(
description
.
get
(
3
).
strip
().
split
(
" "
)[
3
]);
// > If true: throw to monkey 2
Map
<
Boolean
,
Integer
>
targetMonkeys
=
new
HashMap
<>();
targetMonkeys
.
put
(
true
,
Integer
.
parseInt
(
description
.
get
(
4
).
strip
().
split
(
" "
)[
5
]));
// > If false: throw to monkey 3
targetMonkeys
.
put
(
false
,
Integer
.
parseInt
(
description
.
get
(
5
).
strip
().
split
(
" "
)[
5
]));
Monkey
monkey
=
new
Monkey
(
items
,
worryLevelModifier
,
testDivisor
,
targetMonkeys
);
if
(
monkey
.
getMonkeyNumber
()
!=
intendedMonkeyNumber
)
{
System
.
err
.
println
(
"[WARNING] expected to create monkey "
+
intendedMonkeyNumber
+
" but created monkey "
+
monkey
.
getMonkeyNumber
());
}
if
(
monkey
.
getMonkeyNumber
()
!=
monkeys
.
size
())
{
System
.
err
.
println
(
"[WARNING] monkey "
+
monkey
.
getMonkeyNumber
()
+
" will be placed in position "
+
monkeys
.
size
()
+
" in the list."
);
}
if
(
verbose
)
{
System
.
out
.
println
(
monkey
);
}
monkeys
.
add
(
monkey
);
return
monkey
;
}
public
static
void
clearMonkeys
()
{
monkeys
.
clear
();
}
private
Monkey
(
List
<
Integer
>
items
,
UnaryOperator
<
Integer
>
worryLevelModifier
,
int
testDivisor
,
Map
<
Boolean
,
Integer
>
targetMonkeys
)
{
this
.
monkeyNumber
=
monkeys
.
size
();
this
.
items
=
items
;
this
.
worryLevelModifier
=
worryLevelModifier
;
this
.
testDivisor
=
testDivisor
;
this
.
targetMonkeys
=
targetMonkeys
;
this
.
inspectionCount
=
0
;
}
private
int
getMonkeyNumber
()
{
return
monkeyNumber
;
}
private
List
<
Integer
>
getItems
()
{
return
Collections
.
unmodifiableList
(
items
);
}
public
int
getNumberOfInspections
()
{
if
(
verbose
)
{
System
.
out
.
println
(
"Monkey "
+
monkeyNumber
+
" inspected items "
+
inspectionCount
+
" times."
);
}
return
inspectionCount
;
}
public
void
throwItems
()
{
if
(
verbose
)
{
System
.
out
.
println
(
"Monkey: "
+
monkeyNumber
);
}
items
.
forEach
(
this
::
throwItem
);
items
.
clear
();
// probably should remove each item in `throwItem()` but that could screw with the iterator
}
private
void
throwItem
(
Integer
item
)
{
inspectionCount
++;
int
worryLevel
=
item
;
if
(
verbose
)
{
System
.
out
.
println
(
" Monkey inspects an item with a worry level of "
+
worryLevel
+
"."
);
}
worryLevel
=
worryLevelModifier
.
apply
(
worryLevel
);
if
(
verbose
)
{
System
.
out
.
println
(
" Worry level is modified by ("
+
worryLevelModifier
+
") to "
+
worryLevel
+
"."
);
}
worryLevel
=
useBoredomModifier
?
worryLevel
/
BOREDOM_DIVISOR
:
worryLevel
;
boolean
worryLevelIsDivisibleByTestDivisor
=
worryLevel
%
testDivisor
==
0
;
if
(
verbose
)
{
if
(
useBoredomModifier
)
{
System
.
out
.
println
(
" Monkey gets bored with item. Worry level is divided by "
+
BOREDOM_DIVISOR
+
" to "
+
worryLevel
+
"."
);
}
else
{
System
.
out
.
println
(
" Monkey doesn't get bored with item. Worry level remains "
+
worryLevel
+
"."
);
}
System
.
out
.
println
(
" Current worry level is "
+
(
worryLevelIsDivisibleByTestDivisor
?
""
:
"not "
)
+
"divisible by "
+
testDivisor
+
"."
);
System
.
out
.
println
(
" Item with worry level "
+
worryLevel
+
" is thrown to monkey "
+
targetMonkeys
.
get
(
worryLevelIsDivisibleByTestDivisor
)
+
"."
);
}
monkeys
.
get
(
targetMonkeys
.
get
(
worryLevelIsDivisibleByTestDivisor
)).
receiveItem
(
worryLevel
);
}
private
void
receiveItem
(
Integer
item
)
{
items
.
add
(
item
);
}
@Override
public
String
toString
()
{
return
"Monkey "
+
monkeyNumber
+
System
.
lineSeparator
()
+
" Items: "
+
items
+
System
.
lineSeparator
()
+
" Operation: "
+
worryLevelModifier
+
System
.
lineSeparator
()
+
" Test: divisible by "
+
testDivisor
+
System
.
lineSeparator
()
+
" If true: throw to monkey "
+
targetMonkeys
.
get
(
true
)
+
System
.
lineSeparator
()
+
" If false: throw to monkey "
+
targetMonkeys
.
get
(
false
);
}
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment