Skip to content
Snippets Groups Projects
Commit 8e24234f authored by Christopher Bohn's avatar Christopher Bohn :thinking:
Browse files

Day 5 complete

parent 637d3eeb
No related branches found
No related tags found
No related merge requests found
......@@ -22,3 +22,17 @@ This problem is a little more interesting since there are two stringly types in
the data, and one of them (the Bingo cards) requires a delimiter between
instances. Defining a custom class to represent Bingo cards simplifies the
post-parsing problem.
## Day 5
This is a pretty straight-forward problem. The only real challenge is that there
are two significant sub-problems: computing the line segments and computing the
vent map. I suppose an alternative approach would be to compute the y=mx+b form
of the lines and algebraically determining their intersections.
I definitely need to get into the habit of thinking about computationally
less-complex approaches. The straight-forward design I came up with for Day 5 is
O(num_lines * num_rows * num_columns); the algebraic approach would be
O(num_lines^2), so not too much of a big deal on this problem. But (I'm sure)
there will be some problems whose straight-forward solution are a tad
intractable.
\ No newline at end of file
......@@ -21,13 +21,13 @@ public class Main {
Integer.toString(calendar.get(Calendar.YEAR)), scanner));
int day = Integer.parseInt(getUserInput("Enter puzzle day",
Integer.toString(calendar.get(Calendar.DAY_OF_MONTH)), scanner));
boolean useProductionData = getUserInput("Use sample data (Y/N)?", "Y", scanner).toUpperCase().charAt(0) != 'Y';
scanner.close();
ImportData dataSource = new ImportData(apiKey, year, day);
String className = Main.class.getPackageName() + ".year" + year + ".Day" + day;
Puzzle puzzle = null;
try {
puzzle = (Puzzle)Class.forName(className).getConstructors()[0]
.newInstance();
puzzle = (Puzzle)Class.forName(className).getConstructors()[0].newInstance(useProductionData);
} catch (ClassNotFoundException classNotFoundException) {
System.err.println("Could not find class " + className);
System.exit(1);
......
......@@ -4,9 +4,12 @@ import java.io.IOException;
import java.util.List;
public abstract class Puzzle {
protected Integer day = null;
protected String sampleData = "";
protected boolean isProductionReady = false;
protected boolean isProductionReady;
public Puzzle(boolean isProductionReady) {
this.isProductionReady = isProductionReady;
}
public abstract int computePart1(List<String> data);
public abstract int computePart2(List<String> data);
......
......@@ -9,8 +9,8 @@ import java.util.List;
public class Day1 extends Puzzle {
private List<Integer> depths;
public Day1() {
day = 1;
public Day1(boolean isProductionReady) {
super(isProductionReady);
sampleData = """
199
200
......@@ -22,7 +22,6 @@ public class Day1 extends Puzzle {
269
260
263""";
isProductionReady = true;
}
private int countIncreases(List<Integer> values) {
......
......@@ -16,8 +16,8 @@ public class Day2 extends Puzzle {
@SuppressWarnings("FieldCanBeLocal")
private int aim;
public Day2() {
day = 2;
public Day2(boolean isProductionReady) {
super(isProductionReady);
sampleData = """
forward 5
down 5
......@@ -25,7 +25,6 @@ public class Day2 extends Puzzle {
up 3
down 8
forward 2""";
isProductionReady = true;
}
@Override
......
......@@ -12,8 +12,8 @@ public class Day3 extends Puzzle {
private int reportLength;
private int[] ones, zeroes;
public Day3() {
day = 3;
public Day3(boolean isProductionReady) {
super(isProductionReady);
sampleData = """
00100
11110
......@@ -27,7 +27,6 @@ public class Day3 extends Puzzle {
11001
00010
01010""";
isProductionReady = true;
}
@Override
......
......@@ -13,8 +13,8 @@ public class Day4 extends Puzzle {
private List<Integer> numbers;
private List<BingoCard> cards;
public Day4() {
day = 4;
public Day4(boolean isProductionReady) {
super(isProductionReady);
sampleData = """
7,4,9,5,11,17,23,2,0,14,21,24,10,16,13,6,15,25,12,22,18,20,8,19,3,26,1
......@@ -35,7 +35,6 @@ public class Day4 extends Puzzle {
18 8 23 26 20
22 11 13 6 5
2 0 12 3 7""";
isProductionReady = true;
}
private void parseData(List<String> data) {
......
package edu.unl.cse.bohn.year2021;
import edu.unl.cse.bohn.Puzzle;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
@SuppressWarnings("unused")
public class Day5 extends Puzzle {
public record Point(int x, int y) {
}
List<List<Point>> lineSegments;
int greatestX, greatestY;
public Day5(boolean isProductionReady) {
super(isProductionReady);
sampleData = """
0,9 -> 5,9
8,0 -> 0,8
9,4 -> 3,4
2,2 -> 2,1
7,0 -> 7,4
6,4 -> 2,0
0,9 -> 2,9
3,4 -> 1,4
0,0 -> 8,8
5,5 -> 8,2""";
}
private void parseData(List<String> data, boolean considerDiagonals) {
greatestX = greatestY = 0;
lineSegments = new LinkedList<>();
for (String datum : data) {
List<Point> lineSegment = new LinkedList<>();
String[] endPoints = datum.split(" -> ");
String[] point = endPoints[0].split(",");
int x1 = Integer.parseInt(point[0]);
int y1 = Integer.parseInt(point[1]);
point = endPoints[1].split(",");
int x2 = Integer.parseInt(point[0]);
int y2 = Integer.parseInt(point[1]);
greatestX = Integer.max(greatestX, Integer.max(x1, x2));
greatestY = Integer.max(greatestY, Integer.max(y1, y2));
if (x1 == x2) { // vertical line
int yMin = Integer.min(y1, y2);
int yMax = Integer.max(y1, y2);
for (int y = yMin; y <= yMax; y++) {
lineSegment.add(new Point(x1, y));
}
} else if (y1 == y2) { // horizontal line
int xMin = Integer.min(x1, x2);
int xMax = Integer.max(x1, x2);
for (int x = xMin; x <= xMax; x++) {
lineSegment.add(new Point(x, y1));
}
} else if (considerDiagonals) {
int y = y1;
if (x1 < x2) {
for (int x = x1; x <= x2; x++) {
lineSegment.add(new Point(x,y));
y = y1 < y2 ? y+1 : y-1;
}
} else {
for (int x = x1; x >= x2; x--) {
lineSegment.add(new Point(x,y));
y = y1 < y2 ? y+1 : y-1;
}
}
}
lineSegments.add(lineSegment);
}
}
private int countIntersectingVentLines() {
int[][] ventMap = new int[greatestX + 1][greatestY + 1];
for (int[] row : ventMap) {
Arrays.fill(row, 0);
}
for (List<Point> lineSegment : lineSegments) {
for (Point point : lineSegment) {
ventMap[point.x()][point.y()]++;
}
}
int numberOfIntersections = 0;
for (int x = 0; x <= greatestX; x++) {
for (int y = 0; y <= greatestY; y++) {
if (ventMap[x][y] > 1) {
numberOfIntersections++;
}
}
}
return numberOfIntersections;
}
@Override
public int computePart1(List<String> data) {
parseData(data, false);
return countIntersectingVentLines();
}
@Override
public int computePart2(List<String> data) {
parseData(data, true);
return countIntersectingVentLines();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment