Quest 6: Mentorship Matrix

  • 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/

  • janAkali@lemmy.sdf.org
    link
    fedilink
    arrow-up
    2
    ·
    edit-2
    10 days ago

    Nim

    parts 1 and 2 - easy

    For part 3 - When I first looked at the example input - it seemed a bit daunting to solve. But then I had a hunch and decided to check the real input and turns out - I was right! The real input is easier to solve because it’s longer than 1000 chars.

    This means that there is only 3 possible configurations we care about in repeated input: leftmost section, rightmost section and 998 identical sections in the middle. We solve each individually and sum them.

    Another trick I used is looking up mentors with modulo to avoid copying the input.

    proc solve_part1*(input: string): Solution =
      var mentors: CountTable[char]
      for c in input:
        if c notin {'a','A'}: continue
        if c.isUpperAscii: mentors.inc c
        else:
          result.intVal += mentors.getOrDefault(c.toUpperAscii)
    
    proc solve_part2*(input: string): Solution =
      var mentors: CountTable[char]
      for c in input:
        if c.isUpperAscii: mentors.inc c
        else:
          result.intVal += mentors.getOrDefault(c.toUpperAscii)
    
    proc solve_part3*(input: string): Solution =
      var mentors: Table[char, seq[int]]
      for index in -1000 ..< input.len + 1000:
        let mi = index.euclMod input.len
        if input[mi].isLowerAscii: continue
        let lower = input[mi].toLowerAscii
        if mentors.hasKeyOrPut(lower, @[index]):
          mentors[lower].add index
    
      var most, first, last = 0
      for ci, ch in input:
        if ch.isUpperAscii: continue
        for mi in mentors[ch]:
          let dist = abs(mi - ci)
          if dist <= 1000:
            inc most
            if mi >= 0: inc first
            if mi <= input.high: inc last
    
      result := first + (most * 998) + last
    

    Full solution at Codeberg: solution.nim