Commits

Taylor Venable committed cada0be

Solution for #079.

Comments (0)

Files changed (1)

+(define-structure pin-digit value left right)
+
+(define list-range
+  (lambda (start end)
+    (let loop ((result '()) (i start))
+      (if (> i end)
+        (reverse result)
+        (loop (cons i result) (+ i 1))))))
+
+(define make-new-pin-digit
+  (lambda (v n)
+    (vector-set! v n (make-pin-digit n (make-vector 10 #f) (make-vector 10 #f)))
+    (vector-ref v n)))
+
+(define make-pin-vector
+  (lambda ()
+    (with-input-from-file
+      "keylog.txt"
+      (lambda ()
+        (let ((result (make-vector 10 #f)))
+          (let loop ()
+            (let ((line (read-line)))
+              (if (eof-object? line)
+                result
+                (let* ((lst (map (lambda (c) (- (char->integer c) (char->integer #\0))) (string->list line)))
+                       (fst (or (vector-ref result (list-ref lst 0)) (make-new-pin-digit result (list-ref lst 0))))
+                       (snd (or (vector-ref result (list-ref lst 1)) (make-new-pin-digit result (list-ref lst 1))))
+                       (trd (or (vector-ref result (list-ref lst 2)) (make-new-pin-digit result (list-ref lst 2)))))
+                  (vector-set! (pin-digit-right fst) (pin-digit-value snd) #t)
+                  (vector-set! (pin-digit-left snd) (pin-digit-value fst) #t)
+                  (vector-set! (pin-digit-right snd) (pin-digit-value trd) #t)
+                  (vector-set! (pin-digit-left trd) (pin-digit-value snd) #t)
+                  (loop))))))))))
+
+(define remove-digit
+  (lambda (v n)
+    (vector-for-each v (lambda (p)
+                         (if p
+                           (vector-set! (pin-digit-left p) n #f))))))
+
+;; Determines how many fields have been set to a true value in a vector.
+
+(define number-set
+  (lambda (v)
+    (let loop ((result 0) (i 0))
+      (if (>= i (vector-length v))
+        result
+        (loop (if (vector-ref v i) (+ result 1) result) (+ i 1))))))
+
+;; Returns the PIN digit which has no digits to the left of it.
+;; As a side effect, also removes the digit from the list so it won't be checked again.
+
+(define none-on-the-left
+  (lambda (v)
+    (let loop ((i 0))
+      (if (>= i (vector-length v))
+        #f
+        (if (and (vector-ref v i) (zero? (number-set (pin-digit-left (vector-ref v i)))))
+          (begin
+            (vector-set! v i #f)
+            i)
+          (loop (+ i 1)))))))
+
+(define solve
+  (lambda ()
+    (let ((pins (make-pin-vector)))
+      (let loop ()
+        (let ((next (none-on-the-left pins)))
+          (if next
+            (begin
+              (display next)
+              (newline)
+              (remove-digit pins next)
+              (loop))
+            pins))))))
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.