|
|
|
@ -1,7 +1,5 @@
|
|
|
|
|
#lang br/quicklang
|
|
|
|
|
#lang br/quicklang ;; http://adventofcode.com/2016/day/14
|
|
|
|
|
(require openssl/md5)
|
|
|
|
|
;; http://adventofcode.com/2016/day/13
|
|
|
|
|
(require graph)
|
|
|
|
|
(provide read-syntax
|
|
|
|
|
(rename-out [mb #%module-begin]))
|
|
|
|
|
|
|
|
|
@ -12,4 +10,32 @@
|
|
|
|
|
|
|
|
|
|
(define-macro (mb SALT)
|
|
|
|
|
#'(#%module-begin
|
|
|
|
|
(md5 (open-input-string SALT))))
|
|
|
|
|
(solve SALT)
|
|
|
|
|
(parameterize ([key-stretch 2017])
|
|
|
|
|
(solve SALT))))
|
|
|
|
|
|
|
|
|
|
(define key-stretch (make-parameter 0))
|
|
|
|
|
(require sugar/cache)
|
|
|
|
|
(define/caching (get-hash salt i)
|
|
|
|
|
(for/fold ([str (string-downcase (format "~a~a" salt i))])
|
|
|
|
|
([i (in-range (key-stretch))])
|
|
|
|
|
(md5 (open-input-string str))))
|
|
|
|
|
|
|
|
|
|
(define (valid? hash salt i)
|
|
|
|
|
(let* ([triple-char-pat (pregexp "(.)\\1\\1")]
|
|
|
|
|
[result (regexp-match triple-char-pat hash)])
|
|
|
|
|
(and result
|
|
|
|
|
(let* ([repeated-char (cadr result)]
|
|
|
|
|
[penta-char-pat (pregexp (format "(~a)\\1\\1\\1\\1" repeated-char))])
|
|
|
|
|
(for/or ([idx (in-range (add1 i) (+ 1001 i))])
|
|
|
|
|
(regexp-match penta-char-pat (get-hash salt idx)))))))
|
|
|
|
|
|
|
|
|
|
(define (solve salt)
|
|
|
|
|
(caar
|
|
|
|
|
(for/fold ([keys empty])
|
|
|
|
|
([i (in-naturals)]
|
|
|
|
|
#:break (= (length keys) 64))
|
|
|
|
|
(define hash (get-hash salt i))
|
|
|
|
|
(if (valid? hash salt i)
|
|
|
|
|
(report* i hash (cons (cons i hash) keys))
|
|
|
|
|
keys))))
|
|
|
|
|