Skip to content

Commit 64a26f9

Browse files
committed
WIP Days 23-25
1 parent 3078fd4 commit 64a26f9

File tree

6 files changed

+462
-4
lines changed

6 files changed

+462
-4
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,4 @@ target/
77
src/test/resources/config.properties
88
src/test/resources/input
99
src/test/resources/2020
10+
.DS_Store

src/test/java/com/macasaet/Day23.java

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package com.macasaet;
22

3-
import static org.junit.jupiter.api.Assertions.assertEquals;
4-
import static org.junit.jupiter.api.Assertions.assertTrue;
3+
import org.junit.jupiter.api.Disabled;
4+
import org.junit.jupiter.api.Nested;
5+
import org.junit.jupiter.api.Test;
56

67
import java.util.*;
78
import java.util.concurrent.ConcurrentHashMap;
@@ -12,8 +13,8 @@
1213
import java.util.stream.Stream;
1314
import java.util.stream.StreamSupport;
1415

15-
import org.junit.jupiter.api.Nested;
16-
import org.junit.jupiter.api.Test;
16+
import static org.junit.jupiter.api.Assertions.assertEquals;
17+
import static org.junit.jupiter.api.Assertions.assertTrue;
1718

1819
/**
1920
* --- Day 23: Amphipod ---
@@ -796,6 +797,7 @@ public final void verifyEstimatedDistanceIsZero() {
796797
assertEquals(0, result);
797798
}
798799

800+
@Disabled
799801
@Test
800802
public final void verifyEstimationOrdering() {
801803
// given
@@ -883,6 +885,7 @@ public final void part1() {
883885
System.out.println("Part 1: " + lowest(initial));
884886
}
885887

888+
@Disabled
886889
@Test
887890
public final void part2() {
888891
final var lines = getInput().collect(Collectors.toList());

src/test/java/com/macasaet/Day24.java

Lines changed: 284 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,284 @@
1+
package com.macasaet;
2+
3+
import org.junit.jupiter.api.Disabled;
4+
import org.junit.jupiter.api.Nested;
5+
import org.junit.jupiter.api.Test;
6+
7+
import java.math.BigInteger;
8+
import java.util.ArrayList;
9+
import java.util.List;
10+
import java.util.PrimitiveIterator;
11+
import java.util.concurrent.atomic.AtomicInteger;
12+
import java.util.function.Consumer;
13+
import java.util.function.Supplier;
14+
import java.util.stream.Stream;
15+
import java.util.stream.StreamSupport;
16+
17+
import static org.junit.jupiter.api.Assertions.assertEquals;
18+
19+
/**
20+
* --- Day 24: Arithmetic Logic Unit ---
21+
*/
22+
public class Day24 {
23+
24+
protected Stream<String> getInput() {
25+
return StreamSupport
26+
.stream(new LineSpliterator("day-24.txt"),
27+
false);
28+
}
29+
30+
public static class ArithmeticLogicUnit {
31+
public BigInteger getW() {
32+
return w;
33+
}
34+
35+
public void setW(BigInteger w) {
36+
this.w = w;
37+
}
38+
39+
public BigInteger getX() {
40+
return x;
41+
}
42+
43+
public void setX(BigInteger x) {
44+
this.x = x;
45+
}
46+
47+
public BigInteger getY() {
48+
return y;
49+
}
50+
51+
public void setY(BigInteger y) {
52+
this.y = y;
53+
}
54+
55+
public BigInteger getZ() {
56+
return z;
57+
}
58+
59+
public void setZ(BigInteger z) {
60+
this.z = z;
61+
}
62+
63+
private BigInteger w = BigInteger.ZERO, x = BigInteger.ZERO, y = BigInteger.ZERO, z = BigInteger.ZERO;
64+
65+
public List<? extends Instruction> getInstructions() {
66+
return instructions;
67+
}
68+
69+
public void setInstructions(List<? extends Instruction> instructions) {
70+
this.instructions = instructions;
71+
}
72+
73+
private List<? extends Instruction> instructions = new ArrayList<>();
74+
75+
public boolean isValid(final String modelNumber) {
76+
final var iterator = modelNumber.chars().map(Character::getNumericValue).iterator();
77+
for (final var instruction : getInstructions()) {
78+
instruction.evaluate(iterator);
79+
}
80+
return BigInteger.ZERO.equals(getZ());
81+
}
82+
83+
public static ArithmeticLogicUnit parse(final Stream<String> lines) {
84+
final var result = new ArithmeticLogicUnit();
85+
final List<? extends Instruction> instructions = lines.map(line -> {
86+
final var components = line.split(" ");
87+
88+
final Consumer<BigInteger> resultSetter = switch (components[1]) {
89+
case "w" -> result::setW;
90+
case "x" -> result::setX;
91+
case "y" -> result::setY;
92+
case "z" -> result::setZ;
93+
default -> throw new IllegalArgumentException("Invalid instruction, invalid l-value: " + line);
94+
};
95+
final Supplier<BigInteger> xSupplier = switch (components[1]) {
96+
case "w" -> result::getW;
97+
case "x" -> result::getX;
98+
case "y" -> result::getY;
99+
case "z" -> result::getZ;
100+
default -> throw new IllegalArgumentException("Invalid instruction, invalid l-value: " + line);
101+
};
102+
final Supplier<BigInteger> ySupplier = components.length > 2 ? switch (components[2]) {
103+
case "w" -> result::getW;
104+
case "x" -> result::getX;
105+
case "y" -> result::getY;
106+
case "z" -> result::getZ;
107+
default -> () -> new BigInteger(components[2]);
108+
} : () -> {
109+
throw new IllegalStateException();
110+
};
111+
return switch (components[0]) {
112+
case "inp" -> new Input(resultSetter);
113+
case "add" -> new Add(resultSetter, xSupplier, ySupplier);
114+
case "mul" -> new Multiply(resultSetter, xSupplier, ySupplier);
115+
case "div" -> new Divide(resultSetter, xSupplier, ySupplier);
116+
case "mod" -> new Modulo(resultSetter, xSupplier, ySupplier);
117+
case "eql" -> new Equals(resultSetter, xSupplier, ySupplier);
118+
default -> throw new IllegalArgumentException("Invalid instruction: " + line);
119+
};
120+
}).toList();
121+
result.setInstructions(instructions);
122+
return result;
123+
}
124+
125+
public void reset() {
126+
setW(BigInteger.ZERO);
127+
setX(BigInteger.ZERO);
128+
setY(BigInteger.ZERO);
129+
setZ(BigInteger.ZERO);
130+
}
131+
}
132+
133+
public interface Instruction {
134+
void evaluate(PrimitiveIterator.OfInt input);
135+
}
136+
137+
public record Input(Consumer<BigInteger> setter) implements Instruction {
138+
139+
public void evaluate(PrimitiveIterator.OfInt input) {
140+
setter.accept(BigInteger.valueOf(input.nextInt()));
141+
}
142+
}
143+
144+
public record Add(Consumer<BigInteger> resultSetter, Supplier<BigInteger> xSupplier,
145+
Supplier<BigInteger> ySupplier) implements Instruction {
146+
public void evaluate(PrimitiveIterator.OfInt _input) {
147+
resultSetter.accept(xSupplier.get().add(ySupplier.get()));
148+
}
149+
}
150+
151+
public record Multiply(Consumer<BigInteger> resultSetter, Supplier<BigInteger> xSupplier,
152+
Supplier<BigInteger> ySupplier) implements Instruction {
153+
public void evaluate(PrimitiveIterator.OfInt _input) {
154+
resultSetter.accept(xSupplier.get().multiply(ySupplier.get()));
155+
}
156+
}
157+
158+
public record Divide(Consumer<BigInteger> resultSetter, Supplier<BigInteger> xSupplier,
159+
Supplier<BigInteger> ySupplier) implements Instruction {
160+
public void evaluate(PrimitiveIterator.OfInt _input) {
161+
resultSetter.accept(xSupplier.get().divide(ySupplier.get()));
162+
}
163+
}
164+
165+
public record Modulo(Consumer<BigInteger> resultSetter, Supplier<BigInteger> xSupplier,
166+
Supplier<BigInteger> ySupplier) implements Instruction {
167+
public void evaluate(PrimitiveIterator.OfInt _input) {
168+
resultSetter.accept(xSupplier.get().mod(ySupplier.get()));
169+
}
170+
}
171+
172+
public record Equals(Consumer<BigInteger> resultSetter, Supplier<BigInteger> xSupplier,
173+
Supplier<BigInteger> ySupplier) implements Instruction {
174+
public void evaluate(PrimitiveIterator.OfInt _input) {
175+
resultSetter.accept(xSupplier.get().equals(ySupplier.get()) ? BigInteger.ONE : BigInteger.ZERO);
176+
}
177+
}
178+
179+
@Nested
180+
public class ArithmeticLogicUnitTest {
181+
@Disabled
182+
@Test
183+
public void testNegation() {
184+
// given
185+
final var input = """
186+
inp x
187+
mul x -1
188+
""";
189+
final var alu = ArithmeticLogicUnit.parse(input.lines());
190+
191+
// when
192+
alu.isValid("7");
193+
194+
// then
195+
assertEquals(-7, alu.getX());
196+
}
197+
198+
@Disabled
199+
@Test
200+
public final void testThreeTimes() {
201+
// given
202+
final var input = """
203+
inp z
204+
inp x
205+
mul z 3
206+
eql z x
207+
""";
208+
final var alu = ArithmeticLogicUnit.parse(input.lines());
209+
210+
// when
211+
alu.isValid("39");
212+
213+
// then
214+
assertEquals(1, alu.getZ());
215+
}
216+
217+
@Disabled
218+
@Test
219+
public final void testBinaryConversion() {
220+
// given
221+
final var input = """
222+
inp w
223+
add z w
224+
mod z 2
225+
div w 2
226+
add y w
227+
mod y 2
228+
div w 2
229+
add x w
230+
mod x 2
231+
div w 2
232+
mod w 2
233+
""";
234+
final var alu = ArithmeticLogicUnit.parse(input.lines());
235+
236+
// when
237+
alu.isValid("9");
238+
239+
// then
240+
assertEquals(1, alu.getW());
241+
assertEquals(0, alu.getX());
242+
assertEquals(0, alu.getY());
243+
assertEquals(1, alu.getZ());
244+
}
245+
246+
@Test
247+
public final void testIsValid() {
248+
// given
249+
final var alu = ArithmeticLogicUnit.parse(getInput());
250+
251+
// when
252+
final var result = alu.isValid("13579246899999");
253+
254+
// then
255+
System.err.println("z=" + alu.getZ());
256+
}
257+
}
258+
259+
@Disabled
260+
@Test
261+
public final void part1() {
262+
final var monad = getInput().toList();
263+
final var counter = new AtomicInteger(0);
264+
final var result = Stream.iterate(new BigInteger("99999999999999"), previous -> previous.subtract(BigInteger.ONE))
265+
.parallel()
266+
.filter(candidate -> {
267+
final int count = counter.updateAndGet(previous -> previous + 1);
268+
if(count % 10000 == 0) {
269+
System.err.println("Testing: " + candidate);
270+
}
271+
final var alu = ArithmeticLogicUnit.parse(monad.stream());
272+
return alu.isValid(candidate.toString());
273+
}).findFirst();
274+
System.out.println("Part 1: " + result.orElseThrow());
275+
}
276+
277+
@Disabled
278+
@Test
279+
public final void part2() {
280+
281+
System.out.println("Part 2: " + null);
282+
}
283+
284+
}

0 commit comments

Comments
 (0)