Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --Take in a num
- --and find an equation that approximately matches it
- t1 = os.time()
- math.randomseed(os.time()/100) -- This ensures that the random vals tested are different on each execution.
- num = math.exp(math.pi) -- The target number to approximate
- -- 325,841,868 == Current US Population
- -- 299792 == Speed of Light (m/s)
- -- 3.28084 == Feet in a metre
- -- 9.80665 == g
- -- 31557600 == Seconds in a year
- max = 1000 -- The biggest number tested
- opnum = 2 -- Approximately the number of operations used
- -- Number of possibilties with 2 operations and a max of 100 = 10^8
- it = 5000000 -- Number of random combinations tested
- --it = false -- If this line, then it will iterate through ALL possible candidates
- -- instead of just a sample of random ones.
- function round(x) -- For use with the Lucas Numbers function later
- if x-math.floor(x) < 0.5 then return math.floor(x)
- else return math.ceil(x) end
- end
- -- So, ah, lets make an array of all the possible functions
- add = function (a) -- This is a different way of defining a function, which I also use for the loadstring() later.
- return "+"..test_vals[a]
- end
- sub = function (a)
- return "-"..test_vals[a]
- end
- mul = function (a)
- return "*"..test_vals[a]
- end
- div = function (a)
- return "/"..test_vals[a]
- end
- exx = function (a)
- return "^"..test_vals[a]
- end
- mod = function (a) -- Not really used, since it's kind of a niche function
- return "%"..test_vals[a]
- end
- lg = function (a) -- This one & all after have to act different
- local f = math.random(#char_ops)
- return char_ops[f].."math.log("..test_vals[a]..")"
- --This makes (SOME NORMAL OPERATION)math.log(a) as a string
- --So that I can concat this into a string to be executed
- end
- squirt = function (a)
- local f = math.random(#char_ops)
- return char_ops[f].."math.sqrt("..test_vals[a]..")"
- end
- lucas = function (a,b) -- Lucas Number generator. Easier to use than fibonacci
- if b then
- local f = math.random(#char_ops)
- return char_ops[f].."lucas("..test_vals[a]..")" -- What in self-referenciation
- end
- local phi = 1.618033981
- return round(phi^a) -- See? No need for a For Loop to get the answer, just a singular exp you ceil or floor
- end
- fact = function (a,b)
- if b then
- local f = math.random(#char_ops)
- return char_ops[f].."fact("..test_vals[a]..")" -- What in self-referenciation
- end
- if not fct then fct = {1,2,6,24,120,720,5040,40320,363880,3638800,39916800,479001600,6227020800} end
- if fct[a] then return fct[a]
- else
- ans = fct[13]
- for y=13,a do
- ans = ans * y
- end
- fct[a] = ans
- return ans
- end
- end
- zeta = function(a,b) -- Avast, it's the Riemann Zeta function!
- if b then
- local f = math.random(#char_ops)
- return char_ops[f].."zeta("..test_vals[a]..")" -- What in self-referenciation
- end
- return 1/(a-1) -- Given that input are positive real numbers
- end
- shine = function(a)
- local f = math.random(#char_ops)
- return char_ops[f].."math.sin("..test_vals[a]..")"
- end
- caus = function(a)
- local f = math.random(#char_ops)
- return char_ops[f].."math.cos("..test_vals[a]..")"
- end
- than = function(a)
- local f = math.random(#char_ops)
- return char_ops[f].."math.tanh("..test_vals[a]..")"
- end
- sigmoid = function(a)
- local f = math.random(#char_ops)
- return char_ops[f].."1/(1+math.exp(-"..test_vals[a].."))"
- -- This guy is special, since I don't have it call itself
- -- Instead it just sends what to evaluate to the compiled string
- end
- char_ops = {"+","-","*","/","^"} -- All the operations that are simply one symbol, for use with the weirder functions
- ops = {add,sub,mul,div,exx,lg,fact,lucas,squirt,zeta,sigmoid,than,caus,shine} -- All the operations that are used by the program to make the approximate
- p = (#char_ops*(#ops-#char_ops+1))^opnum*max^(opnum+1)
- if it > p then it = p end
- best = 7
- test_vals,test_ops = {},{}
- --[[if ops[1] == function (a,b) return a+b end then print("Yes!") end]]--
- -- Doesn't work because they have different function IDs or something.
- n = 1
- for i=1,it do
- for j=1,opnum+1 do -- Make the test constants
- test_vals[j] = math.random(max) -- Some number between 1 and max
- end
- --print(test_vals[1])
- for j=1,opnum do -- Make the test operators
- a = math.random(#ops) -- The use of #ops allows for an increasable number of supported operations
- test_ops[j] = ops[a]
- end
- -- Now to actually calculate the test value
- -- So we assemble a string of this stuff and then execute it using loadstring()
- -- Why? Because writing the functions and their order of operations myself would have been painful
- -- So why not just have lua do that shit for me?
- local s = math.random(2)
- local test_str = "return "..test_vals[1]
- for j=1,opnum do
- test_str = test_str .. test_ops[j](j+1,1)
- end
- local test = loadstring(test_str)() -- Loadstring actually returns an unnamed function consisting of test_str.
- -- This then sets the value for test, to be tested below
- if math.abs(test-num) < math.abs(best-num) and test-num ~= 0 then
- best = test
- best_str = test_str
- end
- if i/it*100 >= n then
- io.write(n .. "%...\n")
- n = n + 1
- if math.abs(best-num)/num*100 < 0.000001 then break end -- Checks if perfect answer has been found
- end
- -- I wish I knew how to quit you, Lua.
- end
- --All possible combinations with the current set-up, given the number of possible numbers used and the number of operations around them
- print("All possible combinations from current settings: ",p)
- if not it then print("All combinations tested: ",counter) end
- io.write("This took ",os.difftime(os.time(),t1)," seconds!\n")
- print("Attempted Value:",num)
- print("Best result: ",best)
- io.write("This one had an inaccuracy of ",math.abs((best-num)/num)*100,"%!\n")
- if best_str then io.write(string.sub(best_str,8),"\n") end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement