1
+ package com .macasaet ;
2
+
3
+ import java .util .ArrayList ;
4
+ import java .util .Arrays ;
5
+ import java .util .List ;
6
+ import java .util .stream .Collectors ;
7
+ import java .util .stream .IntStream ;
8
+ import java .util .stream .Stream ;
9
+ import java .util .stream .StreamSupport ;
10
+
11
+ import org .junit .jupiter .api .Test ;
12
+
13
+ /**
14
+ * --- Day 7: The Treachery of Whales ---
15
+ */
16
+ public class Day07 {
17
+
18
+ protected Stream <String > getInput () {
19
+ return StreamSupport
20
+ .stream (new LineSpliterator ("day-07.txt" ),
21
+ false );
22
+ }
23
+
24
+ /**
25
+ * @return the horizontal position of each crab submarine in the swarm
26
+ */
27
+ protected List <Integer > getCrabPositions () {
28
+ final var list = getInput ().collect (Collectors .toList ());
29
+ final var line = list .get (0 );
30
+ return Arrays .stream (line .split ("," ))
31
+ .mapToInt (Integer ::parseInt )
32
+ .collect (ArrayList ::new , List ::add , List ::addAll );
33
+ }
34
+
35
+ /**
36
+ * Assuming a constant fuel consumption rate, calculate the fuel required for the swarm to reach <em>alignmentPoint</em>.
37
+ *
38
+ * @param positions the starting position of each crab submarine
39
+ * @param alignmentPoint a potential point for the crabs to gather in order to blast a hole in the ocean floor
40
+ * @return the fuel required to reach the alignment point
41
+ */
42
+ protected int calculateConstantFuel (final Iterable <? extends Integer > positions , final int alignmentPoint ) {
43
+ int sum = 0 ;
44
+ for (final var position : positions ) {
45
+ sum += Math .abs (alignmentPoint - position );
46
+ }
47
+ return sum ;
48
+ }
49
+
50
+ /**
51
+ * Calculate the fuel required for the swarm to reach <em>alignmentPoint</em>
52
+ *
53
+ * @param positions the starting position for each crab submarine
54
+ * @param alignmentPoint a potential point for the crabs to gather in order to blast a hole in the ocean floor
55
+ * @return the fuel required to reach the alignment point
56
+ */
57
+ protected int calculateFuel (final Iterable <? extends Integer > positions , final int alignmentPoint ) {
58
+ int sum = 0 ;
59
+ for (final var position : positions ) {
60
+ sum += calculateFuel (position , alignmentPoint );
61
+ }
62
+ return sum ;
63
+ }
64
+
65
+ /**
66
+ * Calculate the fuel required for a single crab submarine to travel from one horizontal position to the next.
67
+ *
68
+ * @param start the starting position (inclusive)
69
+ * @param end the ending position (inclusive)
70
+ * @return the amount of fuel consumed in the journey
71
+ */
72
+ protected int calculateFuel (final int start , final int end ) {
73
+ final int target = Math .abs (end - start );
74
+ int sum = 0 ;
75
+ for (int i = target ; --i >= 0 ; ) {
76
+ sum += i + 1 ;
77
+ }
78
+ return sum ;
79
+ }
80
+
81
+ @ Test
82
+ public final void part1 () {
83
+ int min = Integer .MAX_VALUE ;
84
+ int max = Integer .MIN_VALUE ;
85
+ final var positions = getCrabPositions ();
86
+ for (final var position : positions ) {
87
+ min = Math .min (min , position );
88
+ max = Math .max (max , position );
89
+ }
90
+ final int result = IntStream .range (min , max )
91
+ .map (alignmentPoint -> calculateConstantFuel (positions , alignmentPoint ))
92
+ .min ()
93
+ .getAsInt ();
94
+ System .out .println ("Part 1: " + result );
95
+ }
96
+
97
+ @ Test
98
+ public final void part2 () {
99
+ int min = Integer .MAX_VALUE ;
100
+ int max = Integer .MIN_VALUE ;
101
+ final var positions = getCrabPositions ();
102
+ for (final var position : positions ) {
103
+ min = Math .min (min , position );
104
+ max = Math .max (max , position );
105
+ }
106
+ final int result = IntStream .range (min , max )
107
+ .map (alignmentPoint -> calculateFuel (positions , alignmentPoint ))
108
+ .min ()
109
+ .getAsInt ();
110
+ System .out .println ("Part 2: " + result );
111
+ }
112
+
113
+ }
0 commit comments