Guest User

Cubically Interpreter

a guest
Aug 1st, 2017
27
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 6.19 KB | None | 0 0
  1. -- Cube
  2. local Cube = {}
  3. function Cube.new()
  4.   local faces = {}
  5.   for i = 0, 5 do
  6.     faces[i] = {}
  7.     for n = 0, 8 do
  8.       faces[i][n] = i
  9.     end
  10.   end
  11.  
  12.   return setmetatable({
  13.     faces = faces
  14.   }, {
  15.     __index = Cube,
  16.     __tostring = Cube.tostring
  17.   })
  18. end
  19.  
  20. function Cube:R(n)
  21.   n = n % 3
  22.  
  23.   local t = 0
  24.   local f = self.faces
  25.   for _ = 1, n do
  26.     for i = 2, 8, 3 do
  27.       t = f[0][i]
  28.       f[0][i] = f[2][i]
  29.       f[2][i] = f[5][10 - i]
  30.       f[5][10 - i] = f[4][10 - i - 2]
  31.       f[4][10 - i - 2] = t
  32.     end
  33.   end
  34.  
  35.   -- Rotate face 3 CW
  36.   f = f[3]
  37.   t = f[0]
  38.   f[0] = f[6]
  39.   f[6] = f[8]
  40.   f[8] = f[2]
  41.   f[2] = t
  42.   t = f[1]
  43.   f[1] = f[3]
  44.   f[3] = f[7]
  45.   f[7] = f[5]
  46.   f[5] = t
  47. end
  48.  
  49. function Cube:L(n)
  50.   n = n % 3
  51.  
  52.   local t = 0
  53.   local f = self.faces
  54.   for _ = 1, n do
  55.     for i = 0, 6, 3 do
  56.       t = f[0][i]
  57.       f[0][i] = f[4][6 - i + 2]
  58.       f[4][6 - i + 2] = f[5][6 - i]
  59.       f[5][6 - i] = f[2][i]
  60.       f[2][i] = t
  61.     end
  62.   end
  63.  
  64.   -- Rotate face 1 CW
  65.   f = f[1]
  66.   t = f[0]
  67.   f[0] = f[6]
  68.   f[6] = f[8]
  69.   f[8] = f[2]
  70.   f[2] = t
  71.   t = f[1]
  72.   f[1] = f[3]
  73.   f[3] = f[7]
  74.   f[7] = f[5]
  75.   f[5] = t
  76. end
  77.  
  78. function Cube:U(n)
  79.   n = n % 3
  80.  
  81.   local t = 0
  82.   local f = self.faces
  83.   for _ = 1, n do
  84.     for i = 0, 2 do
  85.       t = f[1][i]
  86.       f[1][i] = f[2][i]
  87.       f[2][i] = f[3][i]
  88.       f[3][i] = f[4][i]
  89.       f[4][i] = t
  90.     end
  91.   end
  92.  
  93.   -- Rotate face 1 CW
  94.   f = f[0]
  95.   t = f[0]
  96.   f[0] = f[6]
  97.   f[6] = f[8]
  98.   f[8] = f[2]
  99.   f[2] = t
  100.   t = f[1]
  101.   f[1] = f[3]
  102.   f[3] = f[7]
  103.   f[7] = f[5]
  104.   f[5] = t
  105. end
  106.  
  107. function Cube:D(n)
  108.   n = n % 3
  109.  
  110.   local t = 0
  111.   local f = self.faces
  112.   for _ = 1, n do
  113.     for i = 6, 8 do
  114.       t = f[4][i]
  115.       f[4][i] = f[3][i]
  116.       f[3][i] = f[2][i]
  117.       f[2][i] = f[1][i]
  118.       f[1][i] = t
  119.     end
  120.   end
  121.  
  122.   -- Rotate face 1 CW
  123.   f = f[5]
  124.   t = f[0]
  125.   f[0] = f[6]
  126.   f[6] = f[8]
  127.   f[8] = f[2]
  128.   f[2] = t
  129.   t = f[1]
  130.   f[1] = f[3]
  131.   f[3] = f[7]
  132.   f[7] = f[5]
  133.   f[5] = t
  134. end
  135.  
  136. function Cube:F(n)
  137.   n = n % 3
  138.  
  139.   local t = 0
  140.   local f = self.faces
  141.   for _ = 1, n do
  142.     for i = 0, 2 do
  143.       t = f[0][6 + i]
  144.       f[0][6 + i] = f[1][6 - 3 * i + 2]
  145.       f[1][6 - 3 * i + 2] = f[5][8 - i]
  146.       f[5][8 - i] = f[3][3 * i]
  147.       f[3][3 * i] = t
  148.     end
  149.   end
  150.  
  151.   -- Rotate face 2 CW
  152.   f = f[2]
  153.   t = f[0]
  154.   f[0] = f[6]
  155.   f[6] = f[8]
  156.   f[8] = f[2]
  157.   f[2] = t
  158.   t = f[1]
  159.   f[1] = f[3]
  160.   f[3] = f[7]
  161.   f[7] = f[5]
  162.   f[5] = t
  163. end
  164.  
  165. function Cube:B(n)
  166.   n = n % 3
  167.  
  168.   local t = 0
  169.   local f = self.faces
  170.   for _ = 1, n do
  171.     for i = 0, 2 do
  172.       t = f[0][i]
  173.       f[0][i] = f[3][3 * i + 2]
  174.       f[3][3 * i + 2] = f[5][2 - i]
  175.       f[5][2 - i] = f[1][6 - 3 * i]
  176.       f[1][6 - 3 * i] = t
  177.     end
  178.   end
  179.  
  180.   -- Rotate face 4 CW
  181.   f = f[4]
  182.   t = f[0]
  183.   f[0] = f[6]
  184.   f[6] = f[8]
  185.   f[8] = f[2]
  186.   f[2] = t
  187.   t = f[1]
  188.   f[1] = f[3]
  189.   f[3] = f[7]
  190.   f[7] = f[5]
  191.   f[5] = t
  192. end
  193.  
  194. function Cube:value(n)
  195.   if n < 0 or n > 5 or n % 1 ~= 0 then
  196.     return 0
  197.   end
  198.  
  199.   local sum = 0
  200.   for i = 0, 8 do
  201.     sum = sum + self.faces[n][i]
  202.   end
  203.   return sum
  204. end
  205.  
  206. function Cube:tostring()
  207.   local s = ""
  208.   for y = 0, 2 do
  209.     s = s .. "   "
  210.     for x = 0, 2 do
  211.       s = s .. self.faces[0][y * 3 + x]
  212.     end
  213.     s = s .. "\n"
  214.   end
  215.  
  216.   for y = 0, 2 do
  217.     for i = 1, 4 do
  218.       for x = 0, 2 do
  219.         s = s .. self.faces[i][y * 3 + x]
  220.       end
  221.     end
  222.     s = s .. "\n"
  223.   end
  224.  
  225.   for y = 2, 0, -1 do
  226.     s = s .. "   "
  227.     for x = 0, 2 do
  228.       s = s .. self.faces[5][y * 3 + x]
  229.     end
  230.     s = s .. "\n"
  231.   end
  232.  
  233.   return s:sub(1, #s - 1)
  234. end
  235.  
  236. -- Interpreter
  237.  
  238. local C = {}
  239. setmetatable(C, {__call = C.new})
  240.  
  241. function C.new()
  242.   return setmetatable({
  243.     instance = true,
  244.     cube = Cube.new(),
  245.     notepad = 0,
  246.     input = 0,
  247.     command = nil
  248.   }, {__index = C})
  249. end
  250.  
  251. function C:exec(program)
  252.   assert(self.instance, "Must be an instance, call new() first")
  253.   assert(type(program) == "string", "program must be a string")
  254.  
  255.   self.program = program
  256.   for i = 1, #self.program do
  257.     local c = self.program:sub(i, i)
  258.     local n = tonumber(c)
  259.    
  260.     if n then
  261.       if not self.command then
  262.         print(self.cube:tostring())
  263.         return
  264.       end
  265.      
  266.       if self.command then
  267.         self:command(n)
  268.       end
  269.     else
  270.       self.command = self.commands[c]
  271.     end
  272.   end
  273. end
  274.  
  275. function C:value(n)
  276.   if n % 1 ~= 0 then
  277.     return 0
  278.   end
  279.  
  280.   if n >= 0 and n <= 5 then
  281.     return self.cube:value(n)
  282.   elseif n == 6 then
  283.     return self.notepad
  284.   elseif n == 7 then
  285.     return self.input
  286.   else
  287.     return 0
  288.   end
  289. end
  290.  
  291. C.commands = {
  292.   ['R'] = function(self, n)
  293.     self.cube.R(n)
  294.   end,
  295.   ['L'] = function(self, n)
  296.     self.cube.L(n)
  297.   end,
  298.   ['U'] = function(self, n)
  299.     self.cube.U(n)
  300.   end,
  301.   ['D'] = function(self, n)
  302.     self.cube.D(n)
  303.   end,
  304.   ['F'] = function(self, n)
  305.     self.cube.F(n)
  306.   end,
  307.   ['B'] = function(self, n)
  308.     self.cube.B(n)
  309.   end,
  310.  
  311.   ['&'] = function(self, n)
  312.     self.program = ""
  313.   end,
  314.   ['+'] = function(self, n)
  315.     self.notepad = self.notepad + self:value(n)
  316.   end,
  317.   ['-'] = function(self, n)
  318.     self.notepad = self.notepad - self:value(n)
  319.   end,
  320.   ['*'] = function(self, n)
  321.     self.notepad = self.notepad * self:value(n)
  322.   end,
  323.   ['/'] = function(self, n)
  324.     self.notepad = self.notepad / self:value(n)
  325.   end,
  326.   ['^'] = function(self, n)
  327.     self.notepad = self.notepad ^ self:value(n)
  328.   end,
  329.   ['='] = function(self, n)
  330.     self.notepad = (self.notepad == self:value(n)) and 1 or 0
  331.   end,
  332.   [':'] = function(self, n)
  333.     self.notepad = self:value(n)
  334.   end,
  335.  
  336.   ['@'] = function(self, n)
  337.     io.write(string.char(self:value(n) % 256))
  338.   end,
  339.   ['%'] = function(self, n)
  340.     io.write(self:value(n))
  341.   end,
  342.   ['$'] = function(self, n)
  343.     local inp = io.read("*n")
  344.     self.input = inp or self.input
  345.   end,
  346.   ['~'] = function(self, n)
  347.     local inp = io.read(1)
  348.     self.input = inp and string.byte(inp) or -1
  349.   end
  350. }
  351.  
  352. local cubically = C.new()
  353. cubically:exec(select(1, ...))
  354.  
  355. print()
  356. print("============")
  357. print("Final state:")
  358. print(cubically.cube:tostring())
  359. print("Notepad: " .. cubically.notepad)
  360. print("Input: " .. cubically.input)
Advertisement
Add Comment
Please, Sign In to add comment