javagony2/turing/Number.java

262 lines
4.5 KiB
Java
Raw Permalink Normal View History

2021-06-03 17:42:43 +00:00
public class Number {
2021-06-03 19:26:22 +00:00
private static class NumberWrapper {
2021-06-03 17:42:43 +00:00
Number n;
}
static class Zero extends Number {
public Zero() {
super(null);
}
@Override
public void executeIfZero(Action action) {
action.execute();
}
@Override
public void executeIfNotZero(Action action) {
}
@Override
public int value() {
return 0;
}
@Override
public void executeIfEquals(Number n, Action a) {
n.executeIfZero(a);
}
2021-06-03 19:26:22 +00:00
@Override
public void executeIfNotEquals(Number n, Action a) {
n.executeIfNotZero(a);
}
2021-06-03 17:42:43 +00:00
}
static class NegativeNumber extends Number {
private Number positive;
public NegativeNumber(Number p) {
super(null);
positive = p;
}
@Override
public Number succ() {
NumberWrapper w = new NumberWrapper();
positive.executeIfZero(() -> {
w.n = zero().succ();
});
positive.executeIfNotZero(() -> {
w.n = new NegativeNumber(positive.pre);
});
return w.n;
}
@Override
public Number pre() {
return new NegativeNumber(positive.succ());
}
@Override
public int value() {
return -positive.value();
}
@Override
public void executeIfNegative(Action a) {
a.execute();
}
@Override
public void executeIfNotNegative(Action a) {
}
@Override
public void executeIfZero(Action a) {
positive.executeIfZero(a);
}
@Override
public void executeIfNotZero(Action a) {
positive.executeIfNotZero(a);
}
@Override
public void executeIfEquals(Number n, Action a) {
n.executeIfNegative(() -> {
positive.executeIfEquals(((NegativeNumber) n).positive, a);
});
}
2021-06-03 19:26:22 +00:00
@Override
public void executeIfNotEquals(Number n, Action a) {
n.executeIfNegative(() -> {
positive.executeIfNotEquals(((NegativeNumber) n).positive, a);
});
n.executeIfNotNegative(() -> {
a.execute();
});
}
2021-06-03 17:42:43 +00:00
@Override
public void forEach(Action a) {
positive.forEach(a);
}
}
private Number pre;
private Number(Number pre) {
this.pre = pre;
}
public static Number zero() {
return new Zero();
}
public Number succ() {
return new Number(this);
}
public void forEach(Action a) {
executeIfNotZero(() -> {
a.execute();
pre.forEach(a);
});
}
public Number add(Number n) {
NumberWrapper w = new NumberWrapper();
w.n = this;
n.executeIfNegative(() -> {
n.forEach(() -> {
w.n = w.n.pre();
});
});
n.executeIfNotNegative(() -> {
n.forEach(() -> {
w.n = w.n.succ();
});
});
return w.n;
}
public Number pre() {
NumberWrapper w = new NumberWrapper();
executeIfZero(() -> {
w.n = new NegativeNumber(succ());
});
executeIfNotZero(() -> {
w.n = pre;
});
return w.n;
}
2021-06-03 19:26:22 +00:00
public static Number max(Number n1, Number n2) {
NumberWrapper w = new NumberWrapper();
n1.executeIfNegative(() -> {
n2.executeIfNegative(() -> {
w.n = Number.max(((NegativeNumber) n2).positive, ((NegativeNumber) n1).positive);
});
n2.executeIfNotNegative(() -> {
w.n = n2;
});
});
n1.executeIfNotNegative(() -> {
n2.executeIfNegative(() -> {
w.n = n1;
});
n2.executeIfNotNegative(() -> {
n1.executeIfZero(() -> {
n2.executeIfZero(() -> {
w.n = zero();
});
n2.executeIfNotZero(() -> {
w.n = n2;
});
});
n1.executeIfNotZero(() -> {
n2.executeIfZero(() -> {
w.n = n1;
});
n2.executeIfNotZero(() -> {
Number tmp = Number.max(n1.pre, n2.pre);
tmp.executeIfEquals(n1.pre, () -> {
w.n = n1;
});
tmp.executeIfEquals(n2.pre, () -> {
w.n = n2;
});
});
});
});
});
return w.n;
}
public static Number min(Number n1, Number n2) {
Number max = max(n1, n2);
NumberWrapper w = new NumberWrapper();
n1.executeIfEquals(max, () -> {
w.n = n2;
});
n2.executeIfEquals(max, () -> {
w.n = n1;
});
return w.n;
}
2021-06-03 17:42:43 +00:00
public void executeIfZero(Action action) {
}
public void executeIfNotZero(Action action) {
action.execute();
}
public int value() {
return this.pre.value() + 1;
}
public void executeIfEquals(Number n, Action a) {
n.executeIfNotNegative(() -> {
n.executeIfNotZero(() -> {
pre.executeIfEquals(n.pre, a);
});
});
}
2021-06-03 19:26:22 +00:00
public void executeIfNotEquals(Number n, Action a) {
n.executeIfNotNegative(() -> {
n.executeIfNotZero(() -> {
pre.executeIfNotEquals(n.pre, a);
});
});
}
2021-06-03 17:42:43 +00:00
public void executeIfNegative(Action a) {
}
public void executeIfNotNegative(Action a) {
a.execute();
}
public String toString() {
return String.valueOf(value());
}
}