Day 9: Movie Theater

Megathread guidelines

  • Keep top level comments as only solutions, if you want to say something other than a solution put it in a new post. (replies to comments can be whatever)
  • You can send code in code blocks by using three backticks, the code, and then three backticks or use something such as https://topaz.github.io/paste/ if you prefer sending it through a URL

FAQ

  • Avicenna@programming.dev
    link
    fedilink
    arrow-up
    3
    arrow-down
    1
    ·
    edit-2
    21 hours ago

    Yes I used a polygon library so what… I did eyeball the shape and guessed what the result should have been like but still more pleasing to write something that applies generally. Although I did put an area threshold (eyeballed) which subsets the corners to test, it only reduces run time to about 1/2 (from ~10s to ~5s) so that is not necessarily very critical. If I hadn’t used this library, I would probably do sth along the lines of defining my own rectangle classes with unions, intersections etc so wouldn’t be a more clever approach but much more time consuming.

    from pathlib import Path
    
    import numpy as np
    import shapely
    
    cwd = Path(__file__).parent
    
    def parse_input(file_path):
      with file_path.open("r") as fp:
        data = list(map(lambda x: list(map(int,x.split(','))), fp.readlines()))
    
      return np.array(data)
    
    
    def construct_shapes(coordinates, threshold):
    
      Itriu = np.triu_indices(coordinates.shape[0], k=2)
      squares = []
    
      for i0,i1 in zip(*Itriu):
    
        c0 = tuple(coordinates[i0,:])
        c1 = tuple(coordinates[i1,:])
        area = np.prod(abs(np.array(c0) - np.array(c1)) + np.array([1,1]))
    
        if area>threshold:
          c2 = (c0[0],c1[1])
          c3 = (c1[0],c0[1])
          squares.append(shapely.Polygon((c0,c3,c1,c2)))
    
      polygon = shapely.Polygon(coordinates)
    
      return polygon, squares
    
    
    def solve_problem(file_name, redgreen=False, threshold=0):
    
      coordinates = parse_input(Path(cwd, file_name))
    
      if not redgreen:
        areas = np.prod(abs(coordinates[None,:] - coordinates[:,None]) +\
                        np.array([1,1])[None,None,:], axis=-1)
        max_area = np.max(areas)
    
      else:
        polygon, squares = construct_shapes(coordinates, threshold)
        max_area = -np.inf
    
        for inds,square in enumerate(squares):
          if square.area==0:
            continue
    
          if polygon.contains(square):
            c = np.array(list(zip(*square.exterior.coords.xy)))
            if (a:=np.prod(abs(c[0] - c[2]) + np.array([1,1])))>max_area:
              max_area = a
    
      return int(max_area)
    
    
    
    if __name__ == "__main__":
    
      assert solve_problem("test_input") == 50
      assert solve_problem("input") == 4763509452
      assert solve_problem("test_input", True, 1) == 24
      assert solve_problem("input", True, 15000*80000) == 1516897893 # threshold by eyeballing the shape
    
    • CameronDev@programming.devOPM
      link
      fedilink
      arrow-up
      4
      ·
      19 hours ago

      Even with using geo in rust, i am still struggling, so no shame in using the library. I did get the solve in 2m32s, but I dont feel like this is optimal.

      Surely there is a better solution somewhere.