Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Nathan Kallman
Nathan Kallman

Posted on • Edited on • Originally published atkallmanation.com

     

Unconditional Challenge: FizzBuzz without `if`

As the title says, make a classic FizzBuzz function or method without usingif/else (or equivalents like ternaries,?:, sneaky).

Specifically:

  1. The function should accept one argument, assume it will always be a positive integer.
  2. The function should return a string (or something coercible into a string in loosely typed languages) according to the following rules:
    1. If the given number is divisible by3, then returnFizz
    2. If the given number is divisible by5, then returnBuzz
    3. If the given number is divisible by both3 and5, then return the combinationFizzBuzz
    4. If the given number is none of those things, then return the given number

The expected outputs for the first fifteen numbers in order is:

1,2,Fizz,4,Buzz,Fizz,7,8,Fizz,Buzz,11,Fizz,13,14,FizzBuzz
Enter fullscreen modeExit fullscreen mode

Hard mode

Do this without "secret" conditionals like|| and&& (in loosely typed languages like JavaScript) ornull coalescing operators like?? ornull safe operators like?. or&..

Also no looping constructs that could be abused into a conditional likewhile orfor.

Hint number 1

I taggedfunctional on this post because functional programming can be used to solve this.

Hint number 2

I taggedoop on this post because the original object oriented concepts of message passing can be used to solve this.


Post below with your answers!

Think this is impossible? I'll post my own answers in both FP and OOP styles next week.

(If you were hoping for the next installment of myWith Only CSS series, styling radio buttons, that's coming on Monday,follow me so you won't miss it!)

Top comments(48)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss
CollapseExpand
 
vonheikemen profile image
Heiker
Web developer from Venezuela. I like solving problems. Currently trying to improve my communication skills
  • Pronouns
    he/him
  • Joined
• Edited on• Edited

I'm sure I could make a fancy function composition but my brain is satisfied with this.

constTroo=(iff,elz)=>iff;constFalz=(iff,elz)=>elz;constIf=(boolz,iff,elz)=>boolz(iff,elz);constBoolz={from_bool:bool=>[Falz,Troo][Number(bool)],};constis_fizz=n=>Boolz.from_bool(n%3===0);constis_buzz=n=>Boolz.from_bool(n%5===0);constfizzbuzz=n=>If(is_fizz(n),If(is_buzz(n),"FizzBuzz","Fizz"),If(is_buzz(n),"Buzz",n));constrange=(end)=>Array.from({length:end},(val,index)=>index+1);console.log(range(15).map(fizzbuzz).join(","));
CollapseExpand
 
bashunaimiroy profile image
Bashu Naimi-Roy
I write front-end code, with a focus on empathy, good documentation, and Vue.
  • Location
    Montreal
  • Work
    Intermediate Front End Developer at Diff Agency
  • Joined

this blew me away, thank you for posting it

CollapseExpand
 
vonheikemen profile image
Heiker
Web developer from Venezuela. I like solving problems. Currently trying to improve my communication skills
  • Pronouns
    he/him
  • Joined

Glad you like it. I got the idea from this talk by Anjana Vakil.

Thread Thread
 
bashunaimiroy profile image
Bashu Naimi-Roy
I write front-end code, with a focus on empathy, good documentation, and Vue.
  • Location
    Montreal
  • Work
    Intermediate Front End Developer at Diff Agency
  • Joined

Aha! She has several functional programming in JavaScript videos I've been putting off for a while, I think this is my cue to watch one. I'd like to better understand your solution. Cheers!

CollapseExpand
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

Awesome! I think you're really getting at the heart of the prompt by definingtrue andfalse as functions.

CollapseExpand
 
jpantunes profile image
JP Antunes
  • Location
    Netherlands
  • Joined

Does this one count for the hard mode?

constfizzBuzz=n=>{constmapper=(arr,modulo,txt)=>arr.filter(e=>e%modulo==0).forEach(e=>arr[arr.indexOf(e)]=txt);letx=1;constrange=[...Array(n)].map(_=>x++)mapper(range,15,'FizzBuzz');mapper(range,5,'Buzz');mapper(range,3,'Fizz');returnrange.toString();}
Enter fullscreen modeExit fullscreen mode
CollapseExpand
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

Nice solution! For hard mode, I think either do it without.filter or show how.filter could be implemented according to the rules.

CollapseExpand
 
jpantunes profile image
JP Antunes
  • Location
    Netherlands
  • Joined

How about with for loops?

constfizzBuzz=n=>{letx=1;constrange=[...Array(n)].map(_=>x++);for(leti=2;i<=n;i+=3)range[i]='Fizz';for(leti=4;i<=n;i+=5)range[i]='Buzz';for(leti=14;i<=n;i+=15)range[i]='FizzBuzz';returnrange.toString();}
Thread Thread
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

Nice! I'll accept it even though I said nofor loops because I like that you used the stepping statement to simply go through the multiples of 3,5,15. That's creative!

I was more expecting someone to abuse thei <= n into then % 3 type of check in a traditional fizz buzz. (especially abusingwhile(n % 3) into a more convolutedif)

Thread Thread
 
jpantunes profile image
JP Antunes
  • Location
    Netherlands
  • Joined

I missed that! Sorry, but I was running out of ideas :-) Looking forward to seeing your solution(s)!

CollapseExpand
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

Happy Juneteenth! I love everyone's approaches here, it's fun to see the way each person thinks through the problem.

I'll be posting my answers on Monday (along with the next installment ofWith Only CSS) so encourage your friends to give this a shot over the weekend (or take another go yourself)!

Follow me and react with a 🔖 so you remember to come back and see what I post here.

Drop a 🦄 or ❤️ if you'd be interested in some follow up posts going more in depth into each (OO/FP) solution: how they work; how they are similar; and how they are different.

Thanks everyone who took the time to post a solution to my little challenge; I'll see you all on Monday!

CollapseExpand
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

And here is my object-oriented approach (deeper article on it to come soon)

constbaseBoolean={setThen:function(then){return{...this,then};},setOtherwise:function(otherwise){return{...this,otherwise};},};constobjectOrientedTrue={...baseBoolean,evaluate:function(){returnthis.then;},};constobjectOrientedFalse={...baseBoolean,evaluate:function(){returnthis.otherwise;},};constobjectOrientedNumber={value:0,isaMultipleCache:[objectOrientedFalse],setValue:function(n){return{...this,value:n,isaMultipleCache:[objectOrientedTrue,...Array(n).fill(objectOrientedFalse)]};},isaMultipleOf:function(dividend){returnthis.isaMultipleCache[dividend.value%this.value];}};constobjectOrientedFizzBuzz={for:function(n){constnumber=objectOrientedNumber.setValue(n);returnthis.three.isaMultipleOf(number).setThen(this.five.isaMultipleOf(number).setThen("FizzBuzz").setOtherwise("Fizz").evaluate()).setOtherwise(this.five.isaMultipleOf(number).setThen("Buzz").setOtherwise(number.value).evaluate()).evaluate();},three:objectOrientedNumber.setValue(3),five:objectOrientedNumber.setValue(5),};

Similarly to the functional approach; the main part of this solution is defining "true" and "false" as objects. But now instead of parameters, the objects have the same interface and return one or the other of the attributes set on the object.

CollapseExpand
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined
• Edited on• Edited

As promised, here is my functional approach to solving this (deeper article on it to come soon)

constfunctionalTrue=(onTrue,onFalse)=>onTrue;constfunctionalFalse=(onTrue,onFalse)=>onFalse;constisDivisible=(dividend,divisor)=>[functionalTrue,...Array(divisor).fill(functionalFalse)][dividend%divisor];constfunctionalFizzBuzz=(n)=>{constdivisible_by_three=isDivisible(n,3);constdivisible_by_five=isDivisible(n,5);returndivisible_by_three(divisible_by_five("FizzBuzz","Fizz"),divisible_by_five("Buzz",n));};

Similar to Heiker's solution above; the main part of this solution is defining "true" and "false" as functions taking the same two parameters but returning one or the other.

CollapseExpand
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined
• Edited on• Edited

You can see both solutions in action on this codepen (planning one final post doing a compare/contrast between the two approaches)

CollapseExpand
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

I think your.get is a secret conditional. (It will return the value at the givenkey or the defaultIF the value is undefined)

If you can show how to implement.get without anif then I think this is a great answer!

CollapseExpand
 
avaq profile image
Aldwin Vlasblom
FP-in-JS enthousiast; Author of https://github.com/fluture-js/Fluture
  • Location
    Rotterdam
  • Work
    Freelance software architect and developer
  • Joined

Do you consider something like this cheating, because it builds onfilter, a built-in, to handle the conditional logic?

constisFizz=n=>n%3===0constisBuzz=n=>n%5===0constcomplement=f=>x=>!(f(x))constfizzbuzz=n=>{constfizz=[n].filter(isFizz).map(_=>'Fizz')constbuzz=[n].filter(isBuzz).map(_=>'Buzz')constnum=[n].filter(complement(isFizz)).filter(complement(isBuzz)).map(String)return`${fizz.join('')}${buzz.join('')}${num.join('')}`}
CollapseExpand
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

Clever! I'll accept it for the normal challenge :)

If you want hard mode though, I think you'll have to show an implementation of.filter that doesn't useif,?:,||,&&,?., or??. (I'll allow.reduce to be used though, as well as.map)

Well done, thanks for commenting!

CollapseExpand
 
avaq profile image
Aldwin Vlasblom
FP-in-JS enthousiast; Author of https://github.com/fluture-js/Fluture
  • Location
    Rotterdam
  • Work
    Freelance software architect and developer
  • Joined
• Edited on• Edited

Okay, well, my next solution is probably not what you were expecting. It builds on the idea that a boolean can be used as a number. I think it meets the hardcore requirements.

constisFizz=n=>n%3===0constisBuzz=n=>n%5===0constisNeither=n=>!isFizz(n)&&!isBuzz(n)// the magic:constoptional=(f,x)=>Array(Number(f(x))).fill(x)constfizzbuzz=n=>{constfizz=optional(isFizz,n).map(_=>'Fizz')constbuzz=optional(isBuzz,n).map(_=>'Buzz')constnum=optional(isNeither,n).map(String)return`${fizz.join('')}${buzz.join('')}${num.join('')}`}
Thread Thread
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

Very nice! I think you have met the hardcore requirements.

And I think slightly less code than my functional solution will be, well done!

CollapseExpand
 
miketalbot profile image
Mike Talbot ⭐
Serial CTO
  • Location
    Bristol, UK
  • Work
    Chief Technology Officer
  • Joined
• Edited on• Edited
functionmap(compare,say,next=v=>v){returnfunction(value){return[()=>say,next][Math.sign(compare(value))](value)}}constprocess=map(v=>(v%3)+(v%5),"fizzbuzz",map(v=>v%5,"buzz",map(v=>v%3,"fizz")))for(leti=1;i<31;i++){console.log(process(i))}
Enter fullscreen modeExit fullscreen mode
CollapseExpand
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

Well done! Clever use ofMath.sign to select either the first or second element from an array

CollapseExpand
 
miketalbot profile image
Mike Talbot ⭐
Serial CTO
  • Location
    Bristol, UK
  • Work
    Chief Technology Officer
  • Joined
• Edited on• Edited

Slightly shorter without bothering to call out for variable potential conditions and using anons:

letmap=(compare,say,next=v=>v)=>v=>[()=>say,next][Math.sign(v%compare)](v)constprocess=map(15,"FizzBuzz",map(5,"Buzz",map(3,"Fizz")))
Enter fullscreen modeExit fullscreen mode
CollapseExpand
 
vidit1999 profile image
Vidit Sarkar
Studying Computer Science & Engineering.Prefer to write clean and easy-to-understand code.Languages I use Python, C++, C, Java Script and Java.
  • Location
    India
  • Education
    Bachelor of Computer Science & Engineering
  • Joined

Thanks for the problem. I guess this will not satisfy your conditions, but here is my solution,

constfizzbuzz=n=>(!(n%15)&&"FizzBuzz")||(!(n%5)&&"Buzz")||(!(n%3)&&"Fizz")||n
Enter fullscreen modeExit fullscreen mode
CollapseExpand
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

It's a nice answer! It satisfies the normal rules (noif or?:)

Thanks for taking the time to submit a solution!

CollapseExpand
 
vidit1999 profile image
Vidit Sarkar
Studying Computer Science & Engineering.Prefer to write clean and easy-to-understand code.Languages I use Python, C++, C, Java Script and Java.
  • Location
    India
  • Education
    Bachelor of Computer Science & Engineering
  • Joined

Thanks for the reply. I think re-submission is also allowed. So, here is a C++ solution, which again, may not satisfy all your conditions.

stringfizzbuzz(intn){stringnum_string=to_string(n);stringall_options[5][3]={{"FizzBuzz","Buzz","Buzz"},{"Fizz",num_string,num_string},{"Fizz",num_string,num_string},{"Fizz",num_string,num_string},{"Fizz",num_string,num_string}};returnall_options[n%5][n%3];}
Thread Thread
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

Well done! I think you've got a solution

CollapseExpand
 
jpantunes profile image
JP Antunes
  • Location
    Netherlands
  • Joined

Still not perfect, but this one comes with a special thanks to Mr.Kevlin Henney

constfizzBuzz=n=>{constisFizzBuzz=n=>({false:'',true:'Fizz'}[n%3==0]+{false:'',true:'Buzz'}[n%5==0]||n.toString());letx=1;return[...Array(n)].map(_=>isFizzBuzz(x++)).toString();}
Enter fullscreen modeExit fullscreen mode
CollapseExpand
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

Nice! I like how it usesfalse andtrue as keys on an object to select the resulting string.

If you can get rid of the|| usage, then this will meet the hard mode requirements...

CollapseExpand
 
jpantunes profile image
JP Antunes
  • Location
    Netherlands
  • Joined
• Edited on• Edited

Well Mr. Henney has a great answer:

constfizzBuzz=n=>{consttest=(d,s,x)=>n%d==0?_=>s+x(''):x;constfizz=x=>test(3,'Fizz',x);constbuzz=x=>test(5,'Buzz',x);returnfizz(buzz(x=>x))(n.toString());}

edit: but it still has a conditional...

CollapseExpand
 
indebanvdhamer profile image
Eric Nijman
  • Joined

This could probably get simplified (I've seen the one-liner of this one), but I still wanted to post mine

constfbMap=[()=>'FizzBuzz',String,String,()=>'Fizz',String,()=>'Buzz',()=>'Fizz',String,String,()=>'Fizz',()=>'Buzz',String,()=>'Fizz',String,String,];constfizzBuzz=x=>fbMap[x%fbMap.length](x);
Enter fullscreen modeExit fullscreen mode
CollapseExpand
 
bashunaimiroy profile image
Bashu Naimi-Roy
I write front-end code, with a focus on empathy, good documentation, and Vue.
  • Location
    Montreal
  • Work
    Intermediate Front End Developer at Diff Agency
  • Joined

holy COW did I find out a lot of things about object destructuring while making this. Thanks for the challenge, Nathan. It was so great to notice how instinctively I reach for a conditional.

CollapseExpand
 
kallmanation profile image
Nathan Kallman
Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

I'm glad you liked it! I think its good to do a little self reflection on the way we do things every once in a while.

And WOW is that an impressive use of destructuring in JS. I knew about each of those things independently; I never have thought about putting them all together like that!

Some comments may only be visible to logged-in visitors.Sign in to view all comments.

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Husband; Father; Software Engineer; Gamer; Tinkerer; Writing about code on DEV.
  • Location
    Columbus, OH
  • Education
    B.S. Computer Engineering
  • Work
    Engineering Manager at Root Insurance
  • Joined

More fromNathan Kallman

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp