Quest 8: The Art of Connection

  • 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

Link to participate: https://everybody.codes/

you are viewing a single comment's thread
view the rest of the comments
[โ€“] 2 points 1 year ago

Nim

Part 2 - I just really didn't want to think that day. So when puzzle asked me to check if lines intersect - I wrote the intersection checking solution with 2D points.

Part 3 is geometry + bruteforce.

proc solve_part1*(input: string): Solution =
  let pins = input.split(',').mapIt(parseInt(it))
  for i in 0 ..< pins.high:
    let d = abs(pins[i] - pins[i+1])
    if d == 16: inc result.intVal

proc ccw(A,B,C: Vec2): bool = (C.y-A.y) * (B.x-A.x) > (B.y-A.y) * (C.x-A.x)
proc isIntersection(A,B,C,D: Vec2): bool = ccw(A,C,D) != ccw(B,C,D) and ccw(A,B,C) != ccw(A,B,D)

proc solve_part2*(input: string): Solution =
  const two_pi = PI * 2
  const pin_count = 256

  var pins: array[pin_count, Vec2]
  for i in 0 ..< pin_count:
    let angle = two_pi * (i / pin_count)
    let point: Vec2 = (cos(angle), sin(angle))
    pins[i] = point

  let inst = input.split(',').mapIt(parseInt(it))
  var lines: seq[(Vec2, Vec2)]

  for i in 0 ..< inst.high:
    let A = pins[inst[i]-1]
    let B = pins[inst[i+1]-1]

    for (C, D) in lines:
      if isIntersection(A,B,C,D):
        inc result.intVal
    lines.add shortenSegment(A, B, 0.0001)

proc solve_part3*(input: string): Solution =
  const two_pi = PI * 2
  const pin_count = 256

  var pins: array[pin_count, Vec2]
  for i in 0 ..< pin_count:
    let angle = two_pi * (i / pin_count)
    let point: Vec2 = (cos(angle), sin(angle))
    pins[i] = point

  let inst = input.split(',').mapIt(parseInt(it))
  var lines: seq[(Vec2, Vec2)]

  for i in 0 ..< inst.high:
    let A = pins[inst[i]-1]
    let B = pins[inst[i+1]-1]
    lines.add shortenSegment(A, B, 0.0001)

  var bestSum = 0
  for i in 0 ..< pin_count:
    for j in i+1 ..< pin_count:
      let A = pins[i]
      let B = pins[j]
      var sum = 0
      for (C, D) in lines:
        if isIntersection(A,B,C,D): inc sum
      if sum > bestSum: bestSum = sum
  result := bestSum

Full solution at Codeberg: solution.nim

  • source