Sherlock and The Beast This is my solution to this question from Hackerrank.


  Given N (&lt;= 100000), find the largest N-digit number such that:
  
  
  The number has only 3 and 5 as its digits.
  Number of times 3 appears is divisible by 5.
  Number of times 5 appears is divisible by 3.
  
  
  If no such number exists, produce -1.


Please guide me. Is there any optimization or improvement that can be done to the code?

a=0
items=[]

a=int(raw_input(''))
for i in range(0,a):
    items.append(int(raw_input('')))



def Sherlock_and_The_Beast(items):
    for i in items:

        if i&lt;3:
            print -1
        elif i%3==0:
            print int(str(5)*i)
        elif i==5:
            print int(str(3)*i)

        else:
            flag=False
            for j in range(i/3,-1,-1):
                if (i-(3*j))%5==0:
                    flag=True
                    print int(str(5)*(3*j)+str(3)*(i-(3*j)))
                    break
            if not flag:
                print -1




Sherlock_and_The_Beast(items)
I think your code could use some restructuring:


The name Sherlock_and_The_Beast is more applicable as a module name instead of a function name. Now, even though I said 'more applicable', it does not mean I would suggest naming your Python script this. I would instead call it sherlock.py.*
Your function should be named something like generate_decent_number. This gives a better description of what it actually does.
I would have your function take a single integer instead of a list and then return the decent number. Doing so, removes the need for a flag variable.
Use xrange instead of range.


There are also a few style notes to point out:


Use descriptive variable names. Even though i (and to some extent j) have been conventionalized as indexing names, I prefer to be more descriptive. i should be item and j should be num.
Use whitespace appropriately. Put single spaces around assignment or conditional operators:

foo = 'bar'
if foo == 'bar'

I prefer to use not when I can. Because 0 evaluates to False in conditional statements, you can use:

elif not item % 5:


instead of:

elif item%5 == 0:


This is mostly a personal preference. Some people abhor checking for negative conditions.


Past these notes above, your code is simple and straightforward which are both Pythonic conventions.



Here is my version:

def get_decent_number(num_digits):
    if num_digits &lt; 3:
        return -1

    three = str(3)
    five = str(5)
    if not num_digits % 3:
        return five*num_digits
    elif num_digits == 5:
        return three*num_digits

    for num in xrange(num_digits/3, -1, -1):
        diff = num_digits - 3*num
        if not diff % 5:            
            return five*3*num + three*diff

    return -1