Day 8

Previous: Day 07 | Next: Day 09

Bing bing wahoo edition

###AUTO-ACQUIRED DATA FOLLOWS…
archivist/day08.lisp
archivist/day08.lisp
(asdf:load-system :split-sequence)
    (asdf:load-system :iterate)
    (defpackage \#:aoc-8
      (:use \#:cl \#:split-sequence \#:iterate))
    (in-package \#:aoc-8)
    
    (defun cat (&rest strs)
        (concatenate &\#39;string strs))
    
    (defun replace-all (string part replacement &key (test \#&\#39;char=))
      "Returns a new string in which all the occurences of the part 
    is replaced with replacement."
      (with-output-to-string (out)
        (loop with part-length = (length part)
              for old-pos = 0 then (+ pos part-length)
              for pos = (search part string
                                :start2 old-pos
                                :test test)
              do (write-string string out
                               :start old-pos
                               :end (or pos (length string)))
              when pos do (write-string replacement out)
              while pos)))
    
    (defstruct machine
        (pointer 0)
        (accum 0))
    (defparameter \*vm\* (make-machine))
    
    (defun copy-array  (array)
        (let ((new (make-array (array-dimensions array) :displaced-to array)))
                   (adjust-array new (array-dimensions array) :displaced-to nil))) 
    
    (defun getinput ()
        (let\* ((fname "bigboylarge")
               (lines (uiop:read-file-lines  fname)))
          lines
          ))
    (defun process (input)
        (make-array (length input) 
                    :initial-contents
                    (mapcar (lambda (x) 
                              (list (str-to-op x)
                                    nil))
                            input)))
    
    (defun str-to-op (str)
        (let ((substr (subseq str 0 3)))
          (list (cond ((equal substr "nop") \#&\#39;nop) 
                      ((equal substr "acc") \#&\#39;acc)
                      ((equal substr "jmp") \#&\#39;jmp))
                (parse-integer (subseq str 4)))))
    
    (defun nop (vm val)
        (incf (machine-pointer vm)))
    
    (defun acc (vm val)
        (setf (machine-accum vm)
              (+ (machine-accum vm)
                 val))
        (incf (machine-pointer vm)))
    
    (defun jmp (vm val)
        (setf (machine-pointer vm)
              (+ (machine-pointer vm)
                 val)))
    
    (defun part1 ()
      (let ((vm (make-machine))
            (code (process (getinput))))
        (iterate 
          (while (and (not (cadr (aref code (machine-pointer vm))))
                      (<= (machine-pointer vm) (length code))))
            (let ((op (aref code (machine-pointer vm))))
              (setf (cadr op) t)
              (funcall (caar op) vm (cadar op)))
          )
        (print code)
        (machine-accum vm)))
    
    (defun part2-run (code)
      (let ((vm (make-machine)))
        (iterate 
          (while (and (< (machine-pointer vm) (length code))
                      (>= (machine-pointer vm) 0)
                   (not (cadr (aref code (machine-pointer vm))))
                      ))
            (let ((op (aref code (machine-pointer vm))))
              (setf (cadr op) t)
              (funcall (caar op) vm (cadar op))
              )
            (finally  (return (if (>= (machine-pointer vm) 
                                    (length code))
                                  (machine-accum vm)
                                  nil))))))
    
    (defun swap (fun)
        (cond ((eq fun \#&\#39;jmp) \#&\#39;nop)
              ((eq fun \#&\#39;nop) \#&\#39;jmp)
              (t fun)))
    
    (defun part2 ()
        (let\* ((code (process (getinput))))
          ;(part2-run vcode)
          ;reset
          (print (1- (length code)))
          (iterate (for i from 0 to (1- (length code))) 
                   (if (eq (mod i 10000) 0) (print i))
                   (let ((op (aref code i)))
                     (if (not (eq (caar op) \#&\#39;acc))
                         (progn 
                           (setf (caar op) 
                                 (swap (caar op)))
                           (let ((res (part2-run code)))
                             (if res (return res)))
                           
                           (iterate (for i from 0 to (1- (length code)))
                                    (setf (cadr (aref code i)) nil))
                           (setf (caar op) 
                                 (swap (caar op)))))))))
    
steveklabnik/steveklabnik-day08.rs
steveklabnik/steveklabnik-day08.rs
\#[derive(Clone, Copy, Debug, Eq, Hash, PartialEq)]
    enum Op {
      Nop,
      Jmp,
      Acc
    }
    
    fn solve(input: &str) -> (i32, i32) {
      let ops: Vec<\_> = input
          .lines()
          .map(|s| {
              let arg = s[4..].parse().unwrap();
    
              match &s[..3] {
                  "nop" => (Op::Nop, arg),
                  "jmp" => (Op::Jmp, arg),
                  "acc" => (Op::Acc, arg),
                  \_ => unreachable!()
              }
          })
          .collect();
    
      let b = (0..ops.len())
          .filter(|&i| ops[i].0 != Op::Acc)
          .map(|i| {
              let mut ops = ops.clone();
              let op = &mut ops[i].0;
              \*op = if \*op == Op::Nop { Op::Jmp } else { Op::Nop };
              ops
          })
          .filter\_map(|ops| run(&ops).ok())
          .next()
          .unwrap();
    
      (run(&ops).unwrap\_err(), b)
    }
    
    fn run(ops: &[(Op, i32)]) -> Result<i32, i32> {
      let mut set = vec![false; ops.len()];
      let mut pc: u32 = 0;
      let mut acc = 0;
    
      while !std::mem::replace(&mut set[pc as usize], true) {
          match ops[pc as usize] {
              (Op::Nop, \_) => pc += 1,
              (Op::Jmp, arg) => pc = ((pc as i32) + arg) as u32,
              (Op::Acc, arg) => {
                  acc += arg;
                  pc += 1;
              }
          }
    
          if pc as usize == ops.len() {
              return Ok(acc);
          }
      }
    
      Err(acc)
    }
    
unknown-cnile/ucnile-day08.c
unknown-cnile/ucnile-day08.c
\#include <stdlib.h>
    \#include <stdio.h>
    \#include <string.h>
    \#include <sys/types.h>
    \#include <sys/stat.h>
    \#include <fcntl.h>
    \#include <sys/mman.h>
    \#include <unistd.h>
    \#include <stdint.h>
    
    void die(char \*str) {
        fprintf(stderr, "[ERROR] %s\n", str);
        exit(-1);
    }
    
    FILE \*map\_file(const char \*filename) {
        int fd;
        if ((fd = open(filename, O\_RDONLY)) == -1) die("failed to open file");
        struct stat fd\_stat;
        if (fstat(fd, &fd\_stat) == -1) die("failed to stat file");
        void \*data;
        // never unmapped, probably fine
        if ((data = mmap(NULL,
                         fd\_stat.st\_size,
                         PROT\_READ,
                         MAP\_PRIVATE,
                         fd, 0)) == MAP\_FAILED) die("failed to map file");
        close(fd);
        return fmemopen(data, fd\_stat.st\_size, "r");
    }
    
    \#define MAX\_DATA 4096
    
    \#define INS\_ACC 0
    \#define INS\_JMP 1
    \#define INS\_NOP 2
    
    struct ins {
        uint32\_t op;
        uint32\_t val;
    };
    
    struct ins asm\_data[MAX\_DATA];
    int asm\_mark[MAX\_DATA];
    int asm\_len = 0;
    
    \#define MAX\_LINE 256
    
    int exec\_asm() {
        int pos = 0, acc = 0;
        while (1) {
            if ((pos > asm\_len) || (pos < 0)) return 0;
            if (pos == asm\_len) {
                printf("P2: %d\n", acc);
                exit(0);
            } else if (asm\_mark[pos]) {
                memset(asm\_mark, 0, sizeof(asm\_mark));
                return acc;
            }
            asm\_mark[pos] = 1;
            switch (asm\_data[pos].op) {
                case INS\_ACC: acc += asm\_data[pos].val; pos++; break;
                case INS\_JMP: pos += asm\_data[pos].val; break;
                case INS\_NOP: pos++; break;
            }
        }
    }
    
    int main(int argc, char \*\*argv) {
        // read input
        FILE \*fd = map\_file("test.txt");
        char line[MAX\_LINE];
        while (fgets(line, MAX\_LINE, fd) != NULL) {
            char optxt[8];
            int arg;
            if (sscanf(line, "%s %d", optxt, &arg) != 2) break;
            asm\_data[asm\_len].val = arg;
            switch (\*optxt) {
                case &\#39;\n&\#39;:
                case &\#39;\0&\#39;: break;
                case &\#39;a&\#39;: asm\_data[asm\_len++].op = INS\_ACC; break;
                case &\#39;j&\#39;: asm\_data[asm\_len++].op = INS\_JMP; break;
                case &\#39;n&\#39;: asm\_data[asm\_len++].op = INS\_NOP; break;
            }
        }
        printf("P1: %d\n", exec\_asm());
        for (int i = 0; i < asm\_len; i++) {
            if (asm\_data[i].op == INS\_ACC) continue;
            asm\_data[i].op ^= 3;
            exec\_asm();
            asm\_data[i].op ^= 3;
        }
        return 0;
    }
    

Tags: