2024st
This commit is contained in:
153
src/j2024/ST/AriadneIterator.java
Normal file
153
src/j2024/ST/AriadneIterator.java
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
package j2024.ST;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.NoSuchElementException;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.Stack;
|
||||||
|
|
||||||
|
public class AriadneIterator implements Iterator<Node> {
|
||||||
|
|
||||||
|
private final Node entry;
|
||||||
|
private Stack<Node> ariadnesThread;
|
||||||
|
private Set<Node> visited;
|
||||||
|
private State currentState;
|
||||||
|
|
||||||
|
public AriadneIterator(Node entry) {
|
||||||
|
this.entry = entry;
|
||||||
|
this.ariadnesThread = new Stack<>();
|
||||||
|
this.visited = new HashSet<>();
|
||||||
|
this.currentState = new Starting();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return currentState.hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Node next() {
|
||||||
|
if (!hasNext()) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
|
||||||
|
step();
|
||||||
|
|
||||||
|
if (ariadnesThread.empty()) {
|
||||||
|
throw new NoSuchElementException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return ariadnesThread.peek();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void step() {
|
||||||
|
currentState.step();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void init() {
|
||||||
|
ariadnesThread.push(entry);
|
||||||
|
visited.add(entry);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean foundMiraculix() {
|
||||||
|
return ariadnesThread.peek().hasMiraculix();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Node nextForward() {
|
||||||
|
Node current = ariadnesThread.peek();
|
||||||
|
|
||||||
|
for (Node next : current.getReachable()) {
|
||||||
|
if (!visited.contains(next)) {
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void seekingStep() {
|
||||||
|
Node next = nextForward();
|
||||||
|
|
||||||
|
if (next != null) {
|
||||||
|
ariadnesThread.push(next);
|
||||||
|
visited.add(next);
|
||||||
|
} else {
|
||||||
|
retreatingStep();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void retreatingStep() {
|
||||||
|
ariadnesThread.pop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private interface State {
|
||||||
|
void step();
|
||||||
|
|
||||||
|
boolean hasNext();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Starting implements State {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void step() {
|
||||||
|
init();
|
||||||
|
|
||||||
|
if (foundMiraculix()) {
|
||||||
|
currentState = new MissionAccomplished();
|
||||||
|
} else {
|
||||||
|
currentState = new SeekingMiraculix();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class SeekingMiraculix implements State {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void step() {
|
||||||
|
seekingStep();
|
||||||
|
|
||||||
|
if (!ariadnesThread.empty() && foundMiraculix()) {
|
||||||
|
currentState = new MissionAccomplished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class MissionAccomplished implements State {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void step() {
|
||||||
|
retreatingStep();
|
||||||
|
|
||||||
|
if (ariadnesThread.size() == 1 && ariadnesThread.peek() == entry) {
|
||||||
|
currentState = new Finished();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return ariadnesThread.size() > 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class Finished implements State {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void step() {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasNext() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
24
src/j2024/ST/AriadneIteratorTest.java
Normal file
24
src/j2024/ST/AriadneIteratorTest.java
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
package j2024.ST;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
public class AriadneIteratorTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testSmallVillage() {
|
||||||
|
Node entry = SampleVillage.createSmallVillage();
|
||||||
|
|
||||||
|
AriadneIterator iter = new AriadneIterator(entry);
|
||||||
|
|
||||||
|
assertEquals(1, iter.next().getNumber());
|
||||||
|
assertEquals(2, iter.next().getNumber());
|
||||||
|
assertEquals(3, iter.next().getNumber());
|
||||||
|
assertEquals(2, iter.next().getNumber());
|
||||||
|
assertEquals(1, iter.next().getNumber());
|
||||||
|
|
||||||
|
assertFalse(iter.hasNext());
|
||||||
|
}
|
||||||
|
}
|
||||||
38
src/j2024/ST/Node.java
Normal file
38
src/j2024/ST/Node.java
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
package j2024.ST;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class Node {
|
||||||
|
|
||||||
|
private final int number;
|
||||||
|
private boolean miraculix;
|
||||||
|
private Set<Node> reachable;
|
||||||
|
|
||||||
|
public Node(int number) {
|
||||||
|
this.number = number;
|
||||||
|
this.miraculix = false;
|
||||||
|
this.reachable = new HashSet<>();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean hasMiraculix() {
|
||||||
|
return miraculix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setMiraculix(boolean miraculix) {
|
||||||
|
this.miraculix = miraculix;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Node> getReachable() {
|
||||||
|
return reachable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addReachable(Node node) {
|
||||||
|
reachable.add(node);
|
||||||
|
node.reachable.add(this);
|
||||||
|
}
|
||||||
|
}
|
||||||
19
src/j2024/ST/SampleVillage.java
Normal file
19
src/j2024/ST/SampleVillage.java
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
package j2024.ST;
|
||||||
|
|
||||||
|
public class SampleVillage {
|
||||||
|
|
||||||
|
public static Node createSmallVillage() {
|
||||||
|
Node n1 = new Node(1);
|
||||||
|
Node n2 = new Node(2);
|
||||||
|
Node n3 = new Node(3);
|
||||||
|
Node n4 = new Node(4);
|
||||||
|
|
||||||
|
n3.setMiraculix(true);
|
||||||
|
|
||||||
|
n1.addReachable(n2);
|
||||||
|
n2.addReachable(n3);
|
||||||
|
n3.addReachable(n4);
|
||||||
|
|
||||||
|
return n1;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user