upload diverse filer
This commit is contained in:
6
Diskret Mat/ipynb filer/README.md
Normal file
6
Diskret Mat/ipynb filer/README.md
Normal file
@@ -0,0 +1,6 @@
|
||||
# Diskret Matematik gode programmer at have
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
BIN
Diskret Mat/ipynb filer/__pycache__/tools.cpython-311.pyc
Normal file
BIN
Diskret Mat/ipynb filer/__pycache__/tools.cpython-311.pyc
Normal file
Binary file not shown.
BIN
Diskret Mat/ipynb filer/__pycache__/tools.cpython-313.pyc
Normal file
BIN
Diskret Mat/ipynb filer/__pycache__/tools.cpython-313.pyc
Normal file
Binary file not shown.
1185
Diskret Mat/ipynb filer/samples.ipynb
Normal file
1185
Diskret Mat/ipynb filer/samples.ipynb
Normal file
File diff suppressed because one or more lines are too long
57
Diskret Mat/ipynb filer/test.py
Normal file
57
Diskret Mat/ipynb filer/test.py
Normal file
@@ -0,0 +1,57 @@
|
||||
from sympy import *
|
||||
|
||||
def check_injective_surjective(func, var, domain, codomain):
|
||||
x, y = symbols('x y')
|
||||
|
||||
# Check if the function is well-defined
|
||||
outputs = {}
|
||||
for val in domain:
|
||||
output = func.subs(var, val)
|
||||
if output in outputs:
|
||||
# If the same output occurs for different inputs, it's not well-defined
|
||||
if outputs[output] != val:
|
||||
return "The function is not well-defined."
|
||||
else:
|
||||
outputs[output] = val
|
||||
|
||||
# Check injectivity
|
||||
injective = True
|
||||
for val1 in domain:
|
||||
for val2 in domain:
|
||||
if val1 != val2:
|
||||
if func.subs(var, val1) == func.subs(var, val2):
|
||||
injective = False
|
||||
break
|
||||
|
||||
# Check surjectivity
|
||||
surjective = True
|
||||
for c_val in codomain:
|
||||
try:
|
||||
solutions = solve(Eq(func, c_val), var)
|
||||
if not any(s in domain for s in solutions):
|
||||
surjective = False
|
||||
break
|
||||
except:
|
||||
surjective = False
|
||||
break
|
||||
|
||||
# Results
|
||||
if injective and surjective:
|
||||
return "The function is bijective (both injective and surjective)."
|
||||
elif injective:
|
||||
return "The function is injective only."
|
||||
elif surjective:
|
||||
return "The function is surjective only."
|
||||
else:
|
||||
return "The function is neither injective nor surjective."
|
||||
|
||||
# Define the function and its domain/codomain
|
||||
x = symbols('x')
|
||||
func = Piecewise((2*x, x >= 0), (-2*x-1, x < 0))
|
||||
domain = range(-20, 20) # For example, integers from -20 to 20
|
||||
codomain = range(0, 40) # Adjusted codomain to include all possible outputs
|
||||
|
||||
result = check_injective_surjective(func, x, domain, codomain)
|
||||
print(result)
|
||||
|
||||
print("please double check it yourself")
|
||||
524
Diskret Mat/ipynb filer/tools.py
Normal file
524
Diskret Mat/ipynb filer/tools.py
Normal file
@@ -0,0 +1,524 @@
|
||||
import re
|
||||
from itertools import permutations, product, chain, combinations
|
||||
import math
|
||||
import numpy as np
|
||||
from sympy import mod_inverse
|
||||
#import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
|
||||
|
||||
def is_prime(n):
|
||||
if n <= 1:
|
||||
return False
|
||||
|
||||
for i in range(2, int(n**0.5) + 1):
|
||||
|
||||
if n % i == 0:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
def primes_below(n):
|
||||
primes = [i for i in range(2, n) if is_prime(i)]
|
||||
return f"Number of primes below {n} is {len(primes)} and the list is {primes}"
|
||||
|
||||
def divide_with_remainder(a, b):
|
||||
if b == 0:
|
||||
return "Division by zero is undefined."
|
||||
|
||||
quotient = a // b
|
||||
remainder = a % b
|
||||
return f"The quotient of {a} divided by {b} is {quotient}, and the remainder is {remainder}."
|
||||
|
||||
|
||||
# sent by jesper TA<3
|
||||
def gcd(a, b):
|
||||
rlist = [a, b]
|
||||
qlist = []
|
||||
|
||||
while True:
|
||||
r1 = rlist[-2]
|
||||
r2 = rlist[-1]
|
||||
if r2 == 0:
|
||||
break
|
||||
new_r = r1 % r2
|
||||
qlist.append(r1 // r2)
|
||||
rlist.append(new_r)
|
||||
|
||||
slist = [1, 0]
|
||||
tlist = [0, 1]
|
||||
|
||||
for q in qlist:
|
||||
s1 = slist[-2]
|
||||
s2 = slist[-1]
|
||||
t1 = tlist[-2]
|
||||
t2 = tlist[-1]
|
||||
|
||||
slist.append(s1 - q * s2)
|
||||
tlist.append(t1 - q * t2)
|
||||
|
||||
i = 0
|
||||
print('i \t r_i \t r_i+1 \t q_i+1 \t r_i+2 \t s_i \t t_i')
|
||||
for r1, r2, r3, q, s, t in zip(rlist, rlist[1:], rlist[2:], qlist, slist, tlist):
|
||||
print(f'{i} \t {r1} \t {r2} \t {q} \t {r3} \t {s} \t {t}')
|
||||
i += 1
|
||||
print(f'\t\t\t\t\t {slist[-2]} \t {tlist[-2]}')
|
||||
|
||||
gcd_value = rlist[-2]
|
||||
s_coeff = slist[-2]
|
||||
t_coeff = tlist[-2]
|
||||
result_string = f"GCD({a}, {b}) = {gcd_value}, with coefficients {s_coeff} and {t_coeff} such that {gcd_value} = ({s_coeff})*{a} + ({t_coeff})*{b}"
|
||||
|
||||
print(f'{result_string}')
|
||||
#return gcd_value, s_coeff, t_coeff, result_string
|
||||
|
||||
def lcm(a, b):
|
||||
def gcd(a, b):
|
||||
while b:
|
||||
a, b = b, a % b
|
||||
return a
|
||||
|
||||
gcd_value = gcd(a, b)
|
||||
lcm_value = abs(a * b) // gcd_value
|
||||
|
||||
result_string = (
|
||||
f"LCM({a}, {b}) = {lcm_value}, Here, GCD({a}, {b}) = {gcd_value}."
|
||||
)
|
||||
|
||||
print(result_string)
|
||||
#return lcm_value, result_string
|
||||
|
||||
|
||||
|
||||
# Sent by Alexander Piepgrass <3
|
||||
def _min_gcd_congruences(a,b):
|
||||
rlist = [a,b]
|
||||
qlist = []
|
||||
|
||||
while True:
|
||||
r1 = rlist[-2]
|
||||
r2 = rlist[-1]
|
||||
if r2==0:
|
||||
break
|
||||
new_r = r1%r2
|
||||
qlist.append(r1//r2)
|
||||
rlist.append(new_r)
|
||||
|
||||
slist = [1,0]
|
||||
tlist = [0,1]
|
||||
|
||||
for q in qlist:
|
||||
s1 = slist[-2]
|
||||
s2 = slist[-1]
|
||||
t1 = tlist[-2]
|
||||
t2 = tlist[-1]
|
||||
|
||||
slist.append(s1-q*s2)
|
||||
tlist.append(t1-q*t2)
|
||||
|
||||
i = 0
|
||||
|
||||
return rlist[-2], slist[-2], tlist[-2]
|
||||
|
||||
# sent by alexander piepgrass <3
|
||||
def congruences_system_solver(system):
|
||||
m=1
|
||||
for cong in system:
|
||||
m*=cong[1]
|
||||
M_list = []
|
||||
for cong in system:
|
||||
M_list.append(m//cong[1])
|
||||
y_list=[]
|
||||
|
||||
for i in range(len(M_list)):
|
||||
r,s,t= _min_gcd_congruences(M_list[i],system[i][1])
|
||||
y_list.append(s)
|
||||
|
||||
x=0
|
||||
|
||||
for i in range(len(M_list)):
|
||||
x+=system[i][0]*M_list[i]*y_list[i]
|
||||
print(f'all solutions are {x % m} + {m}k')
|
||||
return x % m, m, M_list, y_list
|
||||
|
||||
def some_congruences_system_solver(system):
|
||||
normalized_system = []
|
||||
for b, a, n in system:
|
||||
g = math.gcd(b, n)
|
||||
if a % g != 0:
|
||||
raise ValueError(f"No solution exists for {b}*x ≡ {a} (mod {n})")
|
||||
# Reduce b*x ≡ a (mod n) to x ≡ c (mod m)
|
||||
b = b // g
|
||||
a = a // g
|
||||
n = n // g
|
||||
b_inv = mod_inverse(b, n)
|
||||
c = (b_inv * a) % n
|
||||
normalized_system.append((c, n))
|
||||
|
||||
# Solve the normalized system of congruences
|
||||
m = 1
|
||||
for _, n in normalized_system:
|
||||
m *= n
|
||||
M_list = []
|
||||
for _, n in normalized_system:
|
||||
M_list.append(m // n)
|
||||
y_list = []
|
||||
for i in range(len(M_list)):
|
||||
r, s, t = _min_gcd_congruences(M_list[i], normalized_system[i][1])
|
||||
y_list.append(s)
|
||||
|
||||
x = 0
|
||||
for i in range(len(M_list)):
|
||||
x += normalized_system[i][0] * M_list[i] * y_list[i]
|
||||
|
||||
print(f'All solutions are {x % m} + {m}k')
|
||||
return x % m, m, M_list, y_list
|
||||
|
||||
def solve_congruence_general(a, c, m):
|
||||
"""
|
||||
Solves the congruence ax ≡ c (mod m).
|
||||
Returns a general solution in the form x ≡ x0 + k*b (mod m),
|
||||
or 'No solution' if no solution exists.
|
||||
"""
|
||||
from math import gcd
|
||||
|
||||
# Step 1: Compute gcd(a, m)
|
||||
g = gcd(a, m)
|
||||
|
||||
# Step 2: Check if a solution exists
|
||||
if c % g != 0:
|
||||
return "No solution"
|
||||
|
||||
# Step 3: Simplify the congruence
|
||||
a, c, m = a // g, c // g, m // g
|
||||
|
||||
# Step 4: Find the modular inverse of a modulo m
|
||||
def extended_gcd(a, b):
|
||||
"""Helper function to compute the extended GCD."""
|
||||
if b == 0:
|
||||
return a, 1, 0
|
||||
g, x, y = extended_gcd(b, a % b)
|
||||
return g, y, x - (a // b) * y
|
||||
|
||||
g, x, _ = extended_gcd(a, m)
|
||||
if g != 1: # Sanity check for modular inverse
|
||||
return "No solution"
|
||||
|
||||
x = (x % m + m) % m # Ensure x is positive
|
||||
x0 = (c * x) % m # Particular solution
|
||||
|
||||
# General solution is x ≡ x0 + k * m
|
||||
return f"x ≡ {x0} + k * {m}"
|
||||
|
||||
|
||||
|
||||
def explain_quantifiers(logic_string):
|
||||
"""
|
||||
Converts a LaTeX-style logical string into a human-readable explanation.
|
||||
Supports various quantifiers, logical types, and biimplication.
|
||||
"""
|
||||
# Normalize LaTeX equivalents to symbols
|
||||
latex_to_symbol_map = {
|
||||
r"\\forall": "∀",
|
||||
r"\\exists": "∃",
|
||||
r"\\in": "∈",
|
||||
r"\\notin": "∉",
|
||||
r"\\mathbb\{R\}": "ℝ",
|
||||
r"\\neq": "≠",
|
||||
r"\\rightarrow": "→",
|
||||
r"\\leftrightarrow": "↔",
|
||||
r"\\lor": "∨",
|
||||
r"\\land": "∧",
|
||||
r"\\neg": "¬",
|
||||
r"\\leq": "≤",
|
||||
r"\\geq": "≥",
|
||||
r"\\subseteq": "⊆",
|
||||
r"\\supseteq": "⊇",
|
||||
r"\\subset": "⊂",
|
||||
r"\\supset": "⊃",
|
||||
r"\\emptyset": "∅",
|
||||
}
|
||||
|
||||
for latex, symbol in latex_to_symbol_map.items():
|
||||
logic_string = re.sub(latex, symbol, logic_string)
|
||||
|
||||
# Dictionary to map symbols to words
|
||||
symbol_map = {
|
||||
"∀": "For all",
|
||||
"∃": "There exists",
|
||||
"∈": "in",
|
||||
"∉": "not in",
|
||||
"ℝ": "the set of all real numbers",
|
||||
"→": "implies that",
|
||||
"↔": "if and only if",
|
||||
"∨": "or",
|
||||
"∧": "and",
|
||||
"¬": "not",
|
||||
"=": "is equal to",
|
||||
"≠": "is not equal to",
|
||||
"<": "is less than",
|
||||
">": "is greater than",
|
||||
"≤": "is less than or equal to",
|
||||
"≥": "is greater than or equal to",
|
||||
"⊆": "is a subset of",
|
||||
"⊇": "is a superset of",
|
||||
"⊂": "is a proper subset of",
|
||||
"⊃": "is a proper superset of",
|
||||
"∅": "the empty set",
|
||||
}
|
||||
|
||||
# Replace symbols with words
|
||||
for symbol, word in symbol_map.items():
|
||||
logic_string = logic_string.replace(symbol, word)
|
||||
|
||||
# Custom processing for specific patterns
|
||||
# Match quantifiers and variables
|
||||
logic_string = re.sub(r"For all (\w) in (.*?),", r"Given any \1 in \2,", logic_string)
|
||||
logic_string = re.sub(r"There exists (\w) in (.*?),", r"There is a \1 in \2,", logic_string)
|
||||
|
||||
# Handle logical groupings with parentheses
|
||||
logic_string = re.sub(r"\((.*?)\)", r"where \1", logic_string)
|
||||
|
||||
# Ensure precise formatting
|
||||
logic_string = logic_string.strip()
|
||||
return logic_string
|
||||
|
||||
|
||||
def get_permutations(input_string):
|
||||
"""
|
||||
Returns all permutations of the given string.
|
||||
"""
|
||||
# Generate permutations using itertools.permutations
|
||||
perm = permutations(input_string)
|
||||
# Convert to a list of strings
|
||||
perm_list = [''.join(p) for p in perm]
|
||||
return perm_list
|
||||
|
||||
def get_r_permutations(input_string, r):
|
||||
"""
|
||||
Returns all r-permutations of the given string.
|
||||
|
||||
Parameters:
|
||||
input_string (str): The string to generate permutations from.
|
||||
r (int): The length of the permutations.
|
||||
|
||||
Returns:
|
||||
list: A list of all r-permutations as strings.
|
||||
"""
|
||||
# Generate r-permutations using itertools.permutations
|
||||
r_perm = permutations(input_string, r)
|
||||
# Convert to a list of strings
|
||||
r_perm_list = [''.join(p) for p in r_perm]
|
||||
return r_perm_list
|
||||
|
||||
|
||||
|
||||
def get_binary_strings(n, as_strings=False):
|
||||
# Generate all possible bit strings of length n
|
||||
bit_combinations = product([0, 1], repeat=n)
|
||||
if as_strings:
|
||||
# Join bits as strings
|
||||
return ["".join(map(str, bits)) for bits in bit_combinations]
|
||||
else:
|
||||
# Return as lists of integers
|
||||
return [list(bits) for bits in bit_combinations]
|
||||
|
||||
def get_combinations(input_string):
|
||||
"""
|
||||
Returns all combinations of the given string (for all lengths).
|
||||
|
||||
Parameters:
|
||||
input_string (str): The string to generate combinations from.
|
||||
|
||||
Returns:
|
||||
list: A list of all combinations as strings.
|
||||
"""
|
||||
comb_list = []
|
||||
for r in range(1, len(input_string) + 1):
|
||||
comb_list.extend([''.join(c) for c in combinations(input_string, r)])
|
||||
return comb_list
|
||||
|
||||
def get_r_combinations(input_string, r):
|
||||
"""
|
||||
Returns all r-combinations of the given string.
|
||||
|
||||
Parameters:
|
||||
input_string (str): The string to generate combinations from.
|
||||
r (int): The length of the combinations.
|
||||
|
||||
Returns:
|
||||
list: A list of all r-combinations as strings.
|
||||
"""
|
||||
r_comb = combinations(input_string, r)
|
||||
r_comb_list = [''.join(c) for c in r_comb]
|
||||
return r_comb_list
|
||||
|
||||
|
||||
def calculate_number_of_derangements(n):
|
||||
|
||||
"""
|
||||
|
||||
Calculate the number of derangements (Dn) for n elements
|
||||
|
||||
using the formula:
|
||||
|
||||
Dn = n! * (1 - 1/1! + 1/2! - 1/3! + ... + (-1)^n/n!)
|
||||
|
||||
"""
|
||||
|
||||
result = 0
|
||||
|
||||
for i in range(n + 1):
|
||||
|
||||
result += ((-1)**i) / math.factorial(i)
|
||||
|
||||
return round(math.factorial(n) * result)
|
||||
|
||||
def is_derangement(original, perm):
|
||||
"""
|
||||
Checks if a permutation is a derangement of the original string.
|
||||
"""
|
||||
return all(original[i] != perm[i] for i in range(len(original)))
|
||||
|
||||
def get_derangements(input_string):
|
||||
"""
|
||||
Returns all derangements of a given string as an array of strings.
|
||||
"""
|
||||
original = list(input_string)
|
||||
all_permutations = permutations(original)
|
||||
derangements = ["".join(perm) for perm in all_permutations if is_derangement(original, perm)]
|
||||
return derangements
|
||||
|
||||
|
||||
def multiplicative_inverse(n, mod):
|
||||
def gcd_extended(a, b):
|
||||
if a == 0:
|
||||
return b, 0, 1
|
||||
gcd, x1, y1 = gcd_extended(b % a, a)
|
||||
x = y1 - (b // a) * x1
|
||||
y = x1
|
||||
return gcd, x, y
|
||||
|
||||
gcd, x, _ = gcd_extended(n, mod)
|
||||
|
||||
if gcd != 1: # If gcd of n and mod is not 1, inverse doesn't exist
|
||||
return "Does not exist"
|
||||
else:
|
||||
# Make the result positive
|
||||
return x % mod
|
||||
|
||||
|
||||
def minimum_selections_for_sum(numbers, target_sum):
|
||||
selected_numbers = set()
|
||||
|
||||
for num in numbers:
|
||||
if target_sum - num in selected_numbers:
|
||||
# Pair found
|
||||
return len(selected_numbers) + 1
|
||||
|
||||
selected_numbers.add(num)
|
||||
|
||||
# No pair found within the set
|
||||
return None
|
||||
|
||||
|
||||
def is_transitive(R):
|
||||
for a, b in R:
|
||||
for c, d in R:
|
||||
if b == c and ((a, d) not in R):
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def is_reflexive(S, R):
|
||||
newSet = {(a, b) for a in S for b in S if a == b}
|
||||
if R >= newSet:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def is_symmetric(R):
|
||||
if all(tup[::-1] in R for tup in R):
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
|
||||
def is_antisymmetric(R):
|
||||
return all((y, x) not in R for x, y in R if x != y)
|
||||
|
||||
|
||||
def is_equivalence_relation(S, R):
|
||||
return is_symmetric(R) and is_reflexive(S, R) and is_transitive(R)
|
||||
|
||||
|
||||
def is_partial_order(S, R):
|
||||
"""Check if the relation R on set S is a partial order."""
|
||||
return is_antisymmetric(R) and is_reflexive(S, R) and is_transitive(R)
|
||||
|
||||
|
||||
def check_func(func_to_check, domain, codomain):
|
||||
"""
|
||||
Check if a function is "well-defined" over a given domain and codomain constraint.
|
||||
|
||||
Parameters:
|
||||
func_to_check: callable
|
||||
The function to check. It should take one argument.
|
||||
domain: list
|
||||
A list of values to test the function with.
|
||||
codomain: callable
|
||||
A callable that takes the output of the function and returns True if it satisfies the codomain constraint.
|
||||
|
||||
Returns:
|
||||
bool
|
||||
True if the function is well-defined over the domain and codomain, otherwise False.
|
||||
"""
|
||||
well_defined = True
|
||||
|
||||
for x in domain:
|
||||
try:
|
||||
# Evaluate the function
|
||||
output = func_to_check(x)
|
||||
|
||||
# Check the codomain constraint
|
||||
if not codomain(output):
|
||||
print(f"Input {x}: Output {output} is INVALID.")
|
||||
well_defined = False
|
||||
except Exception as e:
|
||||
# Catch errors in evaluation
|
||||
print(f"Input {x}: Error occurred - {str(e)}.")
|
||||
well_defined = False
|
||||
|
||||
if well_defined:
|
||||
print("The function is well-defined over the given domain.")
|
||||
else:
|
||||
print("The function is NOT well-defined over the given domain.")
|
||||
|
||||
return well_defined
|
||||
|
||||
|
||||
|
||||
def plot_function(functions: list, plot_range: list):
|
||||
"""Takes a function and plots the graph using the plot_range.
|
||||
The plot_rage should be a list containing two elements: the minimum value to plot, up to the max value.
|
||||
function should be a list of functions to be drawn. The functions in the list should take one parameter and return a value.
|
||||
"""
|
||||
x_values = range(plot_range[0],plot_range[1])
|
||||
for func in functions:
|
||||
y_points = []
|
||||
x_points = []
|
||||
for i in range(plot_range[0], plot_range[1]):
|
||||
y_points.append(func(i))
|
||||
x_points.append(i)
|
||||
plt.plot(x_points, y_points, label=func.__name__)
|
||||
plt.xlabel('x')
|
||||
plt.ylabel('y')
|
||||
plt.title('Function Plots')
|
||||
plt.legend()
|
||||
plt.grid(True)
|
||||
plt.show()
|
||||
|
||||
print(lcm(82,21))
|
||||
print(lcm(42,123))
|
||||
Reference in New Issue
Block a user