Add Knuth's "man or boy" test.
authorCraig Citro <craigcitro@gmail.com>
Thu, 7 Jan 2010 19:15:42 +0000 (11:15 -0800)
committerCraig Citro <craigcitro@gmail.com>
Thu, 7 Jan 2010 19:15:42 +0000 (11:15 -0800)
tests/run/knuth_man_or_boy_test.pyx [new file with mode: 0644]

diff --git a/tests/run/knuth_man_or_boy_test.pyx b/tests/run/knuth_man_or_boy_test.pyx
new file mode 100644 (file)
index 0000000..5f49fe7
--- /dev/null
@@ -0,0 +1,56 @@
+#
+# Cython version of Knuth's "man or boy" test -- "It separates the man
+# Algol 60 compilers from the boy Algol 60 compilers." Here's the
+# original (from wikipedia):
+#
+# begin
+#   real procedure A (k, x1, x2, x3, x4, x5);
+#   value k; integer k;
+#   begin
+#     real procedure B;
+#     begin k:= k - 1;
+#           B:= A := A (k, B, x1, x2, x3, x4);
+#     end;
+#     if k <= 0 then A:= x4 + x5 else B;
+#   end;
+#   outreal (A (10, 1, -1, -1, 1, 0));
+# end;
+#
+# and a table of values:
+#
+#   k           A
+#   0           1
+#   1           0
+#   2          -2
+#   3          0
+#   4          1
+#   5          0
+#   6          1
+#   7          -1
+#   8          -10
+#   9          -30
+#   10         -67
+#
+# Past 10 or so, we blow the C stack -- can't just set a higher recursion limit
+# to get around that one.
+#
+
+def compute(val):
+    if isinstance(val, int):
+        return val
+    else:
+        return val()
+
+def a(in_k, x1, x2, x3, x4, x5):
+    """
+    >>> import sys
+    >>> sys.setrecursionlimit(1350)
+    >>> a(10, 1, -1, -1, 1, 0)
+    -67
+    """
+    k = [in_k]
+    def b():
+        k[0] -= 1
+        return a(k[0], b, x1, x2, x3, x4)
+    return compute(x4) + compute(x5) if k[0] <= 0 else b()