Perf (Polyglot)¶

In [ ]:
#!import ../../lib/fsharp/Notebooks.dib
#!import ../../lib/fsharp/Testing.dib
In [ ]:
//// test

open testing
open benchmark
In [ ]:
#if !INTERACTIVE
open Lib
#endif

TestCaseResult¶

In [ ]:
type TestCaseResult =
    {
        Input: string
        Expected: string
        Result: string
        TimeList: int64 list
    }

run¶

In [ ]:
let run count (solutions: (string * ('TInput -> 'TExpected)) list) (input, expected) =
    let inputStr =
        match box input with
        | :? System.Collections.ICollection as input ->
            System.Linq.Enumerable.Cast<obj> input
            |> Seq.map string
            |> SpiralSm.concat ","
        | _ -> input.ToString ()

    printfn ""
    printfn $"Solution: {inputStr}  "

    let performanceInvoke (fn: unit -> 'T) =
        GC.Collect ()
        let stopwatch = System.Diagnostics.Stopwatch ()
        stopwatch.Start ()
        let time1 = stopwatch.ElapsedMilliseconds

        let result =
            [| 0 .. count |]
            |> Array.Parallel.map (fun _ ->
                fn ()
            )
            |> Array.last

        let time2 = stopwatch.ElapsedMilliseconds - time1

        result, time2

    let resultsWithTime =
        solutions
        |> List.mapi (fun i (testName, solution) ->
            let result, time = performanceInvoke (fun () -> solution input)
            printfn $"Test case %d{i + 1}. %s{testName}. Time: %A{time}  "
            result, time
        )


    match resultsWithTime |> List.map fst with
    | ([] | [ _ ]) -> ()
    | (head :: tail) when tail |> List.forall ((=) head) -> ()
    | results -> failwithf $"Challenge error: %A{results}"

    {
        Input = inputStr
        Expected = expected.ToString ()
        Result = resultsWithTime |> Seq.map fst |> Seq.head |> _.ToString()
        TimeList = resultsWithTime |> List.map snd
    }

runAll¶

In [ ]:
let runAll testName count (solutions: (string * ('TInput -> 'TExpected)) list) testCases =
    printfn ""
    printfn ""
    printfn $"Test: {testName}"
    testCases
    |> Seq.map (run count solutions)
    |> Seq.toList

sortResultList¶

In [ ]:
let sortResultList resultList =
    let table =
        let rows =
            resultList
            |> List.map (fun result ->
                let best =
                    result.TimeList
                    |> List.mapi (fun i time ->
                        i + 1, time
                    )
                    |> List.sortBy snd
                    |> List.head
                    |> _.ToString()
                let row =
                    [
                        result.Input
                        result.Expected
                        result.Result
                        best
                    ]
                let color =
                    match result.Expected = result.Result with
                    | true -> Some ConsoleColor.DarkGreen
                    | false -> Some ConsoleColor.DarkRed
                row, color
            )
        let header =
            [
                [
                    "Input"
                    "Expected"
                    "Result"
                    "Best"
                ]
                [
                    "---"
                    "---"
                    "---"
                    "---"
                ]
            ]
            |> List.map (fun row -> row, None)
        header @ rows

    let formattedTable =
        let lengthMap =
            table
            |> List.map fst
            |> List.transpose
            |> List.map (fun column ->
                column
                |> List.map String.length
                |> List.sortDescending
                |> List.tryHead
                |> Option.defaultValue 0
            )
            |> List.indexed
            |> Map.ofList
        table
        |> List.map (fun (row, color) ->
            let newRow =
                row
                |> List.mapi (fun i cell ->
                    cell.PadRight lengthMap.[i]
                )
            newRow, color
        )

    printfn ""
    formattedTable
    |> List.iter (fun (row, color) ->
        match color with
        | Some color -> Console.ForegroundColor <- color
        | None -> Console.ResetColor ()

        printfn "%s" (String.Join ("\t| ", row))

        Console.ResetColor ()
    )

    let averages =
        resultList
        |> List.map (fun result -> result.TimeList |> List.map float)
        |> List.transpose
        |> List.map List.average
        |> List.map int64
        |> List.indexed

    printfn ""
    printfn "Average Ranking  "
    averages
    |> List.sortBy snd
    |> List.iter (fun (i, avg) ->
        printfn $"Test case %d{i + 1}. Average Time: %A{avg}  "
    )
In [ ]:
let mutable _count =
    if ("CI" |> System.Environment.GetEnvironmentVariable |> fun x -> $"%A{x}") <> "<null>"
    then 2000000
    else 2000
In [ ]:
inl is_fast () =
    false

empty3Tests¶

Test: Empty3

Solution: (a, a) Test case 1. A. Time: 91L

Solution: (a, a) Test case 1. A. Time: 56L

Input Expected Result Best
(a, a) a a (1, 91)
(a, a) a a (1, 56)

Averages Test case 1. Average Time: 73L

Ranking Test case 1. Average Time: 73L

In [ ]:
//// test

let solutions = [
    "A",
    fun (a, _b) ->
        a
]
let testCases = seq {
    ("a", "a"), "a"
    ("a", "a"), "a"
}
let rec empty3Tests = runAll (nameof empty3Tests) _count solutions testCases
empty3Tests
|> sortResultList

Test: empty3Tests

Solution: (a, a)  
Test case 1. A. Time: 33L  

Solution: (a, a)  
Test case 1. A. Time: 27L  

Input 	| Expected	| Result	| Best   
---   	| ---     	| ---   	| ---    
(a, a)	| a       	| a     	| (1, 33)
(a, a)	| a       	| a     	| (1, 27)

Average Ranking  
Test case 1. Average Time: 30L  

empty2Tests¶

Test: Empty2

Solution: (a, a) Test case 1. A. Time: 59L

Solution: (a, a) Test case 1. A. Time: 53L

Input Expected Result Best
(a, a) a a (1, 59)
(a, a) a a (1, 53)

Averages Test case 1. Average Time: 56L

Ranking Test case 1. Average Time: 56L

In [ ]:
//// test

let solutions = [
    "A",
    fun (a, _b) ->
        a
]
let testCases = seq {
    ("a", "a"), "a"
    ("a", "a"), "a"
}
let rec empty2Tests = runAll (nameof empty2Tests) _count solutions testCases
empty2Tests
|> sortResultList

Test: empty2Tests

Solution: (a, a)  
Test case 1. A. Time: 27L  

Solution: (a, a)  
Test case 1. A. Time: 26L  

Input 	| Expected	| Result	| Best   
---   	| ---     	| ---   	| ---    
(a, a)	| a       	| a     	| (1, 27)
(a, a)	| a       	| a     	| (1, 26)

Average Ranking  
Test case 1. Average Time: 26L  

emptyTests¶

Test: Empty

Solution: 0 Test case 1. A. Time: 61L

Solution: 2 Test case 1. A. Time: 62L

Solution: 5 Test case 1. A. Time: 70L

Input Expected Result Best
0 0 0 (1, 61)
2 2 2 (1, 62)
5 5 5 (1, 70)

Averages Test case 1. Average Time: 64L

Ranking Test case 1. Average Time: 64L

In [ ]:
//// test

let solutions = [
    "A",
    fun n ->
        n + 0
]
let testCases = seq {
    0, 0
    2, 2
    5, 5
}
let rec emptyTests = runAll (nameof emptyTests) _count solutions testCases
emptyTests
|> sortResultList

Test: emptyTests

Solution: 0  
Test case 1. A. Time: 26L  

Solution: 2  
Test case 1. A. Time: 32L  

Solution: 5  
Test case 1. A. Time: 26L  

Input	| Expected	| Result	| Best   
---  	| ---     	| ---   	| ---    
0    	| 0       	| 0     	| (1, 26)
2    	| 2       	| 2     	| (1, 32)
5    	| 5       	| 5     	| (1, 26)

Average Ranking  
Test case 1. Average Time: 28L  

uniqueLettersTests¶

Test: UniqueLetters

Solution: abc Test case 1. A. Time: 1512L Test case 2. B. Time: 1947L Test case 3. C. Time: 2023L Test case 4. D. Time: 1358L Test case 5. E. Time: 1321L Test case 6. F. Time: 1346L Test case 7. G. Time: 1304L Test case 8. H. Time: 1383L Test case 9. I. Time: 1495L Test case 10. J. Time: 1245L Test case 11. K. Time: 1219L

Solution: accabb Test case 1. A. Time: 1648L Test case 2. B. Time: 2061L Test case 3. C. Time: 2413L Test case 4. D. Time: 1561L Test case 5. E. Time: 1593L Test case 6. F. Time: 1518L Test case 7. G. Time: 1415L Test case 8. H. Time: 1510L Test case 9. I. Time: 1445L Test case 10. J. Time: 1636L Test case 11. K. Time: 1317L

Solution: pprrqqpp Test case 1. A. Time: 2255L Test case 2. B. Time: 2408L Test case 3. C. Time: 2393L Test case 4. D. Time: 1675L Test case 5. E. Time: 1911L Test case 6. F. Time: 2126L Test case 7. G. Time: 1504L Test case 8. H. Time: 1715L Test case 9. I. Time: 1537L Test case 10. J. Time: 1522L Test case 11. K. Time: 1322L

Solution: aaaaaaaaaaaaaaccccccabbbbbbbaaacccbbbaaccccccccccacbbbbbbbbbbbbbcccccccbbbbbbbb Test case 1. A. Time: 13073L Test case 2. B. Time: 11519L Test case 3. C. Time: 8373L Test case 4. D. Time: 5860L Test case 5. E. Time: 6490L Test case 6. F. Time: 6325L Test case 7. G. Time: 5799L Test case 8. H. Time: 7099L Test case 9. I. Time: 6133L Test case 10. J. Time: 5993L Test case 11. K. Time: 2040L

Input Expected Result Best
abc abc abc (11, 1219)
accabb acb acb (11, 1317)
pprrqqpp prq prq (11, 1322)
aaaaaaaaaaaaaaccccccabbbbbbbaaacccbbbaaccccccccccacbbbbbbbbbbbbbcccccccbbbbbbbb acb acb (11, 2040)

Averages Test case 1. Average Time: 4622L Test case 2. Average Time: 4483L Test case 3. Average Time: 3800L Test case 4. Average Time: 2613L Test case 5. Average Time: 2828L Test case 6. Average Time: 2828L Test case 7. Average Time: 2505L Test case 8. Average Time: 2926L Test case 9. Average Time: 2652L Test case 10. Average Time: 2599L Test case 11. Average Time: 1474L

Ranking Test case 1. Average Time: 4622L Test case 2. Average Time: 4483L Test case 3. Average Time: 3800L Test case 8. Average Time: 2926L Test case 5. Average Time: 2828L Test case 6. Average Time: 2828L Test case 9. Average Time: 2652L Test case 4. Average Time: 2613L Test case 10. Average Time: 2599L Test case 7. Average Time: 2505L Test case 11. Average Time: 1474L

In [ ]:
//// test

let solutions = [
    "A",
    fun input ->
        input
        |> Seq.toList
        |> List.fold (fun acc x -> if List.contains x acc then acc else acc @ [ x ]) []
        |> Seq.toArray
        |> String

    "B",
    fun input ->
        input
        |> Seq.rev
        |> fun list -> Seq.foldBack (fun x acc -> if List.contains x acc then acc else x :: acc) list []
        |> Seq.rev
        |> Seq.toArray
        |> String

    "C",
    fun input ->
        input
        |> Seq.rev
        |> fun list -> Seq.foldBack (fun x (set, acc) -> if Set.contains x set then set, acc else set.Add x, x :: acc) list (Set.empty, [])
        |> snd
        |> Seq.rev
        |> Seq.toArray
        |> String

    "D",
    fun input ->
        input
        |> Seq.fold (fun (set, acc) x -> if Set.contains x set then set, acc else set.Add x, Array.append acc [| x |]) (Set.empty, [||])
        |> snd
        |> String

    "E",
    fun input ->
        input
        |> Seq.fold (fun (set, acc) x -> if Set.contains x set then set, acc else set.Add x, x :: acc) (Set.empty, [])
        |> snd
        |> List.rev
        |> List.toArray
        |> String

    "F",
    fun input ->
        input
        |> Seq.fold (fun (set, acc) x -> if Set.contains x set then set, acc else set.Add x, acc @ [ x ]) (Set.empty, [])
        |> snd
        |> List.toArray
        |> String

    "G",
    fun input ->
        input
        |> Seq.fold (fun (set, acc) x -> if Set.contains x set then set, acc else set.Add x, x :: acc) (Set.empty, [])
        |> snd
        |> List.toArray
        |> Array.rev
        |> String

    "H",
    fun input ->
        input
        |> Seq.toList
        |> fun list ->
            let rec 루프 set = function
                | head :: tail when Set.contains head set -> 루프 set tail
                | head :: tail -> (루프 (set.Add head) tail) @ [ head ]
                | [] -> []
            루프 Set.empty list
            |> List.rev
        |> List.toArray
        |> String

    "I",
    fun input ->
        input
        |> Seq.toList
        |> fun list ->
            let rec 루프 set = function
                | head :: tail when Set.contains head set -> 루프 set tail
                | head :: tail -> 루프 (set.Add head) tail |> Array.append [| head |]
                | [] -> [||]
            루프 Set.empty list
        |> String

    "J",
    fun input ->
        input
        |> Seq.toList
        |> fun list ->
            let rec 루프 set = function
                | head :: tail when Set.contains head set -> 루프 set tail
                | head :: tail -> head :: 루프 (set.Add head) tail
                | [] -> []
            루프 Set.empty list
        |> List.toArray
        |> String

    "K",
    fun input ->
        input
        |> Seq.distinct
        |> Seq.toArray
        |> String
]
let testCases = seq {
    "abc", "abc"
    "accabb", "acb"
    "pprrqqpp", "prq"
    "aaaaaaaaaaaaaaccccccabbbbbbbaaacccbbbaaccccccccccacbbbbbbbbbbbbbcccccccbbbbbbbb", "acb"
}
let rec uniqueLettersTests = runAll (nameof uniqueLettersTests) _count solutions testCases
uniqueLettersTests
|> sortResultList

Test: uniqueLettersTests

Solution: abc  
Test case 1. A. Time: 753L  
Test case 2. B. Time: 1158L  
Test case 3. C. Time: 1388L  
Test case 4. D. Time: 798L  
Test case 5. E. Time: 785L  
Test case 6. F. Time: 853L  
Test case 7. G. Time: 802L  
Test case 8. H. Time: 882L  
Test case 9. I. Time: 653L  
Test case 10. J. Time: 869L  
Test case 11. K. Time: 726L  

Solution: accabb  
Test case 1. A. Time: 925L  
Test case 2. B. Time: 639L  
Test case 3. C. Time: 666L  
Test case 4. D. Time: 468L  
Test case 5. E. Time: 436L  
Test case 6. F. Time: 439L  
Test case 7. G. Time: 422L  
Test case 8. H. Time: 446L  
Test case 9. I. Time: 444L  
Test case 10. J. Time: 341L  
Test case 11. K. Time: 444L  

Solution: pprrqqpp  
Test case 1. A. Time: 377L  
Test case 2. B. Time: 529L  
Test case 3. C. Time: 718L  
Test case 4. D. Time: 479L  
Test case 5. E. Time: 478L  
Test case 6. F. Time: 490L  
Test case 7. G. Time: 449L  
Test case 8. H. Time: 482L  
Test case 9. I. Time: 451L  
Test case 10. J. Time: 415L  
Test case 11. K. Time: 378L  

Solution: aaaaaaaaaaaaaaccccccabbbbbbbaaacccbbbaaccccccccccacbbbbbbbbbbbbbcccccccbbbbbbbb  
Test case 1. A. Time: 1638L  
Test case 2. B. Time: 1713L  
Test case 3. C. Time: 3007L  
Test case 4. D. Time: 1644L  
Test case 5. E. Time: 1793L  
Test case 6. F. Time: 1860L  
Test case 7. G. Time: 1703L  
Test case 8. H. Time: 1763L  
Test case 9. I. Time: 1611L  
Test case 10. J. Time: 1518L  
Test case 11. K. Time: 868L  

Input                                                                          	| Expected	| Result	| Best     
---                                                                            	| ---     	| ---   	| ---      
abc                                                                            	| abc     	| abc   	| (9, 653) 
accabb                                                                         	| acb     	| acb   	| (10, 341)
pprrqqpp                                                                       	| prq     	| prq   	| (1, 377) 
aaaaaaaaaaaaaaccccccabbbbbbbaaacccbbbaaccccccccccacbbbbbbbbbbbbbcccccccbbbbbbbb	| acb     	| acb   	| (11, 868)

Average Ranking  
Test case 11. Average Time: 604L  
Test case 10. Average Time: 785L  
Test case 9. Average Time: 789L  
Test case 7. Average Time: 844L  
Test case 4. Average Time: 847L  
Test case 5. Average Time: 873L  
Test case 8. Average Time: 893L  
Test case 6. Average Time: 910L  
Test case 1. Average Time: 923L  
Test case 2. Average Time: 1009L  
Test case 3. Average Time: 1444L  

rotateStringsTests¶

https://www.hackerrank.com/challenges/rotate-string/forum

Test: RotateStrings

Solution: abc Test case 1. A. Time: 1842L Test case 2. B. Time: 1846L Test case 3. C. Time: 1936L Test case 4. CA. Time: 2224L Test case 5. CB. Time: 2329L Test case 6. D. Time: 2474L Test case 7. E. Time: 1664L Test case 8. F. Time: 1517L Test case 9. FA. Time: 1651L Test case 10. FB. Time: 3764L Test case 11. FC. Time: 5415L

Solution: abcde Test case 1. A. Time: 3356L Test case 2. B. Time: 2592L Test case 3. C. Time: 2346L Test case 4. CA. Time: 2997L Test case 5. CB. Time: 3061L Test case 6. D. Time: 4051L Test case 7. E. Time: 1905L Test case 8. F. Time: 1771L Test case 9. FA. Time: 2175L Test case 10. FB. Time: 3275L Test case 11. FC. Time: 5266L

Solution: abcdefghi Test case 1. A. Time: 4492L Test case 2. B. Time: 3526L Test case 3. C. Time: 3583L Test case 4. CA. Time: 3711L Test case 5. CB. Time: 4783L Test case 6. D. Time: 7557L Test case 7. E. Time: 3452L Test case 8. F. Time: 3050L Test case 9. FA. Time: 3275L Test case 10. FB. Time: 4635L Test case 11. FC. Time: 5616L

Solution: abab Test case 1. A. Time: 2093L Test case 2. B. Time: 1843L Test case 3. C. Time: 1746L Test case 4. CA. Time: 2085L Test case 5. CB. Time: 2139L Test case 6. D. Time: 2095L Test case 7. E. Time: 1723L Test case 8. F. Time: 1558L Test case 9. FA. Time: 1620L Test case 10. FB. Time: 2319L Test case 11. FC. Time: 3918L

Solution: aa Test case 1. A. Time: 1107L Test case 2. B. Time: 1241L Test case 3. C. Time: 1183L Test case 4. CA. Time: 1563L Test case 5. CB. Time: 1525L Test case 6. D. Time: 1591L Test case 7. E. Time: 1327L Test case 8. F. Time: 1151L Test case 9. FA. Time: 1180L Test case 10. FB. Time: 1733L Test case 11. FC. Time: 2817L

Solution: z Test case 1. A. Time: 816L Test case 2. B. Time: 745L Test case 3. C. Time: 928L Test case 4. CA. Time: 1375L Test case 5. CB. Time: 1029L Test case 6. D. Time: 852L Test case 7. E. Time: 712L Test case 8. F. Time: 263L Test case 9. FA. Time: 232L Test case 10. FB. Time: 773L Test case 11. FC. Time: 1789L

Input Expected Result Best
abc bca cab abc bca cab abc (8, 1517)
abcde bcdea cdeab deabc eabcd abcde bcdea cdeab deabc eabcd abcde (8, 1771)
abcdefghi bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi (8, 3050)
abab baba abab baba abab baba abab baba abab (8, 1558)
aa aa aa aa aa (1, 1107)
z z z (9, 232)

Averages Test case 1. Average Time: 2284L Test case 2. Average Time: 1965L Test case 3. Average Time: 1953L Test case 4. Average Time: 2325L Test case 5. Average Time: 2477L Test case 6. Average Time: 3103L Test case 7. Average Time: 1797L Test case 8. Average Time: 1551L Test case 9. Average Time: 1688L Test case 10. Average Time: 2749L Test case 11. Average Time: 4136L

Ranking Test case 11. Average Time: 4136L Test case 6. Average Time: 3103L Test case 10. Average Time: 2749L Test case 5. Average Time: 2477L Test case 4. Average Time: 2325L Test case 1. Average Time: 2284L Test case 2. Average Time: 1965L Test case 3. Average Time: 1953L Test case 7. Average Time: 1797L Test case 9. Average Time: 1688L Test case 8. Average Time: 1551L

In [ ]:
//// test

let solutions = [
    "A",
    fun (input: string) ->
        let resultList =
            List.fold (fun acc x ->
                let rotate (text: string) (letter: string) = (text |> SpiralSm.slice 1 (input.Length - 1)) + letter
                [ rotate (if acc.IsEmpty then input else acc.Head) (string x) ] @ acc
            ) [] (Seq.toList input)

        (resultList, "")
        ||> List.foldBack (fun acc x -> x + acc + " ")
        |> _.TrimEnd()

    "B",
    fun input ->
        input
        |> Seq.toList
        |> List.fold (fun (acc: string list) letter ->
            let last =
                if acc.IsEmpty
                then input
                else acc.Head

            let item = last.[1 .. input.Length - 1] + string letter

            item :: acc
        ) []
        |> List.rev
        |> SpiralSm.concat " "

    "C",
    fun input ->
        input
        |> Seq.toList
        |> List.fold (fun (acc: string list) letter -> acc.Head.[ 1 .. input.Length - 1 ] + string letter :: acc) [ input ]
        |> List.rev
        |> List.skip 1
        |> SpiralSm.concat " "

    "CA",
    fun input ->
        input
        |> Seq.fold (fun (acc: string list) letter -> acc.Head.[ 1 .. input.Length - 1 ] + string letter :: acc) [ input ]
        |> Seq.rev
        |> Seq.skip 1
        |> SpiralSm.concat " "

    "CB",
    fun input ->
        input
        |> Seq.toArray
        |> Array.fold (fun (acc: string[]) letter -> acc |> Array.append [| acc.[0].[ 1 .. input.Length - 1 ] + string letter |]) [| input |]
        |> Array.rev
        |> Array.skip 1
        |> SpiralSm.concat " "

    "D",
    fun input ->
        input
        |> Seq.toList
        |> fun list ->
            let rec 루프 (acc: char list list) = function
                | _ when acc.Length = list.Length -> acc
                | head :: tail ->
                    let item = tail @ [ head ]
                    루프 (item :: acc) item
                | [] -> []
            루프 [] list
        |> List.rev
        |> List.map (List.toArray >> String)
        |> SpiralSm.concat " "

    "E",
    fun input ->
        input
        |> Seq.toList
        |> fun list ->
            let rec 루프 (last: string) = function
                | head :: tail ->
                    let item = last.[1 .. input.Length - 1] + string head
                    item :: 루프 item tail
                | [] -> []
            루프 input list
        |> SpiralSm.concat " "

    "F",
    fun input ->
        Array.singleton 0
        |> Array.append [| 1 .. input.Length - 1 |]
        |> Array.map (fun i -> input.[ i .. ] + input.[ .. i - 1 ])
        |> SpiralSm.concat " "

    "FA",
    fun input ->
        List.singleton 0
        |> List.append [ 1 .. input.Length - 1 ]
        |> List.map (fun i -> input.[ i .. ] + input.[ .. i - 1 ])
        |> SpiralSm.concat " "

    "FB",
    fun input ->
        Seq.singleton 0
        |> Seq.append (seq { 1 .. input.Length - 1 })
        |> Seq.map (fun i -> input.[ i .. ] + input.[ .. i - 1 ])
        |> SpiralSm.concat " "

    "FC",
    fun input ->
        Array.singleton 0
        |> Array.append [| 1 .. input.Length - 1 |]
        |> Array.Parallel.map (fun i -> input.[ i .. ] + input.[ .. i - 1 ])
        |> SpiralSm.concat " "
]
let testCases = seq {
    "abc", "bca cab abc"
    "abcde", "bcdea cdeab deabc eabcd abcde"
    "abcdefghi", "bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi"
    "abab", "baba abab baba abab"
    "aa", "aa aa"
    "z", "z"
}
let rec rotateStringsTests = runAll (nameof rotateStringsTests) _count solutions testCases
rotateStringsTests
|> sortResultList

Test: rotateStringsTests

Solution: abc  
Test case 1. A. Time: 621L  
Test case 2. B. Time: 509L  
Test case 3. C. Time: 518L  
Test case 4. CA. Time: 704L  
Test case 5. CB. Time: 657L  
Test case 6. D. Time: 569L  
Test case 7. E. Time: 455L  
Test case 8. F. Time: 293L  
Test case 9. FA. Time: 437L  
Test case 10. FB. Time: 896L  
Test case 11. FC. Time: 1148L  

Solution: abcde  
Test case 1. A. Time: 797L  
Test case 2. B. Time: 612L  
Test case 3. C. Time: 658L  
Test case 4. CA. Time: 731L  
Test case 5. CB. Time: 817L  
Test case 6. D. Time: 864L  
Test case 7. E. Time: 590L  
Test case 8. F. Time: 435L  
Test case 9. FA. Time: 589L  
Test case 10. FB. Time: 963L  
Test case 11. FC. Time: 1245L  

Solution: abcdefghi  
Test case 1. A. Time: 1428L  
Test case 2. B. Time: 1033L  
Test case 3. C. Time: 1016L  
Test case 4. CA. Time: 1124L  
Test case 5. CB. Time: 1325L  
Test case 6. D. Time: 1880L  
Test case 7. E. Time: 872L  
Test case 8. F. Time: 731L  
Test case 9. FA. Time: 972L  
Test case 10. FB. Time: 1392L  
Test case 11. FC. Time: 1657L  

Solution: abab  
Test case 1. A. Time: 632L  
Test case 2. B. Time: 540L  
Test case 3. C. Time: 557L  
Test case 4. CA. Time: 675L  
Test case 5. CB. Time: 694L  
Test case 6. D. Time: 711L  
Test case 7. E. Time: 497L  
Test case 8. F. Time: 383L  
Test case 9. FA. Time: 514L  
Test case 10. FB. Time: 886L  
Test case 11. FC. Time: 1177L  

Solution: aa  
Test case 1. A. Time: 388L  
Test case 2. B. Time: 381L  
Test case 3. C. Time: 351L  
Test case 4. CA. Time: 519L  
Test case 5. CB. Time: 446L  
Test case 6. D. Time: 426L  
Test case 7. E. Time: 322L  
Test case 8. F. Time: 258L  
Test case 9. FA. Time: 257L  
Test case 10. FB. Time: 665L  
Test case 11. FC. Time: 1004L  

Solution: z  
Test case 1. A. Time: 207L  
Test case 2. B. Time: 161L  
Test case 3. C. Time: 234L  
Test case 4. CA. Time: 464L  
Test case 5. CB. Time: 291L  
Test case 6. D. Time: 259L  
Test case 7. E. Time: 180L  
Test case 8. F. Time: 70L  
Test case 9. FA. Time: 91L  
Test case 10. FB. Time: 407L  
Test case 11. FC. Time: 830L  

Input    	| Expected                                                                                 	| Result                                                                                   	| Best    
---      	| ---                                                                                      	| ---                                                                                      	| ---     
abc      	| bca cab abc                                                                              	| bca cab abc                                                                              	| (8, 293)
abcde    	| bcdea cdeab deabc eabcd abcde                                                            	| bcdea cdeab deabc eabcd abcde                                                            	| (8, 435)
abcdefghi	| bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi	| bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi	| (8, 731)
abab     	| baba abab baba abab                                                                      	| baba abab baba abab                                                                      	| (8, 383)
aa       	| aa aa                                                                                    	| aa aa                                                                                    	| (9, 257)
z        	| z                                                                                        	| z                                                                                        	| (8, 70) 

Average Ranking  
Test case 8. Average Time: 361L  
Test case 9. Average Time: 476L  
Test case 7. Average Time: 486L  
Test case 2. Average Time: 539L  
Test case 3. Average Time: 555L  
Test case 1. Average Time: 678L  
Test case 4. Average Time: 702L  
Test case 5. Average Time: 705L  
Test case 6. Average Time: 784L  
Test case 10. Average Time: 868L  
Test case 11. Average Time: 1176L  

rotate_strings_tests¶

02:21:12 verbose #1 benchmark.run_all / {count = 2000000; test_name = rotate_strings_tests}

02:21:12 verbose #2 benchmark.run / {input_str = "abc"}
02:21:13 verbose #3 benchmark.run / solutions.map / {i = 1; test_name = F; time = 638}
02:21:14 verbose #4 benchmark.run / solutions.map / {i = 2; test_name = FA; time = 779}

02:21:14 verbose #5 benchmark.run / {input_str = "abcde"}
02:21:15 verbose #6 benchmark.run / solutions.map / {i = 1; test_name = F; time = 745}
02:21:16 verbose #7 benchmark.run / solutions.map / {i = 2; test_name = FA; time = 809}

02:21:16 verbose #8 benchmark.run / {input_str = "abcdefghi"}
02:21:17 verbose #9 benchmark.run / solutions.map / {i = 1; test_name = F; time = 1092}
02:21:18 verbose #10 benchmark.run / solutions.map / {i = 2; test_name = FA; time = 1304}

02:21:18 verbose #11 benchmark.run / {input_str = "abab"}
02:21:19 verbose #12 benchmark.run / solutions.map / {i = 1; test_name = F; time = 536}
02:21:20 verbose #13 benchmark.run / solutions.map / {i = 2; test_name = FA; time = 620}

02:21:20 verbose #14 benchmark.run / {input_str = "aa"}
02:21:21 verbose #15 benchmark.run / solutions.map / {i = 1; test_name = F; time = 365}
02:21:21 verbose #16 benchmark.run / solutions.map / {i = 2; test_name = FA; time = 396}

02:21:21 verbose #17 benchmark.run / {input_str = "z"}
02:21:22 verbose #18 benchmark.run / solutions.map / {i = 1; test_name = F; time = 158}
02:21:22 verbose #19 benchmark.run / solutions.map / {i = 2; test_name = FA; time = 143}

input | expected | result | best
--- | --- | --- | ---
"abc" | "bca cab abc" | "bca cab abc" | 1, 638 "abcde" | "bcdea cdeab deabc eabcd abcde" | "bcdea cdeab deabc eabcd abcde" | 1, 745 "abcdefghi" | "bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi" | "bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi" | 1, 1092 "abab" | "baba abab baba abab" | "baba abab baba abab" | 1, 536 "aa" | "aa aa" | "aa aa" | 1, 365 "z" | "z" | "z" | 2, 143

02:21:22 verbose #20 benchmark.sort_result_list / averages.iter / {avg = 589; i = 1}
02:21:22 verbose #21 benchmark.sort_result_list / averages.iter / {avg = 675; i = 2}
In [ ]:
//// test
//// timeout=60000

inl get_solutions () =
    [
        // "A",
        // fun (input : string) =>
        //     let resultList =
        //         List.fold (fun acc x =>
        //             let rotate (text : string) (letter : string) = text.Substring (1, input.Length - 1) + letter
        //             [ rotate (if acc.IsEmpty then input else acc.Head) (string x) ] ++ acc
        //         ) [] (Seq.toList input)

        //     List.foldBack (fun acc x => x + acc + " ") resultList ""
        //     |> fun x => x.TrimEnd ()

        // "B",
        // fun input =>
        //     input
        //     |> Seq.toList
        //     |> List.fold (fun (acc : string list) letter =>
        //         let last =
        //             if acc.IsEmpty
        //             then input
        //             else acc.Head

        //         let item = last.[1 .. input.Length - 1] + string letter

        //         item :: acc
        //     ) []
        //     |> List.rev
        //     |> SpiralSm.concat " "

        // "C",
        // fun input =>
        //     input
        //     |> Seq.toList
        //     |> List.fold (fun (acc : list string) letter => acc.Head.[ 1 .. input.Length - 1 ] + string letter :: acc) [ input ]
        //     |> List.rev
        //     |> List.skip 1
        //     |> SpiralSm.concat " "

        // "CA",
        // fun input =>
        //     input
        //     |> Seq.fold (fun (acc : list string) letter => acc.Head.[ 1 .. input.Length - 1 ] + string letter :: acc) [ input ]
        //     |> Seq.rev
        //     |> Seq.skip 1
        //     |> SpiralSm.concat " "

        // "CB",
        // fun input =>
        //     input
        //     |> Seq.toArray
        //     |> Array.fold (fun (acc : a _ string) letter => acc |> Array.append (a ;[ acc.[0].[ 1 .. input.Length - 1 ] + string letter ])) (a ;[ input ])
        //     |> Array.rev
        //     |> Array.skip 1
        //     |> SpiralSm.concat " "

        // "D",
        // fun input =>
        //     input
        //     |> Seq.toList
        //     |> fun list =>
        //         let rec 루프 (acc : list (list char)) = function
        //             | _ when acc.Length = list.Length => acc
        //             | head :: tail =>
        //                 let item = tail ++ [ head ]
        //                 루프 (item :: acc) item
        //             | [] => []
        //         루프 [] list
        //     |> List.rev
        //     |> List.map (List.toArray >> String)
        //     |> SpiralSm.concat " "

        // "E",
        // fun input =>
        //     input
        //     |> Seq.toList
        //     |> fun list =>
        //         let rec 루프 (last : string) = function
        //             | head :: tail =>
        //                 let item = last.[1 .. input.Length - 1] + string head
        //                 item :: 루프 item tail
        //             | [] => []
        //         루프 input list
        //     |> SpiralSm.concat " "

        "F",
        fun input =>
        // Array.singleton 0
        // |> Array.append [| 1 .. input.Length - 1 |]
        // |> Array.map (fun i -> input.[ i .. ] + input.[ .. i - 1 ])
        // |> SpiralSm.concat " "
            inl input_length = input |> sm.length
            am.singleton 0i32
            |> am.append (am'.init_series 1 (input_length - 1) 1 |> fun x => a x : _ int _)
            |> fun (a x) => x
            |> am'.map_base fun i =>
                inl a = input |> sm'.slice i (input_length - 1)
                inl b = input |> sm'.slice 0 (i - 1)
                a +. b
            |> fun x => a x : _ int _
            |> seq.of_array
            |> sm'.concat " "

        "FA",
        fun input =>
        //     List.singleton 0
        //     |> List.append [ 1 .. input.Length - 1 ]
        //   //  |> List.map (fun i => input.[ i .. ] + input.[ .. i - 1 ])
        //     |> SpiralSm.concat " "
            inl input_length = input |> sm.length
            listm.singleton 0i32
            |> listm.append (listm'.init_series 1 (input_length - 1) 1)
            |> listm.map (fun i =>
                inl a = input |> sm'.slice i (input_length - 1)
                inl b = if i = 0 then "" else input |> sm'.slice 0 (i - 1)
                a +. b
            )
            |> listm'.box
            |> listm'.to_array'
            |> fun x => a x : _ int _
            |> seq.of_array
            |> sm'.concat " "

        // "FB",
        // fun input =>
        //     Seq.singleton 0
        //   //  |> Seq.append (seq { 1 .. input.Length - 1 })
        //   //  |> Seq.map (fun i => input.[ i .. ] + input.[ .. i - 1 ])
        //     |> SpiralSm.concat " "

        // "FC",
        // fun input =>
        //     Array.singleton 0
        //     |> Array.append (a ;[ 1 .. input.Length - 1 ])
        ////    |> Array.Parallel.map (fun i => input.[ i .. ] + input.[ .. i - 1 ])
        //     |> SpiralSm.concat " "
    ]

inl rec rotate_strings_tests () =
    inl test_cases = [
        "abc", "bca cab abc"
        "abcde", "bcdea cdeab deabc eabcd abcde"
        "abcdefghi", "bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi"
        "abab", "baba abab baba abab"
        "aa", "aa aa"
        "z", "z"
    ]

    inl solutions = get_solutions ()

    // inl is_fast () = true

    inl count =
        if is_fast ()
        then 1000i32
        else 2000000i32

    run_all (reflection.nameof { rotate_strings_tests }) count solutions test_cases
    |> sort_result_list

rotate_strings_tests ()
```
00:00:00 v #1 benchmark.run_all / { test_name = rotate_strings_tests; count = 2000000 }

00:00:00 v #2 benchmark.run / { input_str = abc }
00:00:00 v #3 benchmark.run / solutions.map / { i = 1; test_name = F; time = 528 }
00:00:01 v #4 benchmark.run / solutions.map / { i = 2; test_name = FA; time = 665 }

00:00:01 v #5 benchmark.run / { input_str = abcde }
00:00:02 v #6 benchmark.run / solutions.map / { i = 1; test_name = F; time = 554 }
00:00:03 v #7 benchmark.run / solutions.map / { i = 2; test_name = FA; time = 698 }

00:00:03 v #8 benchmark.run / { input_str = abcdefghi }
00:00:04 v #9 benchmark.run / solutions.map / { i = 1; test_name = F; time = 911 }
00:00:05 v #10 benchmark.run / solutions.map / { i = 2; test_name = FA; time = 1131 }

00:00:05 v #11 benchmark.run / { input_str = abab }
00:00:06 v #12 benchmark.run / solutions.map / { i = 1; test_name = F; time = 448 }
00:00:06 v #13 benchmark.run / solutions.map / { i = 2; test_name = FA; time = 606 }

00:00:06 v #14 benchmark.run / { input_str = aa }
00:00:07 v #15 benchmark.run / solutions.map / { i = 1; test_name = F; time = 284 }
00:00:07 v #16 benchmark.run / solutions.map / { i = 2; test_name = FA; time = 356 }

00:00:07 v #17 benchmark.run / { input_str = z }
00:00:08 v #18 benchmark.run / solutions.map / { i = 1; test_name = F; time = 107 }
00:00:08 v #19 benchmark.run / solutions.map / { i = 2; test_name = FA; time = 116 }
```
input    	| expected                                                                                 	| result                                                                                   	| best  
---      	| ---                                                                                      	| ---                                                                                      	| ---   
abc      	| bca cab abc                                                                              	| bca cab abc                                                                              	| 1, 528
abcde    	| bcdea cdeab deabc eabcd abcde                                                            	| bcdea cdeab deabc eabcd abcde                                                            	| 1, 554
abcdefghi	| bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi	| bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi	| 1, 911
abab     	| baba abab baba abab                                                                      	| baba abab baba abab                                                                      	| 1, 448
aa       	| aa aa                                                                                    	| aa aa                                                                                    	| 1, 284
z        	| z                                                                                        	| z                                                                                        	| 1, 107
```
00:00:08 v #20 benchmark.sort_result_list / averages.iter / { i = 1; avg = 472 }
00:00:08 v #21 benchmark.sort_result_list / averages.iter / { i = 2; avg = 595 }
```
In [ ]:
//// test

// rotate_strings_tests ()
()

binary_search_tests¶

02:19:29 verbose #1 benchmark.run_all / {count = 10000000; test_name = binary_search_tests}

02:19:29 verbose #2 benchmark.run / {input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 6, 7)}
02:19:30 verbose #3 benchmark.run / solutions.map / {i = 1; test_name = semi_open_1; time = 662}
02:19:30 verbose #4 benchmark.run / solutions.map / {i = 2; test_name = closed_1; time = 619}
02:19:31 verbose #5 benchmark.run / solutions.map / {i = 3; test_name = semi_open_2; time = 644}
02:19:32 verbose #6 benchmark.run / solutions.map / {i = 4; test_name = closed_2; time = 610}

02:19:32 verbose #7 benchmark.run / {input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 1, 7)}
02:19:33 verbose #8 benchmark.run / solutions.map / {i = 1; test_name = semi_open_1; time = 607}
02:19:33 verbose #9 benchmark.run / solutions.map / {i = 2; test_name = closed_1; time = 559}
02:19:34 verbose #10 benchmark.run / solutions.map / {i = 3; test_name = semi_open_2; time = 612}
02:19:35 verbose #11 benchmark.run / solutions.map / {i = 4; test_name = closed_2; time = 577}

02:19:35 verbose #12 benchmark.run / {input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 11, 7)}
02:19:35 verbose #13 benchmark.run / solutions.map / {i = 1; test_name = semi_open_1; time = 550}
02:19:36 verbose #14 benchmark.run / solutions.map / {i = 2; test_name = closed_1; time = 580}
02:19:37 verbose #15 benchmark.run / solutions.map / {i = 3; test_name = semi_open_2; time = 624}
02:19:37 verbose #16 benchmark.run / solutions.map / {i = 4; test_name = closed_2; time = 590}

02:19:37 verbose #17 benchmark.run / {input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 12, 7)}
02:19:38 verbose #18 benchmark.run / solutions.map / {i = 1; test_name = semi_open_1; time = 574}
02:19:39 verbose #19 benchmark.run / solutions.map / {i = 2; test_name = closed_1; time = 577}
02:19:39 verbose #20 benchmark.run / solutions.map / {i = 3; test_name = semi_open_2; time = 582}
02:19:40 verbose #21 benchmark.run / solutions.map / {i = 4; test_name = closed_2; time = 585}

02:19:40 verbose #22 benchmark.run / {input_str = struct ([|1; 2; 3; 4...00; ...|], 60, 1000)}
02:19:41 verbose #23 benchmark.run / solutions.map / {i = 1; test_name = semi_open_1; time = 610}
02:19:42 verbose #24 benchmark.run / solutions.map / {i = 2; test_name = closed_1; time = 672}
02:19:42 verbose #25 benchmark.run / solutions.map / {i = 3; test_name = semi_open_2; time = 636}
02:19:43 verbose #26 benchmark.run / solutions.map / {i = 4; test_name = closed_2; time = 629}

02:19:43 verbose #27 benchmark.run / {input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 6, 7)}
02:19:44 verbose #28 benchmark.run / solutions.map / {i = 1; test_name = semi_open_1; time = 599}
02:19:44 verbose #29 benchmark.run / solutions.map / {i = 2; test_name = closed_1; time = 561}
02:19:45 verbose #30 benchmark.run / solutions.map / {i = 3; test_name = semi_open_2; time = 604}
02:19:46 verbose #31 benchmark.run / solutions.map / {i = 4; test_name = closed_2; time = 573}

02:19:46 verbose #32 benchmark.run / {input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 1, 7)}
02:19:47 verbose #33 benchmark.run / solutions.map / {i = 1; test_name = semi_open_1; time = 635}
02:19:47 verbose #34 benchmark.run / solutions.map / {i = 2; test_name = closed_1; time = 603}
02:19:48 verbose #35 benchmark.run / solutions.map / {i = 3; test_name = semi_open_2; time = 644}
02:19:49 verbose #36 benchmark.run / solutions.map / {i = 4; test_name = closed_2; time = 628}

02:19:49 verbose #37 benchmark.run / {input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 11, 7)}
02:19:49 verbose #38 benchmark.run / solutions.map / {i = 1; test_name = semi_open_1; time = 643}
02:19:50 verbose #39 benchmark.run / solutions.map / {i = 2; test_name = closed_1; time = 606}
02:19:51 verbose #40 benchmark.run / solutions.map / {i = 3; test_name = semi_open_2; time = 636}
02:19:52 verbose #41 benchmark.run / solutions.map / {i = 4; test_name = closed_2; time = 624}

02:19:52 verbose #42 benchmark.run / {input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 12, 7)}
02:19:52 verbose #43 benchmark.run / solutions.map / {i = 1; test_name = semi_open_1; time = 689}
02:19:53 verbose #44 benchmark.run / solutions.map / {i = 2; test_name = closed_1; time = 613}
02:19:54 verbose #45 benchmark.run / solutions.map / {i = 3; test_name = semi_open_2; time = 623}
02:19:55 verbose #46 benchmark.run / solutions.map / {i = 4; test_name = closed_2; time = 613}

02:19:55 verbose #47 benchmark.run / {input_str = struct ([|1; 2; 3; 4...100; ...|], 60, 100)}
02:19:55 verbose #48 benchmark.run / solutions.map / {i = 1; test_name = semi_open_1; time = 630}
02:19:56 verbose #49 benchmark.run / solutions.map / {i = 2; test_name = closed_1; time = 633}
02:19:57 verbose #50 benchmark.run / solutions.map / {i = 3; test_name = semi_open_2; time = 653}
02:19:58 verbose #51 benchmark.run / solutions.map / {i = 4; test_name = closed_2; time = 646}

input | expected | result | best
--- | --- | --- | ---
struct ([1; 3; 4; 6; 8; 9; 11], 6, 7) | US4_0 3 | US4_0 3 | 4, 610 struct ([1; 3; 4; 6; 8; 9; 11], 1, 7) | US4_0 0 | US4_0 0 | 2, 559 struct ([1; 3; 4; 6; 8; 9; 11], 11, 7) | US4_0 6 | US4_0 6 | 1, 550 struct ([1; 3; 4; 6; 8; 9; 11], 12, 7) | US4_1 | US4_1 | 1, 574 struct ([1; 2; 3; 4...00; ...], 60, 1000) | US4_0 59 | US4_0 59 | 1, 610 struct ([1; 3; 4; 6; 8; 9; 11], 6, 7) | US4_0 3 | US4_0 3 | 2, 561 struct ([1; 3; 4; 6; 8; 9; 11], 1, 7) | US4_0 0 | US4_0 0 | 2, 603 struct ([1; 3; 4; 6; 8; 9; 11], 11, 7) | US4_0 6 | US4_0 6 | 2, 606 struct ([1; 3; 4; 6; 8; 9; 11], 12, 7) | US4_1 | US4_1 | 2, 613 struct ([1; 2; 3; 4...100; ...], 60, 100) | US4_0 59 | US4_0 59 | 1, 630

02:19:58 verbose #52 benchmark.sort_result_list / averages.iter / {avg = 602; i = 2}
02:19:58 verbose #53 benchmark.sort_result_list / averages.iter / {avg = 607; i = 4}
02:19:58 verbose #54 benchmark.sort_result_list / averages.iter / {avg = 619; i = 1}
02:19:58 verbose #55 benchmark.sort_result_list / averages.iter / {avg = 625; i = 3}
In [ ]:
//// test
//// timeout=90000

inl binary_search_semi_open_1 arr target left right =
    inl rec body left right =
        if left >= right
        then None
        else
            inl mid = (left + right) / 2
            inl item = index arr mid
            if item = target
            then Some mid
            elif item < target
            then 루프 (mid + 1) right
            else 루프 left mid
    and inl 루프 left right =
        if var_is right |> not
        then body left right
        else
            inl left = dyn left
            join body left right
    루프 left right

inl binary_search_closed_1 arr target left right =
    inl rec body left right =
        if left > right
        then None
        else
            inl mid = (left + right) / 2
            inl item = index arr mid
            if item = target
            then Some mid
            elif item < target
            then 루프 (mid + 1) right
            else 루프 left (mid - 1)
    and inl 루프 left right =
        if var_is right |> not
        then body left right
        else
            inl left = dyn left
            join body left right
    루프 left right

inl binary_search_semi_open_2 arr target left right =
    let rec body left right =
        if left >= right
        then None
        else
            inl mid = (left + right) / 2
            inl item = index arr mid
            if item = target
            then Some mid
            elif item < target
            then 루프 (mid + 1) right
            else 루프 left mid
    and inl 루프 left right = body left right
    루프 left right

inl binary_search_closed_2 arr target left right =
    let rec body left right =
        if left > right
        then None
        else
            inl mid = (left + right) / 2
            inl item = index arr mid
            if item = target
            then Some mid
            elif item < target
            then 루프 (mid + 1) right
            else 루프 left (mid - 1)
    and inl 루프 left right = body left right
    루프 left right

inl get_solutions () =
    [
        "semi_open_1",
        fun (arr, (target, len)) =>
            binary_search_semi_open_1 arr target 0 len

        "closed_1",
        fun (arr, (target, len)) =>
            binary_search_closed_1 arr target 0 (len - 1)

        "semi_open_2",
        fun (arr, (target, len)) =>
            binary_search_semi_open_2 arr target 0 len

        "closed_2",
        fun (arr, (target, len)) =>
            binary_search_closed_2 arr target 0 (len - 1)
    ]

inl rec binary_search_tests () =
    inl arr_with_len target len arr =
        arr, (target, (len |> optionm'.default_with fun () => length arr))

    inl test_cases = [
        (a ;[ 1i32; 3; 4; 6; 8; 9; 11 ] |> arr_with_len 6 None), (Some 3i32)
        (a ;[ 1i32; 3; 4; 6; 8; 9; 11 ] |> arr_with_len 1 None), (Some 0i32)
        (a ;[ 1i32; 3; 4; 6; 8; 9; 11 ] |> arr_with_len 11 None), (Some 6i32)
        (a ;[ 1i32; 3; 4; 6; 8; 9; 11 ] |> arr_with_len 12 None), None
        ((am'.init_series 1i32 1000 1 |> fun x => a x : _ int _) |> arr_with_len 60 None), (Some 59)

        (a ;[ 1i32; 3; 4; 6; 8; 9; 11 ] |> arr_with_len 6 (Some 7)), (Some 3i32)
        (a ;[ 1i32; 3; 4; 6; 8; 9; 11 ] |> arr_with_len 1 (Some 7)), (Some 0i32)
        (a ;[ 1i32; 3; 4; 6; 8; 9; 11 ] |> arr_with_len 11 (Some 7)), (Some 6i32)
        (a ;[ 1i32; 3; 4; 6; 8; 9; 11 ] |> arr_with_len 12 (Some 7)), None
        ((am'.init_series 1i32 1000 1 |> fun x => a x : _ int _) |> arr_with_len 60 (Some 100)), (Some 59)
    ]

    inl solutions = get_solutions ()

    // inl is_fast () = true

    inl count =
        if is_fast ()
        then 1000i32
        else 10000000i32

    run_all (reflection.nameof { binary_search_tests }) count solutions test_cases
    |> sort_result_list


let main () =
    binary_search_tests ()
```
00:00:00 v #1 benchmark.run_all / { test_name = binary_search_tests; count = 10000000 }

00:00:00 v #2 benchmark.run / { input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 6, 7) }
00:00:00 v #3 benchmark.run / solutions.map / { i = 1; test_name = semi_open_1; time = 182 }
00:00:00 v #4 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 271 }
00:00:00 v #5 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 158 }
00:00:01 v #6 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 164 }

00:00:01 v #7 benchmark.run / { input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 1, 7) }
00:00:01 v #8 benchmark.run / solutions.map / { i = 1; test_name = semi_open_1; time = 125 }
00:00:01 v #9 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 107 }
00:00:01 v #10 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 102 }
00:00:02 v #11 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 89 }

00:00:02 v #12 benchmark.run / { input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 11, 7) }
00:00:02 v #13 benchmark.run / solutions.map / { i = 1; test_name = semi_open_1; time = 90 }
00:00:02 v #14 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 86 }
00:00:02 v #15 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 90 }
00:00:02 v #16 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 86 }

00:00:02 v #17 benchmark.run / { input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 12, 7) }
00:00:02 v #18 benchmark.run / solutions.map / { i = 1; test_name = semi_open_1; time = 88 }
00:00:03 v #19 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 89 }
00:00:03 v #20 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 88 }
00:00:03 v #21 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 89 }

00:00:03 v #22 benchmark.run / { input_str = struct ([|1; 2; 3; 4...00; ...|], 60, 1000) }
00:00:03 v #23 benchmark.run / solutions.map / { i = 1; test_name = semi_open_1; time = 109 }
00:00:03 v #24 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 119 }
00:00:04 v #25 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 130 }
00:00:04 v #26 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 141 }

00:00:04 v #27 benchmark.run / { input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 6, 7) }
00:00:04 v #28 benchmark.run / solutions.map / { i = 1; test_name = semi_open_1; time = 87 }
00:00:04 v #29 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 88 }
00:00:04 v #30 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 87 }
00:00:05 v #31 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 89 }

00:00:05 v #32 benchmark.run / { input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 1, 7) }
00:00:05 v #33 benchmark.run / solutions.map / { i = 1; test_name = semi_open_1; time = 97 }
00:00:05 v #34 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 84 }
00:00:05 v #35 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 81 }
00:00:05 v #36 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 85 }

00:00:05 v #37 benchmark.run / { input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 11, 7) }
00:00:06 v #38 benchmark.run / solutions.map / { i = 1; test_name = semi_open_1; time = 86 }
00:00:06 v #39 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 86 }
00:00:06 v #40 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 87 }
00:00:06 v #41 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 86 }

00:00:06 v #42 benchmark.run / { input_str = struct ([|1; 3; 4; 6; 8; 9; 11|], 12, 7) }
00:00:06 v #43 benchmark.run / solutions.map / { i = 1; test_name = semi_open_1; time = 89 }
00:00:07 v #44 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 88 }
00:00:07 v #45 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 87 }
00:00:07 v #46 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 89 }

00:00:07 v #47 benchmark.run / { input_str = struct ([|1; 2; 3; 4...100; ...|], 60, 100) }
00:00:07 v #48 benchmark.run / solutions.map / { i = 1; test_name = semi_open_1; time = 118 }
00:00:07 v #49 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 121 }
00:00:08 v #50 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 118 }
00:00:08 v #51 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 123 }
```
input                                    	| expected	| result  	| best  
---                                      	| ---     	| ---     	| ---   
struct ([1; 3; 4; 6; 8; 9; 11], 6, 7)    	| US7_0 3 	| US7_0 3 	| 3, 158
struct ([1; 3; 4; 6; 8; 9; 11], 1, 7)    	| US7_0 0 	| US7_0 0 	| 4, 89 
struct ([1; 3; 4; 6; 8; 9; 11], 11, 7)   	| US7_0 6 	| US7_0 6 	| 2, 86 
struct ([1; 3; 4; 6; 8; 9; 11], 12, 7)   	| US7_1   	| US7_1   	| 1, 88 
struct ([1; 2; 3; 4...00; ...], 60, 1000)	| US7_0 59	| US7_0 59	| 1, 109
struct ([1; 3; 4; 6; 8; 9; 11], 6, 7)    	| US7_0 3 	| US7_0 3 	| 1, 87 
struct ([1; 3; 4; 6; 8; 9; 11], 1, 7)    	| US7_0 0 	| US7_0 0 	| 3, 81 
struct ([1; 3; 4; 6; 8; 9; 11], 11, 7)   	| US7_0 6 	| US7_0 6 	| 1, 86 
struct ([1; 3; 4; 6; 8; 9; 11], 12, 7)   	| US7_1   	| US7_1   	| 3, 87 
struct ([1; 2; 3; 4...100; ...], 60, 100)	| US7_0 59	| US7_0 59	| 1, 118
```
00:00:08 v #52 benchmark.sort_result_list / averages.iter / { i = 3; avg = 102 }
00:00:08 v #53 benchmark.sort_result_list / averages.iter / { i = 4; avg = 104 }
00:00:08 v #54 benchmark.sort_result_list / averages.iter / { i = 1; avg = 107 }
00:00:08 v #55 benchmark.sort_result_list / averages.iter / { i = 2; avg = 113 }
```

returnLettersWithOddCountTests¶

Test: ReturnLettersWithOddCount

Solution: 1 Test case 1. A. Time: 645L

Solution: 2 Test case 1. A. Time: 663L

Solution: 3 Test case 1. A. Time: 680L

Solution: 9 Test case 1. A. Time: 730L

Solution: 10 Test case 1. A. Time: 815L

Input Expected Result Best
1 a a (1, 645)
2 ba ba (1, 663)
3 aaa aaa (1, 680)
9 aaaaaaaaa aaaaaaaaa (1, 730)
10 baaaaaaaaa baaaaaaaaa (1, 815)

Averages Test case 1. Average Time: 706L

Ranking Test case 1. Average Time: 706L

In [ ]:
//// test

let solutions = [
    "A",
    fun n ->
        let mutable _builder = StringBuilder (new string('a', n))
        if n % 2 = 0 then
            _builder.[0] <- 'b'

        _builder.ToString ()
]
let testCases = seq {
    1, "a"
    2, "ba"
    3, "aaa"
    9, "aaaaaaaaa"
    10, "baaaaaaaaa"
}
let rec returnLettersWithOddCountTests =
    runAll (nameof returnLettersWithOddCountTests) _count solutions testCases
returnLettersWithOddCountTests
|> sortResultList

Test: returnLettersWithOddCountTests

Solution: 1  
Test case 1. A. Time: 130L  

Solution: 2  
Test case 1. A. Time: 131L  

Solution: 3  
Test case 1. A. Time: 142L  

Solution: 9  
Test case 1. A. Time: 138L  

Solution: 10  
Test case 1. A. Time: 139L  

Input	| Expected  	| Result    	| Best    
---  	| ---       	| ---       	| ---     
1    	| a         	| a         	| (1, 130)
2    	| ba        	| ba        	| (1, 131)
3    	| aaa       	| aaa       	| (1, 142)
9    	| aaaaaaaaa 	| aaaaaaaaa 	| (1, 138)
10   	| baaaaaaaaa	| baaaaaaaaa	| (1, 139)

Average Ranking  
Test case 1. Average Time: 136L  

hasAnyPairCloseToEachotherTests¶

Test: HasAnyPairCloseToEachother

Solution: 0 Test case 1. A. Time: 137L

Solution: 1,2 Test case 1. A. Time: 186L

Solution: 3,5 Test case 1. A. Time: 206L

Solution: 3,4,6 Test case 1. A. Time: 149L

Solution: 2,4,6 Test case 1. A. Time: 150L

Input Expected Result Best
0 False False (1, 137)
1,2 True True (1, 186)
3,5 False False (1, 206)
3,4,6 True True (1, 149)
2,4,6 False False (1, 150)

Averages Test case 1. Average Time: 165L

Ranking Test case 1. Average Time: 165L

In [ ]:
//// test

let solutions = [
    "A",
    fun (a: int[]) ->
        let indices = System.Linq.Enumerable.Range(0, a.Length) |> System.Linq.Enumerable.ToArray
        System.Array.Sort (a, indices)

        indices
        |> Array.take (a.Length - 1)
        |> Array.exists (fun i -> a.[i + 1] - a.[i] = 1)
]
let testCases = seq {
    [| 0 |], false
    [| 1; 2 |], true
    [| 3; 5 |], false
    [| 3; 4; 6 |], true
    [| 2; 4; 6 |], false
}
let rec hasAnyPairCloseToEachotherTests =
    runAll (nameof hasAnyPairCloseToEachotherTests) _count solutions testCases
hasAnyPairCloseToEachotherTests
|> sortResultList

Test: hasAnyPairCloseToEachotherTests

Solution: 0  
Test case 1. A. Time: 145L  

Solution: 1,2  
Test case 1. A. Time: 152L  

Solution: 3,5  
Test case 1. A. Time: 73L  

Solution: 3,4,6  
Test case 1. A. Time: 64L  

Solution: 2,4,6  
Test case 1. A. Time: 63L  

Input	| Expected	| Result	| Best    
---  	| ---     	| ---   	| ---     
0    	| False   	| False 	| (1, 145)
1,2  	| True    	| True  	| (1, 152)
3,5  	| False   	| False 	| (1, 73) 
3,4,6	| True    	| True  	| (1, 64) 
2,4,6	| False   	| False 	| (1, 63) 

Average Ranking  
Test case 1. Average Time: 99L