csaboka

NON-TRANSITIVE DICE MEMOIZED 2

Jul 12th, 2017
179
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 7.45 KB | None | 0 0
  1. -- The function get_name() should return a single string that is the name of the puzzle.
  2. --
  3. function get_name()
  4.     return "NON-TRANSITIVE DICE BALANCED"
  5. end
  6.  
  7. -- The function get_description() should return an array of strings, where each string is
  8. -- a line of description for the puzzle. Surrounding text with asterisks will cause it to
  9. -- be rendered in bold, something we use when mentioning a signal by name.
  10. --
  11. -- By using the syntax that we use in our puzzle descriptions, you can also create tables:
  12. --
  13. --       "| This is a table. | This is a second column. | This is a column with "
  14. --       "|                  |                          | multiple line of text."
  15. --       "----------------------------------------------------------------------"
  16. --       "| This is a second |                          | More text here!       "
  17. --       "| table row.       |                          |                       "
  18. --
  19. -- Puzzle descriptions are not automatically paginated, so you can use the string "<PAGE>"
  20. -- to start a new page of text. If you don't it will overflow and make Zach sad.
  21. --
  22. function get_description()
  23.     return {
  24.         "*input* is an XBus input connected to a dice database.",
  25.         "*Radio rx* is a non-blocking XBus input connected to a tester.",
  26.         "*Radio tx* is an XBus output connected to an evaluation device.",
  27.         "Values from *input* and *rx* come in packets of 6 with values in range [1-9], in ascending order.",
  28.         "Compare the values on the sides of the die from *rx* to the *input* die.",
  29.         "If the *rx* die is better, output 1. If *input* die is better, output -1. If both are equal, output 0.",
  30.         "<PAGE>",
  31.         "Sides of one die are compared to each other side of the other. The larger number wins, otherwise it is a tie.",
  32.         "There are 36 direct comparisons. For example, 15 wins, 10 ties and 11 loses; means overall win (15 > 11).",
  33.         "For this puzzle, sums of all die are balanced.",
  34.     }
  35. end
  36.  
  37. -- The function get_board() allows you to specify an 18x7 "ASCII art" grid to customize
  38. -- the layout of the board and the placement of the input and output terminals. Generally
  39. -- speaking, inputs are placed on the left of boards, while outputs are placed on the right.
  40. --
  41. -- For empty space, use the '.' character.
  42. -- For buildable board space, use the '#' character.
  43. -- For an input or output terminal, use characters '0' through '9' no more than once each.
  44. -- For the bottom-left corner of the radio, use the 'R' character.
  45. -- For the bottom-left corners of dials, use characters 'A', 'B', and 'C'.
  46. --
  47. function get_board()
  48.     return [[
  49.         #################0
  50.         ##################
  51.         ##################
  52.         ##################
  53.         ##################
  54.         ##################
  55.         ##################
  56.     ]]
  57. end
  58.  
  59. -- The function get_data() is called both to establish information about the puzzle (such as what
  60. -- the inputs and outputs are) and to generate the random test cases. Signal levels and XBus data
  61. -- should change from call to call, but information like the names and types of terminals should
  62. -- not change at all.
  63. --
  64. -- To create a standard input or output terminal, call create_terminal(). Valid terminal types are
  65. -- TYPE_SIMPLE, TYPE_XBUS, and TYPE_XBUS_NONBLOCKING. Valid terminal directions are DIR_INPUT and
  66. -- DIR_OUTPUT. Valid data for a simple I/O signal is an array of integers, 0 - 100 inclusive. Valid
  67. -- data for an XBus signal is an array of integer arrays, each with values -999 to 999 inclusive.
  68. --
  69. --       create_terminal(name, board_character, type, direction, data)
  70. --
  71. -- To create a radio (C2S-RF901), call create_radio(). You may only create one radio in each puzzle.
  72. -- Since radios are XBus-only, the only valid data for data_rx and data_tx are arrays of integer arrays,
  73. -- each with values -999 to 999 inclusive. You cannot customize the signal names for a radio.
  74. --
  75. -- By default the radio will be placed in the bottom-left corner of the screen. However, if you use an
  76. -- 'R' character in your board layout, the bottom-left corner of the radio will be placed there instead.
  77. --
  78. --       create_radio(data_rx, data_tx)
  79. --
  80. -- To create a dial (N4DL-1000), call create_dial(). You may create up to three dials in each puzzle.
  81. -- The names of dials should be kept short, as there is not much room to display them visually. A valid
  82. -- value is an integer between 0 and 99, inclusive.
  83. --
  84. -- By default dials will be placed in the bottom-left corner of the screen. However, if you use an
  85. -- 'A', 'B', or 'C' character in your board layout, the bottom-left corners of the first, second, and
  86. -- third dials will be placed there, respectively.
  87. --
  88. --       create_dial(name, value)
  89. --
  90. -- NOTE: To generate random values you should use math.random(). However, you SHOULD NOT seed
  91. --       the random number generator with a new seed value, as that is how the game ensures that
  92. --       the first test run is consistent for all users, and thus something that allows for the
  93. --       comparison of cycle scores.
  94. --
  95. -- NOTE: Fun fact! Arrays in Lua are implemented as tables (dictionaries) with integer keys that
  96. --       start at 1 by convention. Contrast this with nearly every other programming language, in
  97. --       which arrays start with an index of 0. Because of this, the 60 "time slices" that make
  98. --       up a test case are indexed from 1 to 60 inclusive.
  99. --
  100.  
  101. function gen_dice(num, iteration)
  102.     local tablu = {}
  103.     local index = 1
  104.    
  105.     if (iteration == 0) then
  106.         if num < 10 then
  107.         return {{num}}
  108.         else
  109.             return {}
  110.         end
  111.     else
  112.         local t = 1
  113.         while (t+iteration <= num) and (not (t == 10)) do
  114.             local rest = gen_dice_memoized(num-t, iteration-1)
  115.             for x = 1, #rest do
  116.                 if t <= rest[x][1] then
  117.                     table.insert(rest[x], 1, t)
  118.                     tablu[index] = rest[x]
  119.                     index = index + 1
  120.                 end
  121.             end
  122.             t = t + 1
  123.         end
  124.     end
  125.  
  126.     return tablu
  127.  
  128. end
  129.  
  130. gen_dice_memo = {}
  131.  
  132. function gen_dice_memoized(num, iteration)
  133.     if gen_dice_memo[num] == nil then
  134.         gen_dice_memo[num] = {}
  135.     end
  136.    
  137.     local result;
  138.    
  139.     if gen_dice_memo[num][iteration] == nil then
  140.         result = gen_dice(num, iteration)
  141.         gen_dice_memo[num][iteration] = result
  142.     else
  143.         result = gen_dice_memo[num][iteration]
  144.     end
  145.    
  146.     -- quick hack to deep-copy the result
  147.     local resultcopy = {}
  148.     for key, value in pairs(result) do
  149.         resultcopy[key] = {table.unpack(result[key])}
  150.     end
  151.     return resultcopy
  152. end
  153.  
  154. function compare(d1, d2)
  155.     win = 0
  156.     loss = 0
  157.     tie = 0
  158.    
  159.     for x = 1, 6 do
  160.         for y = 1, 6 do
  161.             if d1[x] == d2[y] then
  162.                 tie = tie + 1
  163.             elseif d1[x] > d2[y] then
  164.                 win = win + 1
  165.             else
  166.                 loss = loss + 1
  167.             end
  168.         end
  169.     end
  170.    
  171.     if win > loss then
  172.         return "win"
  173.     elseif loss > win then
  174.         return "loss"
  175.     else
  176.         return "tie"
  177.     end
  178. end
  179.  
  180. function get_data()
  181.     a = gen_dice_memoized(18, 5)
  182.     input = {}
  183.     inputD = {}
  184.     output = {}
  185.     time = 1
  186.    
  187.     bias = math.random(0, 10)
  188.     cumulative = math.random(11+bias, 49-bias)
  189.    
  190.     die = gen_dice_memoized(cumulative, 5)
  191.     set = die[math.random(1, #die)]
  192.    
  193.     inputD[time] = set
  194.    
  195.     while time <= 60 do
  196.         time = time + math.random(0, math.random(0, 4))
  197.         newinput = die[math.random(1, #die)]
  198.         input[time] = newinput
  199.        
  200.         result = compare(set, newinput)
  201.         if result == "win" then
  202.             output[time] = {1}
  203.         elseif result == "loss" then
  204.             output[time] = {-1}
  205.         else
  206.             output[time] = {0}
  207.         end
  208.         time = time + 6
  209.     end
  210.  
  211.     create_terminal("Input", "0", TYPE_XBUS, DIR_INPUT, input)
  212.     create_radio(inputD, output)
  213. end
Advertisement
Add Comment
Please, Sign In to add comment