The challenge
"7777…8?!??!", exclaimed Bob, "I missed it again! Argh!" Every time there's an interesting number coming up, he notices and then promptly forgets. Who doesn't like catching those one-off interesting mileage numbers?
Let’s make it so Bob never misses another interesting number. We’ve hacked into his car’s computer, and we have a box hooked up that reads mileage numbers. We’ve got a box glued to his dash that lights up yellow or green depending on whether it receives a 1
or a 2
(respectively).
It’s up to you, intrepid warrior, to glue the parts together. Write the function that parses the mileage number input, and returns a 2
if the number is “interesting” (see below), a 1
if an interesting number occurs within the next two miles, or a `` if the number is not interesting.
Note: In Haskell, we use No
, Almost
and Yes
instead of ``, 1
and 2
.
“Interesting” Numbers
Interesting numbers are 3-or-more digit numbers that meet one or more of the following criteria:
- Any digit followed by all zeros:
100
,90000
- Every digit is the same number:
1111
- The digits are sequential, incementing†:
1234
- The digits are sequential, decrementing‡:
4321
- The digits are a palindrome:
1221
or73837
- The digits match one of the values in the
awesome_phrases
array
† For incrementing sequences,
should come after
9
, and not before1
, as in7890
.
‡ For decrementing sequences,should come after
1
, and not before9
, as in3210
.
So, you should expect these inputs and outputs:
# "boring" numbers
is_interesting(3, [1337, 256]) # 0
is_interesting(3236, [1337, 256]) # 0
# progress as we near an "interesting" number
is_interesting(11207, []) # 0
is_interesting(11208, []) # 0
is_interesting(11209, []) # 1
is_interesting(11210, []) # 1
is_interesting(11211, []) # 2
# nearing a provided "awesome phrase"
is_interesting(1335, [1337, 256]) # 1
is_interesting(1336, [1337, 256]) # 1
is_interesting(1337, [1337, 256]) # 2
Error Checking
- A number is only interesting if it is greater than
99
! - Input will always be an integer greater than ``, and less than
1,000,000,000
. - The
awesomePhrases
array will always be provided, and will always be an array, but may be empty. (Not everyone thinks numbers spell funny words…) - You should only ever output ``,
1
, or2
.
Test cases
test.describe("Basic inputs")
test.it("Should handle {0}".format(format_msg(0, "boring numbers")))
test.assert_equals(is_interesting(1, []), 0, result_msg(1, 0))
test.assert_equals(is_interesting(30, []), 0, result_msg(30, 0))
test.assert_equals(is_interesting(88, []), 0, result_msg(88, 0))
test.assert_equals(is_interesting(97, []), 0, result_msg(97, 0))
test.assert_equals(is_interesting(7382, []), 0, result_msg(7382, 0))
test.assert_equals(is_interesting(99919911, []), 0, result_msg(99919911, 0))
test.it("Should handle {0}".format(format_msg(0, "ordered yet still boring numbers")))
test.assert_equals(is_interesting(7540, []), 0, result_msg(7540, 0))
test.assert_equals(is_interesting(1590, []), 0, result_msg(1590, 0))
Some solutions in Python code
Option 1 (using helper functions):
def is_incrementing(number): return str(number) in '1234567890'
def is_decrementing(number): return str(number) in '9876543210'
def is_palindrome(number): return str(number) == str(number)[::-1]
def is_round(number): return set(str(number)[1:]) == set('0')
def is_interesting(number, awesome_phrases):
tests = (is_round, is_incrementing, is_decrementing,
is_palindrome, awesome_phrases.__contains__)
for num, color in zip(range(number, number+3), (2, 1, 1)):
if num >= 100 and any(test(num) for test in tests):
return color
return 0
Option 2 (all inline):
def is_good(n, awesome):
return n in awesome or str(n) in "1234567890 9876543210" or str(n) == str(n)[::-1] or int(str(n)[1:]) == 0
def is_interesting(n, awesome):
if n > 99 and is_good(n, awesome):
return 2
if n > 97 and (is_good(n + 1, awesome) or is_good(n + 2, awesome)):
return 1
return 0
Option 3 (using any
):
def is_interesting(number, awesome_phrases):
for i in [number, number+1, number+2]:
if i<100 :
continue
j=str(i)
if any([
i in awesome_phrases,
all([j[x]=='0' for x in range(1,len(j))]),
all([j[x]==j[0] for x in range(1,len(j))]),
j == j[::-1],
j in '1234567890',
j in '9876543210'
]):
return 2-bool(number-i)
return 0
Option 4 (using zip
):
def is_interesting(number, awesome_phrases):
for r, num in zip((2, 1, 1), range(number, number + 3)):
num_str = str(num)
if num in awesome_phrases or num > 99 and (int(num_str[1:]) == 0 or num_str[::-1] == num_str or num_str in '1234567890' or num_str in '9876543210'):
return r
return 0