Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
81
Task/UPC/Racket/upc.rkt
Normal file
81
Task/UPC/Racket/upc.rkt
Normal file
|
|
@ -0,0 +1,81 @@
|
|||
#lang racket
|
||||
|
||||
;; inspired by Kotlin
|
||||
|
||||
(define (is-#? c) (char=? c #\#))
|
||||
|
||||
(define left-digits
|
||||
(for/hash ((i (in-naturals))
|
||||
(c '((#f #f #t #t #f)
|
||||
(#f #t #t #f #f)
|
||||
(#f #t #f #f #t)
|
||||
(#t #t #t #t #f)
|
||||
(#t #f #f #f #t)
|
||||
(#t #t #f #f #f)
|
||||
(#t #f #t #t #t)
|
||||
(#t #t #t #f #t)
|
||||
(#t #t #f #t #t)
|
||||
(#f #f #t #f #t))))
|
||||
(values `(#f ,@c #t) i)))
|
||||
|
||||
(define right-digits (for/hash (([k v] left-digits)) (values (map not k) v)))
|
||||
|
||||
(define (lookup-blocks bits hsh fail)
|
||||
(let recur ((bs bits) (r null))
|
||||
(if (null? bs)
|
||||
(reverse r)
|
||||
(let-values (((bs′ tl) (split-at bs 7)))
|
||||
(let ((d (hash-ref hsh bs′ (λ () (fail (list 'not-found bs′))))))
|
||||
(recur tl (cons d r)))))))
|
||||
|
||||
(define (extract-blocks b fail)
|
||||
(let*-values
|
||||
(((e-l-m-r-e) (map is-#? (string->list (string-trim b))))
|
||||
((_) (unless (= (length e-l-m-r-e) (+ 3 (* 7 6) 5 (* 7 6) 3))
|
||||
(fail 'wrong-length)))
|
||||
((e l-m-r-e) (split-at e-l-m-r-e 3))
|
||||
((_) (unless (equal? e '(#t #f #t)) (fail 'left-sentinel)))
|
||||
((l-m-r e) (split-at-right l-m-r-e 3))
|
||||
((_) (unless (equal? e '(#t #f #t)) (fail 'right-sentinel)))
|
||||
((l m-r) (split-at l-m-r 42))
|
||||
((m r) (split-at m-r 5))
|
||||
((_) (unless (equal? m '(#f #t #f #t #f)) (fail 'mid-sentinel))))
|
||||
(values l r)))
|
||||
|
||||
(define (upc-checksum? ds)
|
||||
(zero? (modulo (for/sum ((m (in-cycle '(3 1))) (d ds)) (* m d)) 10)))
|
||||
|
||||
(define (lookup-digits l r fail (transform values))
|
||||
(let/ec fail-lookups
|
||||
(define ds (append (lookup-blocks l left-digits (λ _ (fail-lookups #f)))
|
||||
(lookup-blocks r right-digits (λ _ (fail-lookups #f)))))
|
||||
(if (upc-checksum? ds)
|
||||
(transform ds)
|
||||
(fail (list 'checksum (transform ds))))))
|
||||
|
||||
(define (decode-upc barcode upside-down fail)
|
||||
(define-values (l r) (extract-blocks barcode fail))
|
||||
(or (lookup-digits l r fail)
|
||||
(lookup-digits (reverse r) (reverse l) fail upside-down)))
|
||||
|
||||
(define (report-upc barcode)
|
||||
(displayln (decode-upc barcode
|
||||
(λ (v) (cons 'upside-down v))
|
||||
(λ (e) (format "invalid: ~s" e)))))
|
||||
|
||||
(define (UPC)
|
||||
(for-each report-upc
|
||||
'(" # # # ## # ## # ## ### ## ### ## #### # # # ## ## # # ## ## ### # ## ## ### # # # "
|
||||
" # # # ## ## # #### # # ## # ## # ## # # # ### # ### ## ## ### # # ### ### # # # "
|
||||
" # # # # # ### # # # # # # # # # # ## # ## # ## # ## # # #### ### ## # # "
|
||||
" # # ## ## ## ## # # # # ### # ## ## # # # ## ## # ### ## ## # # #### ## # # # "
|
||||
" # # ### ## # ## ## ### ## # ## # # ## # # ### # ## ## # # ### # ## ## # # # "
|
||||
" # # # # ## ## # # # # ## ## # # # # # #### # ## # #### #### # # ## # #### # # "
|
||||
" # # # ## ## # # ## ## # ### ## ## # # # # # # # # ### # # ### # # # # # "
|
||||
" # # # # ## ## # # ## ## ### # # # # # ### ## ## ### ## ### ### ## # ## ### ## # # "
|
||||
" # # ### ## ## # # #### # ## # #### # #### # # # # # ### # # ### # # # ### # # # "
|
||||
" # # # #### ## # #### # # ## ## ### #### # # # # ### # ### ### # # ### # # # ### # # "
|
||||
; first element again, with corrupted second digit
|
||||
" # # # ## # ## # ## ### ## ### ## #### # # # ## ## # # ## ## ### # ## ## ### # # # ")))
|
||||
|
||||
(module+ main (UPC))
|
||||
Loading…
Add table
Add a link
Reference in a new issue