Skip to content

Commit

Permalink
Make functions point free and unify interface
Browse files Browse the repository at this point in the history
  • Loading branch information
bartoszluka committed Aug 22, 2021
1 parent 2593f86 commit e3a19f6
Showing 1 changed file with 75 additions and 69 deletions.
144 changes: 75 additions & 69 deletions Algs/Sorts.fs
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,25 @@ let rec mergeWith compare listA listB : 'a list =
else
y :: (mergeWith compare listA ys)

let merge = mergeWith (<)

let rec mergeSort (list: int list) =
match List.length list with
| len when len <= 1 -> list
| len ->
let lists = List.splitAt (len / 2) list
let listA = fst lists
let listB = snd lists
merge (mergeSort listA) (mergeSort listB)

let partition predicate (list: int list) =
let rec mergeSortWith comparison =
function
| [] -> []
| [ x ] -> [ x ]
| list ->
let len = List.length list
let (listA, listB) = List.splitAt (len / 2) list
mergeWith comparison (mergeSortWith comparison listA) (mergeSortWith comparison listB)


let mergeSort = mergeSortWith (<=)

let mergeSortDescendig = mergeSortWith (>=)

let mergeSortInt (list: int list) = mergeSort list

let mergeSortDescendigInt (list: int list) = mergeSortDescendig list

let partition predicate list =
let rec partHelper pred lst pair =
match lst with
| [] -> pair
Expand All @@ -35,17 +42,27 @@ let partition predicate (list: int list) =

partHelper predicate list ([], [])

let rec quickSort (list: int list) =
match list with
let rec quickSortWith comparison =
function
| [] -> []
| x :: xs ->
let (smaller, bigger) = partition ((>) x) xs
let (bigger, smaller) = partition (comparison x) xs

quickSortWith comparison smaller
@ (x :: quickSortWith comparison bigger)


let quickSort = quickSortWith (<=)

let quickSortDescendig = quickSortWith (>=)

let quickSortInt (list: int list) = quickSort list

quickSort smaller @ (x :: quickSort bigger)
let quickSortDescendigInt (list: int list) = quickSortDescendig list

let mapPair f (x, y) = (f x, f y)

let splitWhen predicate (list: int list) =
let splitWhen predicate list =
let rec splitHelper pred flag lst (left, right) =
match lst with
| [] -> (left, right)
Expand All @@ -62,19 +79,20 @@ let splitWhen predicate (list: int list) =
splitHelper predicate false list ([], [])
|> mapPair List.rev

let flip f x y = f y x

//possibly do binary insert
let insertIntoSorted item (list: int list) =
let insertIntoSorted comparison item list =
// let (smaller, bigger) = splitWhen ((<) item) list
let (smaller, bigger) = splitWhen (fun x -> x >= item) list
let (smaller, bigger) = splitWhen (comparison item) list
//this is faster than this smaller @ [ item ] @ bigger
smaller @ (item :: bigger)

let splitWhenPairwise (f: 'a -> 'a -> bool) (list: list<'a>) =
let splitWhenPairwise compare list =
if (List.isEmpty list) then
([], [])

else
let helper (a, b) = f a b
let helper (a, b) = compare a b

let firstIndex =
list |> List.pairwise |> List.tryFindIndex helper
Expand All @@ -85,75 +103,63 @@ let splitWhenPairwise (f: 'a -> 'a -> bool) (list: list<'a>) =

let swap (x, y) = (y, x)

let insertionSort =
let insertionSortWith comparison =
let rec sortHelper (listIn, listOut) =
match listIn with
| [] -> ([], listOut)
| x :: xs -> sortHelper (xs, insertIntoSorted x listOut)
| x :: xs -> sortHelper (xs, insertIntoSorted comparison x listOut)

splitWhenPairwise (>=)
splitWhenPairwise (flip comparison)
>> swap
>> sortHelper
>> snd

let findMin comparison list = List.reduce comparison
let insertionSort = insertionSortWith (<=)

let flip f x y = f y x
let insertionSortDescendig = insertionSortWith (>=)

let insertionSortInt (list: int list) = insertionSort list

let insertionSortDescendigInt (list: int list) = insertionSortDescendig list

let fork unary1 unary2 binary =
let apply x = binary (unary1 x) (unary2 x)

List.map apply

let removeMin list =
match list with
let removeMin comparison =
function
| [] -> None
| notEmpty ->
let indexedList = List.indexed notEmpty

let min =
indexedList
|> List.reduce (fun (xi, x) (yi, y) -> if x < y then (xi, x) else (yi, y))
|> List.reduce
(fun (xInd, xVal) (yInd, yVal) ->
if comparison xVal yVal then
(xInd, xVal)
else
(yInd, yVal))

List.filter (fun x -> min <> x) indexedList
|> List.map snd
|> (fun l -> ((snd min), l))
|> (fun lst -> ((snd min), lst))
|> Some


let selectionSort (list: int list) =
let selectionSortWith comparison =
let rec sortHelper (listIn, listOut) =
match removeMin listIn with
match removeMin comparison listIn with
| None -> ([], listOut)
| Some (min, rest) -> sortHelper (rest, min :: listOut)

sortHelper (list, []) |> snd |> List.rev
// list
// |> splitWhenPairwise (>=)
// |> sortHelper
// |> snd

// let bubbleSortMutable (l: Foo list) =
// let mutable l' = l |> Array.ofList
// let mutable keepGoing = true

// while keepGoing do
// keepGoing <- false

// for i in [ 1 .. (Array.length l' - 1) ] do
// if l'.[i - 1] > l'.[i] then
// let t = l'.[i - 1]
// l'.[i - 1] <- l'.[i]
// l'.[i] <- t
// keepGoing <- true

// l' |> List.ofArray

// let bubbleSortRecursive (l: Foo list) =
// let rec bubbleSort' a rev l =
// match l, rev with
// | [], true -> List.rev a
// | [], false -> List.rev a |> bubbleSort' [] true
// | h1 :: h2 :: t, _ ->
// if h1 > h2 then
// bubbleSort' (h2 :: a) false (h1 :: t)
// else
// bubbleSort' (h1 :: a) rev (h2 :: t)
// | h :: t, _ -> bubbleSort' (h :: a) rev t

// bubbleSort' [] true l
let pairUp list = (list, [])
pairUp >> sortHelper >> snd >> List.rev

let selectionSort = selectionSortWith (<=)

let selectionSortDescendig = selectionSortWith (>=)

let selectionSortInt (list: int list) = selectionSort list

let selectionSortDescendigInt (list: int list) = selectionSortDescendig list

0 comments on commit e3a19f6

Please sign in to comment.