Phone Numbers
August 15, 2017
Here is our solution:
(define (phone-numbers len skips) (let loop ((len (- len 1)) (nums (map list (list-minus (range 1 10) skips)))) (if (zero? len) (map undigits (map reverse nums)) (loop (- len 1) (mappend (lambda (xs) (filter (lambda (xs) (not (= (car xs) (cadr xs)))) (map (lambda (x) (cons x xs)) (list-minus (range 10) (cons 4 skips))))) nums)))))
That packs a lot into a little space. Nums
is initially a list of lists of the possible first digits, excluding 0 and any digits in the skips
list; the list is extended with an additional digit at each pass through loop
. When len
reduces to zero, the accumulated nums
is reformatted as numbers, using two nested maps, then returned. Otherwise, while len
is still positive, the two nested implicit loops of mappend
and map
extend each number in the list by another digit. Mappend
is used because each member of the input list may be extended into several members of the output list. Filter
removes any consecutive duplicates, and map
adds new digits after adding digit 4 to the skip list. Whew!
Here’s a sample run:
> (phone-numbers 3 '(1 3 5 7 9)) (202 206 208 260 262 268 280 282 286 402 406 408 420 426 428 460 462 468 480 482 486 602 606 608 620 626 628 680 682 686 802 806 808 820 826 828 860 862 868)
You can run the program at http://ideone.com/bGBXHD.
Similar approach – but in perl..
In Python.
Solution in Ruby. Generates all numbers of n length first then select the ones that match the rules.
outputs: