Skip to content

Commit 5a73ccb

Browse files
committed
Day 13
1 parent 1f7a19f commit 5a73ccb

File tree

2 files changed

+208
-0
lines changed

2 files changed

+208
-0
lines changed

src/test/java/com/macasaet/Day13.java

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
package com.macasaet;
2+
3+
import java.util.*;
4+
import java.util.stream.Collectors;
5+
import java.util.stream.Stream;
6+
import java.util.stream.StreamSupport;
7+
8+
import org.junit.jupiter.api.Test;
9+
10+
/**
11+
* --- Day 13: Transparent Origami ---
12+
*/
13+
public class Day13 {
14+
15+
protected Stream<String> getInput() {
16+
return StreamSupport
17+
.stream(new LineSpliterator("day-13.txt"),
18+
false);
19+
}
20+
21+
/**
22+
* A point on the translucent sheet of paper. Note that <em>x</em> and <em>y</em> correspond to a particular
23+
* {@link Axis}.
24+
*/
25+
public record Point(int x, int y) {
26+
}
27+
28+
/**
29+
* An axis of the translucent sheet of paper
30+
*/
31+
public enum Axis {
32+
/**
33+
* The axis that increases to the right
34+
*/
35+
X,
36+
37+
/**
38+
* The axis that increases downward
39+
*/
40+
Y,
41+
}
42+
43+
/**
44+
* An equation for a line
45+
*/
46+
public record Line(Axis axis, int value) {
47+
public String toString() {
48+
return switch (axis()) {
49+
case X -> "x=" + value;
50+
case Y -> "y=" + value;
51+
};
52+
}
53+
}
54+
55+
public record Input(Collection<Point> points, List<Line> folds, int maxX, int maxY) {
56+
public Sheet getSheet() {
57+
final boolean[][] grid = new boolean[maxY + 1][];
58+
for (int i = grid.length; --i >= 0; ) {
59+
grid[i] = new boolean[maxX + 1];
60+
}
61+
for (final var point : points) {
62+
/* The first value, x, increases to the right. The second value, y, increases downward. */
63+
grid[point.y()][point.x()] = true;
64+
}
65+
return new Sheet(grid);
66+
}
67+
}
68+
69+
/**
70+
* A sheet of translucent paper
71+
*/
72+
public record Sheet(boolean[][] grid) {
73+
74+
public int countDots() {
75+
int result = 0;
76+
final var grid = grid();
77+
for (int i = grid.length; --i >= 0; ) {
78+
for (int j = grid[i].length; --j >= 0; ) {
79+
if (grid[i][j]) {
80+
result++;
81+
}
82+
}
83+
}
84+
return result;
85+
}
86+
87+
public String toString() {
88+
final var builder = new StringBuilder();
89+
for (final var row : grid) {
90+
for (final var cell : row) {
91+
builder.append(cell ? '#' : '.');
92+
}
93+
builder.append('\n');
94+
}
95+
return builder.toString();
96+
}
97+
98+
public Sheet fold(final Line line) {
99+
// note, value is always positive
100+
return switch (line.axis()) {
101+
case X -> {
102+
// fold along the x-axis (vertical line)
103+
final var newGrid = new boolean[grid.length][];
104+
for (int i = newGrid.length; --i >= 0; ) {
105+
final var newRow = new boolean[line.value() + 1];
106+
for (int j = newRow.length; --j >= 0; newRow[j] = grid[i][j]) ;
107+
for(int j = grid[i].length - line.value(); --j > 0; ) {
108+
if(grid[i][line.value() + j]) {
109+
newRow[line.value() - j] = true;
110+
}
111+
}
112+
newGrid[i] = newRow;
113+
}
114+
yield new Sheet(newGrid);
115+
}
116+
case Y -> {
117+
// fold along the y-axis (horizontal line)
118+
final var newGrid = new boolean[line.value()][];
119+
for (int i = newGrid.length; --i >= 0; ) {
120+
final var newRow = new boolean[grid[i].length];
121+
for (int j = grid[i].length; --j >= 0; newRow[j] = grid[i][j]) ;
122+
newGrid[i] = newRow;
123+
}
124+
for (int i = grid.length - line.value(); --i > 0; ) {
125+
final var oldRow = grid[line.value() + i];
126+
for (int j = oldRow.length;
127+
--j >= 0;
128+
newGrid[line.value() - i][j] |= oldRow[j])
129+
;
130+
}
131+
yield new Sheet(newGrid);
132+
}
133+
};
134+
}
135+
}
136+
137+
public Input parseInput() {
138+
int section = 0;
139+
final var points = new HashSet<Point>();
140+
final var folds = new ArrayList<Line>();
141+
int maxX = Integer.MIN_VALUE;
142+
int maxY = Integer.MIN_VALUE;
143+
for (final var line : getInput().collect(Collectors.toList())) {
144+
if (line.isBlank()) {
145+
section++;
146+
continue;
147+
}
148+
if (section == 0) { // points
149+
final var components = line.split(",");
150+
final var x = Integer.parseInt(components[0]);
151+
maxX = Math.max(x, maxX);
152+
final var y = Integer.parseInt(components[1]);
153+
maxY = Math.max(y, maxY);
154+
final var point = new Point(x, y);
155+
points.add(point);
156+
} else { // commands
157+
final var equation = line.replaceFirst("fold along ", "");
158+
final var components = equation.split("=");
159+
final var axis = Axis.valueOf(components[0].toUpperCase(Locale.ROOT));
160+
final var value = Integer.parseInt(components[1]);
161+
final var fold = new Line(axis, value);
162+
folds.add(fold);
163+
}
164+
}
165+
return new Input(points, folds, maxX, maxY);
166+
}
167+
168+
@Test
169+
public final void part1() {
170+
final var input = parseInput();
171+
final var sheet = input.getSheet();
172+
final var firstFold = input.folds().get(0);
173+
final var result = sheet.fold(firstFold);
174+
System.out.println("Part 1: " + result.countDots());
175+
}
176+
177+
@Test
178+
public final void part2() {
179+
final var input = parseInput();
180+
var sheet = input.getSheet();
181+
for (final var fold : input.folds()) {
182+
sheet = sheet.fold(fold);
183+
}
184+
System.out.println("Part 2:\n" + sheet);
185+
}
186+
187+
}

src/test/resources/sample/day-13.txt

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
6,10
2+
0,14
3+
9,10
4+
0,3
5+
10,4
6+
4,11
7+
6,0
8+
6,12
9+
4,1
10+
0,13
11+
10,12
12+
3,4
13+
3,0
14+
8,4
15+
1,10
16+
2,14
17+
8,10
18+
9,0
19+
20+
fold along y=7
21+
fold along x=5

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy