{"id":7806,"date":"2023-05-15T11:07:15","date_gmt":"2023-05-15T10:07:15","guid":{"rendered":"https:\/\/solidt.eu\/site\/?p=7806"},"modified":"2025-03-31T10:51:58","modified_gmt":"2025-03-31T09:51:58","slug":"lua-cartesian-product","status":"publish","type":"post","link":"https:\/\/solidt.eu\/site\/lua-cartesian-product\/","title":{"rendered":"Lua Cartesian Product"},"content":{"rendered":"\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"lua\" data-theme=\"monokai\" data-fontsize=\"14\" data-lines=\"Infinity\" data-showlines=\"true\" data-copy=\"false\">function dump(o)\n    if type(o) == 'table' then\n        local s = '{ '\n        for k, v in pairs(o) do\n            if type(k) ~= 'number' then k = '\"' .. k .. '\"' end\n            s = s .. '[' .. k .. ']=' .. dump(v) .. ', '\n        end\n        return s .. '} '\n    else\n        return tostring(o)\n    end\nend\n\nfunction cartesian(arrays)\n    local insert, unpack = table.insert, table.unpack\n    local wrap, yield = coroutine.wrap, coroutine.yield\n    return wrap(function()\n        local function _cartesian(arrs, current, result)\n            if current > #arrs then\n                yield(result)\n            else\n                for _, value in ipairs(arrs[current]) do\n                    local new_result = {}\n                    for _, v in ipairs(result) do\n                        insert(new_result, v)\n                    end\n                    insert(new_result, value)\n                    _cartesian(arrs, current + 1, new_result)\n                end\n            end\n        end\n        _cartesian(arrays, 1, {})\n    end)\nend\n\nlocal arrs = {\n    {'A', 'B', 'C', 'D', 'E', 'F'},\n    {1, 2, 3, 4, 5,6,7,8,9, 10, 11, 12, 13,14,15},\n    {'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'VIIII' }\n}\n\n\nlocal start = os.clock();\nlocal count = 0\nfor a in cartesian(arrs) do\n    count = count + 1\n    if (count % 50 == 0) then\n        print(dump(a))\n    end\nend\nlocal elapsed = os.clock() - start\nprint(\"elapsed:\", elapsed, count)\n\n<\/pre><\/div>\n\n\n\n<p>Another version<\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"lua\" data-theme=\"monokai\" data-fontsize=\"14\" data-lines=\"Infinity\" data-showlines=\"true\" data-copy=\"false\">local function cartesian_product(sets)\n  local result = {}\n  local set_count = #sets\n  local yield = coroutine.yield \n  function descend(depth)\n    if depth == set_count then\n      for k,v in pairs(sets[depth]) do\n        result[depth] = v\n        yield(result)\n      end\n    else\n      for k,v in pairs(sets[depth]) do\n        result[depth] = v\n        descend(depth + 1)\n      end\n    end\n  end\n  return coroutine.wrap(function() descend(1) end)\nend<\/pre><\/div>\n\n\n\n<p>Test code<\/p>\n\n\n\n<div style=\"height: 250px; position:relative; margin-bottom: 50px;\" class=\"wp-block-simple-code-block-ace\"><pre class=\"wp-block-simple-code-block-ace\" style=\"position:absolute;top:0;right:0;bottom:0;left:0\" data-mode=\"lua\" data-theme=\"monokai\" data-fontsize=\"14\" data-lines=\"Infinity\" data-showlines=\"true\" data-copy=\"false\">function dump(o)\n    if type(o) == 'table' then\n        local s = '{ '\n        for k, v in pairs(o) do\n            if type(k) ~= 'number' then k = '\"' .. k .. '\"' end\n            s = s .. '[' .. k .. ']=' .. dump(v) .. ', '\n        end\n        return s .. '} '\n    else\n        return tostring(o)\n    end\nend\n\nfunction cartesian(arrays)\n    local insert, unpack = table.insert, table.unpack\n    local wrap, yield = coroutine.wrap, coroutine.yield\n    return wrap(function()\n        local function _cartesian(arrs, current, result)\n            if current > #arrs then\n                yield(result)\n            else\n                for _, value in ipairs(arrs[current]) do\n                    local new_result = {}\n                    for _, v in ipairs(result) do\n                        insert(new_result, v)\n                    end\n                    insert(new_result, value)\n                    _cartesian(arrs, current + 1, new_result)\n                end\n            end\n        end\n        _cartesian(arrays, 1, {})\n    end)\nend\n\nlocal arrs = {\n    {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J'},\n    {1, 2, 3, 4, 5,6,7,8, 9, 10, 11, 12, 13,14,15,16,17,18,19,20,21,22,23,24},\n    {'I', 'II', 'III', 'IV', 'V', 'VI', 'VII', 'VIII', 'VIIII', 'X' }\n}\n\nlocal function method1() \n    local start = os.clock();\n    local count = 0\n    for a in cartesian(arrs) do\n        count = count + 1\n        if (count % 50 == 0) then\n            print(dump(a))\n        end\n    end\n    local elapsed = os.clock() - start\n    print(\"elapsed:\", elapsed, count)\nend\n\n\nlocal function cartesian_product(sets)\n    local result = {}\n    local set_count = #sets\n    local yield = coroutine.yield \n    function descend(depth)\n      if depth == set_count then\n        for k,v in pairs(sets[depth]) do\n          result[depth] = v\n          yield(result)\n        end\n      else\n        for k,v in pairs(sets[depth]) do\n          result[depth] = v\n          descend(depth + 1)\n        end\n      end\n    end\n    return coroutine.wrap(function() descend(1) end)\n  end\n\nlocal function method2() \n    local start = os.clock();\n    local count = 0\n    for a in cartesian(arrs) do\n        count = count + 1\n        if (count % 50 == 0) then\n            print(dump(a))\n        end\n    end\n    local elapsed = os.clock() - start\n    print(\"elapsed:\", elapsed, count)\nend\n\nmethod1()\nmethod2()<\/pre><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Another version Test code<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-7806","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/7806","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/comments?post=7806"}],"version-history":[{"count":3,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/7806\/revisions"}],"predecessor-version":[{"id":7811,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/posts\/7806\/revisions\/7811"}],"wp:attachment":[{"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/media?parent=7806"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/categories?post=7806"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/solidt.eu\/site\/wp-json\/wp\/v2\/tags?post=7806"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}