From f05676634a9fc2ca6e81b2ee64e8fa91955967ff Mon Sep 17 00:00:00 2001 From: jacekpoz Date: Fri, 21 Jun 2024 16:18:26 +0200 Subject: [PATCH] lab5 --- lab5/zad1/zad1.hs | 78 ++++++++++++++++++++++++++++ lab5/zad1/zad1.lisp | 111 +++++++++++++++++++++++++++++++++++++++ lab5/zad1/zad1.sml | 124 ++++++++++++++++++++++++++++++++++++++++++++ lab5/zad2/zad2.pl | 93 +++++++++++++++++++++++++++++++++ 4 files changed, 406 insertions(+) create mode 100644 lab5/zad1/zad1.hs create mode 100644 lab5/zad1/zad1.lisp create mode 100644 lab5/zad1/zad1.sml create mode 100644 lab5/zad2/zad2.pl diff --git a/lab5/zad1/zad1.hs b/lab5/zad1/zad1.hs new file mode 100644 index 0000000..2f8a0d8 --- /dev/null +++ b/lab5/zad1/zad1.hs @@ -0,0 +1,78 @@ +import Data.List (nub) + +binomial :: (Integral n) => n -> n -> n +binomial n 0 = 1 +binomial n k + | n == k = 1 + | otherwise = binomial (n - 1) k + binomial (n - 1) (k - 1) + +----------------------------------------------- + +binomial2 :: Int -> Int -> Int +binomial2 n k = triangle !! n !! k + where + triangle = iterate next_row [1] + next_row row = zipWith (+) ([0] ++ row) (row ++ [0]) + +----------------------------------------------- + +merge :: Ord a => [a] -> [a] -> [a] +merge xl [] = xl +merge [] yl = yl +merge (x:xl) (y:yl) + | x <= y = x:merge xl (y:yl) + | otherwise = y:merge (x:xl) yl + +mergesort :: Ord a => [a] -> [a] +mergesort [] = [] +mergesort [a] = [a] +mergesort xl = merge (mergesort (first_half xl)) (mergesort (second_half xl)) + +first_half xl = let { n = length xl } in take (div n 2) xl +second_half xl = let { n = length xl } in drop (div n 2) xl + +------------------------------------------------ + +gcde :: (Integral a) => a -> a -> (a, a, a) +gcde 0 b = (b, 0, 1) +gcde a b = + let (g, x, y) = gcde (mod b a) a in (g, y - (div b a) * x, x) + +de :: (Integral a) => a -> a -> (a, a, a) +de a b = let (g, x, y) = gcde a b in (x, y, g) + +------------------------------------------------ + +prime_factors :: (Integral a) => a -> [a] +prime_factors n = factorize n 2 + +factorize :: (Integral a) => a -> a -> [a] +factorize 1 _ = [] +factorize n factor + | mod n factor == 0 = factor : factorize (div n factor) factor + | otherwise = factorize n (factor + 1) + +------------------------------------------------ + +_gcd :: Integral a => a -> a -> a +_gcd 0 b = b +_gcd a b = _gcd (mod b a) a + +is_coprime :: Integral a => a -> a -> Bool +is_coprime a b = _gcd a b == 1 + +totient :: Integral a => a -> a +totient n = fromIntegral (length (filter (is_coprime n) [1..n])) + +------------------------------------------------ + +totient2 :: Integral a => a -> a +totient2 n = foldl (\acc p -> div (acc * (p - 1)) p) n (nub (prime_factors n)) + +------------------------------------------------ + +primes :: Integral a => a -> [a] +primes n = sieve [2..n] + where + sieve [] = [] + sieve (x:xs) = x : sieve [y | y <- xs, mod y x /= 0] diff --git a/lab5/zad1/zad1.lisp b/lab5/zad1/zad1.lisp new file mode 100644 index 0000000..46672d0 --- /dev/null +++ b/lab5/zad1/zad1.lisp @@ -0,0 +1,111 @@ +(defun binomial (n k) + (cond + ((= k 0) 1) + ((= n k) 1) + (t (+ (binomial (- n 1) k) (binomial (- n 1) (- k 1)))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defun next_row (row) + (mapcar #'+ (append '(0) row) (append row '(0)))) + +(defun generate_pascal_row (n current_row) + (if (= n 0) + current_row + (generate_pascal_row (- n 1) (next_row current_row)))) + +(defun generate_pascal (n) + (generate_pascal_row n '(1))) + +(defun binomial2 (n k) + (nth k (generate_pascal n))) + + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun empty_or_singleton (list) + (or (null list) (null (cdr list)))) + +(defun right_half (list) + (last list (ceiling (/ (length list) 2)))) +(defun left_half (list) + (ldiff list (right_half list))) + +(defun mergelists (list1 list2) + (merge 'list list1 list2 #'<)) +(defun mergesort (list) + (if (empty_or_singleton list) list + (mergelists + (mergesort (left_half list)) + (mergesort (right_half list))))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun gcde (a b) + (if (= a 0) + (values b 0 1) + (multiple-value-bind (g x y) + (gcde (mod b a) a) + (values g (- y (* (floor b a) x)) x)))) + +(defun de (a b) + (multiple-value-bind (x y g) + (gcde a b) + (values x y g))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun factorize (n factor) + (cond + ((= 1 n) nil) + ((= 0 (mod n factor)) (cons factor (factorize (/ n factor) factor))) + (t (factorize n (+ factor 1))))) + + +(defun prime_factors (n) + (factorize n 2)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun _gcd (a b) + (if (= a 0) b + (_gcd (mod b a) a))) + +(defun is_coprime (a b) + (= (_gcd a b) 1)) + +(defun totient_helper (n i) + (cond ((= i n) (if (is_coprime n i) 1 0)) + ((is_coprime n i) (1+ (totient_helper n (1+ i)))) + (t (totient_helper n (1+ i))))) + +(defun totient (n) + (totient_helper n 1)) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + +(defun totient2 (n) + (let ((unique_factors (remove-duplicates (prime_factors n)))) + (reduce #'(lambda (acc p) (floor (/ (* acc (- p 1)) p))) unique_factors :initial-value n))) + +;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; + + +(defun prime? (n &optional (divisor 2)) + (cond ((<= n 1) nil) + ((= n 2) t) + ((evenp n) nil) + ((> divisor (isqrt n)) t) + ((zerop (mod n divisor)) nil) + (t (prime? n (+ divisor 1))))) + +(defun primes_helper (n result) + (if (zerop n) + result + (if (prime? n) + (primes_helper (- n 1) (cons n result)) + (primes_helper (- n 1) result)))) + +(defun primes (n) + (primes_helper n '())) diff --git a/lab5/zad1/zad1.sml b/lab5/zad1/zad1.sml new file mode 100644 index 0000000..85f31fd --- /dev/null +++ b/lab5/zad1/zad1.sml @@ -0,0 +1,124 @@ +fun binomial (n, k) = + if k = 0 then 1 + else if k = n then 1 + else binomial (n - 1, k) + binomial(n - 1, k - 1); + +(****************************************************************) + +fun next_row [] = [] + | next_row [x] = [] + | next_row (x::y::rest) = (x + y) :: (next_row (y::rest)) + +fun pascal_row 0 = [1] + | pascal_row n = + let + val prev_row = pascal_row (n - 1) + in + 1 :: (next_row prev_row) @ [1] + end + +fun binomial2 (n, k) = + let + val row = pascal_row n + in + List.nth(row, k) + end + +(****************************************************************) + +fun listOfLists nil = nil + | listOfLists (f::e) = [f]::(listOfLists e); + +fun merge xs nil = xs + | merge nil ys = ys + | merge (x::xs) (y::ys) = + if (x < y) then + x::(merge xs (y::ys)) + else + y::(merge (x::xs) ys); + +fun mergePass [] = [] + | mergePass (x::nil) = [x] + | mergePass (i::j::k) = + if (length (i::j::k)) < 1 then + mergePass (i::j::k) + else + [merge i j] @ (mergePass (List.drop((i::j::k), 2))); + +fun mergeSortCon [] = [] + | mergeSortCon (x::nil) = x + | mergeSortCon (x::y::z) = mergeSortCon ((mergePass (x::y::nil)) @ (mergePass z)); + +fun mergeSort [] = [] + | mergeSort x = mergeSortCon (listOfLists x); + +(****************************************************************) + +fun gcde 0 b = (b, 0, 1) + | gcde a b = + let + val (g, x, y) = gcde (b mod a) a + in + (g, y - (b div a) * x, x) + end + +fun de a b = + let + val (g, x, y) = gcde a b + in + (x, y, g) + end + +(****************************************************************) + +fun primeFactors n = + let + fun factorize 1 _ = [] + | factorize n factor = + if n mod factor = 0 then + factor :: factorize (n div factor) factor + else + factorize n (factor + 1) + in + factorize n 2 + end + +(****************************************************************) + +fun gcd 0 b = b + | gcd a b = gcd (b mod a) a + +fun is_coprime a b = (gcd a b) = 1 + +fun totient n = List.length (List.filter (is_coprime n) (List.tabulate (n, fn x => x + 1))) + +(****************************************************************) + +fun intPow x 0 = 1 + | intPow x n = x * (intPow x (n - 1)) + +fun group [] = [] + | group (x::xs) = + let + val (prefix, suffix) = List.partition (fn y => y = x) xs + in + (x::prefix) :: (group suffix) + end + +fun totient2 n = + let + fun product (p, k) = (p - 1) * (intPow p (k - 1)) + val factors = primeFactors n + val groupedFactors = group factors + val factorCounts = List.map (fn xs => (List.hd xs, List.length xs)) groupedFactors + in + List.foldl (fn (pk, acc) => acc * product pk) 1 factorCounts + end + +(****************************************************************) + +fun primes_helper [] primes = primes + | primes_helper (1::ns) primes = sieveN ns (1::primes) + | primes_helper (n::ns) primes = sieveN (List.filter (fn x => x mod n <> 0) ns) (n::primes); + +fun primes n = primes_helper (List.tabulate (n - 2, fn x => x + 1)) []; diff --git a/lab5/zad2/zad2.pl b/lab5/zad2/zad2.pl new file mode 100644 index 0000000..736c0e3 --- /dev/null +++ b/lab5/zad2/zad2.pl @@ -0,0 +1,93 @@ +mergesort([], []). +mergesort([A], [A]). + +mergesort([A, B | Rest], S) :- + divide([A, B | Rest], L1, L2), + mergesort(L1, S1), + mergesort(L2, S2), + merge(S1, S2, S). + +divide([], [], []). +divide([A], [A], []). + +divide([A, B | R], [A | Ra], [B | Rb]) + :- divide(R, Ra, Rb). + +merge(A, [], A). +merge([], B, B). + +merge([A | Ra], [B | Rb], [A | M]) :- + A =< B, + merge(Ra, [B | Rb], M). +merge([A | Ra], [B | Rb], [B | M]) :- + A > B, + merge([A | Ra], Rb, M). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +egcd(A, 0, 1, 0, A). +egcd(A, B, X, Y, G) :- + B \= 0, + Q is A // B, + R is A mod B, + egcd(B, R, X1, Y1, G), + X is Y1, + Y is X1 - Q * Y1. + +de(A, B, X, Y, Z) :- + egcd(A, B, X, Y, G), + Z is G. + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +prime_factors(N, X) :- + N > 1, + prime_factors(N, 2, X). + +prime_factors(1, _, []). +prime_factors(N, D, [D|X]) :- + N > 1, + N mod D =:= 0, + N1 is N // D, + prime_factors(N1, D, X). +prime_factors(N, D, X) :- + N > 1, + (D = 2 -> D1 is 3 ; D1 is D + 2), + prime_factors(N, D1, X). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +distinct_factors(L, D) :- + sort(L, D). + +totient(N, T) :- + N > 0, + prime_factors(N, Factors), + distinct_factors(Factors, DistinctFactors), + compute_totient(N, DistinctFactors, T). + +compute_totient(N, [], N). +compute_totient(N, [P|Ps], T) :- + N1 is N * (P - 1) // P, + compute_totient(N1, Ps, T). + +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +is_prime(2) :- !. +is_prime(3) :- !. +is_prime(N) :- + integer(N), N > 3, N mod 2 =\= 0, \+ factor(N, 3). + +factor(N, F) :- + N mod F =:= 0. + +factor(N, F) :- + F * F < N, F2 is F + 2, factor(N, F2). + +prime(LO, HI, N) :- + between(LO, HI, N), is_prime(N). + +primes(N, Xs) :- + findall(X, prime(2, N, X), Xs). + +% vim: ft=prolog