congruence_solver 0.3.1 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,54 +1,54 @@
1
- #!/usr/bin/env ruby
2
- require 'congruence_solver'
3
- require "polynomial_interpreter"
4
-
5
-
6
- SOLVE_CONGRUENCE_BENCH_FILE = "../bench/solve_congruence_bm.rb"
7
-
8
-
9
- if ARGV.pop == "bench"
10
- require_relative SOLVE_CONGRUENCE_BENCH_FILE
11
- exit(0)
12
- end
13
-
14
- CONGRUENCE_FORMAT = "(lhs polynomial) = (rhs polynomial) mod (modulus)"
15
- CONGRUENCE_INVALID_MSG = "Congruence invalid: congruences must be of form:\n#{CONGRUENCE_FORMAT}"
16
- POLYNOMIAL_FORMAT = "ax^b+cx^d...\n(integer coefficients, positive integer exponents, order irrelevant)"
17
- LHS_INVALID_MSG = "Left hand polynomial invalid: polynomials must be of form: #{POLYNOMIAL_FORMAT}"
18
- RHS_INVALID_MSG = "Right hand polynomial invalid: polynomials must be of form: #{POLYNOMIAL_FORMAT}"
19
- MOD_INVALID_MSG = "Mod invalid: modulus must be an integer greater than 2"
20
-
21
- puts "Congruence to solve:"
22
-
23
- begin
24
- coeffs, mod = PolynomialInterpreter.read_congruence(STDIN.gets)
25
- rescue ArgumentError => e
26
- if(e == PolynomialInterpreter::Errors::CONGRUENCE_INVALID)
27
- STDERR.puts CONGRUENCE_INVALID_MSG
28
- exit(1)
29
-
30
- elsif(e == PolynomialInterpreter::Errors::LHS_POLYNOMIAL_INVALID)
31
- STDERR.puts LHS_INVALID_MSG
32
- exit(1)
33
-
34
- elsif(e == PolynomialInterpreter::Errors::RHS_POLYNOMIAL_INVALID)
35
- STDERR.puts RHS_INVALID_MSG
36
- exit(1)
37
-
38
- elsif(e == PolynomialInterpreter::Errors::MOD_INVALID)
39
- STDERR.puts MOD_INVALID_MSG
40
- exit(1)
41
-
42
- else
43
- raise e
44
- end
45
- end
46
-
47
- solutions = CongruenceSolver.lift(coeffs, mod).sort
48
-
49
- if solutions.empty?
50
- puts "No solution."
51
- else
52
- puts "Solutions:"
53
- solutions.each_with_index {|sol, i| puts "(#{i}) #{sol}"}
1
+ #!/usr/bin/env ruby
2
+ require 'congruence_solver'
3
+ require "polynomial_interpreter"
4
+
5
+
6
+ SOLVE_CONGRUENCE_BENCH_FILE = "../bench/solve_congruence_bm.rb"
7
+
8
+
9
+ if ARGV.pop == "bench"
10
+ require_relative SOLVE_CONGRUENCE_BENCH_FILE
11
+ exit(0)
12
+ end
13
+
14
+ CONGRUENCE_FORMAT = "(lhs polynomial) = (rhs polynomial) mod (modulus)"
15
+ CONGRUENCE_INVALID_MSG = "Congruence invalid: congruences must be of form:\n#{CONGRUENCE_FORMAT}"
16
+ POLYNOMIAL_FORMAT = "ax^b+cx^d...\n(integer coefficients, positive integer exponents, order irrelevant)"
17
+ LHS_INVALID_MSG = "Left hand polynomial invalid: polynomials must be of form: #{POLYNOMIAL_FORMAT}"
18
+ RHS_INVALID_MSG = "Right hand polynomial invalid: polynomials must be of form: #{POLYNOMIAL_FORMAT}"
19
+ MOD_INVALID_MSG = "Mod invalid: modulus must be an integer greater than 2"
20
+
21
+ puts "Congruence to solve:"
22
+
23
+ begin
24
+ coeffs, mod = PolynomialInterpreter.read_congruence(STDIN.gets)
25
+ rescue ArgumentError => e
26
+ if(e == PolynomialInterpreter::Errors::CONGRUENCE_INVALID)
27
+ STDERR.puts CONGRUENCE_INVALID_MSG
28
+ exit(1)
29
+
30
+ elsif(e == PolynomialInterpreter::Errors::LHS_POLYNOMIAL_INVALID)
31
+ STDERR.puts LHS_INVALID_MSG
32
+ exit(1)
33
+
34
+ elsif(e == PolynomialInterpreter::Errors::RHS_POLYNOMIAL_INVALID)
35
+ STDERR.puts RHS_INVALID_MSG
36
+ exit(1)
37
+
38
+ elsif(e == PolynomialInterpreter::Errors::MOD_INVALID)
39
+ STDERR.puts MOD_INVALID_MSG
40
+ exit(1)
41
+
42
+ else
43
+ raise e
44
+ end
45
+ end
46
+
47
+ solutions = CongruenceSolver.lift(coeffs, mod).sort
48
+
49
+ if solutions.empty?
50
+ puts "No solution."
51
+ else
52
+ puts "Solutions:"
53
+ solutions.each_with_index {|sol, i| puts "(#{i}) #{sol}"}
54
54
  end
data/bin/setup CHANGED
File without changes
@@ -1,38 +1,32 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
3
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
- require 'congruence_solver/version'
5
-
6
- Gem::Specification.new do |spec|
7
- spec.name = "congruence_solver"
8
- spec.version = CongruenceSolver::VERSION
9
- spec.authors = ["lane"]
10
- spec.email = ["lane.barlow@gmail.com"]
11
-
12
- spec.summary = "A gem for solving polynomial congruences."
13
- spec.description = "Provides a class (CongruenceSolver) for finding the modular zeros of a
14
- polynomial (given the coefficients and modulus) and a binary (csolve) to
15
- to solve your congruences at the command line."
16
- spec.homepage = "https://github.com/laneb/congruence_solver"
17
-
18
- spec.files = `git ls-files`.split("\n")
19
- spec.files += `git submodule --quiet foreach pwd`.split("\n").map do |abs_dir|
20
- abs_dir = abs_dir.gsub(/^c:/, "C:")
21
- dir_in_proj = abs_dir.gsub(/^#{Dir.pwd}\/?/, "")
22
- Dir.chdir(abs_dir) do
23
- files = `git ls-files`.split("\n")
24
- files.map {|fname| "#{dir_in_proj}/#{fname}"}
25
- end
26
- end.flatten
27
- spec.bindir = "bin"
28
- spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
29
- spec.require_paths = ["lib"]
30
-
31
- spec.extensions << "ext/congruence_solver/extconf.rb"
32
-
33
- spec.add_development_dependency "bundler", "~> 1.10"
34
- spec.add_development_dependency "rake", "~> 10.0"
35
- spec.add_development_dependency "rspec", "~> 2.4"
36
- spec.add_development_dependency "rake-compiler", "~>0.9"
37
- spec.add_development_dependency "os", "~>0.9"
38
- end
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'congruence_solver/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "congruence_solver"
8
+ spec.version = CongruenceSolver::VERSION
9
+ spec.license = "Apache-2.0"
10
+ spec.authors = ["lane"]
11
+ spec.email = ["lane.barlow@gmail.com"]
12
+
13
+ spec.summary = "A gem for solving polynomial congruences."
14
+ spec.description = "Provides a class (CongruenceSolver) for finding the modular zeros of a
15
+ polynomial (given the coefficients and modulus) and a binary (csolve) to
16
+ to solve your congruences at the command line."
17
+ spec.homepage = "https://github.com/laneb/congruence_solver"
18
+
19
+ spec.files = `git ls-files`.split("\n")
20
+ spec.files += `(ls ext/congruence_solver)`.split("\n").map { |fname| "ext/congruence_solver/" + fname}
21
+ spec.bindir = "bin"
22
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
23
+ spec.require_paths = ["lib"]
24
+
25
+ spec.extensions << "ext/congruence_solver/extconf.rb"
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.10"
28
+ spec.add_development_dependency "rake", "~> 10.0"
29
+ spec.add_development_dependency "rspec", "~> 3.0"
30
+ spec.add_development_dependency "rake-compiler", "~>0.9"
31
+ spec.add_development_dependency "os", "~>0.9"
32
+ end
@@ -1,18 +1,18 @@
1
-
2
- congruences_test: congruences.c test/congruences_test.c test/congruences_test.h arith_utils.c prime_gen.c
3
- gcc -g prime_gen.c arith_utils.c congruences.c test/congruences_test.c -o congruences_test
4
-
5
- arith_utils_test: arith_utils.c test/arith_utils_test.c test/arith_utils_test.h prime_gen.c
6
- gcc -g prime_gen.c arith_utils.c test/arith_utils_test.c -o arith_utils_test
7
-
8
- prime_gen_test: prime_gen.c test/prime_gen_test.c test/prime_gen_test.h
9
- gcc -g prime_gen.c test/prime_gen_test.c -o prime_gen_test
10
-
11
- test: prime_gen_test arith_utils_test congruences_test
12
- ./prime_gen_test
13
- ./arith_utils_test
14
- ./congruences_test
15
-
16
- clean:
17
- rm -f prime_gen_test.exe arith_utils_test.exe congruences_test.exe
1
+
2
+ congruences_test: congruences.c test/congruences_test.c test/congruences_test.h arith_utils.c prime_gen.c
3
+ gcc -g prime_gen.c arith_utils.c congruences.c test/congruences_test.c -o congruences_test
4
+
5
+ arith_utils_test: arith_utils.c test/arith_utils_test.c test/arith_utils_test.h prime_gen.c
6
+ gcc -g prime_gen.c arith_utils.c test/arith_utils_test.c -o arith_utils_test
7
+
8
+ prime_gen_test: prime_gen.c test/prime_gen_test.c test/prime_gen_test.h
9
+ gcc -g prime_gen.c test/prime_gen_test.c -o prime_gen_test
10
+
11
+ test: prime_gen_test arith_utils_test congruences_test
12
+ ./prime_gen_test
13
+ ./arith_utils_test
14
+ ./congruences_test
15
+
16
+ clean:
17
+ rm -f prime_gen_test.exe arith_utils_test.exe congruences_test.exe
18
18
 
@@ -1,136 +1,136 @@
1
- #include <stdio.h>
2
- #include <stdlib.h>
3
- #include "prime_gen.h"
4
- #include "arith_utils.h"
5
-
6
- //Expects 0 <= x,y < mod
7
- int mod_sum(int x, int y, int mod){
8
- if(y >= mod - x){
9
- return y - (mod - x);
10
- }
11
-
12
- else{
13
- return y + x;
14
- }
15
- }
16
-
17
-
18
- int mod_inv(int n, int mod){
19
- int y, a;
20
-
21
- if(n!=0){
22
-
23
- while(n<0){
24
- n+=mod;
25
- }
26
-
27
- for(y = 1; y < mod; y++){
28
- a = mod_product(y, n, mod);
29
-
30
- if(a == 1){
31
- return y;
32
- }
33
- }
34
- }
35
-
36
- return 0;
37
- }
38
-
39
-
40
- int coprime(int n1, int n2){
41
- //naive algorithm but efficient when n1 has already been factorized
42
- int * n1Factors = prime_factors(n1);
43
- int numOfFactors = *n1Factors;
44
- int * factors = n1Factors+1;
45
- int shareFactor = 0;
46
- int i;
47
-
48
- for(i=0; i<numOfFactors; i++){
49
- if(n2 % factors[i] == 0){
50
- shareFactor = 1;
51
- break;
52
- }
53
- }
54
-
55
- free(n1Factors);
56
-
57
- return !shareFactor;
58
- }
59
-
60
-
61
- int mod_product(int num1, int num2, int mod){
62
- int prod = 0;
63
- int i;
64
-
65
- for(i = 0; i < num1; i++){
66
- prod = mod_sum(prod, num2, mod);
67
- }
68
-
69
- return prod;
70
- }
71
-
72
- //expects 0 <= n < mod
73
- int mod_power(int n, int power, int mod){
74
- int product = n;
75
- int i;
76
-
77
- for(i = 1; i < power; i++){
78
- product = mod_product(product, n, mod);
79
- }
80
-
81
- return product;
82
- }
83
-
84
-
85
- int totient(int n){
86
- int * divisorList = prime_factors(n);
87
- int listLength = divisorList[0];
88
- int * divisors = divisorList+1;
89
- int i;
90
-
91
- for(i = 0; i < listLength; i++){
92
- n *= (divisors[i] - 1);
93
- n /= divisors[i];
94
- }
95
-
96
- free(divisorList);
97
-
98
- return n;
99
- }
100
-
101
-
102
-
103
-
104
- int mod_eval_polynomial(int degree, int coeffs[], int mod, int x){
105
- int tot = coeffs[degree];
106
- int i;
107
-
108
- for(i = degree - 1; i >= 0; i--){
109
- tot = mod_product(tot, x, mod);
110
- tot = mod_sum(tot, coeffs[i], mod);
111
- }
112
-
113
- return tot;
114
- }
115
-
116
-
117
- long eval_polynomial(int degree, int coeffs[], int x){
118
- long int sum = coeffs[0];
119
- long int powx;
120
- int i;
121
-
122
- for(i = 1, powx = x; i <= degree; i++, powx*=x){
123
- sum += powx*coeffs[i];
124
- }
125
-
126
- return sum;
127
- }
128
-
129
-
130
-
131
-
132
- /*
133
- int * linear_diophantine_solution(int order, int coeffs[], int scal){
134
-
135
- *=}
1
+ #include <stdio.h>
2
+ #include <stdlib.h>
3
+ #include "prime_gen.h"
4
+ #include "arith_utils.h"
5
+
6
+ //Expects 0 <= x,y < mod
7
+ int mod_sum(int x, int y, int mod){
8
+ if(y >= mod - x){
9
+ return y - (mod - x);
10
+ }
11
+
12
+ else{
13
+ return y + x;
14
+ }
15
+ }
16
+
17
+
18
+ int mod_inv(int n, int mod){
19
+ int y, a;
20
+
21
+ if(n!=0){
22
+
23
+ while(n<0){
24
+ n+=mod;
25
+ }
26
+
27
+ for(y = 1; y < mod; y++){
28
+ a = mod_product(y, n, mod);
29
+
30
+ if(a == 1){
31
+ return y;
32
+ }
33
+ }
34
+ }
35
+
36
+ return 0;
37
+ }
38
+
39
+
40
+ int coprime(int n1, int n2){
41
+ //naive algorithm but efficient when n1 has already been factorized
42
+ int * n1Factors = prime_factors(n1);
43
+ int numOfFactors = *n1Factors;
44
+ int * factors = n1Factors+1;
45
+ int shareFactor = 0;
46
+ int i;
47
+
48
+ for(i=0; i<numOfFactors; i++){
49
+ if(n2 % factors[i] == 0){
50
+ shareFactor = 1;
51
+ break;
52
+ }
53
+ }
54
+
55
+ free(n1Factors);
56
+
57
+ return !shareFactor;
58
+ }
59
+
60
+
61
+ int mod_product(int num1, int num2, int mod){
62
+ int prod = 0;
63
+ int i;
64
+
65
+ for(i = 0; i < num1; i++){
66
+ prod = mod_sum(prod, num2, mod);
67
+ }
68
+
69
+ return prod;
70
+ }
71
+
72
+ //expects 0 <= n < mod
73
+ int mod_power(int n, int power, int mod){
74
+ int product = n;
75
+ int i;
76
+
77
+ for(i = 1; i < power; i++){
78
+ product = mod_product(product, n, mod);
79
+ }
80
+
81
+ return product;
82
+ }
83
+
84
+
85
+ int totient(int n){
86
+ int * divisorList = prime_factors(n);
87
+ int listLength = divisorList[0];
88
+ int * divisors = divisorList+1;
89
+ int i;
90
+
91
+ for(i = 0; i < listLength; i++){
92
+ n *= (divisors[i] - 1);
93
+ n /= divisors[i];
94
+ }
95
+
96
+ free(divisorList);
97
+
98
+ return n;
99
+ }
100
+
101
+
102
+
103
+
104
+ int mod_eval_polynomial(int degree, int coeffs[], int mod, int x){
105
+ int tot = coeffs[degree];
106
+ int i;
107
+
108
+ for(i = degree - 1; i >= 0; i--){
109
+ tot = mod_product(tot, x, mod);
110
+ tot = mod_sum(tot, coeffs[i], mod);
111
+ }
112
+
113
+ return tot;
114
+ }
115
+
116
+
117
+ long eval_polynomial(int degree, int coeffs[], int x){
118
+ long int sum = coeffs[0];
119
+ long int powx;
120
+ int i;
121
+
122
+ for(i = 1, powx = x; i <= degree; i++, powx*=x){
123
+ sum += powx*coeffs[i];
124
+ }
125
+
126
+ return sum;
127
+ }
128
+
129
+
130
+
131
+
132
+ /*
133
+ int * linear_diophantine_solution(int order, int coeffs[], int scal){
134
+
135
+ *=}
136
136
  */
@@ -1,10 +1,10 @@
1
- #ifndef H_ARITH_UTILS
2
- #define H_ARITH_UTILS
3
- int mod_inv(int n, int mod);
4
- int mod_product(int n1, int n2, int mod);
5
- int mod_power(int n, int power, int mod);
6
- int mod_eval_polynomial(int degree, int coeffs[], int mod, int x);
7
- long eval_polynomial(int degree, int coeffs[], int x);
8
- int coprime(int n1, int n2);
9
- int totient(int n);
1
+ #ifndef H_ARITH_UTILS
2
+ #define H_ARITH_UTILS
3
+ int mod_inv(int n, int mod);
4
+ int mod_product(int n1, int n2, int mod);
5
+ int mod_power(int n, int power, int mod);
6
+ int mod_eval_polynomial(int degree, int coeffs[], int mod, int x);
7
+ long eval_polynomial(int degree, int coeffs[], int x);
8
+ int coprime(int n1, int n2);
9
+ int totient(int n);
10
10
  #endif