From 3dace33759d4cd163dc0d4c167fc1099cdb29a42 Mon Sep 17 00:00:00 2001 From: Peet Date: Tue, 12 May 2026 15:54:36 +0200 Subject: [PATCH] 2024st --- src/j2024/ST/AriadneIterator.java | 153 ++++++++++++++++++++++++++ src/j2024/ST/AriadneIteratorTest.java | 24 ++++ src/j2024/ST/Node.java | 38 +++++++ src/j2024/ST/SampleVillage.java | 19 ++++ 4 files changed, 234 insertions(+) create mode 100644 src/j2024/ST/AriadneIterator.java create mode 100644 src/j2024/ST/AriadneIteratorTest.java create mode 100644 src/j2024/ST/Node.java create mode 100644 src/j2024/ST/SampleVillage.java diff --git a/src/j2024/ST/AriadneIterator.java b/src/j2024/ST/AriadneIterator.java new file mode 100644 index 0000000..997fca1 --- /dev/null +++ b/src/j2024/ST/AriadneIterator.java @@ -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 { + + private final Node entry; + private Stack ariadnesThread; + private Set 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; + } + } +} \ No newline at end of file diff --git a/src/j2024/ST/AriadneIteratorTest.java b/src/j2024/ST/AriadneIteratorTest.java new file mode 100644 index 0000000..9fba7e4 --- /dev/null +++ b/src/j2024/ST/AriadneIteratorTest.java @@ -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()); + } +} \ No newline at end of file diff --git a/src/j2024/ST/Node.java b/src/j2024/ST/Node.java new file mode 100644 index 0000000..b6edd25 --- /dev/null +++ b/src/j2024/ST/Node.java @@ -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 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 getReachable() { + return reachable; + } + + public void addReachable(Node node) { + reachable.add(node); + node.reachable.add(this); + } +} \ No newline at end of file diff --git a/src/j2024/ST/SampleVillage.java b/src/j2024/ST/SampleVillage.java new file mode 100644 index 0000000..eb069bc --- /dev/null +++ b/src/j2024/ST/SampleVillage.java @@ -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; + } +} \ No newline at end of file