Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
3
Task/Prime-conspiracy/00-META.yaml
Normal file
3
Task/Prime-conspiracy/00-META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Prime_conspiracy
|
||||
note: Prime Numbers
|
||||
58
Task/Prime-conspiracy/00-TASK.txt
Normal file
58
Task/Prime-conspiracy/00-TASK.txt
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
A recent discovery, quoted from [https://www.quantamagazine.org/20160313-mathematicians-discover-prime-conspiracy/ Quantamagazine] (March 13, 2016):
|
||||
'' Two mathematicians have uncovered a simple, previously unnoticed property of ''
|
||||
'' prime numbers — those numbers that are divisible only by 1 and themselves. ''
|
||||
'' Prime numbers, it seems, have decided preferences about the final digits of ''
|
||||
'' the primes that immediately follow them.
|
||||
and
|
||||
'' This conspiracy among prime numbers seems, at first glance, to violate a ''
|
||||
'' longstanding assumption in number theory: that prime numbers behave much ''
|
||||
'' like random numbers.
|
||||
|
||||
'' ─── (original authors from Stanford University): ''
|
||||
'' ─── Kannan Soundararajan and Robert Lemke Oliver ''
|
||||
|
||||
|
||||
The task is to check this assertion, modulo 10.
|
||||
|
||||
Lets call <big><code> i -> j </code></big> a transition if <big><code> i </code></big> is the last decimal digit of a prime, and <big><code> j </code></big> the last decimal digit of the following prime.
|
||||
|
||||
|
||||
;Task:
|
||||
Considering the first one million primes. Count, for any pair of successive primes, the number of transitions <big><code> i -> j </code></big> and print them along with their relative frequency, sorted by <big><code> i </code>.</big>
|
||||
|
||||
You can see that, for a given <big><code> i </code>,</big> frequencies are not evenly distributed.
|
||||
|
||||
|
||||
;Observation:
|
||||
(Modulo 10), primes whose last digit is '''9''' "prefer" the digit '''1''' to the digit '''9''', as its following prime.
|
||||
|
||||
|
||||
;Extra credit:
|
||||
Do the same for one hundred million primes.
|
||||
|
||||
|
||||
;Example for 10,000 primes:
|
||||
<pre>
|
||||
10000 first primes. Transitions prime % 10 → next-prime % 10.
|
||||
1 → 1 count: 365 frequency: 3.65 %
|
||||
1 → 3 count: 833 frequency: 8.33 %
|
||||
1 → 7 count: 889 frequency: 8.89 %
|
||||
1 → 9 count: 397 frequency: 3.97 %
|
||||
2 → 3 count: 1 frequency: 0.01 %
|
||||
3 → 1 count: 529 frequency: 5.29 %
|
||||
3 → 3 count: 324 frequency: 3.24 %
|
||||
3 → 5 count: 1 frequency: 0.01 %
|
||||
3 → 7 count: 754 frequency: 7.54 %
|
||||
3 → 9 count: 907 frequency: 9.07 %
|
||||
5 → 7 count: 1 frequency: 0.01 %
|
||||
7 → 1 count: 655 frequency: 6.55 %
|
||||
7 → 3 count: 722 frequency: 7.22 %
|
||||
7 → 7 count: 323 frequency: 3.23 %
|
||||
7 → 9 count: 808 frequency: 8.08 %
|
||||
9 → 1 count: 935 frequency: 9.35 %
|
||||
9 → 3 count: 635 frequency: 6.35 %
|
||||
9 → 7 count: 541 frequency: 5.41 %
|
||||
9 → 9 count: 379 frequency: 3.79 %
|
||||
</pre>
|
||||
<br><br>
|
||||
|
||||
27
Task/Prime-conspiracy/11l/prime-conspiracy.11l
Normal file
27
Task/Prime-conspiracy/11l/prime-conspiracy.11l
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
V limit = 1000000
|
||||
V k = limit
|
||||
V n = k * 17
|
||||
V primes = [1B] * n
|
||||
primes[0] = primes[1] = 0B
|
||||
|
||||
L(i) 2..Int(sqrt(n))
|
||||
I !primes[i]
|
||||
L.continue
|
||||
L(j) (i * i .< n).step(i)
|
||||
primes[j] = 0B
|
||||
|
||||
DefaultDict[(Int, Int), Int] trans_map
|
||||
V prev = -1
|
||||
|
||||
L(i) 0 .< n
|
||||
I primes[i]
|
||||
I prev != -1
|
||||
trans_map[(prev, i % 10)]++
|
||||
prev = i % 10
|
||||
|
||||
I --k == 0
|
||||
L.break
|
||||
|
||||
print(‘First #. primes. Transitions prime % 10 > next-prime % 10.’.format(limit))
|
||||
L(trans) sorted(trans_map.keys())
|
||||
print(‘#. -> #. count #5 frequency: #.4%’.format(trans[0], trans[1], trans_map[trans], 100.0 * trans_map[trans] / limit))
|
||||
79
Task/Prime-conspiracy/ALGOL-68/prime-conspiracy.alg
Normal file
79
Task/Prime-conspiracy/ALGOL-68/prime-conspiracy.alg
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
# extend SET, CLEAR and ELEM to operate on rows of BITS #
|
||||
OP SET = ( INT n, REF[]BITS b )REF[]BITS:
|
||||
BEGIN
|
||||
INT w = n OVER bits width;
|
||||
b[ w ] := ( ( 1 + ( n MOD bits width ) ) SET b[ w ] );
|
||||
b
|
||||
END # SET # ;
|
||||
OP CLEAR = ( INT n, REF[]BITS b )REF[]BITS:
|
||||
BEGIN
|
||||
INT w = n OVER bits width;
|
||||
b[ w ] := ( ( 1 + ( n MOD bits width ) ) CLEAR b[ w ] );
|
||||
b
|
||||
END # SET # ;
|
||||
OP ELEM = ( INT n, REF[]BITS b )BOOL: ( 1 + ( n MOD bits width ) ) ELEM b[ n OVER bits width ];
|
||||
|
||||
# constructs a bit array long enough to hold n values #
|
||||
OP BITARRAY = ( INT n )REF[]BITS: HEAP[ 0 : n OVER bits width ]BITS;
|
||||
|
||||
# construct a BITS value of all TRUE #
|
||||
BITS all true = BEGIN
|
||||
BITS v := 16r0;
|
||||
FOR bit TO bits width DO v := bit SET v OD;
|
||||
v
|
||||
END;
|
||||
|
||||
# initialises a bit array to all TRUE #
|
||||
OP SETALL = ( REF[]BITS b )REF[]BITS:
|
||||
BEGIN
|
||||
FOR p FROM LWB b TO UPB b DO b[ p ] := all true OD;
|
||||
b
|
||||
END # SETALL # ;
|
||||
|
||||
# construct a sieve initialised to all TRUE apart from the first bit #
|
||||
INT sieve max = 15 500 000; # somewhat larger than the 1 000 000th prime #
|
||||
INT prime max = 1 000 000;
|
||||
REF[]BITS sieve = 1 CLEAR SETALL BITARRAY sieve max;
|
||||
|
||||
# sieve the primes #
|
||||
FOR s FROM 2 TO ENTIER sqrt( sieve max ) DO
|
||||
IF s ELEM sieve
|
||||
THEN
|
||||
FOR p FROM s * s BY s TO sieve max DO p CLEAR sieve OD
|
||||
FI
|
||||
OD;
|
||||
|
||||
# count the number of times each combination of #
|
||||
# ( last digit of previous prime, last digit of prime ) occurs #
|
||||
[ 0 : 9, 0 : 9 ]INT counts;
|
||||
FOR p FROM 0 TO 9 DO FOR n FROM 0 TO 9 DO counts[ p, n ] := 0 OD OD;
|
||||
INT previous prime := 2;
|
||||
INT primes found := 1;
|
||||
FOR p FROM 3 TO sieve max WHILE primes found < prime max DO
|
||||
IF p ELEM sieve
|
||||
THEN
|
||||
primes found +:= 1;
|
||||
counts[ previous prime MOD 10, p MOD 10 ] +:= 1;
|
||||
previous prime := p
|
||||
FI
|
||||
OD;
|
||||
|
||||
# print the counts #
|
||||
# there are thus 4 possible final digits: 1, 3, 7, 9 #
|
||||
STRING labels = "123456789"; # "labels" for the counts #
|
||||
INT total := 0;
|
||||
FOR p TO 9 DO FOR n TO 9 DO total +:= counts[ p, n ] OD OD;
|
||||
print( ( whole( primes found, 0 ), " primes, last prime considered: ", previous prime, newline ) );
|
||||
FOR p TO 9 DO
|
||||
FOR n TO 9 DO
|
||||
IF counts[ p, n ] /= 0
|
||||
THEN
|
||||
print( ( labels[ p ], "->", labels[ n ]
|
||||
, whole( counts[ p, n ], -8 )
|
||||
, fixed( ( 100 * counts[ p, n ] ) / total, -8, 2 )
|
||||
, newline
|
||||
)
|
||||
)
|
||||
FI
|
||||
OD
|
||||
OD
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
on isPrime(n)
|
||||
if ((n < 4) or (n is 5)) then return (n > 1)
|
||||
if ((n mod 2 = 0) or (n mod 3 = 0) or (n mod 5 = 0)) then return false
|
||||
repeat with i from 7 to (n ^ 0.5) div 1 by 30
|
||||
if ((n mod i = 0) or (n mod (i + 4) = 0) or (n mod (i + 6) = 0) or ¬
|
||||
(n mod (i + 10) = 0) or (n mod (i + 12) = 0) or (n mod (i + 16) = 0) or ¬
|
||||
(n mod (i + 22) = 0) or (n mod (i + 24) = 0)) then return false
|
||||
end repeat
|
||||
|
||||
return true
|
||||
end isPrime
|
||||
|
||||
on conspiracy(limit)
|
||||
script o
|
||||
property counters : {{0, 0, 0, 0, 0, 0, 0, 0, 0}}
|
||||
end script
|
||||
repeat 8 times
|
||||
copy beginning of o's counters to end of o's counters
|
||||
end repeat
|
||||
|
||||
if (limit > 1) then
|
||||
set primeCount to 1
|
||||
set i to 2 -- First prime.
|
||||
set n to 3 -- First number to test for primality.
|
||||
repeat until (primeCount = limit)
|
||||
if (isPrime(n)) then
|
||||
set primeCount to primeCount + 1
|
||||
set j to n mod 10
|
||||
set item j of item i of o's counters to (item j of item i of o's counters) + 1
|
||||
set i to j
|
||||
end if
|
||||
set n to n + 2
|
||||
end repeat
|
||||
end if
|
||||
|
||||
set output to {"First " & limit & " primes: transitions between end digits of consecutive primes."}
|
||||
set totalTransitions to limit - 1
|
||||
repeat with i in {1, 2, 3, 5, 7, 9}
|
||||
set iTransitions to 0
|
||||
repeat with j from 1 to 9 by 2
|
||||
set iTransitions to iTransitions + (item j of item i of o's counters)
|
||||
end repeat
|
||||
repeat with j from 1 to 9 by 2
|
||||
set ijCount to item j of item i of o's counters
|
||||
if (ijCount > 0) then ¬
|
||||
set end of output to ¬
|
||||
(i as text) & " → " & j & ¬
|
||||
(" count: " & ijCount) & ¬
|
||||
(" preference for " & j & ": " & (ijCount * 10000 / iTransitions as integer) / 100) & ¬
|
||||
("% overall occurrence: " & (ijCount * 10000 / totalTransitions as integer) / 100 & "%")
|
||||
end repeat
|
||||
end repeat
|
||||
set astid to AppleScript's text item delimiters
|
||||
set AppleScript's text item delimiters to linefeed
|
||||
set output to output as text
|
||||
set AppleScript's text item delimiters to astid
|
||||
return output
|
||||
end conspiracy
|
||||
|
||||
conspiracy(1000000)
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
"First 1000000 primes: transitions between end digits of consecutive primes.
|
||||
1 → 1 count: 42853 preference for 1: 17.15% overall occurrence: 4.29%
|
||||
1 → 3 count: 77475 preference for 3: 31.0% overall occurrence: 7.75%
|
||||
1 → 7 count: 79453 preference for 7: 31.79% overall occurrence: 7.95%
|
||||
1 → 9 count: 50153 preference for 9: 20.07% overall occurrence: 5.02%
|
||||
2 → 3 count: 1 preference for 3: 100.0% overall occurrence: 0.0%
|
||||
3 → 1 count: 58255 preference for 1: 23.29% overall occurrence: 5.83%
|
||||
3 → 3 count: 39668 preference for 3: 15.86% overall occurrence: 3.97%
|
||||
3 → 5 count: 1 preference for 5: 0.0% overall occurrence: 0.0%
|
||||
3 → 7 count: 72827 preference for 7: 29.12% overall occurrence: 7.28%
|
||||
3 → 9 count: 79358 preference for 9: 31.73% overall occurrence: 7.94%
|
||||
5 → 7 count: 1 preference for 7: 100.0% overall occurrence: 0.0%
|
||||
7 → 1 count: 64230 preference for 1: 25.69% overall occurrence: 6.42%
|
||||
7 → 3 count: 68595 preference for 3: 27.44% overall occurrence: 6.86%
|
||||
7 → 7 count: 39603 preference for 7: 15.84% overall occurrence: 3.96%
|
||||
7 → 9 count: 77586 preference for 9: 31.03% overall occurrence: 7.76%
|
||||
9 → 1 count: 84596 preference for 1: 33.85% overall occurrence: 8.46%
|
||||
9 → 3 count: 64371 preference for 3: 25.75% overall occurrence: 6.44%
|
||||
9 → 7 count: 58130 preference for 7: 23.26% overall occurrence: 5.81%
|
||||
9 → 9 count: 42843 preference for 9: 17.14% overall occurrence: 4.28%"
|
||||
55
Task/Prime-conspiracy/C++/prime-conspiracy-1.cpp
Normal file
55
Task/Prime-conspiracy/C++/prime-conspiracy-1.cpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
#include <vector>
|
||||
#include <iostream>
|
||||
#include <cmath>
|
||||
#include <utility>
|
||||
#include <map>
|
||||
#include <iomanip>
|
||||
|
||||
bool isPrime( int i ) {
|
||||
int stop = std::sqrt( static_cast<double>( i ) ) ;
|
||||
for ( int d = 2 ; d <= stop ; d++ )
|
||||
if ( i % d == 0 )
|
||||
return false ;
|
||||
return true ;
|
||||
}
|
||||
|
||||
class Compare {
|
||||
public :
|
||||
Compare( ) {
|
||||
}
|
||||
|
||||
bool operator( ) ( const std::pair<int , int> & a , const std::pair<int, int> & b ) {
|
||||
if ( a.first != b.first )
|
||||
return a.first < b.first ;
|
||||
else
|
||||
return a.second < b.second ;
|
||||
}
|
||||
};
|
||||
|
||||
int main( ) {
|
||||
std::vector<int> primes {2} ;
|
||||
int current = 3 ;
|
||||
while ( primes.size( ) < 1000000 ) {
|
||||
if ( isPrime( current ) )
|
||||
primes.push_back( current ) ;
|
||||
current += 2 ;
|
||||
}
|
||||
Compare myComp ;
|
||||
std::map<std::pair<int, int>, int , Compare> conspiracy (myComp) ;
|
||||
for ( int i = 0 ; i < primes.size( ) -1 ; i++ ) {
|
||||
int a = primes[i] % 10 ;
|
||||
int b = primes[ i + 1 ] % 10 ;
|
||||
std::pair<int , int> numbers { a , b} ;
|
||||
conspiracy[numbers]++ ;
|
||||
}
|
||||
std::cout << "1000000 first primes. Transitions prime % 10 → next-prime % 10.\n" ;
|
||||
for ( auto it = conspiracy.begin( ) ; it != conspiracy.end( ) ; it++ ) {
|
||||
std::cout << (it->first).first << " -> " << (it->first).second << " count:" ;
|
||||
int frequency = it->second ;
|
||||
std::cout << std::right << std::setw( 15 ) << frequency << " frequency: " ;
|
||||
std::cout.setf(std::ios::fixed, std::ios::floatfield ) ;
|
||||
std::cout.precision( 2 ) ;
|
||||
std::cout << (static_cast<double>(frequency) / 1000000.0) * 100 << " %\n" ;
|
||||
}
|
||||
return 0 ;
|
||||
}
|
||||
31
Task/Prime-conspiracy/C++/prime-conspiracy-2.cpp
Normal file
31
Task/Prime-conspiracy/C++/prime-conspiracy-2.cpp
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
#include <cstdint>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <map>
|
||||
#include <primesieve.hpp>
|
||||
|
||||
void compute_transitions(uint64_t limit) {
|
||||
primesieve::iterator it;
|
||||
std::map<std::pair<uint64_t, uint64_t>, uint64_t> transitions;
|
||||
for (uint64_t count = 0, prev = 0; count < limit; ++count) {
|
||||
uint64_t prime = it.next_prime();
|
||||
uint64_t digit = prime % 10;
|
||||
if (prev != 0)
|
||||
++transitions[std::make_pair(prev, digit)];
|
||||
prev = digit;
|
||||
}
|
||||
std::cout << "First " << limit << " prime numbers:\n";
|
||||
for (auto&& pair : transitions) {
|
||||
double freq = (100.0 * pair.second)/limit;
|
||||
std::cout << pair.first.first << " -> " << pair.first.second
|
||||
<< ": count = " << std::setw(7) << pair.second
|
||||
<< ", frequency = " << std::setprecision(2)
|
||||
<< std::fixed << freq << " %\n";
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
compute_transitions(1000000);
|
||||
compute_transitions(100000000);
|
||||
return 0;
|
||||
}
|
||||
47
Task/Prime-conspiracy/C-sharp/prime-conspiracy.cs
Normal file
47
Task/Prime-conspiracy/C-sharp/prime-conspiracy.cs
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
using System;
|
||||
|
||||
namespace PrimeConspiracy {
|
||||
class Program {
|
||||
static void Main(string[] args) {
|
||||
const int limit = 1_000_000;
|
||||
const int sieveLimit = 15_500_000;
|
||||
|
||||
int[,] buckets = new int[10, 10];
|
||||
int prevDigit = 2;
|
||||
bool[] notPrime = Sieve(sieveLimit);
|
||||
|
||||
for (int n = 3, primeCount = 1; primeCount < limit; n++) {
|
||||
if (notPrime[n]) continue;
|
||||
|
||||
int digit = n % 10;
|
||||
buckets[prevDigit, digit]++;
|
||||
prevDigit = digit;
|
||||
primeCount++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int j = 0; j < 10; j++) {
|
||||
if (buckets[i, j] != 0) {
|
||||
Console.WriteLine("{0} -> {1} count: {2,5:d} frequency : {3,6:0.00%}", i, j, buckets[i, j], 1.0 * buckets[i, j] / limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static bool[] Sieve(int limit) {
|
||||
bool[] composite = new bool[limit];
|
||||
composite[0] = composite[1] = true;
|
||||
|
||||
int max = (int)Math.Sqrt(limit);
|
||||
for (int n = 2; n <= max; n++) {
|
||||
if (!composite[n]) {
|
||||
for (int k = n * n; k < limit; k += n) {
|
||||
composite[k] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return composite;
|
||||
}
|
||||
}
|
||||
}
|
||||
121
Task/Prime-conspiracy/C/prime-conspiracy.c
Normal file
121
Task/Prime-conspiracy/C/prime-conspiracy.c
Normal file
|
|
@ -0,0 +1,121 @@
|
|||
#include <assert.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef unsigned char byte;
|
||||
|
||||
struct Transition {
|
||||
byte a, b;
|
||||
unsigned int c;
|
||||
} transitions[100];
|
||||
|
||||
void init() {
|
||||
int i, j;
|
||||
for (i = 0; i < 10; i++) {
|
||||
for (j = 0; j < 10; j++) {
|
||||
int idx = i * 10 + j;
|
||||
transitions[idx].a = i;
|
||||
transitions[idx].b = j;
|
||||
transitions[idx].c = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void record(int prev, int curr) {
|
||||
byte pd = prev % 10;
|
||||
byte cd = curr % 10;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
int z = 0;
|
||||
if (transitions[i].a == pd) {
|
||||
int t = 0;
|
||||
if (transitions[i].b == cd) {
|
||||
transitions[i].c++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void printTransitions(int limit, int last_prime) {
|
||||
int i;
|
||||
|
||||
printf("%d primes, last prime considered: %d\n", limit, last_prime);
|
||||
|
||||
for (i = 0; i < 100; i++) {
|
||||
if (transitions[i].c > 0) {
|
||||
printf("%d->%d count: %5d frequency: %.2f\n", transitions[i].a, transitions[i].b, transitions[i].c, 100.0 * transitions[i].c / limit);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isPrime(int n) {
|
||||
int s, t, a1, a2;
|
||||
|
||||
if (n % 2 == 0) return n == 2;
|
||||
if (n % 3 == 0) return n == 3;
|
||||
if (n % 5 == 0) return n == 5;
|
||||
if (n % 7 == 0) return n == 7;
|
||||
if (n % 11 == 0) return n == 11;
|
||||
if (n % 13 == 0) return n == 13;
|
||||
if (n % 17 == 0) return n == 17;
|
||||
if (n % 19 == 0) return n == 19;
|
||||
|
||||
// assuming that addition is faster then multiplication
|
||||
t = 23;
|
||||
a1 = 96;
|
||||
a2 = 216;
|
||||
s = t * t;
|
||||
while (s <= n) {
|
||||
if (n % t == 0) return false;
|
||||
|
||||
// first increment
|
||||
s += a1;
|
||||
t += 2;
|
||||
a1 += 24;
|
||||
assert(t * t == s);
|
||||
|
||||
if (s <= n) {
|
||||
if (n % t == 0) return false;
|
||||
|
||||
// second increment
|
||||
s += a2;
|
||||
t += 4;
|
||||
a2 += 48;
|
||||
assert(t * t == s);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define LIMIT 1000000
|
||||
int main() {
|
||||
int last_prime = 3, n = 5, count = 2;
|
||||
|
||||
init();
|
||||
record(2, 3);
|
||||
|
||||
while (count < LIMIT) {
|
||||
if (isPrime(n)) {
|
||||
record(last_prime, n);
|
||||
last_prime = n;
|
||||
count++;
|
||||
}
|
||||
n += 2;
|
||||
|
||||
if (count < LIMIT) {
|
||||
if (isPrime(n)) {
|
||||
record(last_prime, n);
|
||||
last_prime = n;
|
||||
count++;
|
||||
}
|
||||
n += 4;
|
||||
}
|
||||
}
|
||||
|
||||
printTransitions(LIMIT, last_prime);
|
||||
|
||||
return 0;
|
||||
}
|
||||
53
Task/Prime-conspiracy/D/prime-conspiracy.d
Normal file
53
Task/Prime-conspiracy/D/prime-conspiracy.d
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import std.algorithm;
|
||||
import std.range;
|
||||
import std.stdio;
|
||||
import std.typecons;
|
||||
|
||||
alias Transition = Tuple!(int, int);
|
||||
|
||||
bool isPrime(int n) {
|
||||
if (n < 2) return false;
|
||||
if (n % 2 == 0) return n == 2;
|
||||
if (n % 3 == 0) return n == 3;
|
||||
int d = 5;
|
||||
while (d*d <= n) {
|
||||
if (n%d == 0) return false;
|
||||
d += 2;
|
||||
if (n%d == 0) return false;
|
||||
d += 4;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
auto generatePrimes() {
|
||||
import std.concurrency;
|
||||
return new Generator!int({
|
||||
yield(2);
|
||||
int p = 3;
|
||||
while (p > 0) {
|
||||
if (isPrime(p)) {
|
||||
yield(p);
|
||||
}
|
||||
p += 2;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void main() {
|
||||
auto primes = generatePrimes().take(1_000_000).array;
|
||||
int[Transition] transMap;
|
||||
foreach (i; 0 .. primes.length - 1) {
|
||||
auto transition = Transition(primes[i] % 10, primes[i + 1] % 10);
|
||||
if (transition in transMap) {
|
||||
transMap[transition] += 1;
|
||||
} else {
|
||||
transMap[transition] = 1;
|
||||
}
|
||||
}
|
||||
auto sortedTransitions = transMap.keys.multiSort!(q{a[0] < b[0]}, q{a[1] < b[1]});
|
||||
writeln("First 1,000,000 primes. Transitions prime % 10 -> next-prime % 10.");
|
||||
foreach (trans; sortedTransitions) {
|
||||
writef("%s -> %s count: %5d", trans[0], trans[1], transMap[trans]);
|
||||
writefln(" frequency: %4.2f%%", transMap[trans] / 10_000.0);
|
||||
}
|
||||
}
|
||||
19
Task/Prime-conspiracy/EchoLisp/prime-conspiracy.l
Normal file
19
Task/Prime-conspiracy/EchoLisp/prime-conspiracy.l
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
(lib 'math) ;; (in-primes n) stream
|
||||
(decimals 4)
|
||||
|
||||
(define (print-trans trans m N)
|
||||
(printf "%d first primes. Transitions prime %% %d → next-prime %% %d." N m m)
|
||||
(define s (// (apply + (vector->list trans)) 100))
|
||||
(for ((i (* m m)) (t trans))
|
||||
#:continue (<= t 1) ;; get rid of 2,5 primes
|
||||
(printf " %d → %d count: %10d frequency: %d %% "
|
||||
(quotient i m) (% i m) t (// t s) )))
|
||||
|
||||
;; can apply to any modulo m
|
||||
;; (in-primes n) returns a stream of primes
|
||||
|
||||
(define (task (m 10) (N 1000_000))
|
||||
(define trans (make-vector (* m m)))
|
||||
(for ((p1 (in-primes 2)) (p2 (in-primes 3)) (k N))
|
||||
(vector+= trans (+ (* (% p1 m) m) (% p2 m)) 1))
|
||||
(print-trans trans m N))
|
||||
27
Task/Prime-conspiracy/Elixir/prime-conspiracy.elixir
Normal file
27
Task/Prime-conspiracy/Elixir/prime-conspiracy.elixir
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
defmodule Prime do
|
||||
def conspiracy(m) do
|
||||
IO.puts "#{m} first primes. Transitions prime % 10 → next-prime % 10."
|
||||
Enum.map(prime(m), &rem(&1, 10))
|
||||
|> Enum.chunk(2,1)
|
||||
|> Enum.reduce(Map.new, fn [a,b],acc -> Map.update(acc, {a,b}, 1, &(&1+1)) end)
|
||||
|> Enum.sort
|
||||
|> Enum.each(fn {{a,b},v} ->
|
||||
sv = to_string(v) |> String.rjust(10)
|
||||
sf = Float.to_string(100.0*v/m, [decimals: 4])
|
||||
IO.puts "#{a} → #{b} count:#{sv} frequency:#{sf} %"
|
||||
end)
|
||||
end
|
||||
|
||||
def prime(n) do
|
||||
max = n * :math.log(n * :math.log(n)) |> trunc # from Rosser's theorem
|
||||
Enum.to_list(2..max)
|
||||
|> prime(:math.sqrt(max), [])
|
||||
|> Enum.take(n)
|
||||
end
|
||||
defp prime([h|t], limit, result) when h>limit, do: Enum.reverse(result, [h|t])
|
||||
defp prime([h|t], limit, result) do
|
||||
prime((for x <- t, rem(x,h)>0, do: x), limit, [h|result])
|
||||
end
|
||||
end
|
||||
|
||||
Prime.conspiracy(1000000)
|
||||
3
Task/Prime-conspiracy/F-Sharp/prime-conspiracy.fs
Normal file
3
Task/Prime-conspiracy/F-Sharp/prime-conspiracy.fs
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
// Prime Conspiracy. Nigel Galloway: March 27th., 2018
|
||||
primes|>Seq.take 10000|>Seq.map(fun n->n%10)|>Seq.pairwise|>Seq.countBy id|>Seq.groupBy(fun((n,_),_)->n)|>Seq.sortBy(fst)
|
||||
|>Seq.iter(fun(_,n)->Seq.sortBy(fun((_,n),_)->n) n|>Seq.iter(fun((n,g),z)->printfn "%d -> %d ocurred %3d times" n g z))
|
||||
20
Task/Prime-conspiracy/Factor/prime-conspiracy.factor
Normal file
20
Task/Prime-conspiracy/Factor/prime-conspiracy.factor
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
USING: assocs formatting grouping kernel math math.primes math.statistics
|
||||
sequences sorting ;
|
||||
IN: rosetta-code.prime-conspiracy
|
||||
|
||||
: transitions ( n -- alist )
|
||||
nprimes [ 10 mod ] map 2 clump histogram >alist natural-sort ;
|
||||
|
||||
: t-values ( transition -- i j count freq )
|
||||
first2 [ first2 ] dip dup 10000. / ;
|
||||
|
||||
: print-trans ( transition -- )
|
||||
t-values "%d -> %d count: %5d frequency: %5.2f%%\n" printf ;
|
||||
|
||||
: header ( n -- )
|
||||
"First %d primes. Transitions prime %% 10 -> next-prime %% 10.\n" printf ;
|
||||
|
||||
: main ( -- )
|
||||
1,000,000 dup header transitions [ print-trans ] each ;
|
||||
|
||||
MAIN: main
|
||||
44
Task/Prime-conspiracy/Fortran/prime-conspiracy.f
Normal file
44
Task/Prime-conspiracy/Fortran/prime-conspiracy.f
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
PROGRAM INHERIT !Last digit persistence in successive prime numbers.
|
||||
USE PRIMEBAG !Inherit this also.
|
||||
INTEGER MBASE,P0,NHIC !Problem bounds.
|
||||
PARAMETER (MBASE = 13, P0 = 2, NHIC = 100000000) !This should do.
|
||||
INTEGER N(0:MBASE - 1,0:MBASE - 1,2:MBASE) !The counts. A triangular shape would be better.
|
||||
INTEGER I,B,D1,D2 !Assistants.
|
||||
INTEGER P,PP !Prime, and Previous Prime.
|
||||
|
||||
MSG = 6 !Standard output.
|
||||
WRITE (MSG,1) MBASE,P0,NHIC !Announce intent.
|
||||
1 FORMAT ("Working in base 2 to ",I0," count the transitions "
|
||||
1 "from the low-order digit of one prime number ",/,
|
||||
2 "to the low-order digit of its successor. Starting with ",I0,
|
||||
3 " and making ",I0," advances.")
|
||||
IF (.NOT.GRASPPRIMEBAG(66)) STOP "Gan't grab my file!" !Attempt in hope.
|
||||
|
||||
Chug through the primes.
|
||||
10 N = 0 !Clear all my counts!
|
||||
P = P0 !Start with the starting prime.
|
||||
DO I = 1,NHIC !Make the specified number of advances.
|
||||
PP = P !Thus, remember the previous prime.
|
||||
P = NEXTPRIME(P) !And obtain the current prime.
|
||||
DO B = 2,MBASE !For these, step through the relevant bases.
|
||||
D1 = MOD(PP,B) !Last digit of the previous prime.
|
||||
D2 = MOD(P,B) !In the base of the moment.
|
||||
N(D1,D2,B) = N(D1,D2,B) + 1 !Whee!
|
||||
END DO !On to the next base.
|
||||
END DO !And the next advance.
|
||||
WRITE (MSG,11) P !Might as well announce where we got to.
|
||||
11 FORMAT ("Ending with ",I0) !Hopefully, no overflow.
|
||||
|
||||
Cast forth the results.
|
||||
20 DO B = 2,MBASE !Present results for each base.
|
||||
WRITE (MSG,21) B !Announce it.
|
||||
21 FORMAT (/,"For base ",I0) !Set off with a blank line.
|
||||
WRITE (MSG,22) (D1, D1 = 0,B - 1) !The heading.
|
||||
22 FORMAT (" Last digit ending ",I2,66I9) !Alignment to match FORMAT 23.
|
||||
DO D2 = 0,B - 1 !For a given base, these are the possible ending digits of the successor.
|
||||
IF (ALL(N(0:B - 1,D2,B).EQ.0)) CYCLE !No progenitor advanced to this successor digit?
|
||||
WRITE (MSG,23) D2,N(0:B - 1,D2,B) !Otherwise, show the counts for the progenitor's digits.
|
||||
23 FORMAT (" next prime ends",I3,":",I2,66I9) !Ah, layout.
|
||||
END DO !On to the next successor digit.
|
||||
END DO !On to the next base.
|
||||
END !That was easy.
|
||||
57
Task/Prime-conspiracy/FreeBASIC/prime-conspiracy.basic
Normal file
57
Task/Prime-conspiracy/FreeBASIC/prime-conspiracy.basic
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
' version 13-04-2017
|
||||
' updated 09-08-2018 Using bit-sieve of odd numbers
|
||||
' compile with: fbc -s console
|
||||
' compile with: fbc -s console -Wc -O2 ->more than 2x faster(20.2-> 8,7s)
|
||||
|
||||
const max = 2040*1000*1000 ' enough for 100,000,000 primes
|
||||
const max2 = (max -1) \ 2
|
||||
Dim As uByte _bit(7)
|
||||
Dim shared As uByte sieve(max2 \ 8 + 1)
|
||||
Dim shared As ULong end_digit(1 To 9, 1 To 9)
|
||||
Dim As ULong i, j, x, i1, j1, x1, c, c1
|
||||
Dim As String frmt_str = " # " + Chr(26) + " # count:######## frequency:##.##%"
|
||||
|
||||
' bit Mask
|
||||
For i = 0 To 7
|
||||
_bit(i) = 1 shl i
|
||||
Next
|
||||
' sieving
|
||||
For i = 1 To (sqr(max) -1) / 2
|
||||
x = 2*i+1
|
||||
If (sieve(i Shr 3) And _bit(i And 7)) = 0 Then
|
||||
For j = (2*i+2)*i To max2 Step x
|
||||
sieve(j Shr 3) or= _bit(j And 7)
|
||||
Next
|
||||
End If
|
||||
Next
|
||||
|
||||
' count
|
||||
x = 2 : c = 1
|
||||
For i = 1 To max2
|
||||
If (sieve(i Shr 3) And _bit(i And 7)) = 0 Then
|
||||
j = (2*i+1) Mod 10
|
||||
end_digit(x, j) += 1
|
||||
x = j
|
||||
c += 1
|
||||
If c = 1000000 Or c = 100000000 Then
|
||||
Print "first "; c; " primes"
|
||||
c1 = c \ 100
|
||||
For i1 = 1 To 9
|
||||
For j1 = 1 To 9
|
||||
x1 = end_digit(i1, j1)
|
||||
If x1 <> 0 Then
|
||||
Print Using frmt_str; i1; j1; x1; (x1 / c1)
|
||||
End If
|
||||
Next
|
||||
Next
|
||||
Print
|
||||
If c = 100000000 Then Exit for
|
||||
End If
|
||||
End If
|
||||
Next
|
||||
|
||||
' empty keyboard buffer
|
||||
While Inkey <> "" : Wend
|
||||
Print : Print "hit any key to end program"
|
||||
Sleep
|
||||
End
|
||||
72
Task/Prime-conspiracy/Go/prime-conspiracy.go
Normal file
72
Task/Prime-conspiracy/Go/prime-conspiracy.go
Normal file
|
|
@ -0,0 +1,72 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
)
|
||||
|
||||
func sieve(limit uint64) []bool {
|
||||
limit++
|
||||
// True denotes composite, false denotes prime.
|
||||
// We don't bother filling in the even composites.
|
||||
c := make([]bool, limit)
|
||||
c[0] = true
|
||||
c[1] = true
|
||||
p := uint64(3) // Start from 3.
|
||||
for {
|
||||
p2 := p * p
|
||||
if p2 >= limit {
|
||||
break
|
||||
}
|
||||
for i := p2; i < limit; i += 2 * p {
|
||||
c[i] = true
|
||||
}
|
||||
for {
|
||||
p += 2
|
||||
if !c[p] {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
return c
|
||||
}
|
||||
|
||||
func main() {
|
||||
// sieve up to the 100 millionth prime
|
||||
sieved := sieve(2038074743)
|
||||
|
||||
transMap := make(map[int]int, 19)
|
||||
i := 2 // last digit of first prime
|
||||
p := int64(3 - 2) // next prime, -2 since we +=2 first
|
||||
n := 1
|
||||
for _, num := range [...]int{1e4, 1e6, 1e8} {
|
||||
for ; n < num; n++ {
|
||||
// Set p to next prime by skipping composites.
|
||||
p += 2
|
||||
for sieved[p] {
|
||||
p += 2
|
||||
}
|
||||
// Count transition of i -> j.
|
||||
j := int(p % 10)
|
||||
transMap[i*10+j]++
|
||||
i = j
|
||||
}
|
||||
reportTransitions(transMap, n)
|
||||
}
|
||||
}
|
||||
|
||||
func reportTransitions(transMap map[int]int, num int) {
|
||||
keys := make([]int, 0, len(transMap))
|
||||
for k := range transMap {
|
||||
keys = append(keys, k)
|
||||
}
|
||||
sort.Ints(keys)
|
||||
fmt.Println("First", num, "primes. Transitions prime % 10 -> next-prime % 10.")
|
||||
for _, key := range keys {
|
||||
count := transMap[key]
|
||||
freq := float64(count) / float64(num) * 100
|
||||
fmt.Printf("%d -> %d count: %7d", key/10, key%10, count)
|
||||
fmt.Printf(" frequency: %4.2f%%\n", freq)
|
||||
}
|
||||
fmt.Println()
|
||||
}
|
||||
13
Task/Prime-conspiracy/Haskell/prime-conspiracy.hs
Normal file
13
Task/Prime-conspiracy/Haskell/prime-conspiracy.hs
Normal file
|
|
@ -0,0 +1,13 @@
|
|||
import Data.List (group, sort)
|
||||
import Text.Printf (printf)
|
||||
import Data.Numbers.Primes (primes)
|
||||
|
||||
freq :: [(Int, Int)] -> Float
|
||||
freq xs = realToFrac (length xs) / 100
|
||||
|
||||
line :: [(Int, Int)] -> IO ()
|
||||
line t@((n1, n2):xs) = printf "%d -> %d count: %5d frequency: %2.2f %%\n" n1 n2 (length t) (freq t)
|
||||
|
||||
main :: IO ()
|
||||
main = mapM_ line $ groups primes
|
||||
where groups = tail . group . sort . (\n -> zip (0: n) n) . fmap (`mod` 10) . take 10000
|
||||
20
Task/Prime-conspiracy/J/prime-conspiracy-1.j
Normal file
20
Task/Prime-conspiracy/J/prime-conspiracy-1.j
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/:~ (~.,. ' ',. ":@(%/&1 999999)@(#/.~)) 2 (,'->',])&":/\ 10|p:i.1e6
|
||||
1->1 42853 0.042853
|
||||
1->3 77475 0.0774751
|
||||
1->7 79453 0.0794531
|
||||
1->9 50153 0.0501531
|
||||
2->3 1 1e_6
|
||||
3->1 58255 0.0582551
|
||||
3->3 39668 0.039668
|
||||
3->5 1 1e_6
|
||||
3->7 72827 0.0728271
|
||||
3->9 79358 0.0793581
|
||||
5->7 1 1e_6
|
||||
7->1 64230 0.0642301
|
||||
7->3 68595 0.0685951
|
||||
7->7 39603 0.039603
|
||||
7->9 77586 0.0775861
|
||||
9->1 84596 0.0845961
|
||||
9->3 64371 0.0643711
|
||||
9->7 58130 0.0581301
|
||||
9->9 42843 0.042843
|
||||
20
Task/Prime-conspiracy/J/prime-conspiracy-2.j
Normal file
20
Task/Prime-conspiracy/J/prime-conspiracy-2.j
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
/:~ (~.,. ' ',. '%',.~ ":@(%/&1 9999.99)@(#/.~)) 2 (,'->',])&":/\ 10|p:i.1e6
|
||||
1->1 42853 4.2853%
|
||||
1->3 77475 7.74751%
|
||||
1->7 79453 7.94531%
|
||||
1->9 50153 5.01531%
|
||||
2->3 1 0.0001%
|
||||
3->1 58255 5.82551%
|
||||
3->3 39668 3.9668%
|
||||
3->5 1 0.0001%
|
||||
3->7 72827 7.28271%
|
||||
3->9 79358 7.93581%
|
||||
5->7 1 0.0001%
|
||||
7->1 64230 6.42301%
|
||||
7->3 68595 6.85951%
|
||||
7->7 39603 3.9603%
|
||||
7->9 77586 7.75861%
|
||||
9->1 84596 8.45961%
|
||||
9->3 64371 6.43711%
|
||||
9->7 58130 5.81301%
|
||||
9->9 42843 4.2843%
|
||||
22
Task/Prime-conspiracy/J/prime-conspiracy-3.j
Normal file
22
Task/Prime-conspiracy/J/prime-conspiracy-3.j
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
dgpairs=: 2 (,'->',])&":/\ 10 | p:
|
||||
combine=: ~.@[ ,. ' ',. ":@(%/&1 99999999)@(+//.)
|
||||
/:~ combine&;/|: (~.;#/.~)@dgpairs@((+ i.)/)"1 (1e6*i.100),.1e6+99>i.100
|
||||
1->1 4.62304e6 0.0462304
|
||||
1->3 7.42944e6 0.0742944
|
||||
1->7 7.50461e6 0.0750461
|
||||
1->9 5.44234e6 0.0544234
|
||||
2->3 1 1e_8
|
||||
3->1 6.01098e6 0.0601098
|
||||
3->3 4.44256e6 0.0444256
|
||||
3->5 1 1e_8
|
||||
3->7 7.0437e6 0.070437
|
||||
3->9 7.5029e6 0.075029
|
||||
5->7 1 1e_8
|
||||
7->1 6.37398e6 0.0637398
|
||||
7->3 6.7552e6 0.067552
|
||||
7->7 4.43936e6 0.0443936
|
||||
7->9 7.43187e6 0.0743187
|
||||
9->1 7.99143e6 0.0799143
|
||||
9->3 6.37294e6 0.0637294
|
||||
9->7 6.01274e6 0.0601274
|
||||
9->9 4.62292e6 0.0462292
|
||||
45
Task/Prime-conspiracy/Java/prime-conspiracy.java
Normal file
45
Task/Prime-conspiracy/Java/prime-conspiracy.java
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
public class PrimeConspiracy {
|
||||
|
||||
public static void main(String[] args) {
|
||||
final int limit = 1000_000;
|
||||
final int sieveLimit = 15_500_000;
|
||||
|
||||
int[][] buckets = new int[10][10];
|
||||
int prevDigit = 2;
|
||||
boolean[] notPrime = sieve(sieveLimit);
|
||||
|
||||
for (int n = 3, primeCount = 1; primeCount < limit; n++) {
|
||||
if (notPrime[n])
|
||||
continue;
|
||||
|
||||
int digit = n % 10;
|
||||
buckets[prevDigit][digit]++;
|
||||
prevDigit = digit;
|
||||
primeCount++;
|
||||
}
|
||||
|
||||
for (int i = 0; i < 10; i++) {
|
||||
for (int j = 0; j < 10; j++) {
|
||||
if (buckets[i][j] != 0) {
|
||||
System.out.printf("%d -> %d : %2f%n", i,
|
||||
j, buckets[i][j] / (limit / 100.0));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean[] sieve(int limit) {
|
||||
boolean[] composite = new boolean[limit];
|
||||
composite[0] = composite[1] = true;
|
||||
|
||||
int max = (int) Math.sqrt(limit);
|
||||
for (int n = 2; n <= max; n++) {
|
||||
if (!composite[n]) {
|
||||
for (int k = n * n; k < limit; k += n) {
|
||||
composite[k] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return composite;
|
||||
}
|
||||
}
|
||||
59
Task/Prime-conspiracy/Jq/prime-conspiracy.jq
Normal file
59
Task/Prime-conspiracy/Jq/prime-conspiracy.jq
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
# Input should be an integer
|
||||
def isPrime:
|
||||
. as $n
|
||||
| if ($n < 2) then false
|
||||
elif ($n % 2 == 0) then $n == 2
|
||||
elif ($n % 3 == 0) then $n == 3
|
||||
else 5
|
||||
| until( . <= 0;
|
||||
if .*. > $n then -1
|
||||
elif ($n % . == 0) then 0
|
||||
else . + 2
|
||||
| if ($n % . == 0) then 0
|
||||
else . + 4
|
||||
end
|
||||
end)
|
||||
| . == -1
|
||||
end;
|
||||
|
||||
# The first $n primes
|
||||
def sieved($n):
|
||||
[limit($n; range(2;infinite) | select(isPrime)) ];
|
||||
|
||||
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
|
||||
|
||||
# right-pad with 0
|
||||
def rpad($len): tostring | ($len - length) as $l | ("0" * $l)[:$l] + .;
|
||||
|
||||
# Input: a string of digits with up to one "."
|
||||
# Output: the corresponding string representation with exactly $n decimal digits
|
||||
def align_decimal($n):
|
||||
tostring
|
||||
| (capture("(?<i>[0-9]*[.])(?<j>[0-9]{0," + ($n|tostring) + "})") as $ix
|
||||
| $ix.i + ($ix.j|rpad($n)) )
|
||||
// . + "." + ($n*"0") ;
|
||||
|
||||
# Report the noteworthy transitions recorded in the input object
|
||||
def reportTransitions:
|
||||
([.[]] | add) as $num
|
||||
| keys as $keys
|
||||
| "For the first \($num + 1) primes, the noteworthy transitions of the last digit from prime to next-prime are:",
|
||||
($keys[] as $key
|
||||
| .[$key] as $count
|
||||
| select($key | IN("2 => 3", "3 => 5", "5 => 7") | not)
|
||||
| ($count / $num * 100) as $freq
|
||||
| "\($key) count: \($count|lpad(6)) frequency: \($freq | align_decimal(4))%" ) ;
|
||||
|
||||
|
||||
def tasks:
|
||||
1E6 as $n
|
||||
| sieved($n) as $sieved
|
||||
| (1e4, 1e6) as $num
|
||||
| reduce range(1; $num) as $i ({};
|
||||
($sieved[$i] % 10) as $p
|
||||
| ($sieved[$i-1] % 10) as $q
|
||||
| "\($q) => \($p)" as $key
|
||||
| .[$key] += 1)
|
||||
| reportTransitions, "";
|
||||
|
||||
tasks
|
||||
22
Task/Prime-conspiracy/Julia/prime-conspiracy.julia
Normal file
22
Task/Prime-conspiracy/Julia/prime-conspiracy.julia
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
using Printf, Primes
|
||||
using DataStructures
|
||||
|
||||
function counttransitions(upto::Integer)
|
||||
cnt = counter(Pair{Int,Int})
|
||||
tot = 0
|
||||
prv, nxt = 2, 3
|
||||
while nxt ≤ upto
|
||||
push!(cnt, prv % 10 => nxt % 10)
|
||||
prv = nxt
|
||||
nxt = nextprime(nxt + 1)
|
||||
tot += 1
|
||||
end
|
||||
return sort(Dict(cnt)), tot - 1
|
||||
end
|
||||
|
||||
trans, tot = counttransitions(100_000_000)
|
||||
|
||||
println("First 100_000_000 primes, last digit transitions:")
|
||||
for ((i, j), fr) in trans
|
||||
@printf("%i → %i: freq. %3.4f%%\n", i, j, 100fr / tot)
|
||||
end
|
||||
48
Task/Prime-conspiracy/Kotlin/prime-conspiracy.kotlin
Normal file
48
Task/Prime-conspiracy/Kotlin/prime-conspiracy.kotlin
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// version 1.1.2
|
||||
// compiled with flag -Xcoroutines=enable to suppress 'experimental' warning
|
||||
|
||||
import kotlin.coroutines.experimental.*
|
||||
|
||||
typealias Transition = Pair<Int, Int>
|
||||
|
||||
fun isPrime(n: Int) : Boolean {
|
||||
if (n < 2) return false
|
||||
if (n % 2 == 0) return n == 2
|
||||
if (n % 3 == 0) return n == 3
|
||||
var d : Int = 5
|
||||
while (d * d <= n) {
|
||||
if (n % d == 0) return false
|
||||
d += 2
|
||||
if (n % d == 0) return false
|
||||
d += 4
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
fun generatePrimes() =
|
||||
buildSequence {
|
||||
yield(2)
|
||||
var p = 3
|
||||
while (p <= Int.MAX_VALUE) {
|
||||
if (isPrime(p)) yield(p)
|
||||
p += 2
|
||||
}
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val primes = generatePrimes().take(1_000_000).toList()
|
||||
val transMap = mutableMapOf<Transition, Int>()
|
||||
for (i in 0 until primes.size - 1) {
|
||||
val transition = primes[i] % 10 to primes[i + 1] % 10
|
||||
if (transMap.containsKey(transition))
|
||||
transMap[transition] = transMap[transition]!! + 1
|
||||
else
|
||||
transMap.put(transition, 1)
|
||||
}
|
||||
val sortedTransitions = transMap.keys.sortedBy { it.second }.sortedBy { it.first }
|
||||
println("First 1,000,000 primes. Transitions prime % 10 -> next-prime % 10.")
|
||||
for (trans in sortedTransitions) {
|
||||
print("${trans.first} -> ${trans.second} count: ${"%5d".format(transMap[trans])}")
|
||||
println(" frequency: ${"%4.2f".format(transMap[trans]!! / 10000.0)}%")
|
||||
}
|
||||
}
|
||||
51
Task/Prime-conspiracy/Lua/prime-conspiracy.lua
Normal file
51
Task/Prime-conspiracy/Lua/prime-conspiracy.lua
Normal file
|
|
@ -0,0 +1,51 @@
|
|||
-- Return boolean indicating whether or not n is prime
|
||||
function isPrime (n)
|
||||
if n <= 1 then return false end
|
||||
if n <= 3 then return true end
|
||||
if n % 2 == 0 or n % 3 == 0 then return false end
|
||||
local i = 5
|
||||
while i * i <= n do
|
||||
if n % i == 0 or n % (i + 2) == 0 then return false end
|
||||
i = i + 6
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
-- Return table of frequencies for final digits of consecutive primes
|
||||
function primeCon (limit)
|
||||
local count, x, last, ending = 2, 3, 3
|
||||
local freqList = {
|
||||
[1] = {},
|
||||
[2] = {[3] = 1},
|
||||
[3] = {},
|
||||
[5] = {},
|
||||
[7] = {},
|
||||
[9] = {}
|
||||
}
|
||||
repeat
|
||||
x = x + 2
|
||||
if isPrime(x) then
|
||||
ending = x % 10
|
||||
if freqList[last][ending] then
|
||||
freqList[last][ending] = freqList[last][ending] + 1
|
||||
else
|
||||
freqList[last][ending] = 1
|
||||
end
|
||||
last = ending
|
||||
count = count + 1
|
||||
end
|
||||
until count == limit
|
||||
return freqList
|
||||
end
|
||||
|
||||
-- Main procedure
|
||||
local limit = 10^6
|
||||
local t = primeCon(limit)
|
||||
for a = 1, 9 do
|
||||
for b = 1, 9 do
|
||||
if t[a] and t[a][b] then
|
||||
io.write(a .. " -> " .. b .. "\tcount: " .. t[a][b])
|
||||
print("\tfrequency: " .. t[a][b] / limit * 100 .. " %")
|
||||
end
|
||||
end
|
||||
end
|
||||
2
Task/Prime-conspiracy/Mathematica/prime-conspiracy.math
Normal file
2
Task/Prime-conspiracy/Mathematica/prime-conspiracy.math
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
StringForm["`` count: `` frequency: ``", Rule@@ #[[1]], StringPadLeft[ToString@ #[[2]], 8], PercentForm[N@ #[[2]]/(10^8 -1)]]& /@
|
||||
Sort[Tally[Partition[Mod[Prime[Range[10^8]], 10], 2, 1]]] // Column
|
||||
56
Task/Prime-conspiracy/Nim/prime-conspiracy.nim
Normal file
56
Task/Prime-conspiracy/Nim/prime-conspiracy.nim
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
# Prime conspiracy.
|
||||
|
||||
import std/[algorithm, math, sequtils, strformat, tables]
|
||||
|
||||
const N = 1_020_000_000 # Size of sieve of Eratosthenes.
|
||||
|
||||
proc newSieve(): seq[bool] =
|
||||
## Create a sieve with only odd values.
|
||||
## Index "i" in sieve represents value "n = 2 * i + 3".
|
||||
result.setLen(N)
|
||||
for item in result.mitems: item = true
|
||||
# Apply sieve.
|
||||
var i = 0
|
||||
const Limit = sqrt(2 * N.toFloat + 3).int
|
||||
while true:
|
||||
let n = 2 * i + 3
|
||||
if n > Limit:
|
||||
break
|
||||
if result[i]:
|
||||
# Found prime, so eliminate multiples.
|
||||
for k in countup((n * n - 3) div 2, N - 1, n):
|
||||
result[k] = false
|
||||
inc i
|
||||
|
||||
var isPrime = newSieve()
|
||||
|
||||
proc countTransitions(isPrime: seq[bool]; nprimes: int) =
|
||||
## Build the transition count table and print it.
|
||||
|
||||
var counts = [(2, 3)].toCountTable() # Count of transitions.
|
||||
var d1 = 3 # Last digit of first prime in transition.
|
||||
var count = 2 # Count of primes (starting with 2 and 3).
|
||||
for i in 1..isPrime.high:
|
||||
if isPrime[i]:
|
||||
inc count
|
||||
let d2 = (2 * i + 3) mod 10 # Last digit of second prime in transition.
|
||||
counts.inc((d1, d2))
|
||||
if count == nprimes: break
|
||||
d1 = d2
|
||||
|
||||
# Check if sieve was big enough.
|
||||
if count < nprimes:
|
||||
echo &"Found only {count} primes; expected {nprimes} primes. Increase value of N."
|
||||
quit(QuitFailure)
|
||||
|
||||
# Print result.
|
||||
echo &"{nprimes} first primes. Transitions prime (mod 10) → next-prime (mod 10)."
|
||||
for key in sorted(counts.keys.toSeq):
|
||||
let count = counts[key]
|
||||
let freq = count.toFloat * 100 / nprimes.toFloat
|
||||
echo &"{key[0]} → {key[1]} Count: {count:7d} Frequency: {freq:4.2f}%"
|
||||
echo ""
|
||||
|
||||
isPrime.countTransitions(10_000)
|
||||
isPrime.countTransitions(1_000_000)
|
||||
isPrime.countTransitions(100_000_000)
|
||||
17
Task/Prime-conspiracy/PARI-GP/prime-conspiracy-1.parigp
Normal file
17
Task/Prime-conspiracy/PARI-GP/prime-conspiracy-1.parigp
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
conspiracy(maxx)={
|
||||
print("primes considered= ",maxx);
|
||||
x=matrix(9,9);cnt=0;p=2;q=2%10;
|
||||
while(cnt<=maxx,
|
||||
cnt+=1;
|
||||
m=q;
|
||||
p=nextprime(p+1);
|
||||
q= p%10;
|
||||
x[m,q]+=1);
|
||||
print (2," to ",3, " count: ",x[2,3]," freq ", 100./cnt," %" );
|
||||
forstep(i=1,9,2,
|
||||
forstep(j=1,9,2,
|
||||
if( x[i,j]<1,continue);
|
||||
print (i," to ",j, " count: ",x[i,j]," freq ", 100.* x[i,j]/cnt," %" )));
|
||||
print ("total transitions= ",cnt);
|
||||
print(p);
|
||||
}
|
||||
30
Task/Prime-conspiracy/PARI-GP/prime-conspiracy-2.parigp
Normal file
30
Task/Prime-conspiracy/PARI-GP/prime-conspiracy-2.parigp
Normal file
|
|
@ -0,0 +1,30 @@
|
|||
primes considered= 1000000
|
||||
2 to 3 count: 1 freq 0.000100 %
|
||||
1 to 1 count: 42853 freq 4.29 %
|
||||
1 to 3 count: 77475 freq 7.75 %
|
||||
1 to 5 count: 0 freq 0 %
|
||||
1 to 7 count: 79453 freq 7.95 %
|
||||
1 to 9 count: 50153 freq 5.02 %
|
||||
3 to 1 count: 58255 freq 5.83 %
|
||||
3 to 3 count: 39668 freq 3.97 %
|
||||
3 to 5 count: 1 freq 0.000100 %
|
||||
3 to 7 count: 72828 freq 7.28 %
|
||||
3 to 9 count: 79358 freq 7.94 %
|
||||
5 to 1 count: 0 freq 0 %
|
||||
5 to 3 count: 0 freq 0 %
|
||||
5 to 5 count: 0 freq 0 %
|
||||
5 to 7 count: 1 freq 0.000100 %
|
||||
5 to 9 count: 0 freq 0 %
|
||||
7 to 1 count: 64230 freq 6.42 %
|
||||
7 to 3 count: 68595 freq 6.86 %
|
||||
7 to 5 count: 0 freq 0 %
|
||||
7 to 7 count: 39604 freq 3.96 %
|
||||
7 to 9 count: 77586 freq 7.76 %
|
||||
9 to 1 count: 84596 freq 8.46 %
|
||||
9 to 3 count: 64371 freq 6.44 %
|
||||
9 to 5 count: 0 freq 0 %
|
||||
9 to 7 count: 58130 freq 5.81 %
|
||||
9 to 9 count: 42843 freq 4.28 %
|
||||
total transitions= 1000001
|
||||
15485917
|
||||
time = 5,016 ms.
|
||||
127
Task/Prime-conspiracy/Pascal/prime-conspiracy.pas
Normal file
127
Task/Prime-conspiracy/Pascal/prime-conspiracy.pas
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
program primCons;
|
||||
{$IFNDEF FPC}
|
||||
{$APPTYPE CONSOLE}
|
||||
{$ENDIF}
|
||||
const
|
||||
PrimeLimit = 2038074748 DIV 2;
|
||||
type
|
||||
tLimit = 0..PrimeLimit;
|
||||
tCntTransition = array[0..9,0..9] of NativeInt;
|
||||
tCntTransRec = record
|
||||
CTR_CntTrans:tCntTransition;
|
||||
CTR_primCnt,
|
||||
CTR_Limit : NativeInt;
|
||||
end;
|
||||
tCntTransRecField = array[0..19] of tCntTransRec;
|
||||
var
|
||||
primes: array [tLimit] of boolean;
|
||||
CntTransitions : tCntTransRecField;
|
||||
|
||||
procedure SieveSmall;
|
||||
//sieve of eratosthenes with only odd numbers
|
||||
var
|
||||
i,j,p: NativeInt;
|
||||
Begin
|
||||
FillChar(primes[1],SizeOF(primes),chr(ord(true)));
|
||||
i := 1;
|
||||
p := 3;
|
||||
j := i*(i+1)*2;
|
||||
repeat
|
||||
IF (primes[i]) then
|
||||
begin
|
||||
p := i+i+1;
|
||||
repeat
|
||||
primes[j] := false;
|
||||
inc(j,p);
|
||||
until j > PrimeLimit;
|
||||
end;
|
||||
inc(i);
|
||||
j := i*(i+1)*2;//position of i*i
|
||||
IF PrimeLimit < j then
|
||||
BREAK;
|
||||
until false;
|
||||
end;
|
||||
|
||||
procedure OutputTransitions(const Trs:tCntTransRecField);
|
||||
var
|
||||
i,j,k,res,cnt: NativeInt;
|
||||
ThereWasOutput: boolean;
|
||||
Begin
|
||||
cnt := 0;
|
||||
while Trs[cnt].CTR_primCnt > 0 do
|
||||
inc(cnt);
|
||||
dec(cnt);
|
||||
IF cnt < 0 then
|
||||
EXIT;
|
||||
|
||||
write('PrimCnt ');
|
||||
For i := 0 to cnt do
|
||||
write(Trs[i].CTR_primCnt:i+7);
|
||||
writeln;
|
||||
For i := 0 to 9 do
|
||||
Begin
|
||||
ThereWasOutput := false;
|
||||
For j := 0 to 9 do
|
||||
Begin
|
||||
res := Trs[0].CTR_CntTrans[i,j];
|
||||
IF res > 0 then
|
||||
Begin
|
||||
ThereWasOutput := true;
|
||||
write('''',i,'''->''',j,'''');
|
||||
For k := 0 to cnt do
|
||||
Begin
|
||||
res := Trs[k].CTR_CntTrans[i,j];
|
||||
write(res/Trs[k].CTR_primCnt*100:k+6:k+2,'%');
|
||||
end;
|
||||
writeln;
|
||||
end;
|
||||
end;
|
||||
IF ThereWasOutput then
|
||||
writeln;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
pCntTransOld,
|
||||
pCntTransNew : ^tCntTransRec;
|
||||
i,primCnt,lmt : NativeInt;
|
||||
prvChr,
|
||||
nxtChr : NativeInt;
|
||||
Begin
|
||||
SieveSmall;
|
||||
pCntTransOld := @CntTransitions[0].CTR_CntTrans;
|
||||
|
||||
|
||||
pCntTransOld^.CTR_CntTrans[2,3]:= 1;
|
||||
lmt := 10*1000;
|
||||
|
||||
//starting at 2 *2+1 => 5
|
||||
primCnt := 2; // the prime 2,3
|
||||
prvChr := 3;
|
||||
nxtChr := prvChr;
|
||||
for i:= 2 to PrimeLimit do
|
||||
Begin
|
||||
inc(nxtChr,2);
|
||||
if nxtChr >= 10 then nxtChr := 1;
|
||||
IF primes[i] then
|
||||
Begin
|
||||
inc(pCntTransOld^.CTR_CntTrans[prvChr][nxtChr]);
|
||||
inc(primCnt);
|
||||
prvchr := nxtChr;
|
||||
IF primCnt >= lmt then
|
||||
Begin
|
||||
with pCntTransOld^ do Begin
|
||||
CTR_Limit := i;
|
||||
CTR_primCnt := primCnt;
|
||||
end;
|
||||
pCntTransNew := pCntTransOld;
|
||||
inc(pCntTransNew);
|
||||
pCntTransNew^:= pCntTransOld^;
|
||||
pCntTransOld := pCntTransNew;
|
||||
lmt := lmt*10;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
pCntTransOld^.CTR_primCnt := 0;
|
||||
OutputTransitions(CntTransitions);
|
||||
end.
|
||||
15
Task/Prime-conspiracy/Perl/prime-conspiracy.pl
Normal file
15
Task/Prime-conspiracy/Perl/prime-conspiracy.pl
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
use ntheory qw/forprimes nth_prime/;
|
||||
|
||||
my $upto = 1_000_000;
|
||||
my %freq;
|
||||
my($this_digit,$last_digit)=(2,0);
|
||||
|
||||
forprimes {
|
||||
($last_digit,$this_digit) = ($this_digit, $_ % 10);
|
||||
$freq{$last_digit . $this_digit}++;
|
||||
} 3,nth_prime($upto);
|
||||
|
||||
print "$upto first primes. Transitions prime % 10 → next-prime % 10.\n";
|
||||
printf "%s → %s count:\t%7d\tfrequency: %4.2f %%\n",
|
||||
substr($_,0,1), substr($_,1,1), $freq{$_}, 100*$freq{$_}/$upto
|
||||
for sort keys %freq;
|
||||
20
Task/Prime-conspiracy/Phix/prime-conspiracy-1.phix
Normal file
20
Task/Prime-conspiracy/Phix/prime-conspiracy-1.phix
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">p10k</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">get_primes</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">10_000</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">transitions</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span><span style="color: #000000;">9</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p10k</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">p10k</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">curr</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #000000;">l</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">curr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p10k</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">transitions</span><span style="color: #0000FF;">[</span><span style="color: #000000;">last</span><span style="color: #0000FF;">][</span><span style="color: #000000;">curr</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">curr</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">tij</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">transitions</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">tij</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">pc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tij</span><span style="color: #0000FF;">*</span><span style="color: #000000;">100</span><span style="color: #0000FF;">/</span><span style="color: #000000;">l</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%d->%d:%3.2f%%\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pc</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
23
Task/Prime-conspiracy/Phix/prime-conspiracy-2.phix
Normal file
23
Task/Prime-conspiracy/Phix/prime-conspiracy-2.phix
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">p1m</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">get_primes</span><span style="color: #0000FF;">(-</span><span style="color: #000000;">1_000_000</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">transitions</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span><span style="color: #000000;">9</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">results</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p1m</span><span style="color: #0000FF;">),</span> <span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">p1m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">4</span><span style="color: #0000FF;">],</span> <span style="color: #000000;">curr</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">5</span> <span style="color: #008080;">to</span> <span style="color: #000000;">l</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">curr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">remainder</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p1m</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">10</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #000000;">transitions</span><span style="color: #0000FF;">[</span><span style="color: #000000;">last</span><span style="color: #0000FF;">][</span><span style="color: #000000;">curr</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #000000;">last</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">curr</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">9</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">tij</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">transitions</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">][</span><span style="color: #000000;">j</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">tij</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">pc</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">tij</span><span style="color: #0000FF;">*</span><span style="color: #000000;">100</span><span style="color: #0000FF;">/</span><span style="color: #000000;">l</span>
|
||||
<span style="color: #000000;">results</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">results</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">j</span><span style="color: #0000FF;">-</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span><span style="color: #000000;">pc</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">results</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">results</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #7060A8;">papply</span><span style="color: #0000FF;">(</span><span style="color: #004600;">true</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">printf</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,{</span><span style="color: #008000;">"%2d, %d->%d:%3.2f%%\n"</span><span style="color: #0000FF;">},</span><span style="color: #000000;">results</span><span style="color: #0000FF;">})</span>
|
||||
<!--
|
||||
14
Task/Prime-conspiracy/Picat/prime-conspiracy.picat
Normal file
14
Task/Prime-conspiracy/Picat/prime-conspiracy.picat
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
go =>
|
||||
N = 15_485_863, % 1_000_000 primes
|
||||
Primes = {P mod 10 : P in primes(N)},
|
||||
Len = Primes.len,
|
||||
A = new_array(10,10), bind_vars(A,0),
|
||||
foreach(I in 2..Len)
|
||||
P1 = 1 + Primes[I-1], % adjust for 1-based
|
||||
P2 = 1 + Primes[I],
|
||||
A[P1,P2] := A[P1,P2] + 1
|
||||
end,
|
||||
foreach(I in 0..9, J in 0..9, V = A[I+1,J+1], V > 0)
|
||||
printf("%d -> %d count: %5d frequency: %0.4f%%\n", I,J,V,100*V/Len)
|
||||
end,
|
||||
nl.
|
||||
46
Task/Prime-conspiracy/PicoLisp/prime-conspiracy.l
Normal file
46
Task/Prime-conspiracy/PicoLisp/prime-conspiracy.l
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
(load "pluser/sieve.l") # See the task "Sieve of Eratosthanes"
|
||||
|
||||
(setq NthPrime '(
|
||||
( 10 . 29)
|
||||
( 100 . 541)
|
||||
( 1000 . 7919)
|
||||
( 10000 . 104729)
|
||||
( 100000 . 1299709)
|
||||
(1000000 . 15485863)))
|
||||
|
||||
(de conspiracy (Power)
|
||||
(let (Upto (cdr (assoc (** 10 Power) NthPrime)))
|
||||
(if Upto
|
||||
(report Upto)
|
||||
(prog (prinl "Sorry, I don't know the value of the 1e" Power "th prime number.") NIL))))
|
||||
|
||||
(de report (Upto)
|
||||
(for Count (tally Upto)
|
||||
(let (((A . B) . C) Count)
|
||||
(prinl A " -> " B ": " C)))
|
||||
NIL)
|
||||
|
||||
(de tally (Upto)
|
||||
(let
|
||||
(Transitions
|
||||
(maplist '((L)
|
||||
(and
|
||||
(cdr L)
|
||||
(cons
|
||||
(% (car L) 10)
|
||||
(% (cadr L) 10))))
|
||||
(sieve Upto)))
|
||||
(let (Tally NIL)
|
||||
(for Pair Transitions
|
||||
(setq Tally (bump-trans Pair Tally)))
|
||||
(cdr (sort Tally))))) # NOTE: After sorting, first element is NIL
|
||||
# (since the last element from the maplist call is NIL)
|
||||
|
||||
(de bump-trans (Trans Tally)
|
||||
(cond
|
||||
((== Tally NIL)
|
||||
(list (cons Trans 1)))
|
||||
((= Trans (caar Tally))
|
||||
(cons (cons Trans (inc (cdar Tally))) (cdr Tally)))
|
||||
(T
|
||||
(cons (car Tally) (bump-trans Trans (cdr Tally))))))
|
||||
59
Task/Prime-conspiracy/Prolog/prime-conspiracy.pro
Normal file
59
Task/Prime-conspiracy/Prolog/prime-conspiracy.pro
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
% table of nth prime values (up to 100,000)
|
||||
|
||||
nthprime( 10, 29).
|
||||
nthprime( 100, 541).
|
||||
nthprime( 1000, 7919).
|
||||
nthprime( 10000, 104729).
|
||||
nthprime(100000, 1299709).
|
||||
|
||||
conspiracy(M) :-
|
||||
N is 10**M,
|
||||
nthprime(N, P),
|
||||
sieve(P, Ps),
|
||||
tally(Ps, Counts),
|
||||
sort(Counts, Sorted),
|
||||
show(Sorted).
|
||||
|
||||
show(Results) :-
|
||||
forall(
|
||||
member(tr(D1, D2, Count), Results),
|
||||
format("~d -> ~d: ~d~n", [D1, D2, Count])).
|
||||
|
||||
|
||||
% count results
|
||||
|
||||
tally(L, R) :- tally(L, [], R).
|
||||
tally([_], T, T) :- !.
|
||||
tally([A|As], T0, R) :-
|
||||
[B|_] = As,
|
||||
Da is A mod 10, Db is B mod 10,
|
||||
count(Da, Db, T0, T1),
|
||||
tally(As, T1, R).
|
||||
|
||||
count(D1, D2, [], [tr(D1, D2, 1)]) :- !.
|
||||
count(D1, D2, [tr(D1, D2, N)|Ts], [tr(D1, D2, Sn)|Ts]) :- succ(N, Sn), !.
|
||||
count(D1, D2, [T|Ts], [T|Us]) :- count(D1, D2, Ts, Us).
|
||||
|
||||
|
||||
% implement a prime sieve
|
||||
|
||||
sieve(Limit, Ps) :-
|
||||
numlist(2, Limit, Ns),
|
||||
sieve(Limit, Ns, Ps).
|
||||
|
||||
sieve(Limit, W, W) :- W = [P|_], P*P > Limit, !.
|
||||
sieve(Limit, [P|Xs], [P|Ys]) :-
|
||||
Q is P*P,
|
||||
remove_multiples(P, Q, Xs, R),
|
||||
sieve(Limit, R, Ys).
|
||||
|
||||
remove_multiples(_, _, [], []) :- !.
|
||||
remove_multiples(N, M, [A|As], R) :-
|
||||
A =:= M, !,
|
||||
remove_multiples(N, M, As, R).
|
||||
remove_multiples(N, M, [A|As], [A|R]) :-
|
||||
A < M, !,
|
||||
remove_multiples(N, M, As, R).
|
||||
remove_multiples(N, M, L, R) :-
|
||||
plus(M, N, M2),
|
||||
remove_multiples(N, M2, L, R).
|
||||
49
Task/Prime-conspiracy/Python/prime-conspiracy.py
Normal file
49
Task/Prime-conspiracy/Python/prime-conspiracy.py
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
def isPrime(n):
|
||||
if n < 2:
|
||||
return False
|
||||
if n % 2 == 0:
|
||||
return n == 2
|
||||
if n % 3 == 0:
|
||||
return n == 3
|
||||
|
||||
d = 5
|
||||
while d * d <= n:
|
||||
if n % d == 0:
|
||||
return False
|
||||
d += 2
|
||||
|
||||
if n % d == 0:
|
||||
return False
|
||||
d += 4
|
||||
return True
|
||||
|
||||
def generatePrimes():
|
||||
yield 2
|
||||
yield 3
|
||||
|
||||
p = 5
|
||||
while p > 0:
|
||||
if isPrime(p):
|
||||
yield p
|
||||
p += 2
|
||||
if isPrime(p):
|
||||
yield p
|
||||
p += 4
|
||||
|
||||
g = generatePrimes()
|
||||
transMap = {}
|
||||
prev = None
|
||||
limit = 1000000
|
||||
for _ in xrange(limit):
|
||||
prime = next(g)
|
||||
if prev:
|
||||
transition = (prev, prime %10)
|
||||
if transition in transMap:
|
||||
transMap[transition] += 1
|
||||
else:
|
||||
transMap[transition] = 1
|
||||
prev = prime % 10
|
||||
|
||||
print "First {:,} primes. Transitions prime % 10 > next-prime % 10.".format(limit)
|
||||
for trans in sorted(transMap):
|
||||
print "{0} -> {1} count {2:5} frequency: {3}%".format(trans[0], trans[1], transMap[trans], 100.0 * transMap[trans] / limit)
|
||||
25
Task/Prime-conspiracy/R/prime-conspiracy.r
Normal file
25
Task/Prime-conspiracy/R/prime-conspiracy.r
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
suppressMessages(library(gmp))
|
||||
|
||||
limit <- 1e6
|
||||
result <- vector('numeric', 99)
|
||||
prev_prime <- 2
|
||||
count <- 0
|
||||
|
||||
getOutput <- function(transition) {
|
||||
if (result[transition] == 0) return()
|
||||
second <- transition %% 10
|
||||
first <- (transition - second) / 10
|
||||
cat(first,"->",second,"count:", sprintf("%6d",result[transition]), "frequency:",
|
||||
sprintf("%5.2f%%\n",result[transition]*100/limit))
|
||||
}
|
||||
|
||||
while (count <= limit) {
|
||||
count <- count + 1
|
||||
next_prime <- nextprime(prev_prime)
|
||||
transition <- 10*(asNumeric(prev_prime) %% 10) + (asNumeric(next_prime) %% 10)
|
||||
prev_prime <- next_prime
|
||||
result[transition] <- result[transition] + 1
|
||||
}
|
||||
|
||||
cat(sprintf("%d",limit),"first primes. Transitions prime % 10 -> next-prime % 10\n")
|
||||
invisible(sapply(1:99,getOutput))
|
||||
29
Task/Prime-conspiracy/REXX/prime-conspiracy.rexx
Normal file
29
Task/Prime-conspiracy/REXX/prime-conspiracy.rexx
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*REXX pgm shows a table of what last digit follows the previous last digit for N primes*/
|
||||
parse arg N . /*N: the number of primes to be genned*/
|
||||
if N=='' | N=="," then N= 1000000 /*Not specified? Then use the default.*/
|
||||
Np= N+1; w= length(N-1) /*W: width used for formatting output.*/
|
||||
H= N* (2**max(4, (w%2+1) ) ) /*used as a rough limit for the sieve. */
|
||||
@.= . /*assume all numbers are prime (so far)*/
|
||||
#= 1 /*primes found so far {assume prime 2}.*/
|
||||
do j=3 by 2; if @.j=='' then iterate /*Is composite? Then skip this number.*/
|
||||
#= #+1 /*bump the prime number counter. */
|
||||
do m=j*j to H by j+j; @.m= /*strike odd multiples as composite. */
|
||||
end /*m*/
|
||||
if #==Np then leave /*Enough primes? Then done with gen. */
|
||||
end /*j*/ /* [↑] gen using Eratosthenes' sieve. */
|
||||
!.= 0 /*initialize all the frequency counters*/
|
||||
say 'For ' N " primes used in this study:" /*show hdr information about this run. */
|
||||
r= 2 /*the last digit of the very 1st prime.*/
|
||||
#= 1 /*the number of primes looked at so far*/
|
||||
do i=3 by 2; if @.i=='' then iterate /*This number composite? Then ignore it*/
|
||||
#= # + 1; parse var i '' -1 x /*bump prime counter; get its last dig.*/
|
||||
!.r.x= !.r.x +1; r= x /*bump the last digit counter for prev.*/
|
||||
if #==Np then leave /*Done? Then leave this DO loop. */
|
||||
end /*i*/ /* [↑] examine almost all odd numbers.*/
|
||||
say /* [↓] display the results to the term*/
|
||||
do d=1 for 9; if d//2 | d==2 then say /*display a blank line (if appropriate)*/
|
||||
do f=1 for 9; if !.d.f==0 then iterate /*don't show if the count is zero. */
|
||||
say 'digit ' d "──►" f ' has a count of: ',
|
||||
right(!.d.f, w)", frequency of:" right(format(!.d.f / N*100, , 4)'%.', 10)
|
||||
end /*f*/
|
||||
end /*d*/ /*stick a fork in it, we're all done. */
|
||||
19
Task/Prime-conspiracy/Racket/prime-conspiracy.rkt
Normal file
19
Task/Prime-conspiracy/Racket/prime-conspiracy.rkt
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#lang racket
|
||||
|
||||
(require math/number-theory)
|
||||
|
||||
(define limit 1000000)
|
||||
|
||||
(define table
|
||||
(for/fold ([table (hash)] [prev 2] #:result table)
|
||||
([p (in-list (next-primes 2 (sub1 limit)))])
|
||||
(define p-mod (modulo p 10))
|
||||
(values (hash-update table (cons prev p-mod) add1 0) p-mod)))
|
||||
|
||||
(define (pair<? p q) (or (< (car p) (car q)) (and (= (car p) (car q)) (< (cdr p) (cdr q)))))
|
||||
|
||||
(printf "~a first primes. Transitions prime % 10 → next-prime % 10.\n" limit)
|
||||
(for ([item (sort (hash->list table) pair<? #:key car)])
|
||||
(match-define (cons (cons x y) freq) item)
|
||||
(printf "~a → ~a count: ~a frequency: ~a %\n"
|
||||
x y (~a freq #:min-width 8 #:align 'right) (~r (* 100 freq (/ 1 limit)) #:precision '(= 2))))
|
||||
14
Task/Prime-conspiracy/Raku/prime-conspiracy.raku
Normal file
14
Task/Prime-conspiracy/Raku/prime-conspiracy.raku
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
use Math::Primesieve;
|
||||
|
||||
my %conspiracy;
|
||||
my $upto = 1_000_000;
|
||||
my $sieve = Math::Primesieve.new;
|
||||
my @primes = $sieve.n-primes($upto+1);
|
||||
|
||||
@primes[^($upto+1)].reduce: -> $a, $b {
|
||||
my $d = $b % 10;
|
||||
%conspiracy{"$a → $d count:"}++;
|
||||
$d;
|
||||
}
|
||||
|
||||
say "$_ \tfrequency: {($_.value/$upto*100).round(.01)} %" for %conspiracy.sort;
|
||||
12
Task/Prime-conspiracy/Ruby/prime-conspiracy.rb
Normal file
12
Task/Prime-conspiracy/Ruby/prime-conspiracy.rb
Normal file
|
|
@ -0,0 +1,12 @@
|
|||
require "prime"
|
||||
|
||||
def prime_conspiracy(m)
|
||||
conspiracy = Hash.new(0)
|
||||
Prime.take(m).map{|n| n%10}.each_cons(2){|a,b| conspiracy[[a,b]] += 1}
|
||||
puts "#{m} first primes. Transitions prime % 10 → next-prime % 10."
|
||||
conspiracy.sort.each do |(a,b),v|
|
||||
puts "%d → %d count:%10d frequency:%7.4f %" % [a, b, v, 100.0*v/m]
|
||||
end
|
||||
end
|
||||
|
||||
prime_conspiracy(1_000_000)
|
||||
48
Task/Prime-conspiracy/Rust/prime-conspiracy-1.rust
Normal file
48
Task/Prime-conspiracy/Rust/prime-conspiracy-1.rust
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
// main.rs
|
||||
mod bit_array;
|
||||
mod prime_sieve;
|
||||
|
||||
use prime_sieve::PrimeSieve;
|
||||
|
||||
// See https://en.wikipedia.org/wiki/Prime_number_theorem#Approximations_for_the_nth_prime_number
|
||||
fn upper_bound_for_nth_prime(n: usize) -> usize {
|
||||
let x = n as f64;
|
||||
(x * (x.ln() + x.ln().ln())) as usize
|
||||
}
|
||||
|
||||
fn compute_transitions(limit: usize) {
|
||||
use std::collections::BTreeMap;
|
||||
let mut transitions = BTreeMap::new();
|
||||
let mut prev = 2;
|
||||
let mut count = 0;
|
||||
let sieve = PrimeSieve::new(upper_bound_for_nth_prime(limit));
|
||||
let mut n = 3;
|
||||
while count < limit {
|
||||
if sieve.is_prime(n) {
|
||||
count += 1;
|
||||
let digit = n % 10;
|
||||
let key = (prev, digit);
|
||||
if let Some(v) = transitions.get_mut(&key) {
|
||||
*v += 1;
|
||||
} else {
|
||||
transitions.insert(key, 1);
|
||||
}
|
||||
prev = digit;
|
||||
}
|
||||
n += 2;
|
||||
}
|
||||
println!("First {} prime numbers:", limit);
|
||||
for ((from, to), c) in &transitions {
|
||||
let freq = 100.0 * (*c as f32) / (limit as f32);
|
||||
println!(
|
||||
"{} -> {}: count = {:7}, frequency = {:.2} %",
|
||||
from, to, c, freq
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
compute_transitions(1000000);
|
||||
println!();
|
||||
compute_transitions(100000000);
|
||||
}
|
||||
36
Task/Prime-conspiracy/Rust/prime-conspiracy-2.rust
Normal file
36
Task/Prime-conspiracy/Rust/prime-conspiracy-2.rust
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// prime_sieve.rs
|
||||
use crate::bit_array;
|
||||
|
||||
pub struct PrimeSieve {
|
||||
composite: bit_array::BitArray,
|
||||
}
|
||||
|
||||
impl PrimeSieve {
|
||||
pub fn new(limit: usize) -> PrimeSieve {
|
||||
let mut sieve = PrimeSieve {
|
||||
composite: bit_array::BitArray::new(limit / 2),
|
||||
};
|
||||
let mut p = 3;
|
||||
while p * p <= limit {
|
||||
if !sieve.composite.get(p / 2 - 1) {
|
||||
let inc = p * 2;
|
||||
let mut q = p * p;
|
||||
while q <= limit {
|
||||
sieve.composite.set(q / 2 - 1, true);
|
||||
q += inc;
|
||||
}
|
||||
}
|
||||
p += 2;
|
||||
}
|
||||
sieve
|
||||
}
|
||||
pub fn is_prime(&self, n: usize) -> bool {
|
||||
if n < 2 {
|
||||
return false;
|
||||
}
|
||||
if n % 2 == 0 {
|
||||
return n == 2;
|
||||
}
|
||||
!self.composite.get(n / 2 - 1)
|
||||
}
|
||||
}
|
||||
24
Task/Prime-conspiracy/Rust/prime-conspiracy-3.rust
Normal file
24
Task/Prime-conspiracy/Rust/prime-conspiracy-3.rust
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
// bit_array.rs
|
||||
pub struct BitArray {
|
||||
array: Vec<u32>,
|
||||
}
|
||||
|
||||
impl BitArray {
|
||||
pub fn new(size: usize) -> BitArray {
|
||||
BitArray {
|
||||
array: vec![0; (size + 31) / 32],
|
||||
}
|
||||
}
|
||||
pub fn get(&self, index: usize) -> bool {
|
||||
let bit = 1 << (index & 31);
|
||||
(self.array[index >> 5] & bit) != 0
|
||||
}
|
||||
pub fn set(&mut self, index: usize, new_val: bool) {
|
||||
let bit = 1 << (index & 31);
|
||||
if new_val {
|
||||
self.array[index >> 5] |= bit;
|
||||
} else {
|
||||
self.array[index >> 5] &= !bit;
|
||||
}
|
||||
}
|
||||
}
|
||||
34
Task/Prime-conspiracy/Rust/prime-conspiracy-4.rust
Normal file
34
Task/Prime-conspiracy/Rust/prime-conspiracy-4.rust
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
// [dependencies]
|
||||
// primal = "0.2"
|
||||
|
||||
fn compute_transitions(limit: usize) {
|
||||
use std::collections::BTreeMap;
|
||||
let mut transitions = BTreeMap::new();
|
||||
let mut prev = 0;
|
||||
for n in primal::Primes::all().take(limit) {
|
||||
let digit = n % 10;
|
||||
if prev != 0 {
|
||||
let key = (prev, digit);
|
||||
if let Some(v) = transitions.get_mut(&key) {
|
||||
*v += 1;
|
||||
} else {
|
||||
transitions.insert(key, 1);
|
||||
}
|
||||
}
|
||||
prev = digit;
|
||||
}
|
||||
println!("First {} prime numbers:", limit);
|
||||
for ((from, to), c) in &transitions {
|
||||
let freq = 100.0 * (*c as f32) / (limit as f32);
|
||||
println!(
|
||||
"{} -> {}: count = {:7}, frequency = {:.2} %",
|
||||
from, to, c, freq
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
compute_transitions(1000000);
|
||||
println!();
|
||||
compute_transitions(100000000);
|
||||
}
|
||||
53
Task/Prime-conspiracy/Scala/prime-conspiracy-1.scala
Normal file
53
Task/Prime-conspiracy/Scala/prime-conspiracy-1.scala
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
import scala.annotation.tailrec
|
||||
import scala.collection.mutable
|
||||
|
||||
object PrimeConspiracy extends App {
|
||||
val limit = 1000000
|
||||
val sieveTop = 15485863/*one millionth prime*/ + 1
|
||||
val buckets = Array.ofDim[Int](10, 10)
|
||||
var prevPrime = 2
|
||||
|
||||
def sieve(limit: Int) = {
|
||||
val composite = new mutable.BitSet(sieveTop)
|
||||
composite(0) = true
|
||||
composite(1) = true
|
||||
|
||||
for (n <- 2 to math.sqrt(limit).toInt)
|
||||
if (!composite(n)) for (k <- n * n until limit by n) composite(k) = true
|
||||
composite
|
||||
}
|
||||
|
||||
val notPrime = sieve(sieveTop)
|
||||
|
||||
def isPrime(n: Long) = {
|
||||
@tailrec
|
||||
def inner(d: Int, end: Int): Boolean = {
|
||||
if (d > end) true
|
||||
else if (n % d != 0 && n % (d + 2) != 0) inner(d + 6, end) else false
|
||||
}
|
||||
|
||||
n > 1 && ((n & 1) != 0 || n == 2) &&
|
||||
(n % 3 != 0 || n == 3) && inner(5, math.sqrt(n).toInt)
|
||||
}
|
||||
|
||||
var primeCount = 1
|
||||
var n = 3
|
||||
|
||||
while (primeCount < limit) {
|
||||
if (!notPrime(n)) {
|
||||
val prime = n
|
||||
buckets(prevPrime % 10)(prime % 10) += 1
|
||||
prevPrime = prime
|
||||
primeCount += 1
|
||||
}
|
||||
n += 1
|
||||
}
|
||||
|
||||
for {i <- buckets.indices
|
||||
j <- buckets.head.indices} {
|
||||
val nPrime = buckets(i)(j)
|
||||
if (nPrime != 0) println(f"$i%d -> $j%d : $nPrime%5d ${nPrime / (limit / 100.0)}%2f")
|
||||
}
|
||||
|
||||
println(s"Successfully completed without errors. [total ${scala.compat.Platform.currentTime - executionStart} ms]")
|
||||
}
|
||||
23
Task/Prime-conspiracy/Scala/prime-conspiracy-2.scala
Normal file
23
Task/Prime-conspiracy/Scala/prime-conspiracy-2.scala
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
object PrimeConspiracy1 extends App {
|
||||
private val oddPrimes: Stream[Int] =
|
||||
3 #:: Stream.from(5, 2)
|
||||
.filter(n => oddPrimes.takeWhile(k => k * k <= n).forall(d => n % d != 0))
|
||||
val limit = 1000000
|
||||
|
||||
println(s"Population: $limit primes,")
|
||||
println(s"Last considered prime ${oddPrimes(limit - 2)}")
|
||||
val lsd = oddPrimes.take(limit).par.map(_ % 10)
|
||||
|
||||
val results: Seq[(((Int, Int), Int), Int)] =
|
||||
(2 +: lsd).zip(lsd)
|
||||
.groupBy(identity).map { case (k, v) => (k, v.size) }
|
||||
.toList.sortBy { case ((_, _), n) => -n }.zipWithIndex // Add ranking
|
||||
.sorted
|
||||
|
||||
results.foreach { case (((i, j), nPrime), rank) =>
|
||||
println(f"$i%d -> $j%d : $nPrime%5d ${nPrime / (limit / 100.0)}%2f rank:${rank + 1}%3d")
|
||||
}
|
||||
// println(results.map { case (((_, _), n), _) => n }.sum)
|
||||
|
||||
println(s"Successfully completed without errors. [total ${scala.compat.Platform.currentTime - executionStart} ms]")
|
||||
}
|
||||
50
Task/Prime-conspiracy/Seed7/prime-conspiracy.seed7
Normal file
50
Task/Prime-conspiracy/Seed7/prime-conspiracy.seed7
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
$ include "seed7_05.s7i";
|
||||
include "float.s7i";
|
||||
|
||||
const func set of integer: eratosthenes (in integer: n) is func
|
||||
result
|
||||
var set of integer: sieve is EMPTY_SET;
|
||||
local
|
||||
var integer: i is 0;
|
||||
var integer: j is 0;
|
||||
begin
|
||||
sieve := {2 .. n};
|
||||
for i range 2 to sqrt(n) do
|
||||
if i in sieve then
|
||||
for j range i ** 2 to n step i do
|
||||
excl(sieve, j);
|
||||
end for;
|
||||
end if;
|
||||
end for;
|
||||
end func;
|
||||
|
||||
const type: countHashType is hash [string] integer;
|
||||
|
||||
const proc: main is func
|
||||
local
|
||||
const set of integer: primes is eratosthenes(15485863);
|
||||
var integer: lastPrime is 0;
|
||||
var integer: currentPrime is 0;
|
||||
var string: aKey is "";
|
||||
var countHashType: countHash is countHashType.value;
|
||||
var integer: count is 0;
|
||||
var integer: total is 0;
|
||||
begin
|
||||
for currentPrime range primes do
|
||||
if lastPrime <> 0 then
|
||||
incr(total);
|
||||
aKey := str(lastPrime rem 10) <& " -> " <& str(currentPrime rem 10);
|
||||
if aKey in countHash then
|
||||
incr(countHash[aKey]);
|
||||
else
|
||||
countHash @:= [aKey] 1;
|
||||
end if;
|
||||
end if;
|
||||
lastPrime := currentPrime;
|
||||
end for;
|
||||
for aKey range sort(keys(countHash)) do
|
||||
count := countHash[aKey];
|
||||
writeln(aKey <& " count: " <& count lpad 5 <& " frequency: " <&
|
||||
flt(count * 100)/flt(total) digits 2 lpad 4 <& " %");
|
||||
end for;
|
||||
end func;
|
||||
14
Task/Prime-conspiracy/Sidef/prime-conspiracy.sidef
Normal file
14
Task/Prime-conspiracy/Sidef/prime-conspiracy.sidef
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
var primes = (^Inf -> lazy.grep{.is_prime})
|
||||
|
||||
var upto = 1e6
|
||||
var conspiracy = Hash()
|
||||
|
||||
primes.first(upto+1).reduce { |a,b|
|
||||
var d = b%10
|
||||
conspiracy{"#{a} → #{d}"} := 0 ++
|
||||
d
|
||||
}
|
||||
|
||||
for k,v in (conspiracy.sort_by{|k,_v| k }) {
|
||||
printf("%s count: %6s\tfrequency: %2.2f %\n", k, v.commify, v / upto * 100)
|
||||
}
|
||||
82
Task/Prime-conspiracy/VBA/prime-conspiracy.vba
Normal file
82
Task/Prime-conspiracy/VBA/prime-conspiracy.vba
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
Option Explicit
|
||||
|
||||
Sub Main()
|
||||
Dim Dict As Object, L() As Long
|
||||
Dim t As Single
|
||||
|
||||
Init Dict
|
||||
L = ListPrimes(100000000)
|
||||
t = Timer
|
||||
PrimeConspiracy L, Dict, 1000000
|
||||
Debug.Print "----------------------------"
|
||||
Debug.Print "Execution time : " & Format(Timer - t, "0.000s.")
|
||||
Debug.Print ""
|
||||
Init Dict
|
||||
t = Timer
|
||||
PrimeConspiracy L, Dict, 5000000
|
||||
Debug.Print "----------------------------"
|
||||
Debug.Print "Execution time : " & Format(Timer - t, "0.000s.")
|
||||
End Sub
|
||||
|
||||
Private Function ListPrimes(MAX As Long) As Long()
|
||||
'http://rosettacode.org/wiki/Extensible_prime_generator#VBA
|
||||
Dim t() As Boolean, L() As Long, c As Long, s As Long, i As Long, j As Long
|
||||
ReDim t(2 To MAX)
|
||||
ReDim L(MAX \ 2)
|
||||
s = Sqr(MAX)
|
||||
For i = 3 To s Step 2
|
||||
If t(i) = False Then
|
||||
For j = i * i To MAX Step i
|
||||
t(j) = True
|
||||
Next
|
||||
End If
|
||||
Next i
|
||||
L(0) = 2
|
||||
For i = 3 To MAX Step 2
|
||||
If t(i) = False Then
|
||||
c = c + 1
|
||||
L(c) = i
|
||||
End If
|
||||
Next i
|
||||
ReDim Preserve L(c)
|
||||
ListPrimes = L
|
||||
End Function
|
||||
|
||||
Private Sub Init(d As Object)
|
||||
Set d = CreateObject("Scripting.Dictionary")
|
||||
d("1 to 1") = 0
|
||||
d("1 to 3") = 0
|
||||
d("1 to 7") = 0
|
||||
d("1 to 9") = 0
|
||||
d("2 to 3") = 0
|
||||
d("3 to 1") = 0
|
||||
d("3 to 3") = 0
|
||||
d("3 to 5") = 0
|
||||
d("3 to 7") = 0
|
||||
d("3 to 9") = 0
|
||||
d("5 to 7") = 0
|
||||
d("7 to 1") = 0
|
||||
d("7 to 3") = 0
|
||||
d("7 to 7") = 0
|
||||
d("7 to 9") = 0
|
||||
d("9 to 1") = 0
|
||||
d("9 to 3") = 0
|
||||
d("9 to 7") = 0
|
||||
d("9 to 9") = 0
|
||||
End Sub
|
||||
|
||||
Private Sub PrimeConspiracy(Primes() As Long, Dict As Object, Nb)
|
||||
Dim n As Long, temp As String, r, s, K
|
||||
For n = LBound(Primes) To Nb
|
||||
r = CStr((Primes(n)))
|
||||
s = CStr((Primes(n + 1)))
|
||||
temp = Right(r, 1) & " to " & Right(s, 1)
|
||||
If Dict.Exists(temp) Then Dict(temp) = Dict(temp) + 1
|
||||
Next
|
||||
Debug.Print Nb & " primes, last prime considered: " & Primes(Nb)
|
||||
Debug.Print "Transition Count Frequency"
|
||||
Debug.Print "========== ======= ========="
|
||||
For Each K In Dict.Keys
|
||||
Debug.Print K & " " & Right(" " & Dict(K), 6) & " " & Dict(K) / Nb * 100 & "%"
|
||||
Next
|
||||
End Sub
|
||||
41
Task/Prime-conspiracy/Wren/prime-conspiracy.wren
Normal file
41
Task/Prime-conspiracy/Wren/prime-conspiracy.wren
Normal file
|
|
@ -0,0 +1,41 @@
|
|||
import "/fmt" for Fmt
|
||||
import "/math" for Int
|
||||
import "/sort" for Sort
|
||||
|
||||
var reportTransitions = Fn.new { |transMap, num|
|
||||
var keys = transMap.keys.toList
|
||||
Sort.quick(keys)
|
||||
System.print("First %(Fmt.dc(0, num)) primes. Transitions prime \% 10 -> next-prime \% 10.")
|
||||
for (key in keys) {
|
||||
var count = transMap[key]
|
||||
var freq = count / num * 100
|
||||
System.write("%((key/10).floor) -> %(key%10) count: %(Fmt.dc(8, count))")
|
||||
System.print(" frequency: %(Fmt.f(4, freq, 2))\%")
|
||||
}
|
||||
System.print()
|
||||
}
|
||||
|
||||
// sieve up to the 10 millionth prime
|
||||
var start = System.clock
|
||||
var sieved = Int.primeSieve(179424673)
|
||||
var transMap = {}
|
||||
var i = 2 // last digit of first prime (2)
|
||||
var n = 1 // index of next prime (3) in sieved
|
||||
for (num in [1e4, 1e5, 1e6, 1e7]) {
|
||||
while(n < num) {
|
||||
var p = sieved[n]
|
||||
// count transition of i -> j
|
||||
var j = p % 10
|
||||
var k = i*10 + j
|
||||
var t = transMap[k]
|
||||
if (!t) {
|
||||
transMap[k] = 1
|
||||
} else {
|
||||
transMap[k] = t + 1
|
||||
}
|
||||
i = j
|
||||
n = n + 1
|
||||
}
|
||||
reportTransitions.call(transMap, n)
|
||||
}
|
||||
System.print("Took %(System.clock - start) seconds.")
|
||||
11
Task/Prime-conspiracy/Zkl/prime-conspiracy.zkl
Normal file
11
Task/Prime-conspiracy/Zkl/prime-conspiracy.zkl
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
const CNT =0d1_000_000;
|
||||
sieve :=Import("sieve.zkl",False,False,False).postponed_sieve;
|
||||
conspiracy:=Dictionary();
|
||||
Utils.Generator(sieve).reduce(CNT,'wrap(digit,p){
|
||||
d:=p%10;
|
||||
conspiracy.incV("%d → %d count:".fmt(digit,d));
|
||||
d
|
||||
});
|
||||
foreach key in (conspiracy.keys.sort()){ v:=conspiracy[key].toFloat();
|
||||
println("%s%,6d\tfrequency: %2.2F%".fmt(key,v,v/CNT *100))
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue