chicken aoc day01 added by chickendan on Wed Jan 30 15:51:25 2019

* Advent of Code Day 01

https://adventofcode.com/2018/day/1

Example input seperated by newlines: -22 +14 -4 -14 +8 +12 +11 ... (around 1000 inputs)
a) What is the resulting frequency after all of the changes in frequency have been applied?
b) What is the first frequency your device reaches twice? (cumulative result)

* Timings

timed via /usr/bin/time -v <cmd>, sorted by runtime:

| compiler | runtime | max mem  | misc                                                        |
|----------+---------+----------+-------------------------------------------------------------|
| rustc    | 0.075 s | 6.48 mb  | verbose, long compile-time, -opt-level=3, by burntsushi     |
| d-ldc    | 0.081 s | 19.19 mb | almost no type annotations, long compile-time, -O3 -release |
| sbcl     | 0.111 s | 45.92 mb | no explicit optimization annotations, sbcl --script 01.fasl |
| csc (v5) | 0.546 s | 30.77 mb | also zero annotations, -O5 -strict-types -w                 |

Chicken interpreted:
  0.826s CPU time, 0.055s GC time (major),
  326222/306789 mutations (total/tracked),
  4/1925 GCs (major/minor), maximum live heap: 9.76 MiB

Sprinkling fx+, (declare (fixnum sum)), ... on top didn't bring down the runtime at all.

* Code samples

** chicken scheme

As a scheme noob, this was a rather straight-forward port from the common lisp version below.

#+BEGIN_SRC scheme
(import (chicken format) srfi-1 srfi-69)

(define (read-input fname)
  (with-input-from-file fname
    (lambda ()
      (let loop ([x (read)] [res '()])
        (if (eof-object? x)
            (reverse res)
            (loop (read) (cons x res)))))))

(define (freq-repetition freqs)
  (let ([seen (make-hash-table)])
    (let loop ([sum 0]
               [freqs (apply circular-list freqs)])
      (if (hash-table-exists? seen sum)
          sum
          (begin (hash-table-set! seen sum #t)
                 (loop (+ (car freqs) sum) (cdr freqs)))))))

(define (main)
  (let ((freqs (read-input "01.input")))
    (printf "Result 1a: ~a~%" (fold + 0 freqs))
    (printf "Result 1b: ~a~%" (freq-repetition freqs))))

(main)
#+END_SRC

** common lisp

#+BEGIN_SRC lisp
(defun make-circular (list)
  (setf (cdr (last list)) list))

(defun freq-repetition (freqs)
  (loop with freqs = (make-circular freqs)
        with seen = (make-hash-table)
          initially (setf (gethash 0 seen) t)
        for x in freqs
        sum x into freq
        if (gethash freq seen)
          return freq
        else do
          (setf (gethash freq seen) t)))

(defun main ()
  (let ((freqs (with-open-file (in "01.input")
                 (loop for x = (read in nil) while x collect x))))
    (format t "Result 1a: ~d~%" (reduce #'+ freqs))
    (format t "Result 1b: ~d~%" (freq-repetition freqs))))

(main)
#+END_SRC

** dlang

#+BEGIN_SRC d
import std.experimental.all;

void main() {
    const freqs = File("01.input").byLine.map!(to!int).array;
    writeln("Result 1a: ", freqs.sum);

    auto seen = [ 0: true ];
    foreach(freq; freqs.cycle.cumulativeFold!"a+b") {
        if (freq in seen) {
            writeln("Result 1b: ", freq);
            break;
        }
        seen[freq] = true;
    }
}
#+END_SRC

** rust by burntsushi

https://github.com/BurntSushi/advent-of-code/blob/master/aoc01/src/main.rs