algorithm - Filter an array or list by consecutive pairs based on a matching rule -


this trivial, , have solution i'm not happy it. somehow, (much) simpler forms don't seem work , gets messy around corner cases (either first, or last matching pairs in row).

to keep simple, let's define matching rule any 2 or more numbers have difference of two. example:

> filtertwins [1; 2; 4; 6; 8; 10; 15; 17]
val : int list = [2; 4; 6; 8; 10; 15; 17]

the code use this, feels sloppy , overweight:

let filtertwins list =     let func item acc =         let previtem, resultlist = acc         match previtem, resultlist         | 0, []              -> item, []         | var, [] when var - 2 = item             -> item, item::var::resultlist         | var, hd::tl when var - 2 = item && hd <> var             -> item, item::var::resultlist         | var, _ when var - 2 = item             -> item, item::resultlist         | _              -> item, resultlist      list.foldback func list (0, [])     |> snd 

i intended own original exercise experiment list.foldback, large lists , parallel programming (which went well) ended messing "easy" part...

guide through answers

  • daniel's last, 113 characters*, easy follow, slow
  • kvb's 2nd, 106 characters* (if include function), easy, return value requires work
  • stephen's 2nd, 397 characters*, long winded , comparably complex, fastest
  • abel's, 155 characters*, based on daniel's, allows duplicates (this wasn't necessity, btw) , relatively fast.

there more answers, above distinct, believe. hope didn't hurt anybody's feelings accepting daniel's answer solution: each , every 1 solution deserves selected answer(!).

* counting done function names 1 character

would want?

let filtertwins l =      let rec filter l acc flag =         match l         | [] -> list.rev acc         | :: b :: rest when b - 2 = ->              filter (b::rest) (if flag b::acc else b::a::acc) true         | _ :: t -> filter t acc false     filter l [] false 

this terribly inefficient, here's approach using more built-in functions:

let filtertwinssimple l =     l      |> seq.pairwise      |> seq.filter (fun (a, b) -> b - 2 = a)     |> seq.collect (fun (a, b) -> [a; b])     |> seq.distinct     |> seq.tolist 

maybe better:

let filtertwinssimple l =     seq {          (a, b) in seq.pairwise l             if b - 2 =                  yield                 yield b      }     |> seq.distinct     |> seq.tolist 

Comments

Popular posts from this blog

linux - Mailx and Gmail nss config dir -

c# - Is it possible to remove an existing registration from Autofac container builder? -

php - Mysql PK and FK char(36) vs int(10) -