[Haskell-beginners] Translating a while
Daniel Fischer
daniel.is.fischer at web.de
Mon Mar 8 09:29:32 EST 2010
Am Montag 08 März 2010 14:49:15 schrieb Nicolas Couture-Grenier:
> I'm learning Haskell and I'm trying to translate a pseudocode algorithm
> to generate the next permutation from a previous permutation.
Don't try to translate it directly. In Haskell, generally a different
approach than for imperative (pseudo-) code is better.
>
> A permutation is a list of n numbers (let's call it a) in {1 .. n}
> appearing once in arbitrary order.
>
> The first step is to find the largest index j in the list for which a[j]
> < a[j+1].
>
> The pseudocode is simple:
>
> j:= n-1
>
> while a[j] > a[j+1]
> j:=j-1
>
>
> I've coded a haskell function to do this, but it is much uglier than the
> pseudocode :
It's not appropriate for lists, therefore, it's ugly. You can work with
arrays and have a fairly direct correspondence:
import Data.Array
fun :: Array Int Int -> Int
fun a = go (hi-1)
where
(lo,hi) = bounds a
go i
| i < lo = i
| a!i > a!(i+1) = go (i-1)
| otherwise = i
The local "go" is our while-loop, additionally, it checks that we don't
fall off the front of the array.
When working with lists, one would typically not produce the next
permutation from the previous, but generate the list of all permutations
(take a look at the code of "permutations" in Data.List).
>
> j :: Integral a => [a] -> Int
> j [] = 0
> j xs = if (head (tail (reverse xs)) < last xs)
> then (length xs)-2
> else j (take (length xs - 1) xs)
>
>
> Does anyone has a more elegant solution for this first step?
More information about the Beginners
mailing list