I have been attempting google foobar and in the second level i got the task named please-pass-the-coded-messages
. below is the task:
==============================
You need to pass a message to the bunny workers, but to avoid detection, the code
you agreed to use is... obscure, to say the least. The bunnies are given food on
standard-issue plates that are stamped with the numbers 0-9 for easier sorting,
and you need to combine sets of plates to create the numbers in the code. The
signal that a number is part of the code is that it is divisible by 3. You can do
smaller numbers like 15 and 45 easily, but bigger numbers like 144 and 414 are a
little trickier. Write a program to help yourself quickly create large numbers
for use in the code, given a limited number of plates to work with.
You have L, a list containing some digits (0 to 9). Write a function solution(L)
which finds the largest number that can be made from some or all of these digits
and is divisible by 3. If it is not possible to make such a number, return 0 as
the solution. L will contain anywhere from 1 to 9 digits. The same digit may
appear multiple times in the list, but each element in the list may only be used
once.
Languages
=========
To provide a Java solution, edit Solution.java
To provide a Python solution, edit solution.py
Test cases
==========
Your code should pass the following test cases.
Note that it may also be run against hidden test cases not shown here.
-- Java cases --
Input:
Solution.solution({3, 1, 4, 1})
Output:
4311
Input:
Solution.solution({3, 1, 4, 1, 5, 9})
Output:
94311
-- Python cases --
Input:
solution.solution([3, 1, 4, 1])
Output:
4311
Input:
solution.solution([3, 1, 4, 1, 5, 9])
Output:
94311
Use verify [file] to test your solution and see how it does. When you are finished editing your code, use submit [file] to submit your answer. If your solution passes the test cases, it will be removed from your home folder.
I have tried a solution which is working very correct in my IDE(note I wanted a solution without any library)
def solution(l):
# Your code here
if (len(l) == 1 and l[0] % 3 != 0) or (len(l) == 0):
return 0
number = formGreatestNumber(l)
remainder = number % 3
if remainder == 0:
result = formGreatestNumber(l)
return result
result = removeUnwanted(l, remainder)
return result
def formGreatestNumber(li):
li.sort(reverse=True) # descending order
li = [str(d) for d in li] # each digit in string
number = 0
if len(li) > 0:
number = int("".join(li)) # result
return number
def removeUnwanted(l, remainder):
possibleRemovals = [i for i in l if i % 3 == remainder]
if len(possibleRemovals) > 0:
l.remove(min(possibleRemovals))
result = formGreatestNumber(l)
return result
pairs = checkForTwo(l, remainder)
if len(pairs) > 0:
for ind in pairs:
l.remove(ind)
result = formGreatestNumber(l)
return result
else:
divisibleDigits = [d for d in l if d % 3 == 0]
if len(divisibleDigits) > 0:
result = formGreatestNumber(divisibleDigits)
return result
else:
return 0
def checkForTwo(l, remainder): # check of (sum of any two pairs - remainder) is divisible by 3
result = []
for i in range(len(l)):
for j in range(i+1, len(l)):
if ((l[i]+l[j])-remainder) % 3 == 0:
result.append(l[i])
result.append(l[j])
return result
return []
print(solution([]))
print(solution([1]))
print(solution([9]))
print(solution([3, 1, 4, 1, 9, 2, 5, 7]))
however it is on verifying showing:
Verifying solution...
Test 1 passed!
Test 2 passed!
Test 3 failed [Hidden]
Test 4 passed! [Hidden]
Test 5 passed! [Hidden]
so where is the error i am not noticing and is there any other way without any library like itertools?
I won't give away the code and spoil the fun for you, I'll perhaps try to explain the intuition.
About your code, I think the (2nd part of) the function removeUnwanted()
is problematic here.
Let's see.
So first off, you'd arrange the input digits into a single number, in order from largest to smallest, which you've already done.
Then if the number formed isn't divisible by 3, try removing the smallest digit.
If that doesn't work, reinsert the smallest digit and remove the 2nd smallest digit, and so on.
Once you're done with removing all possible digits one at a time, try removing digits two at a time, starting with the two smallest.
If any of these result in a number that is divisible by 3, you're done.
Observe that you'll never need to remove more than 2 digits for this problem. The only way it's impossible to form the required number is if there are 2 or lesser digits and they are both either in the set {1,4,7} or {2,5,8}.
Edit: More about your code -
The initial part of your removeUnwanted()
looks okay where you check if there's a single digit in the number which can be removed, removing the minimum from the choice of single digits and getting the answer.
I reckon the problem lies in your function checkForTwo()
, which you call subsequently in removeUnwanted
.
When you're passing the list to checkForTwo()
, observe that the list is actually sorted in the decreasing order. This is because li.sort(reverse=True)
in your function formGreatestNumber()
sorted the list in place, which means the content of list l
was sorted in descending order too.
And then in checkForTwo()
, you try to find a pair that satisfies the required condition, but you're looping from the biggest 2 pairs that can possibly be removed. i
starts from 0 and j
starts from i+1 which is 1
, and since your list is in descending order, you're trying to remove the biggest 2 elements possible.
A quick fix would be to sort the list in ascending order and then proceed further iterate through the list in reverse order, because since the list is sorted in descending order already, reverse iteration gives you the list in ascending order and saves us from re-sorting which would normally cost an additional O(NlogN) time.