open System
open System.Diagnostics
open System.Threading.Tasks

// Funkcja generująca tablicę losowych liczb o podanej długości w określonym zakresie
let generujLosowaTablice dlugosc =
    let rand = Random()
    Array.init dlugosc (fun _ -> rand.Next(100)) // Ograniczenie zakresu do 0-999999

// Programowanie współbieżne z użyciem asynchronicznych operacji
let programWspolbiezny () =
    async {
        let stoper = new Stopwatch()
        stoper.Start()

        let zadanie1 = async { return generujLosowaTablice 1000 }
        let zadanie2 = async { return generujLosowaTablice 1000 }

        // Oczekiwanie na zakończenie obu zadań jednocześnie
        do! Async.Parallel [zadanie1; zadanie2] |> Async.Ignore

        stoper.Stop()
        printfn "Czas wykonania programu współbieżnego: %f sekundy" (stoper.Elapsed.TotalSeconds)
    }

// Programowanie równoległe z użyciem Parallel.For
let programRownolegly () =
    let stoper = new Stopwatch()
    stoper.Start()

    let tablica1 = generujLosowaTablice 1000
    let tablica2 = generujLosowaTablice 1000

    Parallel.For(1, 3, fun _ -> ignore(tablica1 |> Array.sum; tablica2 |> Array.sum))

    stoper.Stop()
    printfn "Czas wykonania programu równoległego: %f sekundy" (stoper.Elapsed.TotalSeconds)

[<EntryPoint>]
let main argv =
    printfn "Rozpoczęcie programu"

    // Programowanie współbieżne
    Async.RunSynchronously (programWspolbiezny ())

    printfn "Zakończenie programu współbieżnego"

    // Oddzielenie sekcji współbieżnej i równoległej
    printfn "\n---\n"

    // Programowanie równoległe
    programRownolegly ()

    printfn "Zakończenie programu równoległego"

    0 // Zwraca kod zakończenia programu
