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/

you are viewing a single comment's thread
view the rest of the comments
[โ€“] 2 points 11 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)))
  • source