## Phone Numbers

### August 15, 2017

Make a list of n-digit phone numbers according to the following rules:

1) First digit must not be zero.
2) First digit may be four, but no digits after the first may be four.
3) Any two consecutive digits must be different.
4) The user may specify any set of digits that may not appear in the phone number.

For instance, if n = 3 and the digits 1, 3, 5, 7, and 9 don’t appear in the output, the desired list of three-digit numbers starting with 2, 4, 6, or 8 followed by 0, 2, 6 or 8 without consecutive duplicates is: 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.

Your task is to write a program that generates phone numbers according to the rules given above. When you are finished, you are welcome to read or run a suggested solution, or to post your own solution or discuss the exercise in the comments below.

Pages: 1 2

### 3 Responses to “Phone Numbers”

1. Similar approach – but in perl..

use strict;
my \$n = shift;
my %T = map { (\$_,1) } 4, @ARGV;
my @D = grep { ! exists \$T{\$_} } 1..9; # List of digits not including 0+4 and ones listed...

print join q( ), map { gen( \$n-1, \$_ ) } sort 4,@D; # Loop through 4 and digits above
print "\n";

sub gen {
my(\$l,\$s) = @_;
\$l--;
# Skip if the same o/w call gen again if more digits to add for 0 and digits above...
return map { (\$_ eq substr \$s, -1) ? () : \$l ? gen(\$l,"\$s\$_") : "\$s\$_" } 0, @D;
}

2. Paul said

In Python.

from itertools import filterfalse
ALL = list(range(10))

def tel_nums(length, excl, number=None):
if length == 0:
yield "".join(map(str,number))
elif number is None:
for n in filterfalse((excl + (0,)).__contains__, ALL):
yield from tel_nums(length-1, excl+(4,), [n])
else:
for n in filterfalse((excl + (number[-1],)).__contains__, ALL):
yield from tel_nums(length-1, excl, number+[n])

3. V said

Solution in Ruby. Generates all numbers of n length first then select the ones that match the rules.

def generate(n=3, black_list=[])
(0..9).to_a.
repeated_permutation(n).
select { |xs| valid?(xs, black_list) }.
map(&:join).
map(&:to_i)
end

def valid?(xs, black_list)
xs.first != 0 &&
!xs[1..-1].include?(4) &&
xs[0..-2].zip(xs[1..-1]).map { |a,b| a != b }.all? &&
xs - black_list == xs
end

generate(3,  [1, 3, 5, 7, 9])

outputs:

[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]