Keypad Errors
August 2, 2016
The match function returns #t if the target matches the key input with 0 or 1 stuck keys, or #f otherwise:
(define (match target keyed)
(let ((ts (digits target)) (ks (digits keyed)))
(if (equal? ts ks) #t
(let loop ((ds (range 10)))
(if (null? ds) #f
(if (equal? (remove (car ds) ts) ks) #t
(loop (cdr ds))))))))
The first if considers the case where no keys are stuck, then the loop considers each digit in turn, removes all occurrences of the digit, and compares:
> (match 18684 164) #t > (match 17674 164) #t > (match 18684 165) #f > (match 18684 18685) #f
We used digits, remove and range from the Standard Prelude. You can run the program at http://ideone.com/EJJ7oR.
($pin, $v) = @ARGV; my %x=map{eval"$pin=~y{$_}{}dr",1}0..9; print exists $x{$v} ? 'MATCH' : 'NO MATCH',"\n";