InTesting

Base System + SciFi Notat

Oct 6th, 2021 (edited)
441
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 4.68 KB | None | 0 0
  1. --Scifi notif in LuaU
  2.  
  3. -- functions
  4. function splitChars(str)
  5.     str = tostring(str)
  6.  
  7.     return str:split''
  8. end
  9.  
  10. function flipTable(t)
  11.     local t2 = {}
  12.  
  13.     for i, v in next, t do
  14.         t2[v] = i
  15.     end
  16.  
  17.     return t2
  18. end
  19.  
  20. function arrayToCharDict(arr)
  21.     local dict = {}
  22.  
  23.     for i, v in next, arr do
  24.         dict[i - 1] = v
  25.     end
  26.  
  27.     return dict
  28. end
  29.  
  30. function stringToCharDict(str)
  31.     return arrayToCharDict(splitChars(str))
  32. end
  33.  
  34. --  base system
  35. function factNumToStrFromBase(charsDict)
  36.     local base = #charsDict + 1
  37.  
  38.     return function(num)
  39.         local res = ''
  40.  
  41.         local iterations = 1 + math.max(0, math.floor( math.log(num, base)))
  42.  
  43.         for i = iterations, 1, -1  do -- going down number places
  44.             local factor = base ^ (i - 1)
  45.  
  46.             local index = base - 1
  47.  
  48.             for largestDigit = base, 0, -1 do -- going down the base to 1
  49.                 local num2 = factor * largestDigit
  50.  
  51.                 if num - num2 < 0 then continue end
  52.  
  53.                 index = largestDigit
  54.                 num -= num2
  55.  
  56.                 break
  57.             end
  58.             res ..= charsDict[index]
  59.         end
  60.  
  61.         return res
  62.     end
  63. end
  64.  
  65. function factStrToNumFromBase(charsDict)
  66.     local base = #charsDict + 1
  67.     local flippedCharacters = flipTable(charsDict)
  68.  
  69.     return function(str)
  70.         assert(type(str) == 'string')
  71.  
  72.         local res = 0
  73.  
  74.         for index = 1, #str do -- iterate each letter
  75.             local letter = str:sub(index, index)
  76.  
  77.             local num = flippedCharacters[letter] * base ^ (#str - index)
  78.  
  79.             res += num
  80.         end
  81.  
  82.         return res
  83.     end
  84. end
  85.  
  86. --  Scifi notif
  87. function getScifiNotatSet(num, customBase)
  88.     customBase = customBase or 10
  89.    
  90.     assert(
  91.         type(num) == 'number' and
  92.         type(customBase) == 'number'
  93.     )
  94.    
  95.     local res = {
  96.         exponent = 0;
  97.         rational = num;
  98.         sign = math.sign(num)
  99.     }
  100.  
  101.     local absNum = math.abs(num)
  102.  
  103.     if absNum ~= 0 then
  104.         -- check out function later
  105.         -- get how many digits - 1 they have
  106.         local logN = math.floor(math.log(absNum, customBase))
  107.  
  108.         res.exponent = logN
  109.  
  110.         local rational = absNum * customBase ^ (-logN)
  111.  
  112.         res.rational = rational
  113.     else
  114.         res.sign = 1
  115.     end
  116.  
  117.     return res
  118. end
  119.  
  120.  
  121. function factNumToSciFiNotif(charsDict)
  122.     local base = #charsDict + 1
  123.  
  124.     local numToStrConvert = factNumToStrFromBase(charsDict)
  125.  
  126.     return function(num)
  127.         assert(type(num) == 'number')
  128.  
  129.         local res = {
  130.             sign = charsDict[0];
  131.             rational = '';
  132.             exponent = charsDict[1]
  133.         }
  134.  
  135.         -- get set
  136.         local scifiNotifSet = getScifiNotatSet(num, base)
  137.        
  138.         -- set results
  139.         res.sign = charsDict[scifiNotifSet.sign == -1 and 0 or 1]
  140.         res.exponent = numToStrConvert(scifiNotifSet.exponent + 150)
  141.        
  142.         -- set rational
  143.         local rationalStr = ''
  144.  
  145.         local rational = scifiNotifSet.rational
  146.        
  147.         local str = tostring(rational):gsub('%.','')
  148.        
  149.         local digit = 0
  150.        
  151.        
  152.         --  repeat until we eventually reach near zero, note, we round instead of checking exactly because
  153.         --    there is uncountably infinite amount of numbers between 0 and 1 and hitting 0 in a sea of
  154.         --    numbers is touch. Also we offset the rational with 1e12 to try to preserve the decimals.
  155.         while math.round(rational * 1e12) ~= 0 do
  156.            
  157.             -- go down the vase
  158.             for index = 0, base do
  159.                 local num1 = index * (base ^ -digit)
  160.                 local num2 = rational - num1
  161.                
  162.                
  163.                 if math.sign(num2) == -1 then
  164.                     rational -= ((index - 1) * (base ^ -digit))
  165.                    
  166.                     rationalStr ..= charsDict[index - 1]
  167.                    
  168.                     break
  169.                 end
  170.             end
  171.            
  172.             digit += 1
  173.         end
  174.        
  175.         res.rational = rationalStr
  176.        
  177.         -- return
  178.         return res
  179.     end
  180. end
  181.  
  182. function factSciFiNotifToNum(charsDict)
  183.     local base = #charsDict + 1
  184.  
  185.     local strToNumBaseConvert = factStrToNumFromBase(charsDict)
  186.     local flippedDict = flipTable(charsDict)
  187.  
  188.     return function(scifiNotif)
  189.         assert(
  190.             type(scifiNotif) == 'table' and
  191.                 type(scifiNotif.exponent) == 'string' and
  192.                 type(scifiNotif.rational) == 'string' and
  193.                 type(scifiNotif.sign) == 'string'
  194.         )
  195.  
  196.         local res = 0
  197.  
  198.         -- exponent and sign
  199.         local exponent = strToNumBaseConvert(scifiNotif.exponent) - 150
  200.         local sign = flippedDict[scifiNotif.sign] == 0 and -1 or 1
  201.  
  202.         -- give the int and mantissa their own section
  203.         local rationalStr = scifiNotif.rational
  204.         local intStr = rationalStr:sub(1,1)
  205.         local mantissaStr = rationalStr:sub(2)
  206.  
  207.         local number = 0
  208.  
  209.         for exponentB = 0, #rationalStr - 1 do
  210.             local charIndex = exponentB + 1
  211.  
  212.             local char = rationalStr:sub(charIndex, charIndex)
  213.  
  214.             number += flippedDict[char] * (base ^ -exponentB)
  215.         end
  216.  
  217.         -- construct result
  218.         res = sign * (number * (base ^ exponent))
  219.  
  220.         return res
  221.     end
  222. end
  223.  
  224.  
  225. local dict = stringToCharDict'zxcvbnm,./asdfghjkl;qwertyuiop[]1234567890-=ZXCVBNM<>?ASDFGHJKL:"QWERTYUIOP{}|!@#$%^&*()_+'
  226.  
  227. local n = -1
  228. local n2 = factNumToSciFiNotif(dict)(n)
  229. print(n, n2, factSciFiNotifToNum(dict)(n2))
  230.  
Add Comment
Please, Sign In to add comment