Advertisement
Guest User

Untitled

a guest
Jul 29th, 2016
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.12 KB | None | 0 0
  1. _input = {
  2. ["Item1"] = {
  3. min = 1,
  4. max = 1,
  5. pos = {
  6. [1] = nil,
  7. [2] = {--[[somedata]]},
  8. [3] = nil,
  9. [4] = {--[[somedata]]},
  10. [5] = nil,
  11. [6] = {--[[somedata]]},
  12. [7] = nil,
  13. [8] = {--[[somedata]]},
  14. },
  15. },
  16. ["Item2"] = {
  17. min = 1,
  18. max = 1,
  19. pos = {
  20. [1] = nil,
  21. [2] = nil,
  22. [3] = nil,
  23. [4] = {--[[somedata]]},
  24. [5] = {--[[somedata]]},
  25. [6] = {--[[somedata]]},
  26. [7] = nil,
  27. [8] = nil,
  28. },
  29. },
  30. ["Item3"] = {
  31. min = 1,
  32. max = 2,
  33. pos = {
  34. [1] = nil,
  35. [2] = {--[[somedata]]},
  36. [3] = nil,
  37. [4] = {--[[somedata]]},
  38. [5] = {--[[somedata]]},
  39. [6] = {--[[somedata]]},
  40. [7] = nil,
  41. [8] = nil,
  42. },
  43. },
  44. ["Item4"] = {
  45. min = 1,
  46. max = 3,
  47. pos = {
  48. [1] = {--[[somedata]]},
  49. [2] = {--[[somedata]]},
  50. [3] = {--[[somedata]]},
  51. [4] = nil,
  52. [5] = nil,
  53. [6] = nil,
  54. [7] = {--[[somedata]]},
  55. [8] = {--[[somedata]]},
  56. },
  57. },
  58. }
  59.  
  60. _output = {
  61. [1] = {
  62. type = "Item4",
  63. data = {--[[the data from _input["Item4"].pos[1] ]]},
  64. },
  65. [2] = {
  66. type = "Item1",
  67. data = {--[[the data from _input["Item1"].pos[2] ]]},
  68. },
  69. [3] = {
  70. type = "Item4",
  71. data = {--[[the data from _input["Item4"].pos[3] ]]},
  72. },
  73. [4] = {
  74. type = "Item3",
  75. data = {--[[the data from _input["Item3"].pos[4] ]]},
  76. },
  77. [5] = nil,
  78. [6] = {
  79. type = "Item2",
  80. data = {--[[the data from _input["Item2"].pos[6] ]]},
  81. },
  82. [7] = {
  83. type = "Item4",
  84. data = {--[[the data from _input["Item4"].pos[7] ]]},
  85. },
  86. [8] = nil,
  87. }
  88.  
  89. local _output = {
  90. [1] = nil,
  91. [2] = nil,
  92. [3] = nil,
  93. [4] = nil,
  94. [5] = nil,
  95. [6] = nil,
  96. [7] = nil,
  97. [8] = nil,
  98. }
  99. for key in pairs(_input) do
  100. local _item = _input[key]
  101.  
  102. for i=0,math.random(_item.min, _item.max),1 do
  103. -- I omit deepCopy() for readability
  104. local _possibleCopy = deepCopy(_item.pos)
  105.  
  106. for i=1,8,1 do
  107. if _output[i] ~= nil then
  108. _possibleCopy[i] = nil
  109. end
  110. end
  111.  
  112. local _possibleSlots = {}
  113.  
  114. for i=1,8,1 do
  115. if _possibleCopy[i] ~= nil then
  116. _possibleSlots[#_possibleSlots+1] = i
  117. end
  118. end
  119.  
  120. local _slot = _possibleSlots[math.random(1,#_possibleSlots)]
  121.  
  122. if _slot then
  123. _output[_slot] = {
  124. type = key,
  125. data = _item.pos[_slot],
  126. }
  127. end
  128. end
  129. end
  130.  
  131. math.randomseed(os.time())
  132.  
  133. local _input = {
  134. ["Item1"] = {
  135. min = 1,
  136. max = 1,
  137. pos = {
  138. [1] = nil,
  139. [2] = {--[[somedata]]},
  140. [3] = nil,
  141. [4] = {--[[somedata]]},
  142. [5] = nil,
  143. [6] = {--[[somedata]]},
  144. [7] = nil,
  145. [8] = {--[[somedata]]},
  146. },
  147. },
  148. ["Item2"] = {
  149. min = 1,
  150. max = 1,
  151. pos = {
  152. [1] = nil,
  153. [2] = nil,
  154. [3] = nil,
  155. [4] = {--[[somedata]]},
  156. [5] = {--[[somedata]]},
  157. [6] = {--[[somedata]]},
  158. [7] = nil,
  159. [8] = nil,
  160. },
  161. },
  162. ["Item3"] = {
  163. min = 1,
  164. max = 2,
  165. pos = {
  166. [1] = nil,
  167. [2] = {--[[somedata]]},
  168. [3] = nil,
  169. [4] = {--[[somedata]]},
  170. [5] = {--[[somedata]]},
  171. [6] = {--[[somedata]]},
  172. [7] = nil,
  173. [8] = nil,
  174. },
  175. },
  176. ["Item4"] = {
  177. min = 1,
  178. max = 3,
  179. pos = {
  180. [1] = {--[[somedata]]},
  181. [2] = {--[[somedata]]},
  182. [3] = {--[[somedata]]},
  183. [4] = nil,
  184. [5] = nil,
  185. [6] = nil,
  186. [7] = {--[[somedata]]},
  187. [8] = {--[[somedata]]},
  188. },
  189. },
  190. }
  191.  
  192. local function deepCopy(tbl)
  193. -- insert your implementation here
  194. end
  195.  
  196. local input_keys = {} -- [input_key_idx] = input_key
  197. local available = {} -- [input_key_idx][1..8] = true/false
  198. local avail_counters = {} -- [input_key_idx][n] = count of available data items from 1 to n-1
  199. local min, max = {}, {} -- [input_key_idx] = min, max
  200. local spent_data_items = {} -- [input_key_idx] = number of data items included in _output
  201. local selected_data_items = {} -- [1..8] = input_key_idx/0
  202. local cache = {}
  203. local _output
  204.  
  205. for k, v in pairs(_input) do
  206. table.insert(input_keys, k)
  207. local pos_avail = {}
  208. local avail_ctrs = {}
  209. local ctr = 0
  210. for i = 1, 8 do
  211. pos_avail[i] = not not v.pos[i]
  212. avail_ctrs[i] = ctr
  213. ctr = ctr + (pos_avail[i] and 1 or 0)
  214. end
  215. available[#input_keys] = pos_avail
  216. avail_counters[#input_keys] = avail_ctrs
  217. spent_data_items[#input_keys] = 0
  218. min[#input_keys] = v.min
  219. max[#input_keys] = v.max
  220. assert(ctr >= v.min and v.min <= v.max, "Solution does not exist")
  221. end
  222.  
  223. local function enum_solutions(solution_no, n)
  224. -- returns the quantity of good selections
  225. n, solution_no = n or 8, solution_no or -1
  226. local cache_idx = n..";"..table.concat(spent_data_items, ";")
  227. local result = cache[cache_idx]
  228. if not result or solution_no >= 0 and solution_no < result then
  229. if n == 0 then
  230. -- found good selection (that satisfies the rules) in selected_data_items[1..8]
  231. if solution_no == 0 then
  232. _output = {}
  233. for n = 1, 8 do
  234. local key = input_keys[selected_data_items[n]]
  235. if key then
  236. _output[n] = {type = key, data = deepCopy(_input[key].pos[n])}
  237. end
  238. end
  239. end
  240. result = 1
  241. else
  242. local must_be_selected = {}
  243. for input_key_idx = 1, #input_keys do
  244. if available[input_key_idx][n] and avail_counters[input_key_idx][n] + spent_data_items[input_key_idx] < min[input_key_idx] then
  245. table.insert(must_be_selected, input_key_idx)
  246. end
  247. end
  248. if #must_be_selected == 1 then
  249. local input_key_idx = must_be_selected[1]
  250. local spent = spent_data_items[input_key_idx]
  251. spent_data_items[input_key_idx] = spent + 1
  252. selected_data_items[n] = input_key_idx
  253. result = enum_solutions(solution_no, n-1)
  254. spent_data_items[input_key_idx] = spent
  255. elseif #must_be_selected == 0 then
  256. -- selecting nil for position n
  257. selected_data_items[n] = 0
  258. result = enum_solutions(solution_no, n-1)
  259. solution_no = solution_no - result
  260. for input_key_idx = 1, #input_keys do
  261. if available[input_key_idx][n] then
  262. local spent = spent_data_items[input_key_idx]
  263. if spent < max[input_key_idx] then
  264. -- selecting _input[input_keys[input_key_idx]].pos[n] for position n
  265. spent_data_items[input_key_idx] = spent + 1
  266. selected_data_items[n] = input_key_idx
  267. local delta_result = enum_solutions(solution_no, n-1)
  268. result = result + delta_result
  269. solution_no = solution_no - delta_result
  270. spent_data_items[input_key_idx] = spent
  271. end
  272. end
  273. end
  274. else
  275. result = 0
  276. end
  277. end
  278. cache[cache_idx] = result
  279. end
  280. return result
  281. end
  282.  
  283. local number_of_solutions = enum_solutions()
  284. assert(number_of_solutions > 0, "Solution does not exist")
  285. print("There are "..number_of_solutions.." solutions exist")
  286. -- generate 5 random solutions
  287. for _ = 1, 5 do
  288. local k = math.random(number_of_solutions)
  289. print("Solution #"..k)
  290. enum_solutions(k-1)
  291. -- now _output is initialized with k-th variant of solution
  292. for i = 1, 8 do
  293. local v = _output[i]
  294. if v then
  295. print(i, v.type, v.data)
  296. else
  297. print(i, "-")
  298. end
  299. end
  300. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement