Skip to content

Instantly share code, notes, and snippets.

@baio
Last active October 16, 2016 14:44
Show Gist options
  • Save baio/4fac3d8cf185057e8f663be441906f7e to your computer and use it in GitHub Desktop.
Save baio/4fac3d8cf185057e8f663be441906f7e to your computer and use it in GitHub Desktop.
bivalue
// Learn more about F# at http://fsharp.org
// See the 'F# Tutorial' project for more help.
open WEEK3
open Monoid
type BivalAccumulator = {
V1: int Option
V2: int Option
LargestSeqSoFar: int
SeqSoFar: int
}
let bivalSplice : int seq -> int =
Seq.fold(fun acc v ->
match acc with
// accum have a & b from perv iter
| { V1 = Some(a); V2 = Some(b); } ->
//curr val not equal neither first nor second
match a <> v, b <> v with
// currently accumulated seq count greater than pervious largest AND currently accumulated > 2 (if less not bivalue)
| true, true when acc.LargestSeqSoFar < acc.SeqSoFar && acc.SeqSoFar > 2 ->
{V1 = Some(v); V2 = None; LargestSeqSoFar = acc.SeqSoFar; SeqSoFar = 1}
// curr val not equal neither first nor second
| true, true ->
{acc with V1 = Some(v); V2 = None; SeqSoFar = 1}
// curr val equal one of the perv values, just inc accumulated seq count
| _ ->
{acc with SeqSoFar = acc.SeqSoFar + 1}
// Both acc vals are emty (just started), set first one to current val and inc seq count
| { V1 = None; V2 = None; SeqSoFar = 0 } ->
{acc with V1 = Some(v); SeqSoFar = 1; }
// Snd accumulated value is empty, set one to current and inc accum seq count
| { V1 = Some(a); V2 = None; } ->
{acc with V2 = (if a <> v then Some(v) else None); SeqSoFar = acc.SeqSoFar + 1}
| _ ->
failwith "Unreachable code reached ;-/"
) ({V1 = None; V2 = None; LargestSeqSoFar = 0; SeqSoFar = 0})
>> (fun acc ->
match acc with
// accum have a & b from perv iter and latest so far less than current and bivalue
| {LargestSeqSoFar = largestSeqSoFar; SeqSoFar = seqSoFar} when largestSeqSoFar < seqSoFar && seqSoFar > 2 ->
seqSoFar
//case when bivalue consists from single value
| {V1 = Some(_); V2 = None; LargestSeqSoFar = largestSeqSoFar; SeqSoFar = seqSoFar} when largestSeqSoFar < seqSoFar && seqSoFar > 1 ->
seqSoFar
// other cases
| _ ->
acc.LargestSeqSoFar
)
[<EntryPoint>]
let main argv =
let lt = [5; 4; 4; 5; 0; 12]
let actual = lt |> bivalSplice
let f = actual = 4
System.Diagnostics.Debug.Assert f
let lt = [5; 4; 5; 4; 0; 12]
let actual = lt |> bivalSplice
let f = actual = 4
System.Diagnostics.Debug.Assert f
let lt = [0; 12; 5; 4; 5; 4;]
let actual = lt |> bivalSplice
let f = actual = 4
System.Diagnostics.Debug.Assert f
let lt = [4; 4; 4; 4; 4; 4;]
let actual = lt |> bivalSplice
let f = actual = 6
System.Diagnostics.Debug.Assert f
let lt = [4; 0; 12]
let actual = lt |> bivalSplice
let f = actual = 0
System.Diagnostics.Debug.Assert f
let lt = [0]
let actual = lt |> bivalSplice
let f = actual = 0
System.Diagnostics.Debug.Assert f
let lt = []
let actual = lt |> bivalSplice
let f = actual = 0
System.Diagnostics.Debug.Assert f
let lt = [0; 0]
let actual = lt |> bivalSplice
let f = actual = 2
System.Diagnostics.Debug.Assert f
let lt = [0; 1; 0; 1]
let actual = lt |> bivalSplice
let f = actual = 4
System.Diagnostics.Debug.Assert f
System.Console.ReadLine() |> ignore
0 // return an integer exit code
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment