Quest 7: Namegraph

  • 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 11 months ago*

Scheme/Guile

You could probably build a (letter, length) => combination-count mapping pretty quickly for part 3, but dealing with overlap in the input elements seems like a pain if handled this way.

(import (rnrs io ports (6)))
#!curly-infix

(define (parse-file file-name) (let*
  ((lines (string-split (string-trim-both (call-with-input-file file-name get-string-all)) #\newline))
   (names (string-split (car lines) #\,))
   (rule-lines (cddr lines))
   (rules (map (lambda (l) (let*
                       ((sides (string-split l #\space))
                        (r-left (string-ref (car sides) 0))
                        (r-right (caddr sides)))
                       (cons r-left (map (lambda (x) (string-ref x 0)) (string-split r-right #\,))))) rule-lines)))
  (cons names rules)))

(define (check-name rules name)
  (if (eq? 1 (string-length name))
      #t
      (let* ((letter (string-ref name 0))
             (right (assq-ref rules letter))
             (next-letter (string-ref name 1)))
        (if (memq next-letter right)
            (check-name rules (substring/read-only name 1))
            #f))))
(let* ((parsed (parse-file "notes/everybody_codes_e2025_q07_p1.txt"))
       (names (car parsed))
       (rules (cdr parsed)))
  (let loop ((names names))
    (let* ((name (car names)) (name-matches (check-name rules name)))
      (if name-matches
          (format #t "P1 Answer: ~a\n\n" name)
          (loop (cdr names))))))


(let* ((parsed (parse-file "notes/everybody_codes_e2025_q07_p2.txt"))
       (names (car parsed))
       (rules (cdr parsed)))
  (let loop ((i 1) (names names) (name-sum 0))
    (if (null? names)
        (format #t "P2 Answer: ~a\n\n" name-sum)
        (let* ((name (car names)) (name-matches (check-name rules name)))
          (loop (1+ i) (cdr names) (+ name-sum (if name-matches i 0)))))))


(define discovered-prefixes (make-hash-table))
(define (count-prefixes rules name)
  (if (hash-ref discovered-prefixes name)
      0
      (begin
        (hash-set! discovered-prefixes name #t)
        (if {(string-length name) >= 11}
            1
            (+
              (apply + (map
                     (lambda (c) (count-prefixes rules (string-append name (string c))))
                     (or (assq-ref rules (string-ref name (1- (string-length name)))) '())))
              (if {(string-length name) >= 7} 1 0))))))
(let* ((parsed (parse-file "notes/everybody_codes_e2025_q07_p3.txt"))
       (names (car parsed))
       (rules (cdr parsed)))
  (let ((name-count (apply + (map (lambda (name) (count-prefixes rules name)) (filter (lambda (name) (check-name rules name)) names)))))
    (format #t "P3 Answer: ~a\n\n" name-count)))
  • source