• 0 Posts
  • 15 Comments
Joined 3 years ago
cake
Cake day: June 10th, 2023

help-circle

  • Scheme/Guile

    I was stuck on part 3 for a while, for not taking account that a child scale that I’m evaluating may already be a parent scale in some group.

    (import (rnrs io ports (6))
            (srfi srfi-1))
    #!curly-infix
    
    (define (parse-file file-name)
      (let* ((lines (string-split (string-trim-both (call-with-input-file file-name get-string-all)) #\newline))
             (split-lines (map (lambda (l) (string-split l #\:)) lines))
             (parsed-lines (map (lambda (l) (cons (string->number (car l)) (string->list (cadr l)))) split-lines)))
        parsed-lines))
    
    (define (child-score child p1 p2 p1-sim p2-sim)
      (if (and-map null? (list child p1 p2))
          (* p1-sim p2-sim)
          (let ((matches-p1 (eq? (car child) (car p1)))
                (matches-p2 (eq? (car child) (car p2))))
            (cond
              ((not (or matches-p1 matches-p2)) #f)
              (else (child-score (cdr child) (cdr p1) (cdr p2) (+ p1-sim (if matches-p1 1 0)) (+ p2-sim (if matches-p2 1 0))))))))
    (let ((dna-lines (parse-file "notes/everybody_codes_e2025_q09_p1.txt")))
      (format #t "P1 Answer: ~a\n\n" (or
        (child-score (cdar dna-lines) (cdadr dna-lines) (cdaddr dna-lines) 0 0)
        (child-score (cdadr dna-lines) (cdar dna-lines) (cdaddr dna-lines) 0 0)
        (child-score (cdaddr dna-lines) (cdadr dna-lines) (cdar dna-lines) 0 0))))
    
    
    (let ((dna-lines (list->vector (parse-file "notes/everybody_codes_e2025_q09_p2.txt"))))
      (let loop ((child 0) (total-sim 0))
        (if {child < (vector-length dna-lines)}
            (loop (1+ child) (+ total-sim (let loop ((i 0))
              (cond
                ((eq? i child) (loop (1+ i)))
                ({i >= {(vector-length dna-lines) - 1}} 0)
                (else
                  (or
                    (let loop ((j (1+ i)))
                      (cond
                        ((eq? j child) (loop (1+ j)))
                        ({j >= (vector-length dna-lines)} #f)
                        (else (let ((res (child-score
                                   (cdr (vector-ref dna-lines child))
                                   (cdr (vector-ref dna-lines i))
                                   (cdr (vector-ref dna-lines j)) 0 0)))
                          (or res (loop (1+ j)))))))
                    (loop (1+ i))))))))
            (format #t "P2 Answer: ~a\n\n" total-sim))))
    
    
    (define (init-id-to-group dna-lines)
      (let ((table (make-hash-table)))
        (let loop ((i 0))
          (if {i < (vector-length dna-lines)}
              (let ((id (car (vector-ref dna-lines i))))
                (hash-set! table id id)
                (loop (1+ i)))
              table))))
    (define (init-group-to-ids dna-lines)
      (let ((table (make-hash-table)))
        (let loop ((i 0))
          (if {i < (vector-length dna-lines)}
              (let ((id (car (vector-ref dna-lines i))))
                (hash-set! table id (list id))
                (loop (1+ i)))
              table))))
    (let ((dna-lines (list->vector (parse-file "notes/everybody_codes_e2025_q09_p3.txt"))))
      (let ((id-to-group (init-id-to-group dna-lines)) (group-to-ids (init-group-to-ids dna-lines)))
      (let child-loop ((child 0))
        (if {child < (vector-length dna-lines)}
          (let i-loop ((i 0))
            (cond
              ((eq? i child) (i-loop (1+ i)))
              ({i >= {(vector-length dna-lines) - 1}} (child-loop (1+ child)))
              (else
                (let j-loop ((j (1+ i)))
                  (cond
                    ((eq? j child) (j-loop (1+ j)))
                    ({j >= (vector-length dna-lines)} (i-loop (1+ i)))
                    (else (let* ((cl (vector-ref dna-lines child))
                                 (pil (vector-ref dna-lines i))
                                 (pjl (vector-ref dna-lines j))
                                 (res (child-score (cdr cl) (cdr pil) (cdr pjl) 0 0)))
                      (if res
                          (let* ((i-group (hash-ref id-to-group (car pil)))
                                 (j-group (hash-ref id-to-group (car pjl)))
                                 (child-group (hash-ref id-to-group (car cl)))
                                 (i-group-ids (hash-ref group-to-ids i-group))
                                 (j-group-ids (hash-ref group-to-ids j-group))
                                 (child-group-ids (hash-ref group-to-ids child-group))
                                 (new-group-ids (delete-duplicates (append child-group-ids (or i-group-ids '()) (or j-group-ids '())))))
                            (map (lambda (id) (hash-set! id-to-group id child-group)) new-group-ids)
                            (hash-remove! group-to-ids i-group)
                            (hash-remove! group-to-ids j-group)
                            (hash-set! group-to-ids child-group new-group-ids)
                            (child-loop (1+ child)))
                          (j-loop (1+ j))))))))))
            (format #t "P3 Answer: ~a\n\n" (cdr (hash-fold
                    (lambda (_ id-list prior)
                            (let ((group-size (length id-list))
                                  (group-sum (apply + id-list)))
                              (if {group-size > (car prior)}
                                  (cons group-size group-sum)
                                  prior)))
                    (cons 0 0)
                    group-to-ids)))))))
    

  • Scheme/Guile

    Takes about 5 seconds.

    (import (rnrs io ports (6))
            (srfi srfi-1))
    #!curly-infix
    
    (define (parse-file file-name)
      (let ((sequence (map string->number (string-split (string-trim-both (call-with-input-file file-name get-string-all)) #\,))))
        (zip sequence (cdr sequence))))
    
    (let loop ((sequence (parse-file "notes/everybody_codes_e2025_q08_p1.txt")) (count 0))
      (if (null? sequence)
          (format #t "P1 Answer: ~a\n\n" count)
          (loop (cdr sequence) (+ count (if (and last (eq? (modulo (- (cadar sequence) (caar sequence)) 32) 16)) 1 0)))))
    
    (define (crosses-over? a b)
      (let ((a1 (car a))
            (a2 (cadr a))
            (b1 (car b))
            (b2 (cadr b)))
        (let ((a2 (modulo {a2 - a1} 256))
              (b1 (modulo {b1 - a1} 256))
              (b2 (modulo {b2 - a1} 256)))
          (and (not (eq? b1 0)) (not (eq? b2 0))
          (or
            (and {b1 < a2} {b2 > a2})
            (and {b1 > a2} {b2 < a2}))))))
    (define (count-cross-overs sequence a)
      (let loop ((sequence sequence) (count 0))
        (if (null? sequence)
            count
            (loop (cdr sequence) (+ count (if (crosses-over? (car sequence) a) 1 0))))))
    (let loop ((sequence (parse-file "notes/everybody_codes_e2025_q08_p2.txt")) (passed '()) (count 0))
      (if (null? sequence)
          (format #t "P2 Answer: ~a\n\n" count)
          (loop (cdr sequence) (cons (car sequence) passed) (+ count (count-cross-overs passed (car sequence))))))
    
    
    (let ((sequence (parse-file "notes/everybody_codes_e2025_q08_p3.txt")))
      (let loop ((i 1) (greatest 0))
        (if {i > 256}
            (format #t "P3 Answer: ~a\n\n" greatest)
            (loop (1+ i) (max greatest (let loop ((j i) (greatest 0))
                  (if {j > 256}
                      greatest
                      (loop (1+ j) (max greatest (count-cross-overs sequence (list i j)))))))))))
    

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

  • Scheme/Guile

    Part 3 was a fun little challenge.

    (import (rnrs io ports (6)))
    #!curly-infix
    
    (define (parse-file file-name) (string-trim-both (call-with-input-file file-name get-string-all)))
    
    (let* ((line (parse-file "notes/everybody_codes_e2025_q06_p1.txt"))
           (line-length (string-length line)))
      (let loop ((i 0) (knight-count 0) (mentor-count 0))
        (if {i < line-length}
            (let ((letter (string-ref line i)))
              (loop (1+ i) (+ knight-count (if (eq? letter #\A) 1 0)) (+ mentor-count (if (eq? letter #\a) knight-count 0))))
            (format #t "P1 Answer: ~a\n\n" mentor-count))))
    
    (let* ((line (parse-file "notes/everybody_codes_e2025_q06_p2.txt"))
           (line-length (string-length line)))
      (let loop ((i 0) (knight-counts '()) (mentor-count 0))
        (if {i < line-length}
            (let ((letter (string-ref line i)))
              (loop
                (1+ i)
                (if (char-upper-case? letter) (assq-set! knight-counts letter (1+ (or (assq-ref knight-counts letter) 0))) knight-counts)
                (+ mentor-count (if (char-lower-case? letter) (or (assq-ref knight-counts (char-upcase letter)) 0) 0))))
            (format #t "P2 Answer: ~a\n\n" mentor-count))))
    
    
    (let* ((line (parse-file "notes/everybody_codes_e2025_q06_p3.txt"))
           (line-length (string-length line)))
      (let loop ((i 0) (mentor-count 0))
        (if {i < line-length}
            (let ((letter (string-ref line i)))
              (loop
                (1+ i)
                (+ mentor-count
                   (if (char-lower-case? letter)
                       (let loop ((j (- i 1000)) (mentors-here 0))
                         (if {j <= (+ i 1000)}
                             (loop
                               (1+ j)
                               (+ mentors-here
                                  (if {(string-ref line {j modulo line-length}) eq? (char-upcase letter)}
                                      (if (and {0 <= j} {j < line-length}) 1000 999)
                                      0)))
                             mentors-here))
                       0))))
            (format #t "P3 Answer: ~a\n\n" mentor-count))))
    

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

  • maaath

    Scheme/Guile

    (import (rnrs io ports (6)))
    
    (define (parse-file file-name)
           (map string->number (string-split (call-with-input-file file-name get-string-all) #\newline)))
    
    (let* ((gears (parse-file "notes/everybody_codes_e2025_q04_p1.txt")))
      (format #t "P1 Answer: ~a\n\n" (* 2025 (/ (car gears) (car (last-pair gears))))))
    
    
    (let* ((gears (parse-file "notes/everybody_codes_e2025_q04_p2.txt")))
      (format #t "P2 Answer: ~a\n\n" (ceiling (* 10000000000000 (/ (car (last-pair gears)) (car gears))))))
    
    
    (define (parse-file-p3 file-name)
           (map
                  (lambda (line) (map string->number(string-split line #\|)))
                  (string-split (call-with-input-file file-name get-string-all) #\newline)))
    (let* ((gears (parse-file-p3 "notes/everybody_codes_e2025_q04_p3.txt")))
      (format #t "P2 Answer: ~a\n\n"
              (floor (* 100
                 (apply * (map (lambda (gear) (if (= 1 (length gear)) 1 (/ (cadr gear) (car gear)))) gears))
                 (/ (caar gears) (caar (last-pair gears)))))))
    

  • Scheme/Guile

    Guile doesn’t seem to come with a bag implementation :(. Not a big deal, a linear scan works about as well.

    (use-modules (ice-9 rdelim))
    (use-modules (srfi srfi-1))
    
    (define (parse-file file-name)
      (let* ((p (open-input-file file-name))
            (comma-split (string-split (read-line p) #\,))
            (number-list (map string->number comma-split)))
        number-list))
    
    (let* ((crates (parse-file "notes/everybody_codes_e2025_q03_p1.txt"))
           (dedup-crates (delete-duplicates crates)))
      (format #t "P1 Answer: ~a\n\n" (apply + dedup-crates)))
    
    
    (let* ((crates (parse-file "notes/everybody_codes_e2025_q03_p2.txt"))
           (dedup-crates (delete-duplicates crates))
           (sorted-crates (sort dedup-crates <)))
      (format #t "P2 Answer: ~a\n\n" (apply + (take sorted-crates 20))))
    
    
    (let* ((crates (parse-file "notes/everybody_codes_e2025_q03_p3.txt"))
           (sorted-crates (sort crates <))
           (largest-set-size (let loop ((count 0) (l sorted-crates) (c #f) (max-count 0))
             (if (nil? l)
                 max-count
                 (let* ((new-c (car l))
                        (new-count (if (equal? new-c c) (+ count 1) 1)))
                   (loop new-count (cdr l) new-c (max new-count max-count)))))))
      (format #t "P3 Answer: ~a\n\n" largest-set-size))
    

  • I was stuck for a while on part 2. I thought I was running into precision errors, so I re-implemented everything using exact integers, then I re-implemented it in python, but it turns out that I just had an off-by-1 error. It just so happened that my off-by-1 algorithm gave the correct solution to the sample input. Part 3 takes a while to compute.

    Scheme/Guile

    (use-modules (ice-9 rdelim))
    (use-modules (ice-9 format))
    (use-modules (srfi srfi-1))
    
    (define (parse-file file-name)
      (let* ((p (open-input-file file-name))
            (equality-split (string-split (read-line p) #\=))
            (complex-str (list-ref equality-split 1))
            (complex-parts (map string->number (string-split
              (substring/read-only complex-str 1 (- (string-length complex-str) 1))
              #\,))))
        (+ (car complex-parts) (* 0+1i (list-ref complex-parts 1)))))
    (define (special-div numerator divisor)
      (+
        (truncate/ (real-part numerator) (real-part divisor))
        (* 0+1i (truncate/ (imag-part numerator) (imag-part divisor)))))
    
    (let* ((A (parse-file "notes/everybody_codes_e2025_q02_p1.txt")))
      (format #t "Input is ~a\n" A)
      (let loop ((R 0+0i) (i 3))
        (if (> i 0)
          (loop (+ (special-div (* R R) 10+10i) A) (- i 1))
          (format #t "P1 Answer: [~d,~a]\n\n"
                  (inexact->exact (real-part R))
                  (inexact->exact (imag-part R))))))
    
    
    (define (check-engrave-range value)
      (and-map (lambda (x) (<= (abs x) 1000000)) (list (real-part value) (imag-part value))))
    (define (check-engrave point)
      (let loop ((result 0+0i) (i 100))
        (if (and (> i 0) (check-engrave-range result))
          (loop (+ point (special-div (* result result) 100000+100000i)) (- i 1))
          (check-engrave-range result))))
    (let* ((origin (parse-file "notes/everybody_codes_e2025_q02_p2.txt"))
           (engrave-count 0))
      (format #t "Input is ~a\n" origin)
      (let loop ((i 0))
        (if (<= i 1000) (begin
          (let loop ((j 0))
            (if (<= j 1000) (begin
              (set! engrave-count (+ engrave-count
                                     (if (check-engrave (+ origin (+ i (* j 0+1i)))) 1 0)))
              (loop (+ j 10)))))
          (loop (+ i 10)))))
      (format #t "P2 answer: ~a\n\n" engrave-count))
    
    
    (let* ((origin (parse-file "notes/everybody_codes_e2025_q02_p3.txt"))
           (engrave-count 0))
      (format #t "Input is ~a\n" origin)
      (let loop ((i 0))
        (if (<= i 1000) (begin
          (let loop ((j 0))
            (if (<= j 1000) (begin
              (set! engrave-count
                    (+ engrave-count (if (check-engrave (+ origin (+ i (* j 0+1i)))) 1 0)))
              (loop (+ j 1)))))
          (loop (+ i 1)))))
      (format #t "P3 answer: ~a\n\n" engrave-count))
    

  • I’m still learning Scheme, but I wrote a solution in Guile:

    (use-modules (ice-9 rdelim ))
    (use-modules (srfi srfi-1))
    
    (define (parse-step s) (*
        (if (eq? (string-ref s 0) #\L) -1 1)
        (string->number (substring s 1))
    ))
    (define (parse-file file-name) (begin
      (define p (open-input-file file-name))
      (define names-str (read-line p))
      (read-line p)
      (define steps-str (read-line p))
      (cons
        (string-split names-str #\,)
        (map parse-step (string-split steps-str #\,))
      )
    ))
    
    (let* ((parsed-file (parse-file "notes/everybody_codes_e2025_q01_p1.txt"))
           (names (car parsed-file))
           (steps (cdr parsed-file)))
      (format #t "names: ~a\nsteps: ~a\n" names steps)
      (define name-count (length names))
      (define chosen-name-idx (reduce
        (lambda (pos change) (max 0 (min (- name-count 1) (+ pos change))))
        0 steps))
      (format #t "P1: Chosen name(~a): ~a\n\n" chosen-name-idx (list-ref names chosen-name-idx))
    )
    
    (let* ((parsed-file (parse-file "notes/everybody_codes_e2025_q01_p2.txt"))
           (names (car parsed-file))
           (steps (cdr parsed-file)))
      (format #t "names: ~a\nsteps: ~a\n" names steps)
      (define name-count (length names))
      (define chosen-name-idx (modulo (reduce + 0 steps) name-count))
      (format #t "P2: Chosen name(~a): ~a\n\n" chosen-name-idx (list-ref names chosen-name-idx))
    )
    
    (let* ((parsed-file (parse-file "notes/everybody_codes_e2025_q01_p3.txt"))
           (names (list->vector (car parsed-file)))
           (steps (cdr parsed-file)))
      (format #t "names: ~a\nsteps: ~a\n" names steps)
      (define name-count (vector-length names))
      (for-each (lambda (s)
          (define head (vector-ref names 0))
          (define swap-pos (modulo s name-count))
          (vector-set! names 0 (vector-ref names swap-pos))
          (vector-set! names swap-pos head)
        ) steps)
      (format #t "P3: Chosen name: ~a\n" (vector-ref names 0))
    )
    


  • So, if I understood correctly, that was a strange sequence of events.

    spoiler
    • Kilika was tricked, Liam was killed, and Kilika was burdened with guilt.
    • Amelia brought Liam back to life.
    • The king made Kilika forget that she got Liam killed.
    • Everyone shunned Kilika so they wouldn’t reveal that event.
    • Kilika thinks everybody is shunning her because Amelia was found to have an incredible “gift”.
    • Kilika mind-controls all the soldiers. Liam secretly is not mind-controlled, but still plays along with Kilika.
    • Kilika and the soldiers starts to treat Amelia like shit. Liam asks to terminate his engagement to Amelia.
    • Kilika exiles Amelia as revenge for being shunned. Liam is OK with this because he thinks Kilika’s hatred would grow as long as Amelia is around.
    • Amelia returns.
    • Liam tries to drive Amelia away again.
    • Amelia wants to leave, but Kilika refuses this. Kilika tells the soldiers to kill Akira.
    • The King tells Kilika to undo her mind-control. She doesn’t.
    • The King decides a duel between Kilika and Akira, thinking that a victory for Kilika (which would force Amelia to stay) will make dealing with her guilt easier.
    • Liam helps Amelia dispel the mind-control on the soldiers.
    • Kilika suffers a humiliating defeat, the King returns Kilika’s memory anyways. Kilika, Liam, and the King express remorse. Everybody forgives everybody.


  • I’m not familiar with Radeon PowerPlay, so I don’t know if there is a proper way to solve this, but you should be able to make a systemd system service to run the upp command on boot.

    To do so, I think you can use the following:

    [Unit]
    Description=Run my_user_script
    After=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target
    
    
    [Service]
    Type=oneshot
    ExecStart=upp -p /sys/class/drm/card1/device/pp_table set --write smc_pptable/SocketPowerLimitAc/0=312 smc_pptable/SocketPowerLimitDc/0=293 smc_pptable/TdcLimit/0=300 smc_pptable/FreqTableSocclk/1=1350 smc_pptable/FreqTableFclk/1=2000 smc_pptable/FclkBoostFreq=2000
    
    [Install]
    WantedBy=suspend.target hibernate.target hybrid-sleep.target suspend-then-hibernate.target
    

    To configure this service:

    • Save the text (using sudo/root) to a new .service file in /etc/systemd/service. (e.g. /etc/systemd/system/my_update_pp.service)
    • run sudo systemctl daemon-reload to tell systemd to re-read the service files
    • run sudo systemctl restart my_update_pp.service to manually run the service
    • run sudo systemctl enable my_update_pp.service to tell systemd to run your service automatically on boot/wake (WantedBy tells systemd when it should include the unit/service, After, Wants, Requires, and Before help systemd decide the order to run all the units/services)

    Notes

    • Usually for simple systemd services, you can omit After and set WantedBy to just WantedBy=multi-user.target, but if you also need to run upp after sleep or hibernate, then you probably need something more complex. I copied the After and WantedBy from a stackexchange answer, but I haven’t tried using those targets before. You might have to add multi-user.target to the WantedBy list.
    • I don’t actually know if you need to run upp after sleep/hibernate. Running on boot might be sufficient.
    • I think you can skip the chmod if you run upp as sudo/root. Systemd system services run as root by default.
    • I don’t know how safe it is to mess with PowerPlay during boot. My gut says it’s probably fine, but it also seems like something that could cause graphics to not work. Tread carefully.

    References:


  • Use triple backticks for blocks of code-type stuff

    ```

    like so

    ```

    example, wrapped in a spoiler tag.
    upp -p /sys/class/drm/card1/device/pp_table dump
    header:
      structuresize: 2470
      format_revision: 15
      content_revision: 0
    table_revision: 2
    table_size: 802
    golden_pp_id: 2466
    golden_revision: 16307
    format_id: 128
    platform_caps: 24
    thermal_controller_type: 28
    small_power_limit1: 0
    small_power_limit2: 0
    boost_power_limit: 0
    software_shutdown_temp: 118
    reserve:
      reserve 0: 0
      reserve 1: 0
      reserve 2: 0
      reserve 3: 0
      reserve 4: 0
      reserve 5: 0
      reserve 6: 1
      reserve 7: 0
    power_saving_clock:
      revision: 1
      reserve:
    ... and so on ...