from itertools import combinations
def simple_zero_sum_subset(arr):
values = set(arr)
return 0 in values or any(i for i in values if -i in values)
def brute_force_zero_sum_subset(arr):
return any(sum(combo) == 0 for r in xrange(1, len(arr)+1) for combo in combinations(arr, r))
# --- TESTING --- #
simple_tests = {
False: [
[1, 2, 3],
[-5, -3, -1, 2, 4, 6],
[],
],
True: [
[-1, 1],
[-97364, -71561, -69336, 19675, 71561, 97863],
[-53974, -39140, -36561, -23935, -15680, 0],
]
}
assert all(simple_zero_sum_subset(arr) == expected
for expected, arrs in simple_tests.items()
for arr in arrs)
print 'Simple tests passed.'
bonus_tests = {
False: [
[-83314, -82838, -80120, -63468, -62478, -59378, -56958, -50061, -34791, -32264, -21928, -14988, 23767, 24417, 26403, 26511, 36399, 78055],
[-92953, -91613, -89733, -50673, -16067, -9172, 8852, 30883, 46690, 46968, 56772, 58703, 59150, 78476, 84413, 90106, 94777, 95148],
[-94624, -86776, -85833, -80822, -71902, -54562, -38638, -26483, -20207, -1290, 12414, 12627, 19509, 30894, 32505, 46825, 50321, 69294],
[-83964, -81834, -78386, -70497, -69357, -61867, -49127, -47916, -38361, -35772, -29803, -15343, 6918, 19662, 44614, 66049, 93789, 95405],
[-68808, -58968, -45958, -36013, -32810, -28726, -13488, 3986, 26342, 29245, 30686, 47966, 58352, 68610, 74533, 77939, 80520, 87195],
],
True: [
[-97162, -95761, -94672, -87254, -57207, -22163, -20207, -1753, 11646, 13652, 14572, 30580, 52502, 64282, 74896, 83730, 89889, 92200],
[-93976, -93807, -64604, -59939, -44394, -36454, -34635, -16483, 267, 3245, 8031, 10622, 44815, 46829, 61689, 65756, 69220, 70121],
[-92474, -61685, -55348, -42019, -35902, -7815, -5579, 4490, 14778, 19399, 34202, 46624, 55800, 57719, 60260, 71511, 75665, 82754],
[-85029, -84549, -82646, -80493, -73373, -57478, -56711, -42456, -38923, -29277, -3685, -3164, 26863, 29890, 37187, 46607, 69300, 84808],
[-87565, -71009, -49312, -47554, -27197, 905, 2839, 8657, 14622, 32217, 35567, 38470, 46885, 59236, 64704, 82944, 86902, 90487],
],
}
assert all(brute_force_zero_sum_subset(arr) == expected
for expected, arrs in bonus_tests.items()
for arr in arrs)
print 'Bonus tests passed.'
ZnJvbSBpdGVydG9vbHMgaW1wb3J0IGNvbWJpbmF0aW9ucwoKZGVmIHNpbXBsZV96ZXJvX3N1bV9zdWJzZXQoYXJyKToKICAgIHZhbHVlcyA9IHNldChhcnIpCiAgICByZXR1cm4gMCBpbiB2YWx1ZXMgb3IgYW55KGkgZm9yIGkgaW4gdmFsdWVzIGlmIC1pIGluIHZhbHVlcykKCmRlZiBicnV0ZV9mb3JjZV96ZXJvX3N1bV9zdWJzZXQoYXJyKToKICAgIHJldHVybiBhbnkoc3VtKGNvbWJvKSA9PSAwIGZvciByIGluIHhyYW5nZSgxLCBsZW4oYXJyKSsxKSBmb3IgY29tYm8gaW4gY29tYmluYXRpb25zKGFyciwgcikpCgojIC0tLSBURVNUSU5HIC0tLSAjCgpzaW1wbGVfdGVzdHMgPSB7CiAgICBGYWxzZTogWwogICAgICAgIFsxLCAyLCAzXSwKICAgICAgICBbLTUsIC0zLCAtMSwgMiwgNCwgNl0sCiAgICAgICAgW10sCiAgICBdLAogICAgVHJ1ZTogWwogICAgICAgIFstMSwgMV0sCiAgICAgICAgWy05NzM2NCwgLTcxNTYxLCAtNjkzMzYsIDE5Njc1LCA3MTU2MSwgOTc4NjNdLAogICAgICAgIFstNTM5NzQsIC0zOTE0MCwgLTM2NTYxLCAtMjM5MzUsIC0xNTY4MCwgMF0sCiAgICBdCn0KCmFzc2VydCBhbGwoc2ltcGxlX3plcm9fc3VtX3N1YnNldChhcnIpID09IGV4cGVjdGVkCiAgICAgICAgICAgZm9yIGV4cGVjdGVkLCBhcnJzIGluIHNpbXBsZV90ZXN0cy5pdGVtcygpCiAgICAgICAgICAgZm9yIGFyciBpbiBhcnJzKQpwcmludCAnU2ltcGxlIHRlc3RzIHBhc3NlZC4nCgpib251c190ZXN0cyA9IHsKICAgIEZhbHNlOiBbCiAgICAgICAgWy04MzMxNCwgLTgyODM4LCAtODAxMjAsIC02MzQ2OCwgLTYyNDc4LCAtNTkzNzgsIC01Njk1OCwgLTUwMDYxLCAtMzQ3OTEsIC0zMjI2NCwgLTIxOTI4LCAtMTQ5ODgsIDIzNzY3LCAyNDQxNywgMjY0MDMsIDI2NTExLCAzNjM5OSwgNzgwNTVdLAogICAgICAgIFstOTI5NTMsIC05MTYxMywgLTg5NzMzLCAtNTA2NzMsIC0xNjA2NywgLTkxNzIsIDg4NTIsIDMwODgzLCA0NjY5MCwgNDY5NjgsIDU2NzcyLCA1ODcwMywgNTkxNTAsIDc4NDc2LCA4NDQxMywgOTAxMDYsIDk0Nzc3LCA5NTE0OF0sCiAgICAgICAgWy05NDYyNCwgLTg2Nzc2LCAtODU4MzMsIC04MDgyMiwgLTcxOTAyLCAtNTQ1NjIsIC0zODYzOCwgLTI2NDgzLCAtMjAyMDcsIC0xMjkwLCAxMjQxNCwgMTI2MjcsIDE5NTA5LCAzMDg5NCwgMzI1MDUsIDQ2ODI1LCA1MDMyMSwgNjkyOTRdLAogICAgICAgIFstODM5NjQsIC04MTgzNCwgLTc4Mzg2LCAtNzA0OTcsIC02OTM1NywgLTYxODY3LCAtNDkxMjcsIC00NzkxNiwgLTM4MzYxLCAtMzU3NzIsIC0yOTgwMywgLTE1MzQzLCA2OTE4LCAxOTY2MiwgNDQ2MTQsIDY2MDQ5LCA5Mzc4OSwgOTU0MDVdLAogICAgICAgIFstNjg4MDgsIC01ODk2OCwgLTQ1OTU4LCAtMzYwMTMsIC0zMjgxMCwgLTI4NzI2LCAtMTM0ODgsIDM5ODYsIDI2MzQyLCAyOTI0NSwgMzA2ODYsIDQ3OTY2LCA1ODM1MiwgNjg2MTAsIDc0NTMzLCA3NzkzOSwgODA1MjAsIDg3MTk1XSwKICAgIF0sCiAgICBUcnVlOiBbCiAgICAgICAgWy05NzE2MiwgLTk1NzYxLCAtOTQ2NzIsIC04NzI1NCwgLTU3MjA3LCAtMjIxNjMsIC0yMDIwNywgLTE3NTMsIDExNjQ2LCAxMzY1MiwgMTQ1NzIsIDMwNTgwLCA1MjUwMiwgNjQyODIsIDc0ODk2LCA4MzczMCwgODk4ODksIDkyMjAwXSwKICAgICAgICBbLTkzOTc2LCAtOTM4MDcsIC02NDYwNCwgLTU5OTM5LCAtNDQzOTQsIC0zNjQ1NCwgLTM0NjM1LCAtMTY0ODMsIDI2NywgMzI0NSwgODAzMSwgMTA2MjIsIDQ0ODE1LCA0NjgyOSwgNjE2ODksIDY1NzU2LCA2OTIyMCwgNzAxMjFdLAogICAgICAgIFstOTI0NzQsIC02MTY4NSwgLTU1MzQ4LCAtNDIwMTksIC0zNTkwMiwgLTc4MTUsIC01NTc5LCA0NDkwLCAxNDc3OCwgMTkzOTksIDM0MjAyLCA0NjYyNCwgNTU4MDAsIDU3NzE5LCA2MDI2MCwgNzE1MTEsIDc1NjY1LCA4Mjc1NF0sCiAgICAgICAgWy04NTAyOSwgLTg0NTQ5LCAtODI2NDYsIC04MDQ5MywgLTczMzczLCAtNTc0NzgsIC01NjcxMSwgLTQyNDU2LCAtMzg5MjMsIC0yOTI3NywgLTM2ODUsIC0zMTY0LCAyNjg2MywgMjk4OTAsIDM3MTg3LCA0NjYwNywgNjkzMDAsIDg0ODA4XSwKICAgICAgICBbLTg3NTY1LCAtNzEwMDksIC00OTMxMiwgLTQ3NTU0LCAtMjcxOTcsIDkwNSwgMjgzOSwgODY1NywgMTQ2MjIsIDMyMjE3LCAzNTU2NywgMzg0NzAsIDQ2ODg1LCA1OTIzNiwgNjQ3MDQsIDgyOTQ0LCA4NjkwMiwgOTA0ODddLAogICAgXSwKfQoKYXNzZXJ0IGFsbChicnV0ZV9mb3JjZV96ZXJvX3N1bV9zdWJzZXQoYXJyKSA9PSBleHBlY3RlZAogICAgICAgICAgIGZvciBleHBlY3RlZCwgYXJycyBpbiBib251c190ZXN0cy5pdGVtcygpCiAgICAgICAgICAgZm9yIGFyciBpbiBhcnJzKQpwcmludCAnQm9udXMgdGVzdHMgcGFzc2VkLic=