Day 8: Resonant Collinearity

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

  • janAkali
    link
    fedilink
    English
    arrow-up
    1
    ·
    edit-2
    4 days ago

    Nim

    Overall really simple puzzle, but description is so confusing, that I mostly solved it based on example diagrams.
    Edit: much shorter and faster one-pass solution. Runtime: 132 us

    type Vec2 = tuple[x,y: int]
    func delta(a, b: Vec2): Vec2 = (a.x-b.x, a.y-b.y)
    func outOfBounds[T: openarray | string](pos: Vec2, grid: seq[T]): bool =
      pos.x < 0 or pos.y < 0 or pos.x > grid[0].high or pos.y > grid.high
    
    proc solve(input: string): AOCSolution[int, int] =
      var grid = input.splitLines()
      var antennas: Table[char, seq[Vec2]]
    
      for y, line in grid:
        for x, c in line:
          if c != '.':
            discard antennas.hasKeyOrPut(c, newSeq[Vec2]())
            antennas[c].add (x, y)
    
      var antinodesP1: HashSet[Vec2]
      var antinodesP2: HashSet[Vec2]
    
      for _, list in antennas:
        for ind, ant1 in list:
          antinodesP2.incl ant1 # each antenna is antinode
          for ant2 in list.toOpenArray(ind+1, list.high):
            let d = delta(ant1, ant2)
            for dir in [-1, 1]:
              var i = dir
              while true:
                let antinode = (x: ant1.x+d.x*i, y: ant1.y+d.y*i)
                if antinode.outOfBounds(grid): break
                if i in [1, -2]: antinodesP1.incl antinode
                antinodesP2.incl antinode
                i += dir
      result.part1 = antinodesP1.len
      result.part2 = antinodesP2.len
    
    

    Codeberg repo