Implement normalcdf and pick based on arg[1]
dkl9

dkl9 commited on 2025-177 18:11:59
Showing 1 changed files, with 29 additions and 2 deletions.

... ...
@@ -10,6 +10,17 @@ local function cup(x)
10 10
     end
11 11
 end
12 12
 
13
+local function ztable(x)
14
+    -- Sergei Winitzki's 2003 approximation of erf
15
+    local a = 0.140012
16
+    local function erf(x)
17
+        return math.abs(x) / (x == 0 and 1 or x) *
18
+            math.sqrt(1 - math.exp(-x^2 * (4 / math.pi + a * x^2) / (1 + a * x^2)))
19
+    end
20
+    local rev = erf(x / math.sqrt(2))
21
+    return (rev + 1) / 2
22
+end
23
+
13 24
 local TYPES = {
14 25
     ln = {
15 26
         -- how to generate the problem (returns problem-object)
... ...
@@ -31,10 +42,25 @@ local TYPES = {
31 42
         func = math.sin,
32 43
         score = function(p, g) return -(math.log(math.abs(math.sin(p) - g), 10) + 1.5)^3 end
33 44
     },
45
+    normalcdf = {
46
+        gen = function()
47
+            return 5 * math.random() - 2.5
48
+        end,
49
+        disp = "z = %.2f, percentile",
50
+        func = ztable,
51
+        score = function(p, g) return -(math.log(math.abs(ztable(p) - g), 10) + 1.5)^3 end
52
+    },
34 53
 }
35 54
 
36
-local TYPE = TYPES.sin
55
+local TYPE = TYPES[arg[1]]
56
+if not TYPE then
57
+    if arg[1] then
58
+        io.write(string.format("unknown problem type %s\n", arg[1]))
59
+        os.exit(false)
60
+    else
61
+        TYPE = TYPES.normalcdf
62
+    end
63
+end
37 64
 local TIME = 30
38 65
 
39 66
 local ts = 0
... ...
@@ -45,7 +71,7 @@ while os.time() - st < TIME do
45 71
     local ans = TYPE.func(rp)
46 72
     io.write(string.format(TYPE.disp .. " ? ", cup(rp)))
47 73
     io.flush()
48
-    inp = tonumber(io.read("l")) or 0
74
+    local inp = tonumber(io.read("l")) or 0
49 75
     local sc = TYPE.score(rp, inp)
50 76
     if sc > 0 then
51 77
         io.write(string.format("✓ correct (%.3f)\n", ans))
52 78