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
81be6e77
Commit
81be6e77
authored
2 years ago
by
Christopher Bohn
Browse files
Options
Downloads
Patches
Plain Diff
Completed Year 2022 Day 14
parent
2aea3789
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
+22
-1
22 additions, 1 deletion
2022/README.md
2022/src/main/java/edu/unl/cse/bohn/year2022/Day14.java
+178
-0
178 additions, 0 deletions
2022/src/main/java/edu/unl/cse/bohn/year2022/Day14.java
with
200 additions
and
1 deletion
2022/README.md
+
22
−
1
View file @
81be6e77
...
...
@@ -543,7 +543,28 @@ The subproblems are
Since I created a
`compareTo()`
method as part of Part 1, Part 2 is easy.
## Day 14
## Day 1
-
[
The problem
](
https://adventofcode.com/2022/day/14
)
-
[
The solution
](
src/main/java/edu/unl/cse/bohn/year2022/Day14.java
)
### Part 1
The subproblems are
-
Determine which locations are blocked
-
Determine where a unit of sand moves to
-
Can it move?
-
Down, diagonally left, diagonally right?
-
Determine the final status of a unit of sand
-
Stationary, blocking a location
-
Falling forever
### Part 2
Same subproblems, except that falling forever isn't an option.
Instead, we'll have to pretend there's an infinitely-long floor.
## Day 15
(coming soon)
This diff is collapsed.
Click to expand it.
2022/src/main/java/edu/unl/cse/bohn/year2022/Day14.java
0 → 100644
+
178
−
0
View file @
81be6e77
package
edu.unl.cse.bohn.year2022
;
import
edu.unl.cse.bohn.Puzzle
;
import
java.util.*
;
@SuppressWarnings
(
"unused"
)
public
class
Day14
extends
Puzzle
{
public
Day14
(
boolean
isProductionReady
)
{
super
(
isProductionReady
);
sampleData
=
"""
498,4 -> 498,6 -> 496,6
503,4 -> 502,4 -> 502,9 -> 494,9"""
;
}
public
static
final
int
SAND_ORIGIN
=
500
;
public
static
final
boolean
verbose
=
false
;
@Override
public
long
computePart1
(
List
<
String
>
data
)
{
for
(
String
datum
:
data
)
{
Location
.
block
(
datum
);
}
int
amountOfRestingSand
=
0
;
Sand
sand
;
do
{
sand
=
new
Sand
();
//noinspection StatementWithEmptyBody
while
(
sand
.
fall
()
&&
!
sand
.
isFallingForever
())
{
}
if
(
sand
.
isStationary
())
amountOfRestingSand
++;
}
while
(!
sand
.
isFallingForever
());
return
amountOfRestingSand
;
}
@Override
public
long
computePart2
(
List
<
String
>
data
)
{
Location
.
reset
();
for
(
String
datum
:
data
)
{
Location
.
block
(
datum
);
}
Location
.
addFloor
();
int
amountOfRestingSand
=
0
;
Sand
sand
;
do
{
sand
=
new
Sand
();
//noinspection StatementWithEmptyBody
while
(
sand
.
fall
())
{
}
amountOfRestingSand
++;
}
while
(!
Location
.
isBlocked
(
SAND_ORIGIN
,
0
));
return
amountOfRestingSand
;
}
private
record
Location
(
int
x
,
int
y
)
{
private
static
Set
<
Location
>
blockedLocations
=
new
HashSet
<>();
private
static
int
maximumDepth
=
Integer
.
MIN_VALUE
;
private
static
boolean
hasFloor
=
false
;
public
static
void
block
(
int
x
,
int
y
)
{
blockedLocations
.
add
(
new
Location
(
x
,
y
));
if
(
verbose
)
{
System
.
out
.
println
(
"Blocking ("
+
x
+
","
+
y
+
")"
+
((
y
>
maximumDepth
)
?
" ** new maximum depth **"
:
""
));
}
if
(!
hasFloor
&&
y
>
maximumDepth
)
{
maximumDepth
=
y
;
}
}
public
static
boolean
isBlocked
(
int
x
,
int
y
)
{
return
(
hasFloor
&&
y
>=
maximumDepth
+
2
)
||
blockedLocations
.
contains
(
new
Location
(
x
,
y
));
}
public
static
void
block
(
String
structure
)
{
if
(
structure
.
contains
(
" -> "
))
{
int
firstArrowIndex
=
structure
.
indexOf
(
" -> "
);
int
[]
firstPoint
=
Arrays
.
stream
(
structure
.
substring
(
0
,
firstArrowIndex
).
strip
().
split
(
","
))
.
mapToInt
(
Integer:
:
parseInt
).
toArray
();
String
restOftheStructure
=
structure
.
substring
(
firstArrowIndex
+
" -> "
.
length
());
int
endOfNextPointIndex
=
restOftheStructure
.
indexOf
(
" -> "
);
endOfNextPointIndex
=
endOfNextPointIndex
==
-
1
?
restOftheStructure
.
length
()
:
endOfNextPointIndex
;
int
[]
nextPoint
=
Arrays
.
stream
(
restOftheStructure
.
substring
(
0
,
endOfNextPointIndex
).
strip
().
split
(
","
))
.
mapToInt
(
Integer:
:
parseInt
).
toArray
();
int
x
=
firstPoint
[
0
];
int
y
=
firstPoint
[
1
];
while
(
x
!=
nextPoint
[
0
]
||
y
!=
nextPoint
[
1
])
{
Location
.
block
(
x
,
y
);
if
(
x
<
nextPoint
[
0
])
x
++;
if
(
x
>
nextPoint
[
0
])
x
--;
if
(
y
<
nextPoint
[
1
])
y
++;
if
(
y
>
nextPoint
[
1
])
y
--;
}
block
(
restOftheStructure
);
}
else
{
int
[]
coordinates
=
Arrays
.
stream
(
structure
.
strip
().
split
(
","
)).
mapToInt
(
Integer:
:
parseInt
).
toArray
();
block
(
coordinates
[
0
],
coordinates
[
1
]);
}
}
public
static
int
getDeepestDepths
()
{
return
maximumDepth
;
}
public
static
void
reset
()
{
blockedLocations
=
new
HashSet
<>();
maximumDepth
=
Integer
.
MIN_VALUE
;
hasFloor
=
false
;
}
public
static
void
addFloor
()
{
hasFloor
=
true
;
}
public
static
void
removeFloor
()
{
hasFloor
=
false
;
}
@Override
public
boolean
equals
(
Object
other
)
{
if
(
this
==
other
)
return
true
;
if
(!(
other
instanceof
Location
location
))
return
false
;
return
x
==
location
.
x
&&
y
==
location
.
y
;
}
}
private
static
class
Sand
{
private
int
x
,
y
;
public
Sand
()
{
x
=
SAND_ORIGIN
;
y
=
0
;
}
/**
* Causes a grain of sand to move if it can. If (x,y+1) is unblocked, then the sand moves to (x,y+1).
* Otherwise, if (x-1,y+1) is unblocked, then the sand moves to (x-1,y+1).
* Otherwise, if (x+1,y+1) is unblocked, then the sand moves to (x+1,y+1).
* Otherwise, the sand remains stationary.
*
* @return <code>true</code> if the sand moves, <code>false</code> if the sand remains stationary
*/
public
boolean
fall
()
{
boolean
moved
=
false
;
if
(!
Location
.
isBlocked
(
x
,
y
+
1
))
{
y
++;
moved
=
true
;
}
else
if
(!
Location
.
isBlocked
(
x
-
1
,
y
+
1
))
{
x
--;
y
++;
moved
=
true
;
}
else
if
(!
Location
.
isBlocked
(
x
+
1
,
y
+
1
))
{
x
++;
y
++;
moved
=
true
;
}
else
{
Location
.
block
(
x
,
y
);
if
(
verbose
)
{
System
.
out
.
println
(
"Sand is resting at "
+
x
+
","
+
y
);
}
}
return
moved
;
}
public
boolean
isStationary
()
{
return
Location
.
isBlocked
(
x
,
y
+
1
)
&&
Location
.
isBlocked
(
x
-
1
,
y
+
1
)
&&
Location
.
isBlocked
(
x
+
1
,
y
+
1
);
}
@SuppressWarnings
(
"BooleanMethodIsAlwaysInverted"
)
public
boolean
isFallingForever
()
{
if
(
verbose
&&
y
>
Location
.
getDeepestDepths
())
{
System
.
out
.
println
(
"Sand at "
+
x
+
","
+
y
+
" is falling forever"
);
}
return
y
>
Location
.
getDeepestDepths
();
}
}
}
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