Quest 5: Fishbone Order

  • 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* (last edited 1 year ago)

What a fiddlybit. I needed records to save me from list-hell on this one.

Scheme/Guile

(import (rnrs io ports (6))
        (rnrs records syntactic))

(define (parse-file file-name)
  (let* ((lines (string-split (string-trim-both (call-with-input-file file-name get-string-all)) #\newline)))
    (map (lambda (line)
       (let* ((colon-split (string-split line #\:))
             (segments (map string->number (string-split (cadr colon-split) #\,)))
             (label (string->number (car colon-split))))
        (cons label segments)))
       lines)))

(define-record-type fishbone-segment (fields middle left right))
(define (construct-fishbone fishbone segments)
  (if (null? segments)
      fishbone
      (let ((fishbone (add-fishbone-segment fishbone (car segments))))
        (construct-fishbone fishbone (cdr segments)))))
(define (add-fishbone-segment fishbone segment)
  (if (null? fishbone)
      (list (make-fishbone-segment segment #f #f))
      (let* ((fish-head (car fishbone))
             (fish-middle (fishbone-segment-middle fish-head))
             (fish-left (fishbone-segment-left fish-head))
             (fish-right (fishbone-segment-right fish-head)))
        (cond
          ((and (< segment fish-middle) (not fish-left)) (cons (make-fishbone-segment fish-middle segment fish-right) (cdr fishbone)))
          ((and (> segment fish-middle) (not fish-right)) (cons (make-fishbone-segment fish-middle fish-left segment) (cdr fishbone)))
          (else (cons fish-head (add-fishbone-segment (cdr fishbone) segment)))))))
(define (score-fishbone fishbone)
  (string->number (string-join (map (compose number->string fishbone-segment-middle) fishbone) "")))

(define-record-type sword (fields id fishbone quality))
(define (parse-swords file-name)
  (map (lambda (sword-line)
          (let ((fishbone (construct-fishbone '() (cdr sword-line))))
            (make-sword (car sword-line) fishbone (score-fishbone fishbone))))
    (parse-file file-name)))

(format #t "P1 Answer: ~a\n\n" (sword-quality (car (parse-swords "notes/everybody_codes_e2025_q05_p1.txt"))))

(let* ((swords (parse-swords "notes/everybody_codes_e2025_q05_p2.txt"))
       (sword-scores (map sword-quality swords)))
  (format #t "P2 Answer: ~a\n\n" (- (apply max sword-scores) (apply min sword-scores))))


(define (segment-score segment)
  (string->number
    (string-join
     (map (lambda (n) (if (eqv? #f n) "" (number->string n)))
      (list (fishbone-segment-left segment) (fishbone-segment-middle segment) (fishbone-segment-right segment)))
     "")))
(define (sort-fishbones a b)
  (if (null? a) '()
  (let ((line-score-a (segment-score (car a)))
        (line-score-b (segment-score (car b))))
    (cond
      ((> line-score-a line-score-b) #t)
      ((< line-score-a line-score-b) #f)
      (else (sort-fishbones (cdr a) (cdr b)))))))
(define (sort-swords a b)
  (cond
    ((> (sword-quality a) (sword-quality b)) #t)
    ((< (sword-quality a) (sword-quality b)) #f)
    (else (let ((fb-sort (sort-fishbones (sword-fishbone a) (sword-fishbone b))))
      (cond
        ((null? fb-sort) (> (sword-id a) (sword-id b)))
        (else fb-sort))))))
(let* ((swords (parse-swords "notes/everybody_codes_e2025_q05_p3.txt"))
       (sorted-swords (sort swords sort-swords))
       (swords-length (length swords)))
  (let loop ((i 1) (total 0) (sorted-swords sorted-swords))
    (if (<= i swords-length)
        (loop (1+ i) (+ total (* i (sword-id (car sorted-swords)))) (cdr sorted-swords))
        (format #t "P2 Answer: ~a\n\n" total))))
  • source