solution.py 2.4 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. #!/usr/bin/python3
  2. import sys
  3. import re
  4. def part1():
  5. print('part 1')
  6. split = ''.join(sys.stdin.readlines()).split('\n\n')
  7. #seeds = [int(n) for n in re.findall(r'\d+', split[0])]
  8. ranges = [int(n) for n in re.findall(r'\d+', split[0])]
  9. seeds = []
  10. for i in range(0, len(ranges), 2):
  11. for n in range(ranges[i], ranges[i] + ranges[i + 1]):
  12. seeds.append(n)
  13. maps = [m.split('\n') for m in split[1:]]
  14. print(seeds, maps)
  15. for m in maps:
  16. source, sink = m[0].rstrip(' map:').split('-to-')
  17. print(source, sink, seeds)
  18. for i, seed in enumerate(seeds):
  19. for line in m[1:]:
  20. sink_start, source_start, upto = [int(n) for n in line.split(' ')]
  21. #print(sink_start, source_start, upto)
  22. if seed >= source_start and seed < source_start + upto:
  23. #print(f'src {seed} ({i}) in {source_start} {source_start + upto} maps to {sink_start + seed - source_start}')
  24. seeds[i] = sink_start + seed - source_start
  25. print(seeds)
  26. print(min(seeds))
  27. def find_overlap(r1, r2):
  28. start = max(r1[0], r2[0])
  29. end = min(r1[1], r2[1])
  30. return (start, end) if start <= end else None
  31. def shift_range(r, delta):
  32. return (r[0] + delta, r[1] + delta)
  33. def split_range(r, overlap):
  34. result = set()
  35. if r[0] < overlap[0]:
  36. result.add((r[0], overlap[0] - 1))
  37. if r[1] > overlap[1]:
  38. result.add((overlap[1] + 1, r[1]))
  39. return result
  40. def part2():
  41. print('part 2')
  42. split = ''.join(sys.stdin.readlines()).split('\n\n')
  43. seeds = [int(n) for n in re.findall(r'\d+', split[0])]
  44. ranges = set([(seeds[i], seeds[i] + seeds[i + 1] - 1) for i in range(0, len(seeds), 2)])
  45. maps = [m.split('\n') for m in split[1:]]
  46. print(ranges)
  47. for m in maps:
  48. new_ranges = set()
  49. for line in m[1:]:
  50. for r in ranges.copy():
  51. start_sink, start_source, upto = [int(n) for n in line.split(' ')]
  52. range_source = (start_source, start_source + upto - 1)
  53. overlap = find_overlap(r, range_source)
  54. if overlap:
  55. ranges.remove(r)
  56. ranges |= split_range(r, overlap)
  57. new_ranges.add(shift_range(overlap, start_sink - start_source))
  58. ranges |= new_ranges
  59. print(ranges)
  60. print(min(min(ranges)))
  61. if sys.argv[1] in '1':
  62. part1()
  63. else:
  64. part2()