Note that there are some explanatory texts on larger screens.

plurals
  1. POEuler 43 - is there a monad to help write this list comprehension?
    primarykey
    data
    text
    <p>Here is a way to solve Euler problem 43 (please let me know if this doesn't give the correct answer). Is there a monad or some other syntatic sugar which could assist with keeping track of the <code>notElem</code> conditions?</p> <pre><code>toNum xs = foldl (\s d -&gt; s*10+d) 0 xs numTest xs m = (toNum xs) `mod` m == 0 pandigitals = [ [d0,d1,d2,d3,d4,d5,d6,d7,d8,d9] | d7 &lt;- [0..9], d8 &lt;- [0..9], d8 `notElem` [d7], d9 &lt;- [0..9], d9 `notElem` [d8,d7], numTest [d7,d8,d9] 17, d5 &lt;- [0,5], d5 `notElem` [d9,d8,d7], d3 &lt;- [0,2,4,6,8], d3 `notElem` [d5,d9,d8,d7], d6 &lt;- [0..9], d6 `notElem` [d3,d5,d9,d8,d7], numTest [d6,d7,d8] 13, numTest [d5,d6,d7] 11, d4 &lt;- [0..9], d4 `notElem` [d6,d3,d5,d9,d8,d7], numTest [d4,d5,d6] 7, d2 &lt;- [0..9], d2 `notElem` [d4,d6,d3,d5,d9,d8,d7], numTest [d2,d3,d4] 3, d1 &lt;- [0..9], d1 `notElem` [d2,d4,d6,d3,d5,d9,d8,d7], d0 &lt;- [1..9], d0 `notElem` [d1,d2,d4,d6,d3,d5,d9,d8,d7] ] main = do let nums = map toNum pandigitals print $ nums putStrLn "" print $ sum nums </code></pre> <p>For instance, in this case the assignment to <code>d3</code> is not optimal - it really should be moved to just before the <code>numTest [d2,d3,d4] 3</code> test. Doing that, however, would mean changing some of the <code>notElem</code> tests to remove <code>d3</code> from the list being checked. Since the successive <code>notElem</code> lists are obtained by just consing the last chosen value to the previous list, it seems like this should be doable - somehow.</p> <p>UPDATE: Here is the above program re-written with Louis' <code>UniqueSel</code> monad below:</p> <pre><code>toNum xs = foldl (\s d -&gt; s*10+d) 0 xs numTest xs m = (toNum xs) `mod` m == 0 pandigitalUS = do d7 &lt;- choose d8 &lt;- choose d9 &lt;- choose guard $ numTest [d7,d8,d9] 17 d6 &lt;- choose guard $ numTest [d6,d7,d8] 13 d5 &lt;- choose guard $ d5 == 0 || d5 == 5 guard $ numTest [d5,d6,d7] 11 d4 &lt;- choose guard $ numTest [d4,d5,d6] 7 d3 &lt;- choose d2 &lt;- choose guard $ numTest [d2,d3,d4] 3 d1 &lt;- choose guard $ numTest [d1,d2,d3] 2 d0 &lt;- choose guard $ d0 /= 0 return [d0,d1,d2,d3,d4,d5,d6,d7,d8,d9] pandigitals = map snd $ runUS pandigitalUS [0..9] main = do print $ pandigitals </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

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