Drools で再帰を試したくてハノイの塔(Tower of Hanoi)を書いてみた。思ったよりだいぶスッキリと書ける。
package com.sample
import com.sample.HanoiTest.Tower;
import com.sample.HanoiTest.Action;
rule "move one disk"
when
a: Action($height: height,
$from: fromTower, $to: toTower,
height==1)
then
$from.moveOneDisk($to);
end
rule "move disks"
when
a: Action($height: height,
$from: fromTower, $to: toTower, $other: otherTower,
height>1)
then
insert(new Action($height - 1, $other, $to, $from));
insert(new Action(1, $from, $to, $other));
insert(new Action($height - 1, $from, $other, $to));
retract(a);
end
package com.sample;
import 略
public class HanoiTest {
public static final void main(String[] args) throws Exception {
KnowledgeBase kbase = readKnowledgeBase();
StatefulKnowledgeSession ksession = kbase.newStatefulKnowledgeSession();
final Tower t1 = new Tower(1, "A", "B", "C", "D");
final Tower t2 = new Tower(2);
final Tower t3 = new Tower(3);
ksession.insert(t1);
ksession.insert(t2);
ksession.insert(t3);
ksession.insert(new Action(4, t1, t3, t2));
ksession.addEventListener(new DefaultAgendaEventListener() {
public void afterActivationFired(AfterActivationFiredEvent event) {
String ruleName = event.getActivation().getRule().getName();
if ("move one disk".equals(ruleName)) {
System.out.printf("%-15s%-15s%-15s%n", t1, t2, t3);
}
}
});
System.out.printf("%-15s%-15s%-15s%n", t1, t2, t3);
ksession.fireAllRules();
}
private static KnowledgeBase readKnowledgeBase() ・・・ 略
public static class Tower {
private final int number;
private final Stack<String> disks = new Stack<String>();
public Tower(int number, String...disks) {
this.number = number;
this.disks.addAll(Arrays.asList(disks));
}
public int getNumber() {
return number;
}
public String toString() {
return String.format("塔%d%s", number, disks.toString());
}
public void moveOneDisk(Tower to) {
to.disks.push(disks.pop());
}
}
public static class Action {
private int height;
private Tower fromTower;
private Tower toTower;
private Tower otherTower;
コンストラクタとgetter/setter 略
}
}
予定通りの出力になる。
塔1[A, B, C, D] 塔2[] 塔3[]
塔1[A, B, C] 塔2[D] 塔3[]
塔1[A, B] 塔2[D] 塔3[C]
塔1[A, B] 塔2[] 塔3[C, D]
塔1[A] 塔2[B] 塔3[C, D]
塔1[A, D] 塔2[B] 塔3[C]
塔1[A, D] 塔2[B, C] 塔3[]
塔1[A] 塔2[B, C, D] 塔3[]
塔1[] 塔2[B, C, D] 塔3[A]
塔1[] 塔2[B, C] 塔3[A, D]
塔1[C] 塔2[B] 塔3[A, D]
塔1[C, D] 塔2[B] 塔3[A]
塔1[C, D] 塔2[] 塔3[A, B]
塔1[C] 塔2[D] 塔3[A, B]
塔1[] 塔2[D] 塔3[A, B, C]
塔1[] 塔2[] 塔3[A, B, C, D]
0 件のコメント:
コメントを投稿