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 0
if the number is not interesting.
Note: In Haskell, we use No
, Almost
and Yes
instead of 0
, 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,
0
should come after9
, and not before1
, as in7890
.
‡ For decrementing sequences,0
should come after1
, 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
0
, and less than1,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
0
,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