+ 3

# More ways to solve FizzBuzz problem? (python)

I want to know if there are more efficient ways to solve this problem. Please tell me. Here's what I did: for fizzbuzz in range(51): if fizzbuzz % 3 == 0 and fizzbuzz % 5 == 0: print("fizzbuzz") continue elif fizzbuzz % 3 == 0: print("fizz"): continue elif fizzbuzz % 5 == 0: print("buzz"): continue print(fizzbuzz)

12 Réponses

+ 3

Everything you did looks fine. Just remove the "continue" statements. They aren't needed whenever you have "elif" conditions.
Whenever you use "elif" it only takes one of the given conditions that are on the same indentation level and conditional segments.
Also, it evaluates from top to bottom. You did right by placing the "AND" condition at the top because that way that will always be checked first.

+ 13

Indi ,
you can remove all the *continue* statements.
all the rest of your code is well done. it has a good readability, and can be maintained easily.

+ 8

Brian ,
have you done a speed test? (you mentioned that sieve approach is faster than modulo approach)

+ 7

for fizzbuzz in range(51):
if fizzbuzz % 15 == 0:
print("fizzbuzz")
elif fizzbuzz % 3 == 0:
print("fizz")
elif fizzbuzz % 5 == 0:
print("buzz")
else:
print(fizzbuzz)
https://www.sololearn.com/discuss/1007334/?ref=app
https://www.sololearn.com/discuss/2543653/?ref=app
https://www.sololearn.com/discuss/3103786/?ref=app
https://www.sololearn.com/discuss/3102368/?ref=app

+ 7

Brian ,
this differs from my test result. the reason may be the test cases. but i still have my doubts, because:
> your code is iterating
1 x time over the complete numbers to generate a *0*-filled list in a list comprehension. you could also use: b = [0] * int(input())
2 x times over defined ranges
1 x time over the complete numbers.
i did it upto number 5_000_000 and x10 repeates. i removed all print() statements and replaced them by *pass*
measuring was done by timeit()

+ 4

print(*('fizz'*(not n%3)+'buzz'*(not n%5) or n for n in range(100)), sep='\n')

+ 4

Sieve approach (faster than modulo):
b=[0 for i in range(1, int(input()))]
for i in range(3, len(b), 3): b[i] |= 1
for i in range(5, len(b), 5): b[i] |= 2
for i in range(1, len(b)):
print((i,"fizz","buzz","fizzbuzz")[b[i]])
My shortest one-liner:
[print("fizz"*(x%3<1)+"buzz"*(x%5<1)or x)for x in range(1,int(input()))]

+ 3

Lothar thank you for the tip for building a zero-filled list.
I used the same approach that you described for testing, though I was only able to use 500,000 iterations per method due to Sololearn timeout.
The modulo operation is expensive enough to make the extra passes economical. Note that the two sieve loops together only visit half of the elements. Counting initialization as 1 pass, the technique has 1.5 extra passes. Though there are 3 loops, I find the loop overhead to be almost negligible.
Here is my test:
https://code.sololearn.com/czBi3KB4Z1Hm/?ref=app

+ 2

The problem with FizzBuzz is that it specifically asks you to provide the answer in order by itterating from 1 to n. So, skipping (say, only itterating over multiples of 5, then only interating multiples of 3) and keeping the result sorted isn't applicable.
This is why most answers look the same, and it's mainly a problem of how you write code (maintainability) rather than how efficiently your program is (computation speed / scalability).

+ 2

Lothar I did time tests in past codes involving modulo, but had not done this one until you asked. Modulo takes longer than most operators, especially assignment and logical ones -- much longer. My sieve approach performs fewer and faster calculations than the if/elif tree structure. So that was the basis of my assertion.
Now in actual timing tests, the speed improvement of my sieve approach was on average about 30% faster.

0

مرحبا