Advertisement
Guest User

Untitled

a guest
Dec 5th, 2021
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.88 KB | None | 0 0
  1. import argparse
  2. import re
  3. from collections import defaultdict
  4. from typing import List, NamedTuple
  5.  
  6.  
  7. VENT_PATTERNS = r'([0-9]+),([0-9]+) -> ([0-9]+),([0-9]+)'
  8.  
  9.  
  10. class Coordinate(NamedTuple):
  11.     x: int
  12.     y: int
  13.  
  14.  
  15. class Line(NamedTuple):
  16.     source: Coordinate
  17.     destination: Coordinate
  18.  
  19.  
  20. def determine_overlapping_count(lines: List[Line]) -> int:
  21.     """
  22.        --> x
  23.        .......1.. |
  24.        ..1....1.. |
  25.        ..1....1.. V
  26.        .......1.. y
  27.        .112111211
  28.        ..........
  29.        ..........
  30.        ..........
  31.        ..........
  32.        222111....
  33.    """
  34.     count = 0
  35.     points = defaultdict(lambda: 0)
  36.     for line in lines:
  37.         if line.source.x == line.destination.x or line.source.y == line.destination.y:
  38.             #
  39.             # Draw horizontal and vertical lines
  40.             #
  41.             horizontal = line.source.x == line.destination.x
  42.             if line.source.x == line.destination.x:
  43.                 a, b = sorted([line.source.y, line.destination.y])
  44.             elif line.source.y == line.destination.y:
  45.                 a, b = sorted([line.source.x, line.destination.x])
  46.  
  47.             for i in range(a, b+1):
  48.                 if horizontal:
  49.                     pos = Coordinate(x=line.source.x, y=i)
  50.                 else:
  51.                     pos = Coordinate(x=i, y=line.source.y)
  52.  
  53.                 points[pos] += 1
  54.                 if points[pos] == 2:
  55.                     count += 1
  56.         else:
  57.             #
  58.             # Draw diagonal lines
  59.             #
  60.             diff = abs(line.source.x - line.destination.x)
  61.             for i in range(diff+1):
  62.                 x = line.source.x
  63.                 y = line.source.y
  64.                 x += (i) if line.source.x < line.destination.x else -(i)
  65.                 y += (i) if line.source.y < line.destination.y else -(i)
  66.                 pos = Coordinate(x=x, y=y)
  67.  
  68.                 points[pos] += 1
  69.                 if points[pos] == 2:
  70.                     count += 1
  71.  
  72.     return count
  73.  
  74.  
  75. if __name__ == '__main__':
  76.     parser = argparse.ArgumentParser('AoC')
  77.     parser.add_argument('-t', '--test', help="Run sample input and verify answers", action="store_true")
  78.     args = parser.parse_args()
  79.  
  80.     lines = []
  81.     with open('test.txt' if not args.test else 'sample.txt') as f:
  82.         for data in f.readlines():
  83.             match = re.match(VENT_PATTERNS, data.strip())
  84.             lines.append(
  85.                 Line(
  86.                     source=Coordinate(
  87.                         x=int(match.group(1)),
  88.                         y=int(match.group(2))
  89.                     ),
  90.                     destination=Coordinate(
  91.                         x=int(match.group(3)),
  92.                         y=int(match.group(4))
  93.                     )
  94.                 )
  95.             )
  96.  
  97.     points = determine_overlapping_count(lines)
  98.     print(f'Overlapping point count: {len(points)}')
  99.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement