forked from colonelpanic/dotfiles
64 lines
1.5 KiB
Python
64 lines
1.5 KiB
Python
def groupings(numbers):
|
|
if len(numbers) == 0:
|
|
raise StopIteration()
|
|
if len(numbers) == 1:
|
|
yield ((numbers[0],),)
|
|
raise StopIteration()
|
|
this_number = numbers[0]
|
|
this_tuple = (this_number,)
|
|
next_groupings = groupings(numbers[1:])
|
|
for grouping in next_groupings:
|
|
yield (this_tuple,) + grouping
|
|
yield (this_tuple + grouping[0],) + grouping[1:]
|
|
|
|
|
|
def plus_minus_n(numbers, n):
|
|
for grouping in groupings(numbers):
|
|
numbers = map(group_to_int, grouping)
|
|
pms = plus_minuses(len(numbers) - 1)
|
|
for pm in pms:
|
|
result = compute(numbers, pm)
|
|
string = generate_string(numbers, pm)
|
|
if result == n:
|
|
yield string
|
|
|
|
|
|
def generate_string(numbers, pms):
|
|
string = ''
|
|
for number in numbers:
|
|
string += '{0}'.format(number)
|
|
if pms:
|
|
string += '+' if pms[0] is PLUS else '-'
|
|
pms = pms[1:]
|
|
return string
|
|
|
|
|
|
def compute(numbers, plus_minus):
|
|
sum = numbers[0]
|
|
remaining = numbers[1:]
|
|
while remaining:
|
|
if plus_minus[0] == PLUS:
|
|
sum += remaining[0]
|
|
else:
|
|
sum -= remaining[0]
|
|
remaining = remaining[1:]
|
|
plus_minus = plus_minus[1:]
|
|
return sum
|
|
|
|
|
|
def group_to_int(group):
|
|
return int(''.join(map(str, group)))
|
|
|
|
|
|
PLUS = object()
|
|
MINUS = object()
|
|
|
|
|
|
def plus_minuses(n):
|
|
if n == 0:
|
|
yield ()
|
|
raise StopIteration()
|
|
for pm in plus_minuses(n-1):
|
|
yield (PLUS,) + pm
|
|
yield (MINUS,) + pm
|