Note that there are some explanatory texts on larger screens.

plurals
  1. POList comprehension in Haskell, Python and Ruby
    text
    copied!<p>I have started looking at the <a href="http://projecteuler.net/problems" rel="nofollow">project Euler site</a> as a way to learn Haskell, and improve my Python and Ruby. I think the Haskell and Python versions are ok, but I'm sure there must be a cleaner way for Ruby. </p> <p>This is not about how can I make one language look like another one.</p> <p>This is <a href="https://projecteuler.net/problem=1" rel="nofollow">Problem 1</a>:</p> <blockquote> <p>Q: Add all the natural numbers below one thousand that are multiples of 3 or 5.</p> </blockquote> <p>Haskell:</p> <pre><code>sum [ x | x &lt;- [1..999], mod x 3 == 0 || mod x 5 == 0 ] </code></pre> <p>Python:</p> <pre><code>sum ( [ x for x in range(1,1000) if x % 3 == 0 or x % 5 == 0 ] ) </code></pre> <p>Ruby:</p> <pre><code>(1..999) . map {|x| x if x % 3 == 0 || x % 5 == 0 } . compact . inject(:+) </code></pre> <p>They all give the same answer.</p> <hr> <p>OK, so Python can become:</p> <pre><code>sum ( x for x in range(1,1000) if x % 3 == 0 or x % 5 == 0 ) </code></pre> <p>it is now a generator (a good thing as we are not storing the list)</p> <p>but even more fun is:</p> <pre><code>sum( set(range(0,1000,3)) | set(range(0,1000,5)) ) </code></pre> <p>For some reason I was looking at this again and tried a summation approach which should be constant time. In Python 3:</p> <pre><code>def step_sum(mn,mx,step): amax = mx - (mx - mn) % step return (mn + amax) * ((1 + ((amax - mn) / step)) / 2) step_sum(3,999,3) + step_sum(5,999,5) - step_sum(15,999,15) </code></pre> <p>Ruby can become:</p> <pre><code>(1..999) . select {|x| x % 3 == 0 || x % 5 == 0} . inject(:+) </code></pre> <p>or</p> <pre><code>(1..999) . select {|x| x % 3 == 0 or x % 5 == 0} . reduce(:+) </code></pre> <p>I am presuming as unlike <code>map</code>, <code>select</code> doesn't produce 'nul' and therefore there is no need to call <code>compact</code>. nice.</p> <p>Haskell can also be:</p> <pre><code>let ƒ n = sum [0,n..999] in ƒ 3 + ƒ 5 - ƒ 15 </code></pre> <p>or to be clearer:</p> <pre><code>let ƒ n = sum [ 0 , n .. 999 ] in ƒ 3 + ƒ 5 - ƒ (lcm 3 5) </code></pre> <p>as a function that lets us provide the two numbers ourselves:</p> <pre><code>ƒ :: (Integral a) =&gt; a -&gt; a -&gt; a ƒ x y = let ƒ n = sum [0,n..999] in ƒ x + ƒ y - ƒ (lcm x y) </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload