From d5e720baddeae8f72ecd227aea60a5076b9da2ab Mon Sep 17 00:00:00 2001 From: Flashk Date: Tue, 24 Dec 2024 16:16:22 +0100 Subject: [PATCH 1/3] feat: day 24 part 2 WIP --- .../flashk/day24/CrossedWires.java | 154 ++++++++++++++++++ .../com/adventofcode/flashk/day24/Gate.java | 69 ++++++++ .../flashk/day24/LogicalGate.java | 40 +++++ .../adventofcode/flashk/day24/StartGate.java | 10 ++ .../com/adventofcode/flashk/day24/Wire.java | 59 +++++++ .../adventofcode/flashk/day24/WireEdge.java | 10 ++ 6 files changed, 342 insertions(+) create mode 100644 src/main/java/com/adventofcode/flashk/day24/CrossedWires.java create mode 100644 src/main/java/com/adventofcode/flashk/day24/Gate.java create mode 100644 src/main/java/com/adventofcode/flashk/day24/LogicalGate.java create mode 100644 src/main/java/com/adventofcode/flashk/day24/StartGate.java create mode 100644 src/main/java/com/adventofcode/flashk/day24/Wire.java create mode 100644 src/main/java/com/adventofcode/flashk/day24/WireEdge.java diff --git a/src/main/java/com/adventofcode/flashk/day24/CrossedWires.java b/src/main/java/com/adventofcode/flashk/day24/CrossedWires.java new file mode 100644 index 0000000..0ac6183 --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day24/CrossedWires.java @@ -0,0 +1,154 @@ +package com.adventofcode.flashk.day24; + +import org.apache.commons.lang3.StringUtils; +import org.jgrapht.graph.DirectedMultigraph; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; +import java.util.List; +import java.util.Map; +import java.util.PriorityQueue; +import java.util.Set; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class CrossedWires { + + private static final Pattern GATE_PATTERN = Pattern.compile("(\\w*) (AND|XOR|OR) (\\w*) -> (\\w*)"); + + private DirectedMultigraph graph = new DirectedMultigraph<>(WireEdge.class); + + Map wires = new HashMap<>(); + private final List gates = new ArrayList<>(); + + // Attributes that help start and end the algorithm + private final List initialGates = new ArrayList<>(); + private final List endWires = new ArrayList<>(); + + public CrossedWires(List inputs) { + + // Maps a wire with the gate that generates it. + Map originGates = new HashMap<>(); + + boolean inputWires = true; + + for (String input : inputs) { + if (StringUtils.isBlank(input)) { + inputWires = false; + continue; + } + + if (inputWires) { + String[] wireInput = input.replace(StringUtils.SPACE, StringUtils.EMPTY).split(":"); + wires.put(wireInput[0], new Wire(wireInput[0], Integer.parseInt(wireInput[1]))); + } else { + createGate(input, originGates); + } + } + + + // Connect graph gates + /* + for(LogicalGate gate : gates) { + + // First input + if(originGates.containsKey(gate.getInput1())) { + Gate inputGate1 = originGates.get(gate.getInput1()); + graph.addEdge(inputGate1, gate, new WireEdge(gate.getInput1())); + } + + // Second input + if(originGates.containsKey(gate.getInput2())) { + Gate inputGate2 = originGates.get(gate.getInput2()); + graph.addEdge(inputGate2, gate, new WireEdge(gate.getInput2())); + } + } +*/ + } + + private void createGate(String input, Map wireOriginGates) { + Matcher matcher = GATE_PATTERN.matcher(input); + if(matcher.find()) { + + // Create the gate vertex + String operation = matcher.group(2); + LogicalGate gate = new LogicalGate(operation); + + // Create the wires + getOrCreateWire(matcher.group(1)); // Input wire 1 + getOrCreateWire(matcher.group(3)); // Input wire 2 + Wire outputWire = getOrCreateWire(matcher.group(4)); + + + // Add it to structures + gates.add(gate); + graph.addVertex(gate); + + /* + if(gate.canOperate()) { + initialGates.add(gate); + }*/ + + // Wire management for building the graph + if(outputWire.getLabel().startsWith("z")) { + endWires.add(outputWire); + } + + wireOriginGates.put(outputWire, gate); + + } + } + + private void buildGraph() { + LogicalGate start = new StartGate("OR"); + + } + /// Retrieves a [Wire]() associated to the label. + /// + /// If the label does not exist, it creates a new wire and returns it. + /// @param label the wire label + /// @return a [Wire]() + private Wire getOrCreateWire(String label) { + Wire wire = wires.getOrDefault(label, new Wire(label)); + wires.putIfAbsent(label, wire); + return wire; + } + + public long solveA() { + + /* + PriorityQueue gates = new PriorityQueue<>(); + gates.addAll(initialGates); + + while(!gates.isEmpty()) { + + // Extract first those gates which can operate + Gate gate = gates.poll(); + gate.setVisited(true); + + // Operate it + WireEdge outputEdge = gate.operate(); + Wire output = outputEdge.wire(); + System.out.println("Wire "+output.getLabel()+ " has value: "+output.getValue().get()); + + // Calculate the next gate that should be added to the queue. + if(!output.isEnd()) { + Gate outputGate = graph.getEdgeTarget(outputEdge); + if(!outputGate.isVisited()) { + gates.add(outputGate); + } + } + + }*/ + + String binaryValue = endWires.stream().sorted().map(Wire::getBinaryValue).collect(Collectors.joining()); + return Long.valueOf(binaryValue, 2); + } + + private Set getAdjacents(Gate gate) { + // TODO cálculo de adyacentes + return new HashSet<>(); + } +} diff --git a/src/main/java/com/adventofcode/flashk/day24/Gate.java b/src/main/java/com/adventofcode/flashk/day24/Gate.java new file mode 100644 index 0000000..316a22d --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day24/Gate.java @@ -0,0 +1,69 @@ +package com.adventofcode.flashk.day24; + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import org.jetbrains.annotations.NotNull; + +import java.util.UUID; + +@Getter +@Setter +@EqualsAndHashCode +public class Gate implements Comparable { + + private String id = UUID.randomUUID().toString(); + private String operation; + private Wire input1; + private Wire input2; + private Wire output; + private WireEdge outputEdge; + + private boolean visited = false; + + public Gate(String operation, Wire input1, Wire input2, Wire output) { + this.operation = operation; + this.input1 = input1; + this.input2 = input2; + this.output = output; + this.outputEdge = new WireEdge(output); + } + + public boolean canOperate() { + return input1.hasCurrent() && input2.hasCurrent(); + } + + /// Operates the gate using its inputs wires + /// + /// @return the output [Wire]() + /// @throws IllegalStateException if any of the wires has no value present or if the gate operation is unknown. + public WireEdge operate() { + + int value1 = input1.getValue().orElseThrow(IllegalStateException::new); + int value2 = input2.getValue().orElseThrow(IllegalStateException::new); + + switch (operation) { + case "AND" -> output.setValue(value1 & value2); + case "XOR" -> output.setValue(value1 ^ value2); + case "OR" -> output.setValue(value1 | value2); + case null, default -> throw new IllegalStateException("Unknown gate operation: " + operation); + } + + return outputEdge; + } + + + @Override + public int compareTo(@NotNull Gate o) { + if(this.canOperate() && !o.canOperate()) { + return -1; + } + + if(!this.canOperate() && o.canOperate()) { + return 1; + } + + return 0; + } + +} diff --git a/src/main/java/com/adventofcode/flashk/day24/LogicalGate.java b/src/main/java/com/adventofcode/flashk/day24/LogicalGate.java new file mode 100644 index 0000000..93cf923 --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day24/LogicalGate.java @@ -0,0 +1,40 @@ +package com.adventofcode.flashk.day24; + +import java.util.UUID; + +public class LogicalGate { + + private final String id = UUID.randomUUID().toString(); + private final String operation; + + public LogicalGate(String operation) { + this.operation = operation; + } + + public boolean canOperate(Wire input1, Wire input2) { + return input1.getValue().isPresent() && input2.getValue().isPresent(); + } + + /// Operates the gate using its inputs wires + /// + /// @return the output [Wire]() + /// @throws IllegalStateException if any of the wires has no value present or if the gate operation is unknown. + public int operate(Wire input1, Wire input2) { + + int value1 = input1.getValue().orElseThrow(IllegalStateException::new); + int value2 = input2.getValue().orElseThrow(IllegalStateException::new); + + int result; + + switch (operation) { + case "AND" -> result = value1 & value2; + case "XOR" -> result = value1 ^ value2; + case "OR" -> result = value1 | value2; + case null, default -> throw new IllegalStateException("Unknown gate operation: " + operation); + } + + return result; + + } + +} diff --git a/src/main/java/com/adventofcode/flashk/day24/StartGate.java b/src/main/java/com/adventofcode/flashk/day24/StartGate.java new file mode 100644 index 0000000..c93c53f --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day24/StartGate.java @@ -0,0 +1,10 @@ +package com.adventofcode.flashk.day24; + +public class StartGate extends LogicalGate { + + public StartGate(String operation) { + super(operation); + } + + +} diff --git a/src/main/java/com/adventofcode/flashk/day24/Wire.java b/src/main/java/com/adventofcode/flashk/day24/Wire.java new file mode 100644 index 0000000..a53dc17 --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day24/Wire.java @@ -0,0 +1,59 @@ +package com.adventofcode.flashk.day24; + + +import lombok.EqualsAndHashCode; +import lombok.Getter; +import lombok.Setter; +import org.jetbrains.annotations.NotNull; + +import java.util.Optional; + +@Getter +@EqualsAndHashCode +public class Wire implements Comparable{ + + private final String label; + + @Setter + private int value; + + public Wire(String label, int value) { + this.label = label; + this.value = value; + } + + public Wire(String label) { + this.label = label; + this.value = -1; + } + + public String getBinaryValue() { + if(value == -1) { + throw new IllegalStateException("Cannot convert to binary a non set value"); + } + return String.valueOf(value); + } + + public Optional getValue() { + if(value == -1) { + return Optional.empty(); + } + return Optional.of(value); + } + + public boolean hasCurrent() { + return value != -1; + } + + public boolean isStart() { + return label.startsWith("x") || label.startsWith("y"); + } + public boolean isEnd() { + return label.startsWith("z"); + } + + @Override + public int compareTo(@NotNull Wire o) { + return -1 * this.label.compareTo(o.label); + } +} diff --git a/src/main/java/com/adventofcode/flashk/day24/WireEdge.java b/src/main/java/com/adventofcode/flashk/day24/WireEdge.java new file mode 100644 index 0000000..8a9adc0 --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day24/WireEdge.java @@ -0,0 +1,10 @@ +package com.adventofcode.flashk.day24; + +import java.util.UUID; + +public record WireEdge(String id, Wire wire) { + + public WireEdge(Wire wire) { + this(UUID.randomUUID().toString(), wire); + } +} From 7d8808fa925e75b45b93b4ae517c79ae714b2a9b Mon Sep 17 00:00:00 2001 From: Flashk Date: Tue, 24 Dec 2024 16:16:22 +0100 Subject: [PATCH 2/3] feat: day 24 part 2 --- pom.xml | 5 + .../flashk/day24/CrossedWiresVisual.java | 177 ++++++++++++++++++ .../adventofcode/flashk/day24/GateVisual.java | 44 +++++ .../common/test/constants/TestFilename.java | 1 + .../adventofcode/flashk/day24/Day24Test.java | 35 +++- src/test/resources/inputs | 2 +- 6 files changed, 253 insertions(+), 11 deletions(-) create mode 100644 src/main/java/com/adventofcode/flashk/day24/CrossedWiresVisual.java create mode 100644 src/main/java/com/adventofcode/flashk/day24/GateVisual.java diff --git a/pom.xml b/pom.xml index 7a55bd3..e9a3931 100644 --- a/pom.xml +++ b/pom.xml @@ -46,6 +46,11 @@ jgrapht-core 1.5.2 + + org.jgrapht + jgrapht-io + 1.5.2 + com.fasterxml.jackson.core diff --git a/src/main/java/com/adventofcode/flashk/day24/CrossedWiresVisual.java b/src/main/java/com/adventofcode/flashk/day24/CrossedWiresVisual.java new file mode 100644 index 0000000..03abbc0 --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day24/CrossedWiresVisual.java @@ -0,0 +1,177 @@ +package com.adventofcode.flashk.day24; + +import org.apache.commons.lang3.StringUtils; +import org.jgrapht.Graph; +import org.jgrapht.graph.DirectedMultigraph; +import org.jgrapht.nio.dot.DOTExporter; + +import java.io.StringWriter; +import java.io.Writer; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; +import java.util.regex.Matcher; +import java.util.regex.Pattern; +import java.util.stream.Collectors; + +public class CrossedWiresVisual { + + private static final Pattern GATE_PATTERN = Pattern.compile("(\\w*) (AND|XOR|OR) (\\w*) -> (\\w*)"); + + private final Graph graph = new DirectedMultigraph<>(String.class); + + private final Map gatesPerOutput = new HashMap<>(); + private final Map wires = new HashMap<>(); + private final List gates = new ArrayList<>(); + private List endWires; + + public CrossedWiresVisual(List inputs) { + initializeWires(inputs); + initializeGates(inputs); + createStartEndVertexes(); + connectGates(); + } + + private void connectGates() { + // Por cada puerta + // Buscar si existe en gatesPerOutput + for(GateVisual gate : gatesPerOutput.values()) { + String output = gate.getOutput(); + + // Search gates that have this output gate as input 1. + List gatesInput1 = gates.stream().filter(g -> output.equals(g.getInput1())).toList(); + for(GateVisual gateInput1 : gatesInput1) { + String edgeId = output + "_" + UUID.randomUUID(); + graph.addEdge(gate, gateInput1, edgeId); + } + + // Search gates that have this output gate as input 2. + List gatesInput2 = gates.stream().filter(g -> output.equals(g.getInput2())).toList(); + for(GateVisual gateInput2 : gatesInput2) { + String edgeId = output + "_" + UUID.randomUUID(); + graph.addEdge(gate, gateInput2, edgeId); + } + + } + + } + + private void createStartEndVertexes() { + wires.keySet().stream().filter(this::isStartOrEnd).forEach(this::createStartEndVertex); + } + + + private void initializeGates(List inputs) { + List gatesInputs = inputs.stream().skip(inputs.indexOf(StringUtils.EMPTY)+1).toList(); + + for(String input : gatesInputs) { + Matcher matcher = GATE_PATTERN.matcher(input); + if(matcher.find()) { + String operation = matcher.group(2); + String input1 = matcher.group(1); + String input2 = matcher.group(3); + String output = matcher.group(4); + + GateVisual gateVisual = new GateVisual(operation, input1, input2, output); + gates.add(gateVisual); + gatesPerOutput.put(output, gateVisual); + graph.addVertex(gateVisual); + } + } + } + + private void initializeWires(List inputs) { + + boolean inputGates = false; + for (String input : inputs) { + + if (StringUtils.EMPTY.equals(input)) { + inputGates = true; + continue; + } + + if (!inputGates) { + String[] wireInput = input.replace(StringUtils.SPACE, StringUtils.EMPTY).split(":"); + wires.put(wireInput[0], Integer.parseInt(wireInput[1])); + } else { + Matcher matcher = GATE_PATTERN.matcher(input); + if (matcher.find()) { + wires.putIfAbsent(matcher.group(1), -1); + wires.putIfAbsent(matcher.group(3), -1); + wires.putIfAbsent(matcher.group(4), -1); + } + } + } + + endWires = wires.keySet().stream().filter(w -> w.startsWith("z")).sorted().toList().reversed(); + } + + + public String solveB() { + + // Obtain the graph in DOT format: + paint(); + + // Visual finding of invalid edges + System.out.println("Tools:"); + System.out.println("- (Optional) graphviz: sudo apt install graphviz"); + System.out.println("- graphviz2drawio: pip install graphviz2drawio"); + System.out.println(); + System.out.println("Procedure:"); + System.out.println("1. Add the result to a file: dotgraph_day24.txt"); + System.out.println("2. (Optional) Execute command: cat day24.txt | dot -Tsvg > day24.svg"); + System.out.println("3. Execute command: graphviz2drawio dotgraph_day24.txt"); + System.out.println("4. Open the exported 'dotgraph_day24.xml' file at https://draw.io"); + System.out.println("5. Order the graph nodes until you see the invalid connections"); + + // Invalid gates are: + // bbp AND wwg -> z09 + // wwg XOR bbp -> hnd + // ncj OR pwk -> z16 + // jkw XOR mqf -> tdv + // x23 AND y23 -> z23 + // mfr XOR scw -> bks + // x37 AND y37 -> tjp + // x37 XOR y37 -> nrn + + // So the outputs are: z09,hnd,z16,tdv,z23,bks,tjp,nrn + List outputGates = List.of("z09","hnd","z16","tdv","z23","bks","tjp","nrn"); + + return outputGates.stream().sorted().collect(Collectors.joining(",")); + } + + private void createStartEndVertex(String wire) { + GateVisual gateVisual = new GateVisual(wire); + graph.addVertex(gateVisual); + + if(isStart(wire)) { + gatesPerOutput.put(wire, gateVisual); + } else if(isEnd(wire)) { + gates.add(gateVisual); + } + + } + + private boolean isStart(String wire) { + return wire.startsWith("x") || wire.startsWith("y"); + } + + private boolean isEnd(String wire) { + return wire.startsWith("z"); + } + + private boolean isStartOrEnd(String wire) { + return isStart(wire) || isEnd(wire); + } + + private void paint() { + DOTExporter exporter = new DOTExporter<>(v -> v.getLabel()); + Writer writer = new StringWriter(); + exporter.exportGraph(graph, writer); + System.out.println(writer.toString()); + } + + +} diff --git a/src/main/java/com/adventofcode/flashk/day24/GateVisual.java b/src/main/java/com/adventofcode/flashk/day24/GateVisual.java new file mode 100644 index 0000000..cc51bb4 --- /dev/null +++ b/src/main/java/com/adventofcode/flashk/day24/GateVisual.java @@ -0,0 +1,44 @@ +package com.adventofcode.flashk.day24; + +import lombok.Getter; +import org.apache.commons.lang3.StringUtils; + +@Getter +public class GateVisual { + + private static int id = 0; + + private final String label; + private final String operation; + private String input1; + private String input2; + private String output; + + public GateVisual(String label) { + this.label = label; + this.operation = StringUtils.EMPTY; + if(label.startsWith("x") || label.startsWith("y")) { + this.output = label; + } else if(label.startsWith("z")) { + this.input1 = label; + } + } + + public GateVisual(String operation, String input1, String input2, String output) { + this.label = operation + "_" + output; + this.operation = operation; + this.input1 = input1; + this.input2 = input2; + this.output = output; + } + + public int operate(int value1, int value2) { + return switch (operation) { + case "AND" -> value1 & value2; + case "XOR" -> value1 ^ value2; + case "OR" -> value1 | value2; + case null, default -> throw new IllegalStateException("Unknown gate operation: " + operation); + }; + } + +} diff --git a/src/test/java/com/adventofcode/flashk/common/test/constants/TestFilename.java b/src/test/java/com/adventofcode/flashk/common/test/constants/TestFilename.java index 06f010e..fbfd10f 100644 --- a/src/test/java/com/adventofcode/flashk/common/test/constants/TestFilename.java +++ b/src/test/java/com/adventofcode/flashk/common/test/constants/TestFilename.java @@ -8,6 +8,7 @@ private TestFilename() {} public static final String INPUT_FILE = "data.input"; public static final String INPUT_FILE_SAMPLE = "sample.input"; public static final String INPUT_FILE_SAMPLE_2 = "sample_2.input"; + public static final String INPUT_FILE_SAMPLE_3 = "sample_3.input"; public static final String INPUT_FILE_SAMPLE_PART_2 = "sample_part_2.input"; public static final String INPUT_FILE_SINGLE_SAMPLE = "single_sample.input"; public static final String INPUT_FILE_SINGLE_SAMPLE_2 = "single_sample_2.input"; diff --git a/src/test/java/com/adventofcode/flashk/day24/Day24Test.java b/src/test/java/com/adventofcode/flashk/day24/Day24Test.java index a85b890..01838f7 100644 --- a/src/test/java/com/adventofcode/flashk/day24/Day24Test.java +++ b/src/test/java/com/adventofcode/flashk/day24/Day24Test.java @@ -14,15 +14,13 @@ import com.adventofcode.flashk.common.test.constants.TestFilename; import com.adventofcode.flashk.common.test.constants.TestFolder; import com.adventofcode.flashk.common.test.constants.TestTag; -import com.adventofcode.flashk.common.test.utils.PuzzleTest; import com.adventofcode.flashk.common.test.utils.Input; import static org.junit.jupiter.api.Assertions.assertEquals; @DisplayName(TestDisplayName.DAY_24) @TestMethodOrder(OrderAnnotation.class) -@Disabled // TODO Remove comment when implemented -public class Day24Test extends PuzzleTest { +class Day24Test { private static final String INPUT_FOLDER = TestFolder.DAY_24; @@ -31,7 +29,7 @@ public class Day24Test extends PuzzleTest { @Tag(TestTag.PART_1) @Tag(TestTag.SAMPLE) @DisplayName(TestDisplayName.PART_1_SAMPLE) - public void testSolvePart1Sample() { + void part1SampleTest() { // Read input file List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE); @@ -47,7 +45,7 @@ public void testSolvePart1Sample() { @Tag(TestTag.PART_1) @Tag(TestTag.SAMPLE) @DisplayName(TestDisplayName.PART_1_SAMPLE_2) - public void testSolvePart1Sample2() { + void part1Sample2Test() { // Read input file List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE_2); @@ -62,7 +60,7 @@ public void testSolvePart1Sample2() { @Tag(TestTag.PART_1) @Tag(TestTag.INPUT) @DisplayName(TestDisplayName.PART_1_INPUT) - public void testSolvePart1Input() { + void part1InputTest() { // Read input file List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE); @@ -78,11 +76,28 @@ public void testSolvePart1Input() { @Tag(TestTag.PART_2) @Tag(TestTag.SAMPLE) @DisplayName(TestDisplayName.PART_2_SAMPLE) - public void testSolvePart2Sample() { + void part2SampleTest() { // Read input file List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE); + CrossedWiresVisual crossedWires = new CrossedWiresVisual(inputs); + crossedWires.solveB(); + assertEquals(0L,0L); + } + + @Test + @Order(3) + @Tag(TestTag.PART_2) + @Tag(TestTag.SAMPLE) + @DisplayName(TestDisplayName.PART_2_SAMPLE) + void part2Sample3Test() { + + // Read input file + List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE_SAMPLE_3); + CrossedWiresVisual crossedWires = new CrossedWiresVisual(inputs); + + crossedWires.solveB(); assertEquals(0L,0L); } @@ -91,13 +106,13 @@ public void testSolvePart2Sample() { @Tag(TestTag.PART_2) @Tag(TestTag.INPUT) @DisplayName(TestDisplayName.PART_2_INPUT) - public void testSolvePart2Input() { + void part2InputTest() { // Read input file List inputs = Input.readStringLines(INPUT_FOLDER, TestFilename.INPUT_FILE); + CrossedWiresVisual crossedWires = new CrossedWiresVisual(inputs); - System.out.println("Solution: "); - assertEquals(0L,0L); + assertEquals("bks,hnd,nrn,tdv,tjp,z09,z16,z23", crossedWires.solveB()); } diff --git a/src/test/resources/inputs b/src/test/resources/inputs index 9242638..d934f3d 160000 --- a/src/test/resources/inputs +++ b/src/test/resources/inputs @@ -1 +1 @@ -Subproject commit 9242638852acb165f6f55fc53533e2cb02232ac0 +Subproject commit d934f3d88a796442094337e32ae6b9a53b1a30de From ef97b101edd7788391fc9709c0a2ebf45f1b72d6 Mon Sep 17 00:00:00 2001 From: Flashk Date: Thu, 26 Dec 2024 12:54:08 +0100 Subject: [PATCH 3/3] refactor: remove not used classes for day 24 --- .../flashk/day24/CrossedWires.java | 154 ------------------ .../com/adventofcode/flashk/day24/Gate.java | 69 -------- .../flashk/day24/LogicalGate.java | 40 ----- .../adventofcode/flashk/day24/StartGate.java | 10 -- .../com/adventofcode/flashk/day24/Wire.java | 59 ------- .../adventofcode/flashk/day24/WireEdge.java | 10 -- 6 files changed, 342 deletions(-) delete mode 100644 src/main/java/com/adventofcode/flashk/day24/CrossedWires.java delete mode 100644 src/main/java/com/adventofcode/flashk/day24/Gate.java delete mode 100644 src/main/java/com/adventofcode/flashk/day24/LogicalGate.java delete mode 100644 src/main/java/com/adventofcode/flashk/day24/StartGate.java delete mode 100644 src/main/java/com/adventofcode/flashk/day24/Wire.java delete mode 100644 src/main/java/com/adventofcode/flashk/day24/WireEdge.java diff --git a/src/main/java/com/adventofcode/flashk/day24/CrossedWires.java b/src/main/java/com/adventofcode/flashk/day24/CrossedWires.java deleted file mode 100644 index 0ac6183..0000000 --- a/src/main/java/com/adventofcode/flashk/day24/CrossedWires.java +++ /dev/null @@ -1,154 +0,0 @@ -package com.adventofcode.flashk.day24; - -import org.apache.commons.lang3.StringUtils; -import org.jgrapht.graph.DirectedMultigraph; - -import java.util.ArrayList; -import java.util.HashMap; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.PriorityQueue; -import java.util.Set; -import java.util.regex.Matcher; -import java.util.regex.Pattern; -import java.util.stream.Collectors; - -public class CrossedWires { - - private static final Pattern GATE_PATTERN = Pattern.compile("(\\w*) (AND|XOR|OR) (\\w*) -> (\\w*)"); - - private DirectedMultigraph graph = new DirectedMultigraph<>(WireEdge.class); - - Map wires = new HashMap<>(); - private final List gates = new ArrayList<>(); - - // Attributes that help start and end the algorithm - private final List initialGates = new ArrayList<>(); - private final List endWires = new ArrayList<>(); - - public CrossedWires(List inputs) { - - // Maps a wire with the gate that generates it. - Map originGates = new HashMap<>(); - - boolean inputWires = true; - - for (String input : inputs) { - if (StringUtils.isBlank(input)) { - inputWires = false; - continue; - } - - if (inputWires) { - String[] wireInput = input.replace(StringUtils.SPACE, StringUtils.EMPTY).split(":"); - wires.put(wireInput[0], new Wire(wireInput[0], Integer.parseInt(wireInput[1]))); - } else { - createGate(input, originGates); - } - } - - - // Connect graph gates - /* - for(LogicalGate gate : gates) { - - // First input - if(originGates.containsKey(gate.getInput1())) { - Gate inputGate1 = originGates.get(gate.getInput1()); - graph.addEdge(inputGate1, gate, new WireEdge(gate.getInput1())); - } - - // Second input - if(originGates.containsKey(gate.getInput2())) { - Gate inputGate2 = originGates.get(gate.getInput2()); - graph.addEdge(inputGate2, gate, new WireEdge(gate.getInput2())); - } - } -*/ - } - - private void createGate(String input, Map wireOriginGates) { - Matcher matcher = GATE_PATTERN.matcher(input); - if(matcher.find()) { - - // Create the gate vertex - String operation = matcher.group(2); - LogicalGate gate = new LogicalGate(operation); - - // Create the wires - getOrCreateWire(matcher.group(1)); // Input wire 1 - getOrCreateWire(matcher.group(3)); // Input wire 2 - Wire outputWire = getOrCreateWire(matcher.group(4)); - - - // Add it to structures - gates.add(gate); - graph.addVertex(gate); - - /* - if(gate.canOperate()) { - initialGates.add(gate); - }*/ - - // Wire management for building the graph - if(outputWire.getLabel().startsWith("z")) { - endWires.add(outputWire); - } - - wireOriginGates.put(outputWire, gate); - - } - } - - private void buildGraph() { - LogicalGate start = new StartGate("OR"); - - } - /// Retrieves a [Wire]() associated to the label. - /// - /// If the label does not exist, it creates a new wire and returns it. - /// @param label the wire label - /// @return a [Wire]() - private Wire getOrCreateWire(String label) { - Wire wire = wires.getOrDefault(label, new Wire(label)); - wires.putIfAbsent(label, wire); - return wire; - } - - public long solveA() { - - /* - PriorityQueue gates = new PriorityQueue<>(); - gates.addAll(initialGates); - - while(!gates.isEmpty()) { - - // Extract first those gates which can operate - Gate gate = gates.poll(); - gate.setVisited(true); - - // Operate it - WireEdge outputEdge = gate.operate(); - Wire output = outputEdge.wire(); - System.out.println("Wire "+output.getLabel()+ " has value: "+output.getValue().get()); - - // Calculate the next gate that should be added to the queue. - if(!output.isEnd()) { - Gate outputGate = graph.getEdgeTarget(outputEdge); - if(!outputGate.isVisited()) { - gates.add(outputGate); - } - } - - }*/ - - String binaryValue = endWires.stream().sorted().map(Wire::getBinaryValue).collect(Collectors.joining()); - return Long.valueOf(binaryValue, 2); - } - - private Set getAdjacents(Gate gate) { - // TODO cálculo de adyacentes - return new HashSet<>(); - } -} diff --git a/src/main/java/com/adventofcode/flashk/day24/Gate.java b/src/main/java/com/adventofcode/flashk/day24/Gate.java deleted file mode 100644 index 316a22d..0000000 --- a/src/main/java/com/adventofcode/flashk/day24/Gate.java +++ /dev/null @@ -1,69 +0,0 @@ -package com.adventofcode.flashk.day24; - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import org.jetbrains.annotations.NotNull; - -import java.util.UUID; - -@Getter -@Setter -@EqualsAndHashCode -public class Gate implements Comparable { - - private String id = UUID.randomUUID().toString(); - private String operation; - private Wire input1; - private Wire input2; - private Wire output; - private WireEdge outputEdge; - - private boolean visited = false; - - public Gate(String operation, Wire input1, Wire input2, Wire output) { - this.operation = operation; - this.input1 = input1; - this.input2 = input2; - this.output = output; - this.outputEdge = new WireEdge(output); - } - - public boolean canOperate() { - return input1.hasCurrent() && input2.hasCurrent(); - } - - /// Operates the gate using its inputs wires - /// - /// @return the output [Wire]() - /// @throws IllegalStateException if any of the wires has no value present or if the gate operation is unknown. - public WireEdge operate() { - - int value1 = input1.getValue().orElseThrow(IllegalStateException::new); - int value2 = input2.getValue().orElseThrow(IllegalStateException::new); - - switch (operation) { - case "AND" -> output.setValue(value1 & value2); - case "XOR" -> output.setValue(value1 ^ value2); - case "OR" -> output.setValue(value1 | value2); - case null, default -> throw new IllegalStateException("Unknown gate operation: " + operation); - } - - return outputEdge; - } - - - @Override - public int compareTo(@NotNull Gate o) { - if(this.canOperate() && !o.canOperate()) { - return -1; - } - - if(!this.canOperate() && o.canOperate()) { - return 1; - } - - return 0; - } - -} diff --git a/src/main/java/com/adventofcode/flashk/day24/LogicalGate.java b/src/main/java/com/adventofcode/flashk/day24/LogicalGate.java deleted file mode 100644 index 93cf923..0000000 --- a/src/main/java/com/adventofcode/flashk/day24/LogicalGate.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.adventofcode.flashk.day24; - -import java.util.UUID; - -public class LogicalGate { - - private final String id = UUID.randomUUID().toString(); - private final String operation; - - public LogicalGate(String operation) { - this.operation = operation; - } - - public boolean canOperate(Wire input1, Wire input2) { - return input1.getValue().isPresent() && input2.getValue().isPresent(); - } - - /// Operates the gate using its inputs wires - /// - /// @return the output [Wire]() - /// @throws IllegalStateException if any of the wires has no value present or if the gate operation is unknown. - public int operate(Wire input1, Wire input2) { - - int value1 = input1.getValue().orElseThrow(IllegalStateException::new); - int value2 = input2.getValue().orElseThrow(IllegalStateException::new); - - int result; - - switch (operation) { - case "AND" -> result = value1 & value2; - case "XOR" -> result = value1 ^ value2; - case "OR" -> result = value1 | value2; - case null, default -> throw new IllegalStateException("Unknown gate operation: " + operation); - } - - return result; - - } - -} diff --git a/src/main/java/com/adventofcode/flashk/day24/StartGate.java b/src/main/java/com/adventofcode/flashk/day24/StartGate.java deleted file mode 100644 index c93c53f..0000000 --- a/src/main/java/com/adventofcode/flashk/day24/StartGate.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.adventofcode.flashk.day24; - -public class StartGate extends LogicalGate { - - public StartGate(String operation) { - super(operation); - } - - -} diff --git a/src/main/java/com/adventofcode/flashk/day24/Wire.java b/src/main/java/com/adventofcode/flashk/day24/Wire.java deleted file mode 100644 index a53dc17..0000000 --- a/src/main/java/com/adventofcode/flashk/day24/Wire.java +++ /dev/null @@ -1,59 +0,0 @@ -package com.adventofcode.flashk.day24; - - -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.Setter; -import org.jetbrains.annotations.NotNull; - -import java.util.Optional; - -@Getter -@EqualsAndHashCode -public class Wire implements Comparable{ - - private final String label; - - @Setter - private int value; - - public Wire(String label, int value) { - this.label = label; - this.value = value; - } - - public Wire(String label) { - this.label = label; - this.value = -1; - } - - public String getBinaryValue() { - if(value == -1) { - throw new IllegalStateException("Cannot convert to binary a non set value"); - } - return String.valueOf(value); - } - - public Optional getValue() { - if(value == -1) { - return Optional.empty(); - } - return Optional.of(value); - } - - public boolean hasCurrent() { - return value != -1; - } - - public boolean isStart() { - return label.startsWith("x") || label.startsWith("y"); - } - public boolean isEnd() { - return label.startsWith("z"); - } - - @Override - public int compareTo(@NotNull Wire o) { - return -1 * this.label.compareTo(o.label); - } -} diff --git a/src/main/java/com/adventofcode/flashk/day24/WireEdge.java b/src/main/java/com/adventofcode/flashk/day24/WireEdge.java deleted file mode 100644 index 8a9adc0..0000000 --- a/src/main/java/com/adventofcode/flashk/day24/WireEdge.java +++ /dev/null @@ -1,10 +0,0 @@ -package com.adventofcode.flashk.day24; - -import java.util.UUID; - -public record WireEdge(String id, Wire wire) { - - public WireEdge(Wire wire) { - this(UUID.randomUUID().toString(), wire); - } -}