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
36263956
Commit
36263956
authored
2 years ago
by
Christopher Bohn
Browse files
Options
Downloads
Patches
Plain Diff
Day 15 part 1 complete
parent
f224a445
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
+9
-0
9 additions, 0 deletions
2022/README.md
2022/src/main/java/edu/unl/cse/bohn/year2022/Day15.java
+32
-85
32 additions, 85 deletions
2022/src/main/java/edu/unl/cse/bohn/year2022/Day15.java
with
41 additions
and
85 deletions
2022/README.md
+
9
−
0
View file @
36263956
...
...
@@ -580,6 +580,15 @@ The subproblems are
-
Determine which positions cannot contain a beacon (
*i.e.*
, which positions are no closer to the sensor
than the beacon)
Creating many, many beacons would seem to be untenable from a memory perspective.
I think we're going to have to dynamically build the map and then forget which sensor detected which beacon.
This is going to be a PITA Linked List of Linked Lists.
*Or*
, I could make two passes, one to determine the matrix's dimensions, and one to populate it.
Okay, the problem (unsurprisingly) wasn't all the Sensor data; it was the 6,862,736 x 6,004,906 matrix.
What? You don't have several terabytes just lying around?
Clearly we need to go
*back*
to tracking the Sensor data and dynamically determine whether a given position is covered.
### Part 2
...
...
...
This diff is collapsed.
Click to expand it.
2022/src/main/java/edu/unl/cse/bohn/year2022/Day15.java
+
32
−
85
View file @
36263956
...
...
@@ -2,13 +2,12 @@ package edu.unl.cse.bohn.year2022;
import
edu.unl.cse.bohn.Puzzle
;
import
java.util.Arrays
;
import
java.util.HashSet
;
import
java.util.List
;
import
java.util.Set
;
import
java.util.stream.IntStream
;
@SuppressWarnings
(
"unused"
)
@SuppressWarnings
(
{
"unused"
}
)
public
class
Day15
extends
Puzzle
{
public
Day15
(
boolean
isProductionReady
)
{
super
(
isProductionReady
);
...
...
@@ -34,12 +33,8 @@ public class Day15 extends Puzzle {
for
(
String
datum
:
data
)
{
new
Sensor
(
datum
);
}
Sensor
.
markPositionsAsHavingNoUnknownBeacon
();
// Sensor.printMap();
// System.out.println("===");
//noinspection MagicNumber
return
Sensor
.
countPositionsWithNoUnknownBeacon
(
isProductionReady
?
2000000
:
10
);
// return 0;
return
Sensor
.
countLocationsThatCannotHaveBeacon
(
isProductionReady
?
2000000
:
10
);
}
@Override
...
...
@@ -53,8 +48,11 @@ public class Day15 extends Puzzle {
private
static
final
Set
<
Sensor
>
sensors
=
new
HashSet
<>();
private
static
boolean
[][]
mightContainAnUnknownBeacon
=
null
;
private
static
int
xOffset
,
yOffset
;
// private static boolean[][] mightContainAnUnknownBeacon = null;
private
static
int
minimumX
=
Integer
.
MAX_VALUE
;
private
static
int
maximumX
=
Integer
.
MIN_VALUE
;
private
static
int
minimumY
=
Integer
.
MAX_VALUE
;
private
static
int
maximumY
=
Integer
.
MIN_VALUE
;
public
Sensor
(
String
description
)
{
String
[]
hardwareDescriptions
=
description
.
split
(
":"
);
...
...
@@ -67,6 +65,11 @@ public class Day15 extends Puzzle {
nearestBeaconY
=
Integer
.
parseInt
(
coordinateDescriptions
[
1
].
substring
(
coordinateDescriptions
[
1
].
indexOf
(
'='
)
+
1
));
sensors
.
add
(
this
);
int
distance
=
computeManhattanDistance
(
x
,
y
,
nearestBeaconX
,
nearestBeaconY
);
minimumX
=
Math
.
min
(
minimumX
,
x
-
distance
);
minimumY
=
Math
.
min
(
minimumY
,
y
-
distance
);
maximumX
=
Math
.
max
(
maximumX
,
x
+
distance
);
maximumY
=
Math
.
max
(
maximumY
,
y
+
distance
);
}
public
int
getDistanceToBeacon
()
{
...
...
@@ -74,7 +77,7 @@ public class Day15 extends Puzzle {
}
private
int
getDistanceToLocation
(
int
x
,
int
y
)
{
return
Math
.
abs
(
x
-
this
.
x
)
+
Math
.
abs
(
y
-
this
.
y
);
return
computeManhattanDistance
(
this
.
x
,
this
.
y
,
x
,
y
);
}
public
boolean
isNoFartherThanBeacon
(
int
x
,
int
y
)
{
...
...
@@ -87,93 +90,37 @@ public class Day15 extends Puzzle {
+
", y="
+
nearestBeaconY
+
"\t(distance="
+
getDistanceToBeacon
()
+
")"
;
}
public
static
int
computeManhattanDistance
(
int
x1
,
int
y1
,
int
x2
,
int
y2
)
{
return
Math
.
abs
(
x1
-
x2
)
+
Math
.
abs
(
y1
-
y2
);
}
public
static
Sensor
getSensorAt
(
int
x
,
int
y
)
{
return
sensors
.
stream
().
filter
(
s
->
s
.
x
==
x
&&
s
.
y
==
y
).
findFirst
().
orElse
(
null
);
}
public
static
boolean
aSensorIsAt
(
int
x
,
int
y
)
{
return
sensors
.
stream
().
anyMatch
(
s
->
s
.
x
==
x
&&
s
.
y
==
y
);
}
public
static
Sensor
getSensorDetectingBeaconAt
(
int
x
,
int
y
)
{
return
sensors
.
stream
()
.
filter
(
s
->
s
.
nearestBeaconX
==
x
&&
s
.
nearestBeaconY
==
y
).
findFirst
().
orElse
(
null
);
}
public
static
void
markPositionsAsHavingNoUnknownBeacon
()
{
// create the matrix
int
maximumX
=
sensors
.
stream
()
.
mapToInt
(
sensor
->
sensor
.
x
+
sensor
.
getDistanceToBeacon
())
.
max
().
orElse
(
Integer
.
MIN_VALUE
);
int
minimumX
=
sensors
.
stream
()
.
mapToInt
(
sensor
->
sensor
.
x
-
sensor
.
getDistanceToBeacon
())
.
min
().
orElse
(
Integer
.
MAX_VALUE
);
int
maximumY
=
sensors
.
stream
()
.
mapToInt
(
sensor
->
sensor
.
y
+
sensor
.
getDistanceToBeacon
())
.
max
().
orElse
(
Integer
.
MIN_VALUE
);
int
minimumY
=
sensors
.
stream
()
.
mapToInt
(
sensor
->
sensor
.
y
-
sensor
.
getDistanceToBeacon
())
.
min
().
orElse
(
Integer
.
MAX_VALUE
);
xOffset
=
minimumX
;
yOffset
=
minimumY
;
mightContainAnUnknownBeacon
=
new
boolean
[
maximumY
-
yOffset
+
1
][
maximumX
-
xOffset
+
1
];
IntStream
.
range
(
0
,
mightContainAnUnknownBeacon
.
length
)
.
forEach
(
i
->
Arrays
.
fill
(
mightContainAnUnknownBeacon
[
i
],
true
));
// make our deductions
for
(
int
i
=
0
;
i
<
mightContainAnUnknownBeacon
.
length
;
i
++)
{
for
(
int
j
=
0
;
j
<
mightContainAnUnknownBeacon
[
i
].
length
;
j
++)
{
int
y
=
i
+
yOffset
,
x
=
j
+
xOffset
;
for
(
Sensor
sensor
:
sensors
)
{
if
(
sensor
.
isNoFartherThanBeacon
(
x
,
y
))
{
mightContainAnUnknownBeacon
[
i
][
j
]
=
false
;
}
}
}
}
}
public
static
int
countPositionsWithNoUnknownBeacon
(
int
y
)
{
if
(
mightContainAnUnknownBeacon
==
null
)
{
markPositionsAsHavingNoUnknownBeacon
();
}
// System.out.print(xOffset + " ");
int
countOfObservedLocations
=
0
;
int
countOfKnownBeacons
=
0
;
int
i
=
y
-
yOffset
;
boolean
[]
row
=
mightContainAnUnknownBeacon
[
i
];
for
(
int
j
=
0
;
j
<
row
.
length
;
j
++)
{
int
x
=
j
+
xOffset
;
// System.out.print(row[j] ? '.' : "#");
countOfObservedLocations
+=
row
[
j
]
?
0
:
1
;
countOfKnownBeacons
+=
(
getSensorDetectingBeaconAt
(
x
,
y
)
==
null
)
?
0
:
1
;
}
// System.out.println(" " + (mightContainAnUnknownBeacon[y - yOffset].length - xOffset - 1));
return
countOfObservedLocations
-
countOfKnownBeacons
;
}
public
static
void
printMap
()
{
if
(
mightContainAnUnknownBeacon
==
null
)
{
markPositionsAsHavingNoUnknownBeacon
();
}
System
.
out
.
println
(
"xOffset = "
+
xOffset
+
"\tyOffset = "
+
yOffset
);
for
(
int
i
=
0
;
i
<
mightContainAnUnknownBeacon
.
length
;
i
++)
{
int
y
=
i
+
yOffset
;
for
(
int
j
=
0
;
j
<
mightContainAnUnknownBeacon
[
i
].
length
;
j
++)
{
int
x
=
j
+
xOffset
;
if
(
getSensorAt
(
x
,
y
)
!=
null
)
{
System
.
out
.
print
(
"S"
);
}
else
if
(
getSensorDetectingBeaconAt
(
x
,
y
)
!=
null
)
{
System
.
out
.
print
(
"B"
);
}
else
if
(
mightContainAnUnknownBeacon
[
i
][
j
])
{
System
.
out
.
print
(
"."
);
}
else
{
System
.
out
.
print
(
"#"
);
}
if
(
x
%
5
==
4
||
x
==
-
1
)
{
System
.
out
.
print
(
" "
);
}
}
System
.
out
.
println
();
if
(
y
%
5
==
4
||
y
==
-
1
)
{
System
.
out
.
println
();
public
static
boolean
aKnownBeaconIsAt
(
int
x
,
int
y
)
{
return
sensors
.
stream
().
anyMatch
(
s
->
s
.
nearestBeaconX
==
x
&&
s
.
nearestBeaconY
==
y
);
}
public
static
boolean
isCoveredBySensor
(
int
x
,
int
y
)
{
return
sensors
.
stream
().
anyMatch
(
sensor
->
sensor
.
isNoFartherThanBeacon
(
x
,
y
));
}
public
static
int
countLocationsThatCannotHaveBeacon
(
int
y
)
{
int
locationsInRangeOfSensor
=
IntStream
.
rangeClosed
(
minimumX
,
maximumX
).
map
(
x
->
isCoveredBySensor
(
x
,
y
)
?
1
:
0
).
sum
();
int
locationsWithKnownBeacon
=
IntStream
.
rangeClosed
(
minimumX
,
maximumX
).
map
(
x
->
aKnownBeaconIsAt
(
x
,
y
)
?
1
:
0
).
sum
();
return
locationsInRangeOfSensor
-
locationsWithKnownBeacon
;
}
}
}
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