Fizz Buzz with XPath 2.0/3.0

A few days ago Jim Fuller asked on Twitter:

@xquery fizz buzz with xquery http://bit.ly/wC6Ra5 can anyone come up with a faster version ? #xquery9:00 AM Feb 26, 2012

Here are my two answers in the categories: 1) Elegant; 2) Fast

These and other solutions can be found at: http://en.wikibooks.org/wiki/XQuery/Fizzbuzz

for $n  in (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)])

No explicit conditional if/then/else clauses are used here. No XQuery-only cpecific constructs.

This XPath 2.0 expression can be evaluated “as-is” in any XPath 2.0 host (XSLT 2.0, XQuery 1.0 or other).

2.

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)

This expression could be efficient because there is no mod operator used at all.

It is a pure XPath 3.0 expression and can be evaluated “as-is” in any XPath 3.0 host (XSLT 3.0, XQuery 3.0 or other).

UPDATE:

Kit Wallace has collected all offered solutions and on his page one can compare all of them for running times. Here is a typical screensshot (RQ-1-CW and DN-2 seem to have almost identical speed. If you repeatedly refresh this page, half of the times one of these solutions is the fastest and half of the time — the other.):


Home fizzbuzz Timing

The Fizzbuzz problem was created as a test for prospective programmers.

Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.

Script

Author

Title

Milliseconds *

DN-2 Dimitre Novatchev A highly optimised algorithm 0.98
RQ-1-CW Rob Whitby Optimised by factoring a repeated subsequence – modified 1.01
CW-2 Chris Wallace An algorithm 2.29
JF-1 Jim Fuller A simple, clean algorithm 3.3
ML-1 Mark Lawson A simple algorithm 3.67
DN-1 Dimitre Novatchev An XPath algorithm 4.11
CW-1 Chris Wallace Strings and their modulus values parameterised to support ease of modification 6.57
RQ-1 Rob Whitby Optimised by factoring a repeated subsequence failed
About these ads
This entry was posted in Performance Optimization, XPath, XPath 3.0, XSLT 2.0, XSLT 3.0. Bookmark the permalink.

3 Responses to Fizz Buzz with XPath 2.0/3.0

  1. Alejandro says:

    Sorry for the delay, but Is the let clause really necessary?

  2. Peter Kofler says:

    Dimitre, thank you for pointing me to this page. Where I was just dabbling with XSLT 1.0 and FindBuzz as code kata I have to say that these XSLT 2/3 solutions are amazing. Well done!

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s