Files

524 lines
14 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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))