; IBAN
(define (split n xs)
(let loop ((n n) (xs xs) (zs '()))
(if (or (zero? n) (null? xs))
(values (reverse zs) xs)
(loop (- n 1) (cdr xs) (cons (car xs) zs)))))
(define (flatten xs)
(cond ((null? xs) xs)
((pair? xs)
(append (flatten (car xs))
(flatten (cdr xs))))
(else (list xs))))
(define (iban str)
(let-values (((start end) (split 4 (string->list str))))
(let loop ((cs (append end start)) (zs (list)))
(cond ((null? cs)
(string->number
(list->string
(flatten
(reverse zs)))))
((char-alphabetic? (car cs))
(loop (cdr cs)
(cons (string->list
(number->string
(- (char->integer (car cs)) 55)))
zs)))
(else (loop (cdr cs) (cons (car cs) zs)))))))
(define (valid? str) (= 1 (modulo (iban str) 97)))
(define (gen str) (- 98 (modulo (iban str) 97)))
(display (valid? "GB82WEST12345698765432")) (newline)
(display (gen "GB00WEST12345698765432")) (newline)
OyBJQkFOCgooZGVmaW5lIChzcGxpdCBuIHhzKQoJKGxldCBsb29wICgobiBuKSAoeHMgeHMpICh6cyAnKCkpKQoJICAoaWYgKG9yICh6ZXJvPyBuKSAobnVsbD8geHMpKQoJICAgICAgKHZhbHVlcyAocmV2ZXJzZSB6cykgeHMpCgkgICAgICAobG9vcCAoLSBuIDEpIChjZHIgeHMpIChjb25zIChjYXIgeHMpIHpzKSkpKSkKCihkZWZpbmUgKGZsYXR0ZW4geHMpCgkoY29uZCAoKG51bGw/IHhzKSB4cykKCSAgICAgICgocGFpcj8geHMpCgkgICAgICAgIChhcHBlbmQgKGZsYXR0ZW4gKGNhciB4cykpCgkgICAgICAgICAgICAgICAgKGZsYXR0ZW4gKGNkciB4cykpKSkKCSAgICAgIChlbHNlIChsaXN0IHhzKSkpKQoKKGRlZmluZSAoaWJhbiBzdHIpCiAgKGxldC12YWx1ZXMgKCgoc3RhcnQgZW5kKSAoc3BsaXQgNCAoc3RyaW5nLT5saXN0IHN0cikpKSkKICAgIChsZXQgbG9vcCAoKGNzIChhcHBlbmQgZW5kIHN0YXJ0KSkgKHpzIChsaXN0KSkpCiAgICAgIChjb25kICgobnVsbD8gY3MpCiAgICAgICAgICAgICAgKHN0cmluZy0+bnVtYmVyCiAgICAgICAgICAgICAgICAobGlzdC0+c3RyaW5nCiAgICAgICAgICAgICAgICAgIChmbGF0dGVuCiAgICAgICAgICAgICAgICAgICAgKHJldmVyc2UgenMpKSkpKQogICAgICAgICAgICAoKGNoYXItYWxwaGFiZXRpYz8gKGNhciBjcykpCiAgICAgICAgICAgICAgKGxvb3AgKGNkciBjcykKICAgICAgICAgICAgICAgICAgICAoY29ucyAoc3RyaW5nLT5saXN0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAobnVtYmVyLT5zdHJpbmcKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKC0gKGNoYXItPmludGVnZXIgKGNhciBjcykpIDU1KSkpCiAgICAgICAgICAgICAgICAgICAgICAgICAgenMpKSkKICAgICAgICAgICAgKGVsc2UgKGxvb3AgKGNkciBjcykgKGNvbnMgKGNhciBjcykgenMpKSkpKSkpCgooZGVmaW5lICh2YWxpZD8gc3RyKSAoPSAxIChtb2R1bG8gKGliYW4gc3RyKSA5NykpKQooZGVmaW5lIChnZW4gc3RyKSAoLSA5OCAobW9kdWxvIChpYmFuIHN0cikgOTcpKSkKCihkaXNwbGF5ICh2YWxpZD8gIkdCODJXRVNUMTIzNDU2OTg3NjU0MzIiKSkgKG5ld2xpbmUpCihkaXNwbGF5IChnZW4gIkdCMDBXRVNUMTIzNDU2OTg3NjU0MzIiKSkgKG5ld2xpbmUp