| 1234567891011121314151617181920212223242526272829303132333435363738 |
- #!/usr/bin/env python3
- import sys
- from functools import cache
- def place_iter(size, record):
- groupend = record.find('.', 1) + 1
- if groupend != len(record):
- group = record[:groupend]
- for rem in place(size, group):
- yield rem + record[groupend:]
- if '#' not in group:
- yield from place(size, record[groupend - 1:])
- else:
- for start in range(1, len(record) - size):
- end = start + size
- if record[start - 1] != '#' and record[end] != '#' and \
- all(record[i] != '.' for i in range(start, end)):
- yield '.' + record[min(end + 1, len(record) - 1):]
- if record[start] == '#':
- break
- @cache
- def place(size, record):
- return tuple(place_iter(size, record))
- @cache
- def arrangements(record, sizes):
- if not sizes:
- return int('#' not in record)
- return sum(arrangements(r, sizes[1:]) for r in place(sizes[0], record))
- def normalize(record):
- return '.' + '.'.join(record.replace('.', ' ').split()) + '.'
- records = [(record, tuple(map(int, numbers.split(','))))
- for record, numbers in map(str.split, sys.stdin)]
- print(sum(arrangements(normalize(r), d) for r, d in records))
- print(sum(arrangements(normalize('?'.join([r] * 5)), d * 5) for r, d in records))
|