local function identity(x) return x end local TYPES = { ln = { -- inputs to the operation argc = 1, -- bounds on inputs min = {0.01}, max = {1000}, -- how to present the problem (for string.format) disp = "ln(%.2f)", -- transform input to output func = math.log, -- check guess g to canonical answer c good = function(c, g) return math.abs(c - g) < 0.05 end, -- transform range [0, 1) to a good distribution bias = function(r) return r^2 end, }, } -- ideally, configure these parameters with options/inputs local COUNT = 10 local TYPE = TYPES.ln local TRIES = 1 local TIME = 3 local sc = 0 local oc = 0 for i = 1,COUNT do local rarg = {} for j = 1,TYPE.argc do table.insert(rarg, TYPE.min[j] + (TYPE.max[j] - TYPE.min[j]) * (TYPE.bias or identity)(math.random())) end local ans = TYPE.func(table.unpack(rarg)) io.write(string.format(TYPE.disp .. " ? ", table.unpack(rarg))) io.flush() local st = os.time() local inp local fails = 0 while os.time() - st < TIME do inp = tonumber(io.read("l")) or 0 if os.time() - st > TIME then if TYPE.good(ans, inp) then oc = oc + 1 end io.write(string.format("too slow! (%.2f)\n", ans)) elseif TYPE.good(ans, inp) then io.write("✓ correct\n") sc = sc + 1 break elseif fails < TRIES then io.write("wrong, try again ") io.flush() fails = fails + 1 else io.write(string.format("wrong (%.2f)\n", ans)) break end end end io.write(string.format("%d/%d correct, of which %d were too slow\n", (sc + oc), COUNT, oc))