Last modified on 29 July 2013, at 11:01

# XQuery/Fizzbuzz

see [1] for the full set of executablescripts and timing comparisons.

Here's an XQuery solution to the FizzBuzz problem posed in David Patterson's blog.. who wrote an XSLT solution.

Chris Wallace wrote this solution to David's configurable version of the problem:

```let \$config :=
<fizzbuzz>
<range min="1" max="100"/>
<test>
<mod value="3" test="0">Fizz</mod>
<mod value="5" test="0">Buzz</mod>
</test>
</fizzbuzz>

return
string-join(
for \$i in (\$config/range/@min to \$config/range/@max)
let \$s :=
for \$mod in \$config/test/mod
return
if (\$i mod \$mod/@value = \$mod/@test)
then string(\$mod)
else ()
return
if (exists(\$s))
then string-join(\$s,' ')
else string(\$i),
"
"
)

```

Execute

The parameterisation of the algorithm was in the original problem as proposed by David Patterson. Simpler solutions are possible if the parameters are fixed.

Here is a solution from Jim Fuller:

```for \$n in (1 to 100)
let \$fizz := if (\$n mod 3) then () else "fizz"
let \$buzz := if (\$n mod 5) then () else "buzz"
return
if (\$fizz or \$buzz) then concat(\$fizz,\$buzz) else \$n

```

Execute

Here is a short and simple solution by Dimitre Novatchev -- note that there isn't any explicit if ... then ... else. (Also, this can be shortened to 3 lines if the \$fizz and \$buzz variables are eliminated):

```for \$n in (1 to 100),
\$fizz in not(\$n mod 3),
\$buzz in not(\$n mod 5)
return
concat("fizz"[\$fizz], "buzz"[\$buzz], \$n[not(\$fizz or \$buzz)])
```

Execute

One may notice that the above solution doesn't use any XQuery features that aren't also in XPath -- therefore this is a pure XPath 2.0 solution.

Another solution by Dimitre, which might be faster as it doesn't use any mod operator at all:

```      for \$k in 1 to 100 idiv 15 +1,
\$start in 15*(\$k -1) +1,
\$end in min((100, \$start + 14))
return
let \$results :=
(\$start, \$start+1,
'fizz',
\$start+3,
'buzz', 'fizz',
\$start+6, \$start+7,
'fizz',
'buzz',
\$start+10,
'fizz',
\$start+12, \$start+13,
'fizzbuzz')
return
subsequence(\$results, 1, \$end -\$start +1)
```

Execute

Again, the above solution doesn't use any XQuery features that aren't also in XPath 3.0 -- therefore this is a pure XPath 3.0 solution.

Here is a solution from Dino Fancellu, pure XPath 3.0:

```(1 to 30)!(if (. mod 15=0) then "fizzbuzz" else if (. mod 3 = 0) then "fizz" else if (. mod 5 = 0) then "buzz" else .)
```