Quest 1: Whispers in the Shell

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

  • ystael@beehaw.org
    link
    fedilink
    arrow-up
    1
    ·
    2 months ago

    It’s been too long since I wrote any Lisp, so obviously I should use the one hallowed by decades of tradition, not any of the fancy new ones with sane naming conventions and unified library systems. :D

    (ql:quickload :str)
    
    (defun parse-insn (insn)
      (let ((direction (str:s-first insn))
            (magnitude (parse-integer (str:s-rest insn))))
        (* magnitude (cond ((equal direction "L") -1)
                           ((equal direction "R") 1)
                           (t 0)))))
    
    (defun read-inputs-1 (filename)
      (let ((input-lines (uiop:read-file-lines filename)))
        (destructuring-bind (names _ instructions) input-lines
          (list (str:split "," names)
                (mapcar #'parse-insn (str:split "," instructions))))))
    
    (defun apply-insns-1 (names insns)
      (let ((max-pos (- (length names) 1)))
        (labels ((apply-from (insns pos)
                   (if (null insns)
                       (nth pos names)
                       (let* ((maybe-next-pos (+ pos (car insns)))
                              (next-pos (max 0 (min max-pos maybe-next-pos))))
                         (apply-from (cdr insns) next-pos)))))
          (apply-from insns 0))))
    
    (defun main-1 (filename)
      (apply #'apply-insns-1 (read-inputs-1 filename)))
    
    (defun apply-insns-2 (names insns)
      (labels ((apply-from (insns pos)
                 (if (null insns)
                     (nth pos names)
                     (let ((next-pos (mod (+ pos (car insns)) (length names))))
                       (apply-from (cdr insns) next-pos)))))
        (apply-from insns 0)))
    
    (defun main-2 (filename)
      (apply #'apply-insns-2 (read-inputs-1 filename)))
    
    (defun apply-insns-3 (names insns)
      (let* ((vnames (coerce names 'vector))
             (n (length vnames)))
        (labels ((apply-from (insns)
                   (if (null insns)
                       (aref vnames 0)
                       (let* ((tgt (mod (car insns) n))
                              (src-name (aref vnames 0))
                              (tgt-name (aref vnames tgt)))
                         (setf (aref vnames 0) tgt-name)
                         (setf (aref vnames tgt) src-name)
                         (apply-from (cdr insns))))))
          (apply-from insns))))
    
    (defun main-3 (filename)
      (apply #'apply-insns-3 (read-inputs-1 filename)))