-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsubsets.rb
More file actions
45 lines (40 loc) · 1.48 KB
/
Copy pathsubsets.rb
File metadata and controls
45 lines (40 loc) · 1.48 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
# returns all possible subsets for the provided items
# e.g. [1, 2, 3] should include all of the following subsets:
# [ [], [1], [1, 2], [1, 3], [1, 2, 3], [2], [2, 3], [3] ]
# duplicates_allowed defines whether there are duplicates allowed in the set
def subsets(items, duplicates_allowed = false)
if duplicates_allowed
items.sort!
end
backtrack([], [], items, 0, duplicates_allowed)
end
def backtrack(result, current, items, start, duplicates_allowed)
result.push(current)
(start...items.size).each do |i|
# if duplicates are allowed, we'll have sorted above in subsets, so we can
# make sure we don't backtrack on the same number (i.e. so sets like [1, 2, 2] dont end up putting 2 copies of [2], [1, 2] and [2, 2] in results)
next if duplicates_allowed and i > start and items[i] == items[i-1]
backtrack(result, current + [items[i]], items, i+1, duplicates_allowed)
end
result
end
def test
test_cases = {
[] => [[]],
[1] => [[], [1]],
[1, 2] => [[], [1], [1, 2], [2]],
[1, 2, 3] => [ [], [1], [1, 2], [1, 2, 3], [1, 3], [2], [2, 3], [3] ],
[1, 2, 2] => [ [], [1], [1, 2], [1, 2, 2], [2], [2, 2] ]
}
test_result = true
test_cases.each do |input, expected_result|
actual_result = subsets(input, true)
unless actual_result == expected_result
puts "Failed test #{input}\n Expected: #{expected_result}\nActual: #{actual_result}"
test_result = false
end
end
return test_result
end
puts "Running test"
puts "Success!" if test