From 7d9c4a6d3edeacc952d3eeae9730e780b4d0b0a9 Mon Sep 17 00:00:00 2001 From: Francesco Minnocci Date: Sat, 14 May 2022 20:27:29 +0200 Subject: [PATCH] Add sumDivisors and peterson implementation --- esperimenti/Program.fs | 2 +- ludo/Program.fs | 47 ---------------- ludo2/Program.fs | 113 -------------------------------------- peterson.c | 87 +++++++++++++++++++++++++++++ sumDivisors/Program.fs | 43 +++++++++++++++ sumDivisors/sumDivisors.m | 24 ++++++++ 6 files changed, 155 insertions(+), 161 deletions(-) delete mode 100644 ludo/Program.fs delete mode 100644 ludo2/Program.fs create mode 100644 peterson.c create mode 100644 sumDivisors/Program.fs create mode 100644 sumDivisors/sumDivisors.m diff --git a/esperimenti/Program.fs b/esperimenti/Program.fs index 62620ca..e7a6647 100644 --- a/esperimenti/Program.fs +++ b/esperimenti/Program.fs @@ -23,4 +23,4 @@ printfn "%b" (isPippo(parolaPippo("pipo"))) printfn "%b" (isPippo(parolaPippo("pippo"))) let s = Seq.initInfinite (fun s -> s*s) -Seq.toList (Seq.take 10 s) +printfn "%A" (Seq.toList (Seq.take 10 s)) diff --git a/ludo/Program.fs b/ludo/Program.fs deleted file mode 100644 index 9708eb6..0000000 --- a/ludo/Program.fs +++ /dev/null @@ -1,47 +0,0 @@ -// For more information see https://aka.ms/fsharp-console-apps -printfn "Hello from F#" - -// printfn "%A" ((fun x -> x+1)3) - -let ratio(x,y) = - let z = x * y - let w = 2 * (x + y) - w / z - -let ratio2(x : float, y : float) = - let z = x * y - let w = ((2 : float) * x) + ((2 : float) * y) - w / z - -printfn "%A" (ratio2(2.1,3.0)) - -let getType(x) = x.GetType().FullName - -let rec Fib (n : int) = - if (n = 0 || n = 1) then 1 - else Fib (n - 1) + Fib (n - 2) - -let TrNum (n : int) = n*(n+1)/2 - -printfn "%A" (TrNum(10)) - -let rec ProdNum (n : int) = - match n with - | 1 -> 1 - | _ -> ProdNum(n-1)*n - -let rec sumFirstFun f k = - if k<=0 then 0 else f k + sumFirstFun f (k-1) - -let rec fold g f k1 k2 z = - if (k2 < k1) then z - else g (fold g f (k1+1) k2 z) (f(k1)) - -let sum x y = x + y -let double x = 2*x - -printfn "%A" (fold sum double 10 100 0) - -printfn "%A" (ProdNum(5)) - -printfn "%A" (Fib (5)) diff --git a/ludo2/Program.fs b/ludo2/Program.fs deleted file mode 100644 index f994299..0000000 --- a/ludo2/Program.fs +++ /dev/null @@ -1,113 +0,0 @@ -let rec foldLeft g f k1 k2 z = - if k1 >= k2 then g(z,f(k1)) - else g(foldLeft g f k1 (k2-1) z, f k2) - - -let rec foldRight g f k1 k2 z = - if k1 >= k2 then g(f(k1),z) - else g(f k1, foldRight g f (k1+1) k2 z) - - - -let list1 = [1; 2; 3] -let list2 = [1,2,3] -let list2' = [(1,2,3)] -let list3 = (1,2,3) -let list4 = [] -let list5 = 4::list1 - -let rec lngth lst = - if lst = [] - then 0 - else 1 + (lngth (List.tail lst)) - -//printfn "%A" (lngth [1;3;4]) - -let rec invList l i = - if l = [] then [] - else if ((List.length l) - i) = 0 then [List.head l] - else - l[List.length l - i] :: (invList l (i+1)) - -//printfn "%A" (invList [1;2;3;4] 1) - -let reverseList l = - let rec reverseL acc l = - if l = [] then acc - else - reverseL ( (List.head l) :: acc) (List.tail l) - reverseL [] l - -//printfn "%A" (reverseList [1;2;3;4]) - -let rec sumList (l: int list) = - if l = [] then 0 - else - List.head l + sumList (List.tail l) - -let rec maxL (l : int list) (max : int) = - if l = [] then max - else - if (List.head l) > max then maxL (List.tail l) (List.head l) - else maxL (List.tail l) max - -let maxList l = if l= [] then failwith "Lista vuota" else maxL l (List.head l) - -//printfn "%A" (sumList [1;2;3;4]) - -//printfn "%A" (maxList [1;2;3;4]) - -//printfn "%A" (maxList []) - -let rec fib x = - match x with - | 1 -> 1 - | 2 -> 1 - | n -> fib (n-1) + fib (n-2) - -let rec fib2 x = - match x with - | n when n < 1 -> failwith (sprintf "Error: %d is less than 1" x) - | (1|2) -> 1 - | n -> fib (n-1) + fib (n-2) - -let rec fn2 a = - match a with - | (x,y) when x > 0 && y > 0 -> x + y - | (x,_) when x < 0 -> 0 - | _ -> failwith "This makes no sense" - -let rec length2 l = - match l with - | [] -> 0 - | _ :: xs -> 1 + (length2 xs) - -let rec nth i l = - match (i,l) with - | (_,[]) -> failwith "Errore: ricorsione termina in lista vuota" - | (0, x :: _) -> x - | (n, _ :: xs) when n > 0 -> nth (n-1) xs - | _ -> failwith "Errore: indice negativo" - -// printfn "%A" (nth 4 [1;2;3;4;5]) - -let rec EuclidsAlg n m = - match (a,b) with - | _ when (a <= 0 || b <= 0) -> failwith "Errore: almeno un numero non positivo" - | _ when (a = b) -> a - | _ when (a > b) -> EuclidsAlg (a-b) b - | _ -> EuclidsAlg a (b-a) - -let rec unzip l = - match l with - | [] -> ([],[]) - | (a,b) :: xs -> (a :: (fst (unzip xs)), b :: (snd (unzip xs)));; - -// printfn "%A" (EuclidsAlg 48 12) - -let rec unzip' l = - match l with - | [] -> ([],[]) - | (a,b) :: xs -> - let (aa,bb) = unzip xs - (a :: aa, b :: bb) \ No newline at end of file diff --git a/peterson.c b/peterson.c new file mode 100644 index 0000000..3651e2e --- /dev/null +++ b/peterson.c @@ -0,0 +1,87 @@ +#include +#include + +#include +#include +#include +#include + +// This program illustrates the use of Peterson's algorithm to synchronize +// multiple threads.Two new threads are created and alternate writing to the +// standard output. +// +// The key difference between Peterson's algorithm and strict alternation is +// the inclusion of flags indicating whether a thread is ready to enter the +// critical section. + +// This function is taken from `~/.local/src/dwm/util.c`. +// +// Print the error message and `perror` if the message ends in `':'`. Assumes +// `fmt` is not `NULL`. +void die(const char* fmt, ...) { + va_list ap; + + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + + // Following Unix convention (see `man perror`), first check if the string is + // not empty. + if(fmt[0] && fmt[strlen(fmt) - 1] == ':') { + fputc(' ', stderr); + perror(NULL); + } else { + fputc('\n', stderr); + } + + exit(0); +} + +// The `turn` variable indicates which thread should enter the critical +// section. Unlike strict alternation, the `turn` variable is set _before_ +// entering the critical section. +// +// Note that globally-scoped variables are initialized to zero. +int turn; +int flag[2]; + +void* f0(void* arg) { + while(1) { + // Signal that this thread wants to enter the critical section. + flag[0] = 1; + // Signal to the other thread that it is their turn. + turn = 1; + while(flag[1] && turn == 1); + puts("hello"); + flag[0] = 0; + sleep(1); + } +} + +void* f1(void* arg) { + while(1) { + flag[1] = 1; + turn = 0; + while(flag[0] && turn == 0); + puts("world"); + flag[1] = 0; + sleep(1); + } +} + +int main(void) { + // A POSIX thread has two main components: an object of type `pthread_t` + // which represents the thread and a function pointer of type + // `void* (*)(void*)` which will be the entry point of the thread. + pthread_t t0, t1; + + // Creates new threads. The second argument is a pointer to a + // `pthread_attr_t`, if `NULL` the thread is created with default attributes. + // The last argument is the argument that is given to the thread's entry + // point function, unused in this example. + if(pthread_create(&t0, NULL, f0, NULL)) die("unable to create thread"); + if(pthread_create(&t1, NULL, f1, NULL)) die("unable to create thread"); + + // Yes, I could have just created one thread. + while(1); +} diff --git a/sumDivisors/Program.fs b/sumDivisors/Program.fs new file mode 100644 index 0000000..95ad7d1 --- /dev/null +++ b/sumDivisors/Program.fs @@ -0,0 +1,43 @@ +open System + +let factorsWithMolteplicity n = + let rec loop c p = + if c < (p * p) then [c] + elif c % p = 0 then p :: (loop (c/p) p) + else loop c (p + 1) + loop n 2 + |> List.countBy id + +let isPerfect n = + let sumDiv k = + k + |> factorsWithMolteplicity + |> List.map (fun (p,m) -> ((pown p (m+1))-1)/(p-1)) + |> List.fold (*) 1 + sumDiv n = 2*n + +// brute-force approach +let divisors n = + [1..n/2] + |> Seq.filter (fun f -> n % f = 0) +let sumProperDivisors n = + n + |> divisors + |> Seq.sum + +// perfect +let isPerfect2 n = (sumProperDivisors n = n) + +let timer = new System.Diagnostics.Stopwatch() +timer.Start() +printfn "%A" (isPerfect 8128) +timer.Stop() +printfn "%f" timer.Elapsed.TotalMilliseconds +printfn "Elapsed Time: %i" timer.ElapsedMilliseconds + +let timer2 = new System.Diagnostics.Stopwatch() +timer2.Start() +printfn "%A" (isPerfect2 8128) +timer2.Stop() +printfn "%f" timer2.Elapsed.TotalMilliseconds +printfn "Elapsed Time: %i" timer2.ElapsedMilliseconds diff --git a/sumDivisors/sumDivisors.m b/sumDivisors/sumDivisors.m new file mode 100644 index 0000000..6a14398 --- /dev/null +++ b/sumDivisors/sumDivisors.m @@ -0,0 +1,24 @@ +N=1e7; + +for n=2:N + % A contains the unique prime factors of n; M their multiplicities + [A,M]=factor(n); + l=length(A); + s=1; + for i=1:l + % formula for the sum of divisors of p^k + c(i)=((A(i)^(M(i)+1))-1)/(A(i)-1); + s*=c(i); + end + if 2*n==s + printf("%d is Perfect!\n",n) + m=n; + k=0; + while mod(m,2)==0 + m=m/2; + k++; + end + k++; + printf("The corresponding Mersenne prime is %d\n",((2^k)-1)) + end +end \ No newline at end of file