congruence_solver 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -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