loading...

Discussion on: Unconditional Challenge: FizzBuzz without `if`

Collapse
avaq profile image
Aldwin Vlasblom

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

const isFizz = n => n % 3 === 0
const isBuzz = n => n % 5 === 0
const complement = f => x => !(f (x))

const fizzbuzz = n => {
  const fizz = [n].filter(isFizz).map(_ => 'Fizz')
  const buzz = [n].filter(isBuzz).map(_ => 'Buzz')
  const num = [n].filter(complement(isFizz)).filter(complement(isBuzz)).map(String)
  return `${fizz.join('')}${buzz.join('')}${num.join('')}`
}
Collapse
kallmanation profile image
Nathan Kallman Author

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 use if, ?:, ||, &&, ?., or ??. (I'll allow .reduce to be used though, as well as .map)

Well done, thanks for commenting!

Collapse
avaq profile image
Aldwin Vlasblom

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.

const isFizz = n => n % 3 === 0
const isBuzz = n => n % 5 === 0
const isNeither = n => !isFizz(n) && !isBuzz(n)

// the magic:
const optional = (f, x) => Array(Number(f(x))).fill(x)

const fizzbuzz = n => {
  const fizz = optional(isFizz, n).map(_ => 'Fizz')
  const buzz = optional(isBuzz, n).map(_ => 'Buzz')
  const num = optional(isNeither, n).map(String)
  return `${fizz.join('')}${buzz.join('')}${num.join('')}`
}
Thread Thread
kallmanation profile image
Nathan Kallman Author

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

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

Thread Thread
yujiri8 profile image
Ryan Westlund

Well, it still uses && which you said wasn't allowed...

Thread Thread
avaq profile image
Aldwin Vlasblom

You are referring to the following clause:

Do this without "secret" conditionals like || and && (in loosely typed languages like JavaScript)

My understanding is that this applies to the usage of such operators as conditionals when they are applied to non-boolean types. For example:

const fizz = n % 3 === 0 && 'Fizz' || String(n)

In my code, it is used strictly on Boolean values, which I don't think was against the rules.

Thread Thread
kallmanation profile image
Nathan Kallman Author

It uses it in a strictly boolean sense, which I'll allow. What isn't allowed is the loose/early-return way JS can use &&; a contrived example that would not pass hard mode:

const fizzbuzz = n => (n % 3 && (n % 5 && n || "Buzz")) || (n % 5 && "Fizz" || "FizzBuzz")

(an easy litmus test: does changing the order of the && expression change the result?)