generated from Flashky/advent-of-code-yyyy
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
342 additions
and
0 deletions.
There are no files selected for viewing
154 changes: 154 additions & 0 deletions
154
src/main/java/com/adventofcode/flashk/day24/CrossedWires.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<LogicalGate,WireEdge> graph = new DirectedMultigraph<>(WireEdge.class); | ||
|
||
Map<String, Wire> wires = new HashMap<>(); | ||
private final List<LogicalGate> gates = new ArrayList<>(); | ||
|
||
// Attributes that help start and end the algorithm | ||
private final List<LogicalGate> initialGates = new ArrayList<>(); | ||
private final List<Wire> endWires = new ArrayList<>(); | ||
|
||
public CrossedWires(List<String> inputs) { | ||
|
||
// Maps a wire with the gate that generates it. | ||
Map<Wire,LogicalGate> 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<Wire,LogicalGate> 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<Gate> 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<Gate> getAdjacents(Gate gate) { | ||
// TODO cálculo de adyacentes | ||
return new HashSet<>(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Gate> { | ||
|
||
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; | ||
} | ||
|
||
} |
40 changes: 40 additions & 0 deletions
40
src/main/java/com/adventofcode/flashk/day24/LogicalGate.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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; | ||
|
||
} | ||
|
||
} |
10 changes: 10 additions & 0 deletions
10
src/main/java/com/adventofcode/flashk/day24/StartGate.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
package com.adventofcode.flashk.day24; | ||
|
||
public class StartGate extends LogicalGate { | ||
|
||
public StartGate(String operation) { | ||
super(operation); | ||
} | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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<Wire>{ | ||
|
||
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<Integer> 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); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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); | ||
} | ||
} |