[Haskell-beginners] eve / did = 0.talktalktalk...
Daniel Fischer
daniel.is.fischer at web.de
Thu Apr 22 14:35:05 EDT 2010
Am Donnerstag 22 April 2010 19:05:39 schrieb Alexander.Vladislav.Popov:
> Excuse me for repetition, but I first time at beginners at haskell.org and
> very first time when I sent the message I was not registered, so now I
> forward it as rightful member. I must clarify the problem a little. The
> solution I represent below is using only 1 processor from 2 of available
> but I suspect that using `par` can help to load my computer in full. So
> :
>
> ---------- Forwarded message ----------
> From: Alexander.Vladislav.Popov <alexander.vladislav.popov at gmail.com>
> Date: 2010/4/22
> Subject: eve / did = 0.talktalktalk...
> To: beginners at haskell.org
>
>
> Dear Everebody.
>
> Hepl me please to parallelize (parallel computing of evedidtalk
> function) the rebus:
The only way to exploit parallelism here that I see is to split the work
into smaller pieces, say
evedidone = [ ([e, v, e], [d, i, d], [t, a, l, k]) |
e <- [0 .. 4],
v <- ten, v /= e,
...
]
evedidtwo = [ ([e, v, e], [d, i, d], [t, a, l, k]) |
e <- [5 .. 9],
...
]
evedidtalk = evedidone `par` evedidtwo `pseq` (evedidone ++ evedidtwo)
However, just a slightly less brutish brute force will make it return the
answer in less time than it takes to get two cores working and collect the
results.
>
> -- | eve / did = 0.talktalktalk...
Since the quotient is < 1, we must have eve < did, hence e < d.
That roughly halves the work.
>
> ten :: Integral a => [a]
> ten = [0..9]
>
> infixr 7 /:
>
> (/:) :: (Integral a) => [a] -> [a] -> [a]
> (/:) [] _ = [0]
> (/:) _ [] = []
> (/:) x y = coldiv (getInteger x) (getInteger y)
>
> getInteger :: (Num a) => [a] -> a
> getInteger = foldl ((+) . (*10)) 0
>
> coldiv :: (Integral a) => a -> a -> [a]
> coldiv a b = q : if r == 0
> then []
> else coldiv (r * 10) b
> where
> (q, r) = a `quotRem` b
>
> evedidtalk = [ ([e, v, e], [d, i, d], [t, a, l, k]) |
> e <- ten,
e <- [0 .. 8], -- though we could also exclude 0 a priori
> v <- ten, v /= e,
> d <- ten, d /= e, d /= v,
d <- [e+1 .. 9], d /= v,
> i <- ten, i /= e, i /= v, i /= d,
The following is bad:
> t <- ten, t /= e, t /= v, t /= d, t /= i,
> a <- ten, a /= e, a /= v, a /= d, a /= i, a /= t,
> l <- ten, l /= e, l /= v, l /= d, l /= i, l /= t, l /= a,
> k <- ten, k /= e, k /= v, k /= d, k /= i, k /= t, k /= a, k
> /= l,
instead:
let [0,t,a,l,k,s,m,o,g] = take 9 ([e,v,e] /: [d,i,d]),
t == s, t `notElem` [e,v,d,i],
a == m, a `notElem` [e,v,d,i,t],
l == o, l `notElem` [e,v,d,i,t,a],
k == g, k `notElem` [e,v,d,i,t,a,l]
> take 9 ([e, v, e] /: [d, i, d]) == [0, t, a, l, k, t, a, l,
> k] ]
Not to mention that there are only two possibilities for did, 303 and 909,
so you could make it a little faster still using that.
>
> Sincerely, Alexander
More information about the Beginners
mailing list