loading...

Discussion on: Daily Challenge #82 - English Beggars

Collapse
citizen428 profile image
Michael Kohl

F#

let beggars (donations : int list) (count : int) : int list =
    let sums =
        donations
        |> List.indexed
        |> List.groupBy (fun (i, _) -> i % count)
        |> List.map (fun (_, l) -> List.sumBy (snd) l)
    sums @ List.replicate (count - sums.Length) 0

Because I was bored I also did a pointless version using pointfree style in the pipeline:

let flip f a b = f b a

let beggars (donations : int list) (count : int) : int list =
    let sums =
        donations
        |> List.indexed
        |> List.groupBy (fst >> (flip (%) count))
        |> List.map (snd >> List.sumBy (snd))
    sums @ List.replicate (count - sums.Length) 0

Tests:

module DailyChallengeTest

open FsUnit.Xunit
open Xunit
open DailyChallenge

[<Fact>]
let ``2 beggars, 5 donations``() =
    beggars [ 1; 2; 3; 4; 5 ] 2 |> should equal [ 9; 6 ]

[<Fact>]
let ``3 beggars, 5 donations``() =
    beggars [ 1; 2; 3; 4; 5 ] 3 |> should equal [ 5; 7; 3 ]

[<Fact>]
let ``2 beggars, 1 donations``() = 
    beggars [ 1 ] 2 |> should equal [ 1; 0 ]

[<Fact>]
let ``2 beggars, 0 donations``() = 
    beggars [] 2 |> should equal [ 0; 0 ]
Collapse
aminnairi profile image
Amin

Could you remind me what is the concept of point free style? I know I heard it somewhere when playing with Haskell but I can't remember haha!

Collapse
citizen428 profile image
Michael Kohl

Making new functions by composing others without mentioning the actual arguments. In this specific case I did it for the higher-order ones in the pipeline:

(fun (i, _) -> i % count) -> (fst >> (flip (%) count))

or

(fun (_, l) -> List.sumBy (snd) l) -> (snd >> List.sumBy (snd))

One could maybe justify the second one (though it's probably still harder to read than the corresponding lambda for most people), but the first one isn't even shorter than the lambda and I had to implement flip myself since it's not part of F#'s standard library.