diff --git a/MANIFEST b/MANIFEST index 68c6153d..44024533 100644 --- a/MANIFEST +++ b/MANIFEST @@ -195,7 +195,9 @@ scripts/extend_your_language.sf 'scripts/Extended tests/chebyshev_factorization_method.sf' 'scripts/Extended tests/digits2num.pl' 'scripts/Extended tests/fermat_pseudoprimes.sf' +'scripts/Extended tests/fermat_pseudoprimes_to_base_n.sf' 'scripts/Extended tests/fermat_with_n_factors.sf' +'scripts/Extended tests/fermat_with_n_factors_to_base_n.sf' 'scripts/Extended tests/inverse_of_multiplicative_functions.sf' 'scripts/Extended tests/inverse_sigma.sf' 'scripts/Extended tests/is_almost_prime.sf' @@ -218,7 +220,9 @@ scripts/extend_your_language.sf 'scripts/Extended tests/range_sum.sf' 'scripts/Extended tests/sqrtmod.pl' 'scripts/Extended tests/squarefree_pseudoprimes.sf' +'scripts/Extended tests/strong_fermat_pseudoprimes_to_base_n.sf' 'scripts/Extended tests/strong_fermat_with_n_factors.sf' +'scripts/Extended tests/strong_fermat_with_n_factors_to_base_n.sf' 'scripts/Extended tests/sumdigits.pl' scripts/fast_fourier_transform.sf scripts/faulhaber_s_formula.sf diff --git a/bin/sidef b/bin/sidef index dc2be55a..9f9adda8 100755 --- a/bin/sidef +++ b/bin/sidef @@ -897,7 +897,7 @@ Outputs: The interactive mode (a.k.a. REPL) is available by simply executing the C command, or by specifying the C<-i> command-line switch: $ sidef -i - Sidef 22.12, running on Linux, using Perl v5.36.0. + Sidef 23.03, running on Linux, using Perl v5.36.0. Type "help", "copyright" or "license" for more information. > n = 41 #1 = 41 diff --git a/lib/Sidef.pm b/lib/Sidef.pm index 1fb69440..d6514ffa 100644 --- a/lib/Sidef.pm +++ b/lib/Sidef.pm @@ -3,7 +3,7 @@ package Sidef { use utf8; use 5.016; - our $VERSION = '22.12'; + our $VERSION = '23.03'; our $SPACES = 0; # the current number of indentation spaces our $SPACES_INCR = 4; # the number of indentation spaces diff --git a/scripts/Extended tests/fermat_pseudoprimes_to_base_n.sf b/scripts/Extended tests/fermat_pseudoprimes_to_base_n.sf new file mode 100644 index 00000000..6146bb83 --- /dev/null +++ b/scripts/Extended tests/fermat_pseudoprimes_to_base_n.sf @@ -0,0 +1,45 @@ +#!/usr/bin/ruby + +# Tests for the Number "fermat_psp" method. + +# Timings: +# 04 March 2023: 2.813s (with MPU) +# 04 March 2023: 3.690s (without MPU) + +func T(n,k) { # OEIS: A271873 + if (n < 2) { + return [] + } + + var x = 1 + var y = 2*x + + loop { + var v = k.fermat_psp(n,x,y) + v.len >= 1 && return v[0] + x = y+1 + y = 2*x + } +} + +assert_eq( + {|x| {|y| T(x,y) }.map(2..6) }.map(2..6), + [ + %n[341 561 11305 825265 45593065] + %n[ 91 286 41041 825265 130027051] + %n[ 15 435 11305 418285 30534805] + %n[124 561 41041 2203201 68800501] + %n[ 35 1105 25585 682465 12306385] + ] +) + +assert_eq( + {|k| + {|n| + T(n, k - n + 2) + }.map(2..k) + }.map(2..14).flat, + %n[341, 561, 91, 11305, 286, 15, 825265, 41041, 435, 124, 45593065, 825265, 11305, 561, 35, 370851481, 130027051, 418285, 41041, 1105, 6, 38504389105, 2531091745, 30534805, 2203201, 25585, 561, 21, 7550611589521, 38504389105, 370851481, 68800501, 682465, 62745, 105, 28, 277960972890601, 5342216661145, 38504389105, 979865601, 12306385, 902785, 1365, 286, 33, 32918038719446881, 929845918823185, 7550611589521, 232250619601, 305246305, 87570145, 121485, 2926, 561, 10, 1730865304568301265, 36116918534792305, 277960972890601, 9746347772161, 16648653385, 9073150801, 2103465, 421876, 41041, 70, 65, 606395069520916762801, 6748244949134115505, 32918038719446881, 1237707914764321, 1387198666945, 211215631705, 96537441, 5533066, 1242241, 1330, 385, 6, 59989606772480422038001, 144331068898382107105, 1730865304568301265, 21083752607078161, 75749848475665, 24465723528961, 3958035081, 85851766, 68800501, 668865, 5005, 105, 15] +) + +say ":: Test passed!" diff --git a/scripts/Extended tests/fermat_with_n_factors_to_base_n.sf b/scripts/Extended tests/fermat_with_n_factors_to_base_n.sf new file mode 100644 index 00000000..73d0cefa --- /dev/null +++ b/scripts/Extended tests/fermat_with_n_factors_to_base_n.sf @@ -0,0 +1,38 @@ +#!/usr/bin/ruby + +# Smallest base-n Fermat pseudoprime with n distinct prime factors. +# https://oeis.org/A271874 + +# Timings: +# 04 march 2023: 3.305s (with MPU) +# 04 march 2023: 3.637s (without MPU) + +func a(n) { + return nil if (n < 2) + + var x = 1 + var y = 2*x + + loop { + #say "Sieving range: #{[x,y]}" + var arr = n.fermat_psp(n,x,y) + + if (arr.len >= 1) { + return arr[0] + } + + x = y+1 + y = 2*x + } +} + +var arr = gather { + for n in (2..16) { + say "a(#{n}) = #{take(a(n))}" + } +} + +assert_eq( + arr, + %n[341, 286, 11305, 2203201, 12306385, 9073150801, 3958035081, 2539184851126, 152064312120721, 10963650080564545, 378958695265110961, 1035551157050957605345, 57044715596229144811105, 6149883077429715389052001, 426634466310819456228926101] +) diff --git a/scripts/Extended tests/pseudoprimes.sf b/scripts/Extended tests/pseudoprimes.sf index d0598203..622a91b3 100644 --- a/scripts/Extended tests/pseudoprimes.sf +++ b/scripts/Extended tests/pseudoprimes.sf @@ -2,6 +2,10 @@ # Extended tests for some pseudoprime-related functions. +# Timings: +# 5 Mar 2023: 5.869s (with MPU) +# 5 Mar 2023: 8.218s (without MPU) + assert_eq( 13.lucas_carmichael(2*409810997884396741919), %n[409810997884396741919, 527999053751911334879, 752983545644288511839, 760276539527430038399, 761686421126390272799, 777695624868402683135] diff --git a/scripts/Extended tests/strong_fermat_pseudoprimes_to_base_n.sf b/scripts/Extended tests/strong_fermat_pseudoprimes_to_base_n.sf new file mode 100644 index 00000000..8888d47b --- /dev/null +++ b/scripts/Extended tests/strong_fermat_pseudoprimes_to_base_n.sf @@ -0,0 +1,45 @@ +#!/usr/bin/ruby + +# Tests for the Number "strong_fermat_psp" method. + +# Timings: +# 05 March 2023: 1.617s (with MPU) +# 05 March 2023: 2.512s (without MPU) + +func T(n,k) { # OEIS: A271873 + if (n < 2) { + return [] + } + + var x = 1 + var y = 2*x + + loop { + var v = k.strong_fermat_psp(n,x,y) + v.len >= 1 && return v[0] + x = y+1 + y = 2*x + } +} + +assert_eq( + {|x| {|y| T(x,y) }.map(2..6) }.map(2..6), + [ + %n[2047, 15841, 800605, 293609485, 10761055201] + %n[ 703, 8911, 152551, 41341321, 12283706701] + %n[ 341, 4371, 129921, 9224391, 2592053871] + %n[ 781, 24211, 4382191, 381347461, 9075517561] + %n[ 217, 29341, 3405961, 557795161, 333515107081] + ] +) + +assert_eq( + {|k| + {|n| + T(n, k - n + 2) + }.map(2..k) + }.map(2..10).flat, + %n[2047, 15841, 703, 800605, 8911, 341, 293609485, 152551, 4371, 781, 10761055201, 41341321, 129921, 24211, 217, 5478598723585, 12283706701, 9224391, 4382191, 29341, 325, 713808066913201, 1064404682551, 2592053871, 381347461, 3405961, 58825, 65, 90614118359482705, 19142275066201, 201068525791, 9075517561, 557795161, 1611805, 15841, 91, 5993318051893040401, 31475449738947061, 15804698567581, 2459465259031, 333515107081, 299048101, 205465, 1729, 91] +) + +say ":: Test passed!" diff --git a/scripts/Extended tests/strong_fermat_with_n_factors_to_base_n.sf b/scripts/Extended tests/strong_fermat_with_n_factors_to_base_n.sf new file mode 100644 index 00000000..b13682e9 --- /dev/null +++ b/scripts/Extended tests/strong_fermat_with_n_factors_to_base_n.sf @@ -0,0 +1,37 @@ +#!/usr/bin/ruby + +# Smallest base-n strong Fermat pseudoprime with n distinct prime factors. + +# Timings: +# 04 march 2023: 1.308s (with MPU) +# 04 march 2023: 1.929s (without MPU) + +func a(n) { + return nil if (n < 2) + + var x = 1 + var y = 2*x + + loop { + #say "Sieving range: #{[x,y]}" + var arr = n.strong_fermat_psp(n,x,y) + + if (arr.len >= 1) { + return arr[0] + } + + x = y+1 + y = 2*x + } +} + +var arr = gather { + for n in (2..9) { + say "a(#{n}) = #{take(a(n))}" + } +} + +assert_eq( + arr, + %n[2047, 8911, 129921, 381347461, 333515107081, 37388680793101, 713808066913201, 665242007427361] +)