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: 37L  

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

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

Average Ranking  
Test case 1. Average Time: 32L  

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: 28L  

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

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

Average Ranking  
Test case 1. Average Time: 27L  

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: 25L  

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

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

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

Average Ranking  
Test case 1. Average Time: 27L  

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: 700L  
Test case 2. B. Time: 1142L  
Test case 3. C. Time: 1396L  
Test case 4. D. Time: 814L  
Test case 5. E. Time: 848L  
Test case 6. F. Time: 815L  
Test case 7. G. Time: 833L  
Test case 8. H. Time: 912L  
Test case 9. I. Time: 678L  
Test case 10. J. Time: 920L  
Test case 11. K. Time: 722L  

Solution: accabb  
Test case 1. A. Time: 991L  
Test case 2. B. Time: 1535L  
Test case 3. C. Time: 1966L  
Test case 4. D. Time: 523L  
Test case 5. E. Time: 462L  
Test case 6. F. Time: 441L  
Test case 7. G. Time: 463L  
Test case 8. H. Time: 487L  
Test case 9. I. Time: 440L  
Test case 10. J. Time: 345L  
Test case 11. K. Time: 428L  

Solution: pprrqqpp  
Test case 1. A. Time: 420L  
Test case 2. B. Time: 611L  
Test case 3. C. Time: 830L  
Test case 4. D. Time: 515L  
Test case 5. E. Time: 490L  
Test case 6. F. Time: 504L  
Test case 7. G. Time: 453L  
Test case 8. H. Time: 517L  
Test case 9. I. Time: 467L  
Test case 10. J. Time: 427L  
Test case 11. K. Time: 373L  

Solution: aaaaaaaaaaaaaaccccccabbbbbbbaaacccbbbaaccccccccccacbbbbbbbbbbbbbcccccccbbbbbbbb  
Test case 1. A. Time: 1521L  
Test case 2. B. Time: 2363L  
Test case 3. C. Time: 3761L  
Test case 4. D. Time: 1858L  
Test case 5. E. Time: 1839L  
Test case 6. F. Time: 1957L  
Test case 7. G. Time: 1887L  
Test case 8. H. Time: 1816L  
Test case 9. I. Time: 1810L  
Test case 10. J. Time: 1491L  
Test case 11. K. Time: 825L  

Input                                                                          	| Expected	| Result	| Best     
---                                                                            	| ---     	| ---   	| ---      
abc                                                                            	| abc     	| abc   	| (9, 678) 
accabb                                                                         	| acb     	| acb   	| (10, 345)
pprrqqpp                                                                       	| prq     	| prq   	| (11, 373)
aaaaaaaaaaaaaaccccccabbbbbbbaaacccbbbaaccccccccccacbbbbbbbbbbbbbcccccccbbbbbbbb	| acb     	| acb   	| (11, 825)

Average Ranking  
Test case 11. Average Time: 587L  
Test case 10. Average Time: 795L  
Test case 9. Average Time: 848L  
Test case 1. Average Time: 908L  
Test case 5. Average Time: 909L  
Test case 7. Average Time: 909L  
Test case 4. Average Time: 927L  
Test case 6. Average Time: 929L  
Test case 8. Average Time: 933L  
Test case 2. Average Time: 1412L  
Test case 3. Average Time: 1988L  

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: 630L  
Test case 2. B. Time: 537L  
Test case 3. C. Time: 535L  
Test case 4. CA. Time: 723L  
Test case 5. CB. Time: 733L  
Test case 6. D. Time: 636L  
Test case 7. E. Time: 473L  
Test case 8. F. Time: 309L  
Test case 9. FA. Time: 431L  
Test case 10. FB. Time: 875L  
Test case 11. FC. Time: 1191L  

Solution: abcde  
Test case 1. A. Time: 808L  
Test case 2. B. Time: 656L  
Test case 3. C. Time: 678L  
Test case 4. CA. Time: 756L  
Test case 5. CB. Time: 851L  
Test case 6. D. Time: 935L  
Test case 7. E. Time: 630L  
Test case 8. F. Time: 457L  
Test case 9. FA. Time: 614L  
Test case 10. FB. Time: 1008L  
Test case 11. FC. Time: 1279L  

Solution: abcdefghi  
Test case 1. A. Time: 1429L  
Test case 2. B. Time: 1037L  
Test case 3. C. Time: 1070L  
Test case 4. CA. Time: 1104L  
Test case 5. CB. Time: 1341L  
Test case 6. D. Time: 1906L  
Test case 7. E. Time: 977L  
Test case 8. F. Time: 771L  
Test case 9. FA. Time: 1010L  
Test case 10. FB. Time: 1449L  
Test case 11. FC. Time: 1683L  

Solution: abab  
Test case 1. A. Time: 659L  
Test case 2. B. Time: 583L  
Test case 3. C. Time: 589L  
Test case 4. CA. Time: 710L  
Test case 5. CB. Time: 714L  
Test case 6. D. Time: 766L  
Test case 7. E. Time: 572L  
Test case 8. F. Time: 403L  
Test case 9. FA. Time: 548L  
Test case 10. FB. Time: 874L  
Test case 11. FC. Time: 1193L  

Solution: aa  
Test case 1. A. Time: 409L  
Test case 2. B. Time: 415L  
Test case 3. C. Time: 381L  
Test case 4. CA. Time: 536L  
Test case 5. CB. Time: 491L  
Test case 6. D. Time: 430L  
Test case 7. E. Time: 330L  
Test case 8. F. Time: 265L  
Test case 9. FA. Time: 282L  
Test case 10. FB. Time: 675L  
Test case 11. FC. Time: 1180L  

Solution: z  
Test case 1. A. Time: 238L  
Test case 2. B. Time: 236L  
Test case 3. C. Time: 271L  
Test case 4. CA. Time: 413L  
Test case 5. CB. Time: 310L  
Test case 6. D. Time: 246L  
Test case 7. E. Time: 177L  
Test case 8. F. Time: 72L  
Test case 9. FA. Time: 93L  
Test case 10. FB. Time: 352L  
Test case 11. FC. Time: 943L  

Input    	| Expected                                                                                 	| Result                                                                                   	| Best    
---      	| ---                                                                                      	| ---                                                                                      	| ---     
abc      	| bca cab abc                                                                              	| bca cab abc                                                                              	| (8, 309)
abcde    	| bcdea cdeab deabc eabcd abcde                                                            	| bcdea cdeab deabc eabcd abcde                                                            	| (8, 457)
abcdefghi	| bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi	| bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi	| (8, 771)
abab     	| baba abab baba abab                                                                      	| baba abab baba abab                                                                      	| (8, 403)
aa       	| aa aa                                                                                    	| aa aa                                                                                    	| (8, 265)
z        	| z                                                                                        	| z                                                                                        	| (8, 72) 

Average Ranking  
Test case 8. Average Time: 379L  
Test case 9. Average Time: 496L  
Test case 7. Average Time: 526L  
Test case 2. Average Time: 577L  
Test case 3. Average Time: 587L  
Test case 1. Average Time: 695L  
Test case 4. Average Time: 707L  
Test case 5. Average Time: 740L  
Test case 6. Average Time: 819L  
Test case 10. Average Time: 872L  
Test case 11. Average Time: 1244L  

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 = 540 }
00:00:01 v #4 benchmark.run / solutions.map / { i = 2; test_name = FA; time = 735 }

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 = 649 }
00:00:03 v #7 benchmark.run / solutions.map / { i = 2; test_name = FA; time = 689 }

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 = 891 }
00:00:05 v #10 benchmark.run / solutions.map / { i = 2; test_name = FA; time = 1102 }

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 = 469 }
00:00:07 v #13 benchmark.run / solutions.map / { i = 2; test_name = FA; time = 608 }

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

00:00:08 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, 540
abcde    	| bcdea cdeab deabc eabcd abcde                                                            	| bcdea cdeab deabc eabcd abcde                                                            	| 1, 649
abcdefghi	| bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi	| bcdefghia cdefghiab defghiabc efghiabcd fghiabcde ghiabcdef hiabcdefg iabcdefgh abcdefghi	| 1, 891
abab     	| baba abab baba abab                                                                      	| baba abab baba abab                                                                      	| 1, 469
aa       	| aa aa                                                                                    	| aa aa                                                                                    	| 1, 292
z        	| z                                                                                        	| z                                                                                        	| 1, 107
```
00:00:08 v #20 benchmark.sort_result_list / averages.iter / { i = 1; avg = 491 }
00:00:08 v #21 benchmark.sort_result_list / averages.iter / { i = 2; avg = 601 }
```
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 = 253 }
00:00:00 v #4 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 139 }
00:00:00 v #5 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 134 }
00:00:01 v #6 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 142 }

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 = 84 }
00:00:01 v #9 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 89 }
00:00:01 v #10 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 90 }
00:00:02 v #11 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 85 }

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 = 88 }
00:00:02 v #14 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 87 }
00:00:02 v #15 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 84 }
00:00:02 v #16 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 92 }

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 = 90 }
00:00:03 v #20 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 86 }
00:00:03 v #21 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 88 }

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 = 110 }
00:00:03 v #24 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 123 }
00:00:04 v #25 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 114 }
00:00:04 v #26 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 117 }

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 = 72 }
00:00:04 v #29 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 75 }
00:00:04 v #30 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 74 }
00:00:05 v #31 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 75 }

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 = 83 }
00:00:05 v #34 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 85 }
00:00:05 v #35 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 85 }
00:00:05 v #36 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 90 }

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

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:06 v #44 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 86 }
00:00:07 v #45 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 85 }
00:00:07 v #46 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 88 }

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 = 100 }
00:00:07 v #49 benchmark.run / solutions.map / { i = 2; test_name = closed_1; time = 108 }
00:00:07 v #50 benchmark.run / solutions.map / { i = 3; test_name = semi_open_2; time = 102 }
00:00:08 v #51 benchmark.run / solutions.map / { i = 4; test_name = closed_2; time = 275 }
```
input                                    	| expected	| result  	| best  
---                                      	| ---     	| ---     	| ---   
struct ([1; 3; 4; 6; 8; 9; 11], 6, 7)    	| US7_0 3 	| US7_0 3 	| 3, 134
struct ([1; 3; 4; 6; 8; 9; 11], 1, 7)    	| US7_0 0 	| US7_0 0 	| 1, 84 
struct ([1; 3; 4; 6; 8; 9; 11], 11, 7)   	| US7_0 6 	| US7_0 6 	| 3, 84 
struct ([1; 3; 4; 6; 8; 9; 11], 12, 7)   	| US7_1   	| US7_1   	| 3, 86 
struct ([1; 2; 3; 4...00; ...], 60, 1000)	| US7_0 59	| US7_0 59	| 1, 110
struct ([1; 3; 4; 6; 8; 9; 11], 6, 7)    	| US7_0 3 	| US7_0 3 	| 1, 72 
struct ([1; 3; 4; 6; 8; 9; 11], 1, 7)    	| US7_0 0 	| US7_0 0 	| 1, 83 
struct ([1; 3; 4; 6; 8; 9; 11], 11, 7)   	| US7_0 6 	| US7_0 6 	| 3, 83 
struct ([1; 3; 4; 6; 8; 9; 11], 12, 7)   	| US7_1   	| US7_1   	| 3, 85 
struct ([1; 2; 3; 4...100; ...], 60, 100)	| US7_0 59	| US7_0 59	| 1, 100
```
00:00:08 v #52 benchmark.sort_result_list / averages.iter / { i = 3; avg = 93 }
00:00:08 v #53 benchmark.sort_result_list / averages.iter / { i = 2; avg = 96 }
00:00:08 v #54 benchmark.sort_result_list / averages.iter / { i = 1; avg = 105 }
00:00:08 v #55 benchmark.sort_result_list / averages.iter / { i = 4; avg = 114 }
```

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: 140L  

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

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

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

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

Input	| Expected  	| Result    	| Best    
---  	| ---       	| ---       	| ---     
1    	| a         	| a         	| (1, 140)
2    	| ba        	| ba        	| (1, 164)
3    	| aaa       	| aaa       	| (1, 137)
9    	| aaaaaaaaa 	| aaaaaaaaa 	| (1, 139)
10   	| baaaaaaaaa	| baaaaaaaaa	| (1, 144)

Average Ranking  
Test case 1. Average Time: 144L  

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: 146L  

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

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

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

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

Input	| Expected	| Result	| Best    
---  	| ---     	| ---   	| ---     
0    	| False   	| False 	| (1, 146)
1,2  	| True    	| True  	| (1, 92) 
3,5  	| False   	| False 	| (1, 55) 
3,4,6	| True    	| True  	| (1, 64) 
2,4,6	| False   	| False 	| (1, 67) 

Average Ranking  
Test case 1. Average Time: 84L