-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathitertools.lua
More file actions
139 lines (114 loc) · 3.77 KB
/
itertools.lua
File metadata and controls
139 lines (114 loc) · 3.77 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
local itertools = {}
-- Chaining iterators for unordered key-value tables (pairs)
function itertools.chain(...)
local iterators = { ... }
local i = 1
local current_iter, current_table, current_key = pairs(iterators[i] or {})
return function()
while i <= #iterators do
local new_key, new_value = current_iter(current_table, current_key)
if new_key ~= nil then
current_key = new_key
return new_key, new_value
end
-- Move to the next iterator when the current one is exhausted
i = i + 1
if i <= #iterators then
current_iter, current_table, current_key = pairs(iterators[i] or {})
end
end
end
end
-- Chaining iterators for ordered arrays (ipairs)
function itertools.ichain(...)
local iterators = { ... }
local i = 1
local current_iter, current_table, current_index = ipairs(iterators[i] or {})
return function()
while i <= #iterators do
local new_index, new_value = current_iter(current_table, current_index)
if new_index ~= nil then
current_index = new_index
return new_index, new_value
end
-- Move to the next iterator when the current one is exhausted
i = i + 1
if i <= #iterators then
current_iter, current_table, current_index = ipairs(iterators[i] or {})
end
end
end
end
function itertools.product(arrays, current, results, index)
-- Example usage:
-- local p = itertools.product({{1, 2}, {"a", "b"}})
current = current or {}
results = results or {}
index = index or 1
if index > #arrays then
table.insert(results, {table.unpack(current)})
return results
end
for _, value in ipairs(arrays[index]) do
current[index] = value
itertools.product(arrays, current, results, index + 1)
end
return results
end
function itertools.permutations(arr, length, current, used, results)
-- Example usage:
-- local perm = itertools.permutations({1, 2, 3}, 2)
length = length or #arr
current = current or {}
used = used or {}
results = results or {}
if #current == length then
table.insert(results, {table.unpack(current)})
return results
end
for i, value in ipairs(arr) do
if not used[i] then
used[i] = true
table.insert(current, value)
itertools.permutations(arr, length, current, used, results)
table.remove(current)
used[i] = false
end
end
return results
end
function itertools.combinations(arr, length, start, current, results)
-- Example usage:
-- local comb = itertools.combinations({1, 2, 3}, 2)
start = start or 1
current = current or {}
results = results or {}
if #current == length then
table.insert(results, {table.unpack(current)})
return results
end
for i = start, #arr do
table.insert(current, arr[i])
itertools.combinations(arr, length, i + 1, current, results)
table.remove(current)
end
return results
end
function itertools.combinations_with_replacement(arr, length, start, current, results)
-- Example usage:
-- local comb_wr = itertools.combinations_with_replacement({1, 2, 3}, 2)
start = start or 1
current = current or {}
results = results or {}
if #current == length then
table.insert(results, {table.unpack(current)})
return results
end
for i = start, #arr do
table.insert(current, arr[i])
itertools.combinations_with_replacement(arr, length, i, current, results)
table.remove(current)
end
return results
end
return itertools