Sunday 25 April 2010

SplitAt (Alternate definition)



let rec splitAt n xs = match (n, xs) with
                       | 0, xs -> ([], xs)
                       | _, [] -> ([], [])
                       | n, x::xs -> let (xs', xs'') = splitAt (n - 1) xs in
                                     (x::xs', xs'')

Friday 23 April 2010

C# SplitEvery



private static IEnumerable<IEnumerable<T>> SplitEvery<T>(this IEnumerable<T> xs, int n)
{
    return xs.Unfold(ys => ys.Take(n), ys => ys.Any(), ys => ys.Skip(n));
}

private static IEnumerable<T> Unfold<T>(this T x, Func<T, T> h, Func<T, bool> p, Func<T, T> t)
{
    for (var i = x; p(i); i = t(i))
        yield return h(i);
}

SplitEvery (New version, no explicit recursion)



open System.Linq

let repeat x = Seq.initInfinite (fun _ -> x)

let scan = Seq.scan

let iterate f x = scan (fun l _ -> f l) x (repeat x)

let any = Enumerable.Any

let take n = fun xs -> Enumerable.Take (xs, n)

let skip n = fun xs -> Enumerable.Skip (xs, n)

let unfold h p t =  iterate t >> Seq.takeWhile p >> Seq.map h 

let splitAt n = unfold (take n) any (skip n)

Tuesday 13 April 2010

C# Permutations (using Rx System.Interactive)



public static IEnumerable<IEnumerable<T>> Permutations<T>(this IEnumerable<T> xs)
{
    if (!xs.Any())
        return EnumerableEx.Return(Enumerable.Empty<T>());
    else
        return from zs in Permutations(xs.Skip(1))
               from i in Enumerable.Range(0, zs.Count() + 1)
               select zs.Take(i).Concat(EnumerableEx.Return(xs.First())).Concat(zs.Skip(i));                  
}

Sunday 11 April 2010

Permutations



let length = Seq.length
let take = Seq.take
let skip = Seq.skip
let (++) = Seq.append
let concat = Seq.concat
let map = Seq.map

let (|Empty|Cons|) (xs:seq<'a>) : Choice<Unit, 'a * seq<'a>> =
    if (Seq.isEmpty xs) then Empty else Cons(Seq.head xs, Seq.skip 1 xs)

let interleave x ys =
    seq { for i in [0..length ys] ->
            (take i ys) ++ seq [x] ++ (skip i ys) }

let rec permutations xs =
            match xs with
            | Empty -> seq [seq []]
            | Cons(x,xs) -> concat(map (interleave x) (permutations xs))