Skip to content

Commit 5c5ea57

Browse files
committed
Tweak PMD ruleset
1 parent 60707b4 commit 5c5ea57

File tree

13 files changed

+639
-0
lines changed

13 files changed

+639
-0
lines changed

ruleset.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,12 @@
3232
</properties>
3333
</rule>
3434

35+
<rule ref="category/java/codestyle.xml/TooManyStaticImports">
36+
<properties>
37+
<property name="maximumStaticImports" value="10" /><!-- Default is 4, which is too low IMO. -->
38+
</properties>
39+
</rule>
40+
3541
<rule ref="category/java/codestyle.xml/LongVariable">
3642
<properties>
3743
<property name="minimum" value="65" /> <!-- Default max is 16, which is not always enough for a descriptive name; allow longer variables. -->
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package eu.happycoders.adventofcode2022.day24;
2+
3+
/**
4+
* Advent of Code 2022 – Object-Oriented Solutions in Java.
5+
*
6+
* <p>Puzzle solver for day 24.
7+
*
8+
* @author <a href="mailto:sven@happycoders.eu">Sven Woltmann</a>
9+
*/
10+
class Day24Solver {
11+
12+
static int solveTask1(String input) {
13+
ValleyMap valleyMap = PuzzleInputParser.parse(input);
14+
ValleyWalker valleyWalker = new ValleyWalker(valleyMap);
15+
return valleyWalker.findFastestPath(1);
16+
}
17+
18+
static int solveTask2(String input) {
19+
ValleyMap valleyMap = PuzzleInputParser.parse(input);
20+
ValleyWalker valleyWalker = new ValleyWalker(valleyMap);
21+
return valleyWalker.findFastestPath(3);
22+
}
23+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
package eu.happycoders.adventofcode2022.day24;
2+
3+
/**
4+
* Advent of Code 2022 – Object-Oriented Solutions in Java.
5+
*
6+
* <p>Main application for day 24.
7+
*
8+
* @author <a href="mailto:sven@happycoders.eu">Sven Woltmann</a>
9+
*/
10+
class Main24 {
11+
12+
private static final String INPUT =
13+
"""
14+
#.########################################################################################################################
15+
#.v^<>^^.<^^<v>v>>>.<^<<v.^>vv>>^<<<v>.v<^v^<v<<^<^^<^<^v><^vv.v^^.>^><vv><^<.<^v<>.v<v..^>><v>.vvv.v>^^<^>.<<^<^<^>v.^^<#
16+
#.^^<v>><<v><vv<>..<>v<^v><<>><>v.>v.^^<<.v.^<^<vv><v<<v><<^<>^v>v>><>v..v^<^.v><>^>><v<<>v^<<v<v>v.v<v>><<v>^v<v^...<<<>#
17+
#><vv>>v>v<^>^^^^vv^<v^<<v<>^<^.^^>^<^vv>^v>><<^^<.>^>v<^v<.v.^<^^v.<.>.<^>v^>.v>>^vv^v.>>>v<<<<v.^^v<^^<^><<<<.^>.>vvv>>#
18+
#<.vv>.><<.<^v.>v^v>><v>><<^vv>^v^>.><v>>><^><v<v^^vv>.v^^<v>vv<>v>^v.>>v^>..v<>^v.^>><.vv><^...<>^^>v>vvv>^<^<><v>v<^^^<#
19+
#>^.^>vvv>vv>^^vv>v^^v>vv>v^v>^<v>>vvvv^>.v^<v^><^>vvv<>vv<^v<.<^v^>^vv^<><>.^.^>><<^^>^<v^>>>>v><<v^^>^^>>v^v.<^vv^<^v<>#
20+
#><^>><vv^vvv.v><v<>^v>^<<<^^<><^<<v<>^<<v><<<v>><v<^^<vv<.>^v>^<v>.>v>>^^>^>><>.<<v<^><>>>^.<vv>.^^<.^^>>v.><<v<>><>v^><#
21+
#>>^.<<v.^v>^^v.>v.vv^<<.v<v<..<<v^^>^v.><>v<^^<<.>v>v>v>^v>.<>v<><<^v><^>><^v>v^v>^vvv>>>..>^>>.><v><>.^^v.><<vv<.v>^^<.#
22+
#>vv>^^.<>^v<^<<v^>v<^^v><>>>>v^vv>v<^v^><><^.<v^>.<^.v^>><vv>>vvv>^v<<<><vv<v^<<>v>>^v>^^^>^v><^^>^^^<<^^<v<<v<v>^^^<^>>#
23+
#>.v^<<.vv<^v>^>>v<>v^v^^v^v<^^<<..<<^v<<<<^<v>^>.<>v<v<v<.<.v>vv^>><^.<.v<^<^v><v<v>.v.><<^>>v^.^vv.vv^.>^^>vv<>^..v>^v<#
24+
#..v.>^><<>..<>.<^<<v>^^^^><<><<vv><^>v>^v<vv>v><vv.^<.<<<<v^v<>^^^vv>.>>>v^v<v<^.<v<<^.v<><<>>v<<<.>>v.^^>^^.>.<.>vv>^>>#
25+
#>^^vv<<><<v<^.v>>v>^^^v^<v.^><<<<<v^v>v<<^v..^<.vv.^v>vvv>^v<..v<><<^<<vv<>>>>^>^^<>^<^<^^.vv>>^>^>^v^>.<^.<<.>v^>vv<.^<#
26+
#<v^vv>^^v>vv>^.^>v>v^v>vv.>>.>v^v^>.^v<^.>^<<<v.>^>^^<>vv<.<^^<^v<^><v^v^.^<><v^^v^>.<vv^>v^v<v^><>^<vv>v<><^v<v.<<^.>^>#
27+
#<>^<^<v><^^.^^>..^^>v>>>>^v<.<>>.<^v^>vvvvv>^<<.><^<v<.v<^><^^>vv<^<^<>v>v<>^^v>>^^>>v<^^<v>v^^^vvv<<<<<>>>v>^v.<^^>^>^<#
28+
#>.<^v<.<^v.v>^.>>><^<<^^<<.<>><>>>^vvv<v<v<<^^vv<<<^v^v^vv<^v>>^^vv.^>^.v^^^>>v^>.<>.^^>v^^^^><^^>^>>.v<v^<^>^v^>^<<<v<<#
29+
#>><><.>v^<>^^>.^>^v>^.^<v><><>.<v<^v>>>>v.<>>.^vv>v.vv.><vv^v>^<>>v>vv.v>v>v<><>>>^..^v>^^><..^..^..^vvv>><>v<>v<^<<>v<<#
30+
#<vv^vvv><>v^v.<^v^^v<.<>v<>.^v^<<^<><.^vv<>^>>.v<<><vv<^^<>>v^.^v><v^^<>v.v<.>^^v^<<<^^<<v<^^^<<<<>^^v>><><<><>v>v<v.>^>#
31+
#.<.^>^>^>^v..v>^.<v<^<<<^vvv>vv><^^v^<.>>.^<.^^<<>>^><<>>^^.^<<^^><^v<.><>.<<<.vvv>>vv^v<^v<>vv<<^v^^<v.v^<<^>v^>v<><vv<#
32+
#.vvvv>>^>^<..^>>^>vv^.^>^<<v>^^v>v>^<>.>vv<v^>>>^.^<<^>>^>^>vvv><vv^^<^.^^.<^^v.<v<>^<<<v^>><<.^^^^>^>>>v<<>>v>v<>v<v><.#
33+
#<<vv.<v>^^v<.>>^>^<>^><.<v^><>>.^<v^v<<.v>>.<>.v>^>^v><><^<><<<v^<><<v^..^v^v>^.><>>>v^.^>vv<<^>v<><.^^v<>vv>v^v<><^>>><#
34+
#><>^v>v<>><vv>>v<>^<v>v^^>^v^>^^<v>v>^^v><<^v>>vv<^><>^>^^>>v^^<^<v>.^>v^vv^<.v>^v^.v^><><>>v.v^vv^<v>^>^><v>^>^>v>^v..<#
35+
#>v<^^<^>.<>v<v<.^vv^>>v><^^v<^^>>^>^<^^>>>^<v<^v<>v<^>v>^>v^v>^.<<v^>vv<^<.><^><<^>v><^<v>^<^v>v^>><^vvv^>>v>>vv>v^>^><<#
36+
#<vvv<><^.>v.^><v<^^<v><^<vvv.^..v^>...v^><<^^><^>^^vv>^v>v^<v<<>^>^^..<^<<v><<>.><<>^vvvv>v^><.^^>>v>>>^>>^<^<^<v^>vvv>>#
37+
#><<<^^.^<.^.^^<>^.vv^^^<v^<<<vv<<>^<v<^>>v^>>v<<v^^.v^<.vv<v<><<.v><<^>>v><.v><v>v^^v^v<^><vvvvv<^.<<>v^.<>^.^><>^v><>^<#
38+
#<.<>.>v^><<>^^<<vv>^>^v>>>v>v><^v><v.>>^<>>.<vv<<<v<v^<<vv^<.v^^>vv>>^<^<v<v<<>vv.><v..>>>.>^v<<vv><v^^^vv^^<>^>v<^^>v.>#
39+
#<>^^<>>^v>v<<>^.>>^^^<<v>^vv^<^<.<<<vv>>v>^^<^v><><>.<>.^><<^^^>^vv><>v.<>v<.<v>>><v.^>^>vv<v>^<v^<<v^v>v..>^^<^^.><>^><#
40+
########################################################################################################################.#""";
41+
42+
public static void main(String[] args) {
43+
System.out.println(Day24Solver.solveTask1(INPUT));
44+
System.out.println(Day24Solver.solveTask2(INPUT));
45+
}
46+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
package eu.happycoders.adventofcode2022.day24;
2+
3+
/**
4+
* Advent of Code 2022 – Object-Oriented Solutions in Java.
5+
*
6+
* <p>A position on the valley map.
7+
*
8+
* @author <a href="mailto:sven@happycoders.eu">Sven Woltmann</a>
9+
*/
10+
@SuppressWarnings("PMD.ShortVariable") // x and y are OK!
11+
record Position(int column, int row) {
12+
13+
Position up() {
14+
return new Position(column, row - 1);
15+
}
16+
17+
Position down() {
18+
return new Position(column, row + 1);
19+
}
20+
21+
Position left() {
22+
return new Position(column - 1, row);
23+
}
24+
25+
Position right() {
26+
return new Position(column + 1, row);
27+
}
28+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
package eu.happycoders.adventofcode2022.day24;
2+
3+
/**
4+
* Advent of Code 2022 – Object-Oriented Solutions in Java.
5+
*
6+
* <p>Parses the input text into the valley map of blizzards.
7+
*
8+
* @author <a href="mailto:sven@happycoders.eu">Sven Woltmann</a>
9+
*/
10+
class PuzzleInputParser {
11+
12+
static ValleyMap parse(String input) {
13+
String[] lines = input.split("\\n");
14+
int height = lines.length - 2;
15+
int width = lines[0].length() - 2;
16+
17+
Tile[][] tiles = new Tile[height][width];
18+
19+
for (int row = 0; row < height; row++) {
20+
String line = lines[row + 1];
21+
22+
for (int column = 0; column < width; column++) {
23+
tiles[row][column] = Tile.of(line.charAt(column + 1));
24+
}
25+
}
26+
27+
return new ValleyMap(tiles);
28+
}
29+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package eu.happycoders.adventofcode2022.day24;
2+
3+
/**
4+
* Advent of Code 2022 – Object-Oriented Solutions in Java.
5+
*
6+
* <p>A tile on the valley map.
7+
*
8+
* @author <a href="mailto:sven@happycoders.eu">Sven Woltmann</a>
9+
*/
10+
enum Tile {
11+
CLEAR_GROUND('.'),
12+
UP('^'),
13+
DOWN('v'),
14+
LEFT('<'),
15+
RIGHT('>');
16+
17+
private final char symbol;
18+
19+
Tile(char symbol) {
20+
this.symbol = symbol;
21+
}
22+
23+
char symbol() {
24+
return symbol;
25+
}
26+
27+
static Tile of(char symbol) {
28+
// No need to optimize for speed here, this is called only once when the map is parsed
29+
for (Tile value : values()) {
30+
if (value.symbol == symbol) {
31+
return value;
32+
}
33+
}
34+
throw new IllegalArgumentException("Unknown symbol: " + symbol);
35+
}
36+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
package eu.happycoders.adventofcode2022.day24;
2+
3+
import java.util.Arrays;
4+
5+
/**
6+
* Advent of Code 2022 – Object-Oriented Solutions in Java.
7+
*
8+
* <p>The valley map of blizzards.
9+
*
10+
* @author <a href="mailto:sven@happycoders.eu">Sven Woltmann</a>
11+
*/
12+
class ValleyMap {
13+
14+
private final int width;
15+
private final int height;
16+
private final Tile[][] tiles;
17+
private final Position startPosition;
18+
private final Position targetPosition;
19+
20+
ValleyMap(Tile[][] tiles) {
21+
this.width = tiles[0].length;
22+
this.height = tiles.length;
23+
this.tiles = tiles;
24+
25+
this.startPosition = new Position(0, -1);
26+
this.targetPosition = new Position(width - 1, height);
27+
}
28+
29+
Position startPosition() {
30+
return startPosition;
31+
}
32+
33+
Position targetPosition() {
34+
return targetPosition;
35+
}
36+
37+
boolean contains(Position position) {
38+
return position.column() >= 0
39+
&& position.column() < width
40+
&& position.row() >= 0
41+
&& position.row() < height;
42+
}
43+
44+
boolean isBlizzardAtMinute(Position position, int minute) {
45+
return isUpBlizzardAtMinute(position, minute)
46+
|| isDownBlizzardAtMinute(position, minute)
47+
|| isLeftBlizzardAtMinute(position, minute)
48+
|| isRightBlizzardAtMinute(position, minute);
49+
}
50+
51+
private boolean isUpBlizzardAtMinute(Position position, int minute) {
52+
return tiles[modulo(position.row() + minute, height)][position.column()] == Tile.UP;
53+
}
54+
55+
private boolean isDownBlizzardAtMinute(Position position, int minute) {
56+
return tiles[modulo(position.row() - minute, height)][position.column()] == Tile.DOWN;
57+
}
58+
59+
private boolean isLeftBlizzardAtMinute(Position position, int minute) {
60+
return tiles[position.row()][modulo(position.column() + minute, width)] == Tile.LEFT;
61+
}
62+
63+
private boolean isRightBlizzardAtMinute(Position position, int minute) {
64+
return tiles[position.row()][modulo(position.column() - minute, width)] == Tile.RIGHT;
65+
}
66+
67+
private int modulo(int numerator, int denominator) {
68+
int result = numerator % denominator;
69+
if (result < 0) {
70+
result += denominator;
71+
}
72+
return result;
73+
}
74+
75+
@Override
76+
public boolean equals(Object object) {
77+
if (this == object) {
78+
return true;
79+
}
80+
81+
if (object == null || getClass() != object.getClass()) {
82+
return false;
83+
}
84+
85+
ValleyMap that = (ValleyMap) object;
86+
return Arrays.deepEquals(tiles, that.tiles);
87+
}
88+
89+
@Override
90+
public int hashCode() {
91+
return Arrays.deepHashCode(tiles);
92+
}
93+
94+
@Override
95+
public String toString() {
96+
return toStringAtTime(0);
97+
}
98+
99+
String toStringAtTime(int minute) {
100+
StringBuilder result = new StringBuilder();
101+
102+
for (int row = 0; row < height; row++) {
103+
for (int column = 0; column < width; column++) {
104+
result.append(getSymbolAtMinute(new Position(column, row), minute));
105+
}
106+
result.append('\n');
107+
}
108+
109+
return result.toString();
110+
}
111+
112+
private char getSymbolAtMinute(Position position, int minute) {
113+
boolean isUpBlizzard = isUpBlizzardAtMinute(position, minute);
114+
boolean isDownBlizzard = isDownBlizzardAtMinute(position, minute);
115+
boolean isLeftBlizzard = isLeftBlizzardAtMinute(position, minute);
116+
boolean isRightBlizzard = isRightBlizzardAtMinute(position, minute);
117+
118+
int count = countBlizzards(isUpBlizzard, isDownBlizzard, isLeftBlizzard, isRightBlizzard);
119+
if (count == 0) {
120+
return Tile.CLEAR_GROUND.symbol();
121+
} else if (count == 1) {
122+
if (isUpBlizzard) {
123+
return Tile.UP.symbol();
124+
} else if (isDownBlizzard) {
125+
return Tile.DOWN.symbol();
126+
} else if (isLeftBlizzard) {
127+
return Tile.LEFT.symbol();
128+
} else {
129+
return Tile.RIGHT.symbol();
130+
}
131+
} else {
132+
return (char) ('0' + count);
133+
}
134+
}
135+
136+
private static int countBlizzards(
137+
boolean isUpBlizzard,
138+
boolean isDownBlizzard,
139+
boolean isLeftBlizzard,
140+
boolean isRightBlizzard) {
141+
int count = 0;
142+
if (isUpBlizzard) {
143+
count++;
144+
}
145+
if (isDownBlizzard) {
146+
count++;
147+
}
148+
if (isLeftBlizzard) {
149+
count++;
150+
}
151+
if (isRightBlizzard) {
152+
count++;
153+
}
154+
return count;
155+
}
156+
}

0 commit comments

Comments
 (0)