Data update

This commit is contained in:
Ingy döt Net 2025-08-11 18:05:26 -07:00
parent 4d5544505c
commit 4924dd0264
3073 changed files with 55820 additions and 4408 deletions

View file

@ -1,10 +1,10 @@
'''[[wp:Modular arithmetic|Modular arithmetic]]''' is a form of arithmetic (a calculation technique involving the concepts of addition and multiplication) which is done on numbers with a defined [[wp:equivalence relation|equivalence relation]] called ''congruence''.
For any positive integer <math>p</math> called the ''congruence modulus'',
two numbers <math>a</math> and <math>b</math> are said to be ''congruent modulo p'' whenever there exists an integer <math>k</math> such that:
:<math>a = b + k\,p</math>
For any positive integer <math>m</math> called the ''congruence modulus'',
two numbers <math>a</math> and <math>b</math> are said to be ''congruent modulo m'' whenever there exists an integer <math>k</math> such that:
:<math>a = b + k\,m</math>
The corresponding set of [[wp:equivalence class|equivalence class]]es forms a [[wp:ring (mathematics)|ring]] denoted <math>\frac{\Z}{p\Z}</math>. When p is a prime number, this ring becomes a [[wp:field (mathematics)|field]] denoted <math>\mathbb{F}_p</math>, but you won't have to implement the [[wp:multiplicative inverse|multiplicative inverse]] for this task.
The corresponding set of [[wp:equivalence class|equivalence class]]es forms a [[wp:ring (mathematics)|ring]] denoted <math>\Z/m\Z</math>. When <math>q=p^k \,(k>0)</math> is a prime power, the ring <math>\Z/q\Z</math> becomes a [[wp:Finite field|finite field]], usually denoted <math>\mathbb{F}_q</math> or <math>\mathrm{GF}(q)</math>, but you won't have to implement the [[wp:multiplicative inverse|multiplicative inverse]] for this task.
Addition and multiplication on this ring have the same algebraic structure as in usual arithmetic, so that a function such as a polynomial expression could receive a ring element as argument and give a consistent result.
@ -22,3 +22,4 @@ In other words, the function is an algebraic expression that could be used with
;Related tasks:
[[Modular exponentiation]]
<br><br>

View file

@ -0,0 +1,25 @@
(defpackage :rosetta-code/modular-arithmetic
(:use :cl))
(in-package :rosetta-code/modular-arithmetic)
(defparameter *modulus* nil)
(defun make-modular (op)
(lambda (&rest args)
(let ((result (apply op args)))
(if *modulus*
(mod result *modulus*)
result))))
(let ((ops '(+ expt))) ; add more operators as you need
(shadow ops)
(dolist (op ops)
(setf (symbol-function (find-symbol (symbol-name op)))
(make-modular (symbol-function (find-symbol (symbol-name op) :cl))))))
(defun f (x)
(+ (expt x 100) x 1))
(format t "No modulus: f(~a) = ~a~%" 10 (f 10))
(format t "Modulus 13: f(~a) = ~a~%" 10 (let ((*modulus* 13)) (f 10)))

View file

@ -0,0 +1,177 @@
use std::fmt;
use std::ops::{Add, Mul};
// Generic function f that works with any type T that implements the required traits
fn f<T>(x: T) -> T
where
T: Copy + Add<Output = T> + From<i32>,
ModularInteger: From<T>,
T: From<ModularInteger>,
{
// Convert to ModularInteger to use the pow function, then convert back
let mod_int = ModularInteger::from(x);
let powered = mod_int.pow(100);
T::from(powered + ModularInteger::from(x) + ModularInteger::from(T::from(1)))
}
// For the specific case of ModularInteger, we implement f directly
impl ModularInteger {
fn f_specific(self) -> Self {
self.pow(100) + self + ModularInteger::new(1, self.modulus)
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct ModularInteger {
value: i32,
modulus: i32,
}
impl ModularInteger {
fn new(v: i32, m: i32) -> Self {
ModularInteger {
value: v.rem_euclid(m), // Use rem_euclid for proper modular arithmetic
modulus: m,
}
}
fn get_value(&self) -> i32 {
self.value
}
fn get_modulus(&self) -> i32 {
self.modulus
}
fn validate_op(&self, rhs: &ModularInteger) -> Result<(), String> {
if self.modulus != rhs.modulus {
Err("Left-hand modulus does not match right-hand modulus.".to_string())
} else {
Ok(())
}
}
fn pow(&self, mut exp: i32) -> Self {
if exp < 0 {
panic!("Power must not be negative.");
}
let mut base = ModularInteger::new(1, self.modulus);
let mut current = *self;
// Use fast exponentiation algorithm
while exp > 0 {
if exp % 2 == 1 {
base = base * current;
}
current = current * current;
exp /= 2;
}
base
}
}
// Implement Add trait for ModularInteger + ModularInteger
impl Add<ModularInteger> for ModularInteger {
type Output = ModularInteger;
fn add(self, rhs: ModularInteger) -> ModularInteger {
self.validate_op(&rhs).expect("Modulus mismatch");
ModularInteger::new(self.value + rhs.value, self.modulus)
}
}
// Implement Add trait for ModularInteger + i32
impl Add<i32> for ModularInteger {
type Output = ModularInteger;
fn add(self, rhs: i32) -> ModularInteger {
ModularInteger::new(self.value + rhs, self.modulus)
}
}
// Implement Mul trait for ModularInteger * ModularInteger
impl Mul<ModularInteger> for ModularInteger {
type Output = ModularInteger;
fn mul(self, rhs: ModularInteger) -> ModularInteger {
self.validate_op(&rhs).expect("Modulus mismatch");
ModularInteger::new(self.value * rhs.value, self.modulus)
}
}
// Implement Display trait for pretty printing
impl fmt::Display for ModularInteger {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "ModularInteger({}, {})", self.value, self.modulus)
}
}
// Conversion traits for the generic function
impl From<i32> for ModularInteger {
fn from(value: i32) -> Self {
ModularInteger::new(value, 13) // Default modulus for demonstration
}
}
impl From<ModularInteger> for i32 {
fn from(mod_int: ModularInteger) -> Self {
mod_int.value
}
}
fn main() {
let input = ModularInteger::new(10, 13);
let output = input.f_specific(); // Using the specific implementation for ModularInteger
println!("f({}) = {}", input, output);
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_modular_integer_creation() {
let mi = ModularInteger::new(15, 13);
assert_eq!(mi.get_value(), 2);
assert_eq!(mi.get_modulus(), 13);
}
#[test]
fn test_addition() {
let mi1 = ModularInteger::new(10, 13);
let mi2 = ModularInteger::new(5, 13);
let result = mi1 + mi2;
assert_eq!(result.get_value(), 2); // (10 + 5) % 13 = 2
}
#[test]
fn test_multiplication() {
let mi1 = ModularInteger::new(10, 13);
let mi2 = ModularInteger::new(5, 13);
let result = mi1 * mi2;
assert_eq!(result.get_value(), 11); // (10 * 5) % 13 = 11
}
#[test]
fn test_power() {
let mi = ModularInteger::new(2, 13);
let result = mi.pow(3);
assert_eq!(result.get_value(), 8); // 2^3 = 8
}
#[test]
#[should_panic(expected = "Modulus mismatch")]
fn test_mismatched_modulus() {
let mi1 = ModularInteger::new(10, 13);
let mi2 = ModularInteger::new(5, 17);
let _ = mi1 + mi2;
}
#[test]
#[should_panic(expected = "Power must not be negative")]
fn test_negative_power() {
let mi = ModularInteger::new(2, 13);
mi.pow(-1);
}
}

View file

@ -0,0 +1,94 @@
const std = @import("std");
const print = std.debug.print;
// Generic function f that works with any type T
fn f(comptime T: type, x: T) T {
const pow_result = pow(T, x, 100);
const temp = pow_result.add(x) catch unreachable; // Same modulus, won't error
return temp.addInt(1);
}
// ModularInteger struct
const ModularInteger = struct {
value: i32,
modulus: i32,
const Self = @This();
// Constructor
pub fn init(v: i32, m: i32) Self {
return Self{
.value = @mod(v, m),
.modulus = m,
};
}
// Getter methods
pub fn getValue(self: Self) i32 {
return self.value;
}
pub fn getModulus(self: Self) i32 {
return self.modulus;
}
// Validation helper
fn validateOp(self: Self, rhs: Self) !void {
if (self.modulus != rhs.modulus) {
return error.ModulusMismatch;
}
}
// Addition with another ModularInteger
pub fn add(self: Self, rhs: Self) !Self {
try self.validateOp(rhs);
return Self.init(self.value + rhs.value, self.modulus);
}
// Addition with integer
pub fn addInt(self: Self, rhs: i32) Self {
return Self.init(self.value + rhs, self.modulus);
}
// Multiplication with another ModularInteger
pub fn mul(self: Self, rhs: Self) !Self {
try self.validateOp(rhs);
return Self.init(self.value * rhs.value, self.modulus);
}
// Format for printing
pub fn format(
self: Self,
comptime fmt: []const u8,
options: std.fmt.FormatOptions,
writer: anytype,
) !void {
_ = fmt;
_ = options;
try writer.print("ModularInteger({}, {})", .{ self.value, self.modulus });
}
};
// Power function for ModularInteger
fn pow(comptime T: type, base: T, power: i32) T {
if (power < 0) {
@panic("Power must not be negative.");
}
var result = T.init(1, base.getModulus());
var p = power;
while (p > 0) : (p -= 1) {
result = result.mul(base) catch unreachable; // Same modulus, won't error
}
return result;
}
// Operator overloading using + syntax (though Zig doesn't have true operator overloading)
// We use methods instead, but you could create wrapper functions if desired
pub fn main() !void {
const input = ModularInteger.init(10, 13);
const output = f(ModularInteger, input);
print("f({}) = {}\n", .{ input, output });
}