Ascending primes
You are encouraged to solve this task according to the task description, using any language you may know.
Generate and show all primes with strictly ascending decimal digits.
Aside: Try solving without peeking at existing solutions. I had a weird idea for generating a prime sieve faster, which needless to say didn't pan out. The solution may be p(r)etty trivial but generating them quickly is at least mildly interesting. Tip: filtering all 7,027,260 primes below 123,456,789 probably won't kill you, but there is at least one significantly better and much faster way, needing a mere 511 odd/prime tests.
- See also
- Related
- Primes with digits in nondecreasing order (infinite series allowing duplicate digits, whereas this isn't and doesn't)
- Pandigital prime (whereas this is the smallest, with gaps in the used digits being permitted)
- Descending primes
11l
F isprime(n)
I n == 2
R 1B
I n == 1 | n % 2 == 0
R 0B
V root1 = Int(n ^ 0.5) + 1
L(k) (3 .< root1).step(2)
I n % k == 0
R 0B
R 1B
V queue = Array(1..9)
[Int] primes
L !queue.empty
V n = queue.pop(0)
I isprime(n)
primes.append(n)
queue.extend((n % 10 + 1 .< 10).map(k -> @n * 10 + k))
print(primes)
- Output:
[2, 3, 5, 7, 13, 17, 19, 23, 29, 37, 47, 59, 67, 79, 89, 127, 137, 139, 149, 157, 167, 179, 239, 257, 269, 347, 349, 359, 367, 379, 389, 457, 467, 479, 569, 1237, 1249, 1259, 1279, 1289, 1367, 1459, 1489, 1567, 1579, 1789, 2347, 2357, 2389, 2459, 2467, 2579, 2689, 2789, 3457, 3467, 3469, 4567, 4679, 4789, 5689, 12347, 12379, 12457, 12479, 12569, 12589, 12689, 13457, 13469, 13567, 13679, 13789, 15679, 23459, 23567, 23689, 23789, 25679, 34589, 34679, 123457, 123479, 124567, 124679, 125789, 134789, 145679, 234589, 235679, 235789, 245789, 345679, 345689, 1234789, 1235789, 1245689, 1456789, 12356789, 23456789]
ALGOL 68
Uses Pete's hint to enumerate the 512 possible numbers.
The numbers are generated in order of the first digit, so we have to sort them.
As there are only 512 possible numbers to consider, it doesn't attempt the optimisation that the final digit can't be 4, 6 or 8 and can only be 2 or 5 if it is the only digit (also, I always forget that can't be even thing...).
BEGIN # find all primes with strictly increasing digits #
PR read "primes.incl.a68" PR # include prime utilities #
PR read "rows.incl.a68" PR # include array utilities #
[ 1 : 512 ]INT primes; # there will be at most 512 (2^9) primes #
INT p count := 0; # number of primes found so far #
FOR d1 FROM 0 TO 1 DO
INT n1 = d1;
FOR d2 FROM 0 TO 1 DO
INT n2 = IF d2 = 1 THEN ( n1 * 10 ) + 2 ELSE n1 FI;
FOR d3 FROM 0 TO 1 DO
INT n3 = IF d3 = 1 THEN ( n2 * 10 ) + 3 ELSE n2 FI;
FOR d4 FROM 0 TO 1 DO
INT n4 = IF d4 = 1 THEN ( n3 * 10 ) + 4 ELSE n3 FI;
FOR d5 FROM 0 TO 1 DO
INT n5 = IF d5 = 1 THEN ( n4 * 10 ) + 5 ELSE n4 FI;
FOR d6 FROM 0 TO 1 DO
INT n6 = IF d6 = 1 THEN ( n5 * 10 ) + 6 ELSE n5 FI;
FOR d7 FROM 0 TO 1 DO
INT n7 = IF d7 = 1 THEN ( n6 * 10 ) + 7 ELSE n6 FI;
FOR d8 FROM 0 TO 1 DO
INT n8 = IF d8 = 1 THEN ( n7 * 10 ) + 8 ELSE n7 FI;
FOR d9 FROM 0 TO 1 DO
INT n9 = IF d9 = 1 THEN ( n8 * 10 ) + 9 ELSE n8 FI;
IF n9 > 0 THEN
IF is probably prime( n9 ) THEN
# have a prime with strictly ascending digits #
primes[ p count +:= 1 ] := n9
FI
FI
OD
OD
OD
OD
OD
OD
OD
OD
OD;
QUICKSORT primes FROMELEMENT 1 TOELEMENT p count; # sort the primes #
FOR i TO p count DO # display the primes #
print( ( " ", whole( primes[ i ], -8 ) ) );
IF i MOD 10 = 0 THEN print( ( newline ) ) FI
OD
END
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
ALGOL W
...and only a few characters different from the Algol W Descending primes sample.
begin % find all primes with strictly ascending digits - translation of Lua %
% quicksorts v, the bounds of v must be specified in lb and ub %
procedure quicksort ( integer array v( * )
; integer value lb, ub
) ;
if ub > lb then begin
% more than one element, so must sort %
integer left, right, pivot;
left := lb;
right := ub;
% choosing the middle element of the array as the pivot %
pivot := v( left + ( ( right + 1 ) - left ) div 2 );
while begin
while left <= ub and v( left ) < pivot do left := left + 1;
while right >= lb and v( right ) > pivot do right := right - 1;
left <= right
end do begin
integer swap;
swap := v( left );
v( left ) := v( right );
v( right ) := swap;
left := left + 1;
right := right - 1
end while_left_le_right ;
quicksort( v, lb, right );
quicksort( v, left, ub )
end quicksort ;
% returns true if n is prime, false otherwise %
logical procedure is_prime( integer value n ) ;
if n < 2 then false
else if n rem 2 = 0 then n = 2
else if n rem 3 = 0 then n = 3
else begin
logical prime; prime := true;
for f := 5 step 6 until entier( sqrt( n ) ) do begin
if n rem f = 0 or n rem ( f + 2 ) = 0 then begin
prime := false;
goto done
end if_n_rem_f_eq_0_or_n_rem_f_plus_2_eq_0
end for_f;
done: prime
end is_prime ;
% increments n and also returns its new value %
integer procedure inc ( integer value result n ) ; begin n := n + 1; n end;
% sets primes to the list of ascending primes and lenPrimes to the %
% number of ascending primes - primes must be big enough, e.g. have 511 %
% elements %
procedure ascending_primes ( integer array primes ( * )
; integer result lenPrimes
) ;
begin
integer array digits ( 1 :: 9 );
integer array candidates ( 1 :: 6000 );
integer lenCandidates;
candidates( 1 ) := 0;
lenCandidates := 1;
lenPrimes := 0;
for i := 1 until 9 do digits( i ) := i;
for i := 1 until 9 do begin
for j := 1 until lenCandidates do begin
integer cValue; cValue := candidates( j ) * 10 + digits( i );
if is_prime( cValue ) then primes( inc( lenPrimes ) ) := cValue;
candidates( inc( lenCandidates ) ) := cValue
end for_j
end for_i ;
quickSort( primes, 1, lenPrimes );
end ascending_primes ;
begin % find the ascending primes and print them %
integer array primes ( 1 :: 512 );
integer lenPrimes;
ascending_primes( primes, lenPrimes );
for i := 1 until lenPrimes do begin
writeon( i_w := 8, s_w := 0, " ", primes( i ) );
if i rem 10 = 0 then write()
end for_i
end
end.
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Arturo
ascending?: function [x][
initial: digits x
and? [equal? sort initial initial][equal? size initial size unique initial]
]
candidates: select (1..1456789) ++ [
12345678, 12345679, 12345689, 12345789, 12346789,
12356789, 12456789, 13456789, 23456789, 123456789
] => prime?
ascendingNums: select candidates => ascending?
loop split.every:10 ascendingNums 'nums [
print map nums 'num -> pad to :string num 10
]
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
AWK
# syntax: GAWK -f ASCENDING_PRIMES.AWK
BEGIN {
start = 1
stop = 23456789
for (i=start; i<=stop; i++) {
if (is_prime(i)) {
primes++
leng = length(i)
flag = 1
for (j=1; j<leng; j++) {
if (substr(i,j,1) >= substr(i,j+1,1)) {
flag = 0
break
}
}
if (flag) {
printf("%9d%1s",i,++count%10?"":"\n")
}
}
}
printf("\n%d-%d: %d primes, %d ascending primes\n",start,stop,primes,count)
exit(0)
}
function is_prime(n, d) {
d = 5
if (n < 2) { return(0) }
if (n % 2 == 0) { return(n == 2) }
if (n % 3 == 0) { return(n == 3) }
while (d*d <= n) {
if (n % d == 0) { return(0) }
d += 2
if (n % d == 0) { return(0) }
d += 4
}
return(1)
}
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789 1-23456789: 1475171 primes, 100 ascending primes
C
/*
* Ascending primes
*
* Generate and show all primes with strictly ascending decimal digits.
*
*
* Solution
*
* We only consider positive numbers in the range 1 to 123456789. We would
* get 7027260 primes, because there are so many primes smaller than 123456789
* (see also Wolfram Alpha).On the other hand, there are only 511 distinct
* nonzero positive integers having their digits arranged in ascending order.
* Therefore, it is better to start with numbers that have properly arranged
* digitsand then check if they are prime numbers.The method of generating
* a sequence of such numbers is not indifferent.We want this sequence to be
* monotonically increasing, because then additional sorting of results will
* be unnecessary. It turns out that by using a queue we can easily get the
* desired effect. Additionally, the algorithm then does not use recursion
* (although the program probably does not have to comply with the MISRA
* standard). The problem to be solved is the queue size, the a priori
* assumption that 1000 is good enough, but a bit magical.
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <math.h>
#if UINT_MAX < 123456789
#error "we need at least 9 decimal digits (32-bit integers)"
#endif
#define MAXSIZE 1000
unsigned queue[MAXSIZE];
unsigned primes[MAXSIZE];
unsigned begin = 0;
unsigned end = 0;
unsigned n = 0;
bool isPrime(unsigned n)
{
if (n == 2)
{
return true;
}
if (n == 1 || n % 2 == 0)
{
return false;
}
unsigned root = sqrt(n);
for (unsigned k = 3; k <= root; k += 2)
{
if (n % k == 0)
{
return false;
}
}
return true;
}
int main(int argc, char argv[])
{
for (int k = 1; k <= 9; k++)
{
queue[end++] = k;
}
while (begin < end)
{
int value = queue[begin++];
if (isPrime(value))
{
primes[n++] = value;
}
for (int k = value % 10 + 1; k <= 9; k++)
{
queue[end++] = value * 10 + k;
}
}
for (int k = 0; k < n; k++)
{
printf("%u ", primes[k]);
}
return EXIT_SUCCESS;
}
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
C++
/*
* Ascending primes
*
* Generate and show all primes with strictly ascending decimal digits.
*
*
* Solution
*
* We only consider positive numbers in the range 1 to 123456789. We would
* get 7027260 primes, because there are so many primes smaller than 123456789
* (see also Wolfram Alpha).On the other hand, there are only 511 distinct
* nonzero positive integers having their digits arranged in ascending order.
* Therefore, it is better to start with numbers that have properly arranged
* digitsand then check if they are prime numbers.The method of generating
* a sequence of such numbers is not indifferent.We want this sequence to be
* monotonically increasing, because then additional sorting of results will
* be unnecessary. It turns out that by using a queue we can easily get the
* desired effect. Additionally, the algorithm then does not use recursion
* (although the program probably does not have to comply with the MISRA
* standard). The problem to be solved is the queue size, the a priori
* assumption that 1000 is good enough, but a bit magical.
*/
#include <cmath>
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
queue<unsigned> suspected;
vector<unsigned> primes;
bool isPrime(unsigned n)
{
if (n == 2)
{
return true;
}
if (n == 1 || n % 2 == 0)
{
return false;
}
unsigned root = sqrt(n);
for (unsigned k = 3; k <= root; k += 2)
{
if (n % k == 0)
{
return false;
}
}
return true;
}
int main(int argc, char argv[])
{
for (unsigned k = 1; k <= 9; k++)
{
suspected.push(k);
}
while (!suspected.empty())
{
int n = suspected.front();
suspected.pop();
if (isPrime(n))
{
primes.push_back(n);
}
// The value of n % 10 gives the least significient digit of n
//
for (unsigned k = n % 10 + 1; k <= 9; k++)
{
suspected.push(n * 10 + k);
}
}
copy(primes.begin(), primes.end(), ostream_iterator<unsigned>(cout, " "));
return EXIT_SUCCESS;
}
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
C#
using System;
using System.Collections.Generic;
namespace ascendingprimes
{
class Program
{
static bool isPrime(uint n)
{
if (n == 2)
return true;
if (n == 1 || n % 2 = 0)
return false;
uint root = (uint)Math.Sqrt(n);
for (uint k = 3; k <= root; k += 2)
if (n % k == 0)
return false;
return true;
}
static void Main(string[] args)
{
var queue = new Queue<uint>();
var primes = new List<uint>();
for (uint k = 1; k <= 9; k++)
queue.Enqueue(k);
while(queue.Count > 0)
{
uint n = queue.Dequeue();
if (isPrime(n))
primes.Add(n);
for (uint k = n % 10 + 1; k <= 9; k++)
queue.Enqueue(n * 10 + k);
}
foreach (uint p in primes)
{
Console.Write(p);
Console.Write(" ");
}
Console.WriteLine();
}
}
}
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Delphi
uses Windows,SysUtils,StdCtrls;
type TProgress = procedure(Percent: integer);
procedure ShowAscendingPrimes(Memo: TMemo; Prog: TProgress);
implementation
function IsPrime(N: integer): boolean;
{Optimised prime test - about 40% faster than the naive approach}
var I,Stop: integer;
begin
if (N = 2) or (N=3) then Result:=true
else if (n <= 1) or ((n mod 2) = 0) or ((n mod 3) = 0) then Result:= false
else
begin
I:=5;
Stop:=Trunc(sqrt(N));
Result:=False;
while I<=Stop do
begin
if ((N mod I) = 0) or ((N mod (i + 2)) = 0) then exit;
Inc(I,6);
end;
Result:=True;
end;
end;
function IsAscending(N: integer): boolean;
{Determine if each digit is greater than previous, left to right}
var S: string;
var I: integer;
begin
Result:=False;
S:=IntToStr(N);
for I:=1 to Length(S)-1 do
if S[I]>=S[I+1] then exit;
Result:=True;
end;
procedure ShowAscendingPrimes(Memo: TMemo; Prog: TProgress);
{Write Ascending primes up to 123,456,789 }
{It has an optional, user-supplied progress routine }
var I,Cnt: integer;
var S: string;
const Max = 123456789;
begin
if Assigned(Prog) then Prog(0);
S:='';
Cnt:=0;
for I:=2 to Max do
begin
if ((I mod 1000000)=0) and Assigned(Prog) then Prog(Trunc(100*(I/Max)));
if IsAscending(I) and IsPrime(I) then
begin
S:=S+Format('%9.0d', [I]);
Inc(Cnt);
if (Cnt mod 10)=0 then
begin
Memo.Lines.Add(S);
S:='';
end;
end;
end;
end;
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Dylan
define function prime? (n :: <integer>) => (p :: <boolean>)
case
n == 2
=> #t;
n == 1 | remainder(n, 2) == 0
=> #f;
otherwise
=> let root = sqrt(as(<double-float>, n));
iterate loop (k = 3)
case
remainder(n, k) == 0 => #f;
k > root => #t;
otherwise => loop(k + 2);
end
end
end case
end function;
define function ascending-primes () => (primes :: <sequence>)
let maybe = make(<deque>);
for (k from 1 to 9)
push-last(maybe, k)
end;
let primes = make(<stretchy-vector>);
while (~empty?(maybe))
let n = pop(maybe);
if (prime?(n))
add!(primes, n)
end;
for (k from modulo(n, 10) + 1 to 9)
push-last(maybe, n * 10 + k)
end
end;
primes
end function;
format-out("%=", ascending-primes());
- Output:
{stretchy vector 2, 5, 7, 13, 17, 19, 23, 29, 37, 47, 59, 67, 79, 89, 127, 137, 139, 149, 157, 167, 179, 239, 257, 269, 347, 349, 359, 367, 379, 389, 457, 467, 479, 569, 1237, 1249, 1259, 1279, 1289, 1367, 1459, 1489, 1567, 1579, 1789, 2347, 2357, 2389, 2459, 2467, 2579, 2689, 2789, 3457, 3467, 3469, 4567, 4679, 4789, 5689, 12347, 12379, 12457, 12479, 12569, 12589, 12689, 13457, 13469, 13567, 13679, 13789, 15679, 23459, 23567, 23689, 23789, 25679, 34589, 34679, 123457, 123479, 124567, 124679, 125789, 134789, 145679, 234589, 235679, 235789, 245789, 345679, 345689, 1234789, 1235789, 1245689, 1456789, 12356789, 23456789}
EasyLang
This outputs all 100 ascending primes. They are not sorted - that was not demanded anyway.
func isprim num .
if num < 2
return 0
.
i = 2
while i <= sqrt num
if num mod i = 0
return 0
.
i += 1
.
return 1
.
proc nextasc n . .
if isprim n = 1
write n & " "
.
if n > 123456789
return
.
for d = n mod 10 + 1 to 9
nextasc n * 10 + d
.
.
nextasc 0
F#
This task uses Extensible Prime Generator (F#)
// Ascending primes. Nigel Galloway: April 19th., 2022
[2;3;5;7]::List.unfold(fun(n,i)->match n with []->None |_->let n=n|>List.map(fun(n,g)->[for n in n.. -1..1->(n-1,i*n+g)])|>List.concat in Some(n|>List.choose(fun(_,n)->if isPrime n then Some n else None),(n|>List.filter(fst>>(<)0),i*10)))([(2,3);(6,7);(8,9)],10)
|>List.concat|>List.sort|>List.iter(printf "%d "); printfn ""
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Factor
The approach taken is to check the members of the powerset of [1..9] (of which there are only 512 if you include the empty set) for primality.
USING: grouping math math.combinatorics math.functions
math.primes math.ranges prettyprint sequences sequences.extras ;
9 [1,b] all-subsets [ reverse 0 [ 10^ * + ] reduce-index ]
[ prime? ] map-filter 10 group simple-table.
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Forth
#! /usr/bin/gforth
\ Ascending primes
\ checks (by simple trial-division) whether the TOS is prime
: prime? ( n -- f )
dup 1 <= IF
drop false
ELSE
dup 2 = IF
drop true
ELSE
2
BEGIN
2dup dup * > >r
2dup mod 0> r>
over and
WHILE
drop 1+
REPEAT
nip nip
THEN
THEN
;
: ascending-primes-aux ( n i -- )
dup 10 = IF
drop
dup prime? IF
.
ELSE
drop
THEN
ELSE
2dup 1+ recurse \ do not include digit i
swap 10 * over + swap 1+ recurse \ do include digit i
THEN
;
\ prints all primes with strictly ascending digits
: ascending-primes ( -- )
0 1 ascending-primes-aux cr
;
ascending-primes bye
- Output:
./ascending-primes.fs 89 7 79 67 5 59 569 5689 47 479 4789 467 4679 457 4567 3 389 37 379 367 359 349 347 3469 3467 34679 34589 3457 345689 345679 2 29 2789 269 2689 257 2579 25679 2467 2459 245789 23 239 2389 23789 23689 2357 235789 23567 235679 2347 23459 234589 23456789 19 17 179 1789 167 157 1579 1567 15679 149 1489 1459 145679 1456789 13 139 137 13789 1367 13679 13567 134789 13469 13457 1289 127 1279 12689 1259 12589 125789 12569 1249 12479 124679 12457 1245689 124567 1237 12379 1235789 12356789 12347 123479 1234789 123457
Fortran
! Ascending primes
!
! Generate and show all primes with strictly ascending decimal digits.
!
!
! Solution
!
! We only consider positive numbers in the range 1 to 123456789. We would get
! 7027260 primes, because there are so many primes smaller than 123456789 (see
! also Wolfram Alpha). On the other hand, there are only 511 distinct positive
! integers having their digits arranged in ascending order. Therefore, it is
! better to start with numbers that have properly arranged digits and then check
! if they are prime numbers. The method of generating a sequence of such numbers
! is not indifferent. We want this sequence to be monotonically increasing,
! because then additional sorting of results will be unnecessary. It turns out
! that by using a queue we can easily get the desired effect. Additionally, the
! algorithm then does not use recursion (although the program probably does not
! have to comply with the MISRA standard). The problem to be solved is the queue
! size, the a priori assumption that 1000 is good enough, but a bit magical.
program prog
parameter (MAXSIZE = 1000)
logical isprime
dimension iqueue(MAXSIZE)
dimension iprimes(MAXSIZE)
ibegin = 1
iend = 1
n = 0
do k = 1, 9
iqueue(iend) = k
iend = iend + 1
end do
do while (ibegin .lt. iend)
iv = iqueue(ibegin)
ibegin = ibegin + 1
if (isprime(iv)) then
n = n + 1
iprimes(n) = iv
end if
lsd1 = mod(iv, 10) + 1
if (lsd1 .le. 9) then
do k = lsd1, 9
iqueue(iend) = iv * 10 + k
iend = iend + 1
end do
end if
end do
print *, (iprimes(i), i = 1, n)
end program
logical function isprime(n)
! Slightly improved algorithm for checking if a number is prime.
! First, we check the special cases: 0, 1, 2. Then we check whether
! the number is divisible by 2. If it is not divisible by two,
! we check whether it is divisible by odd numbers not greater than
! the square root of that number.
!
! Positive numbers only. BTW, negative numbers are prime numbers
! if their absolute values are prime numbers.
isprime = .FALSE.
if (n .eq. 0 .or. n .eq. 1) then
return
end if
if (n .ne. 2) then
if (mod(n, 2) .eq. 0) then
return
end if
m = n**0.5
do k = 3, m, 2
if (mod(n, k) .eq. 0) then
return
end if
end do
end if
isprime = .TRUE.
end function
- Output:
The estimated execution time is 1.5 milliseconds on the same hardware on which the Java program was run. It should be remembered that modern CPUs do not have a constant clock speed and additionally the measured times depend on the system load with other tasks. Nevertheless, the Fortran program seems to be 4 times faster than the Java program.
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
FreeBASIC
Power Set
#include "isprime.bas"
#include "sort.bas"
Dim As Integer i, n, tmp, num, cant = 0
Dim Shared As Integer matriz(512)
For i = 0 To Ubound(matriz)-1
n = 0
tmp = i
num = 1
While tmp
If tmp And 1 Then n = n * 10 + num
tmp Shr= 1
num += 1
Wend
matriz(i)= n
Next i
Sort(matriz())
For i = 1 To Ubound(matriz)-1 'skip empty set
n = matriz(i)
If isPrime(n) Then
Print Using "#########"; n;
cant += 1
If cant Mod 10 = 0 Then Print
End If
Next i
Print Using !"\nThere are & ascending primes."; cant
Sleep
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789 There are 100 ascending primes.
FutureBasic
local fn IsPrime( n as NSUInteger ) as BOOL
BOOL isPrime = YES
NSUInteger i
if n < 2 then exit fn = NO
if n = 2 then exit fn = YES
if n mod 2 == 0 then exit fn = NO
for i = 3 to int(n^.5) step 2
if n mod i == 0 then exit fn = NO
next
end fn = isPrime
void local fn AscendingPrimes( limit as long )
long i, n, mask, num, count = 0
for i = 0 to limit -1
n = 0 : mask = i : num = 1
while ( mask )
if mask & 1 then n = n * 10 + num
mask = mask >> 1
num++
wend
mda(i) = n
next
mda_sort @"compare:"
for i = 1 to mda_count (0) - 1
n = mda_integer(i)
if ( fn IsPrime( n ) )
printf @"%10ld\b", n
count++
if count mod 10 == 0 then print
end if
next
printf @"\n\tThere are %ld ascending primes.", count
end fn
window 1, @"Ascending Primes", ( 0, 0, 780, 230 )
print
CFTimeInterval t
t = fn CACurrentMediaTime
fn AscendingPrimes( 512 )
printf @"\n\tCompute time: %.3f ms\n",(fn CACurrentMediaTime-t)*1000
HandleEvents
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789 There are 100 ascending primes. Compute time: 9.008 ms
Go
Using a generator.
package main
import (
"fmt"
"rcu"
"sort"
)
var ascPrimesSet = make(map[int]bool) // avoids duplicates
func generate(first, cand, digits int) {
if digits == 0 {
if rcu.IsPrime(cand) {
ascPrimesSet[cand] = true
}
return
}
for i := first; i < 10; i++ {
next := cand*10 + i
generate(i+1, next, digits-1)
}
}
func main() {
for digits := 1; digits < 10; digits++ {
generate(1, 0, digits)
}
le := len(ascPrimesSet)
ascPrimes := make([]int, le)
i := 0
for k := range ascPrimesSet {
ascPrimes[i] = k
i++
}
sort.Ints(ascPrimes)
fmt.Println("There are", le, "ascending primes, namely:")
for i := 0; i < le; i++ {
fmt.Printf("%8d ", ascPrimes[i])
if (i+1)%10 == 0 {
fmt.Println()
}
}
}
- Output:
There are 100 ascending primes, namely: 2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
J
Compare with Descending primes.
_10 ]\ /:~ (#~ 1&p:) 10&#.@I. #: i. 513
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Java
/*
* Ascending primes
*
* Generate and show all primes with strictly ascending decimal digits.
*
*
* Solution
*
* We only consider positive numbers in the range 1 to 123456789. We would
* get 7027260 primes, because there are so many primes smaller than 123456789
* (see also Wolfram Alpha).On the other hand, there are only 511 distinct
* positive integers having their digits arranged in ascending order.
* Therefore, it is better to start with numbers that have properly arranged
* digits and then check if they are prime numbers.The method of generating
* a sequence of such numbers is not indifferent.We want this sequence to be
* monotonically increasing, because then additional sorting of results will
* be unnecessary. It turns out that by using a queue we can easily get the
* desired effect. Additionally, the algorithm then does not use recursion
* (although the program probably does not have to comply with the MISRA
* standard). The problem to be solved is the queue size, the a priori
* assumption that 1000 is good enough, but a bit magical.
*/
package example.rossetacode.ascendingprimes;
import java.util.Arrays;
public class Program implements Runnable {
public static void main(String[] args) {
long t1 = System.nanoTime();
new Program().run();
long t2 = System.nanoTime();
System.out.println(
"total time consumed = " + (t2 - t1) * 1E-6 + " milliseconds");
}
public void run() {
final int MAX_SIZE = 1000;
final int[] queue = new int[MAX_SIZE];
int begin = 0;
int end = 0;
for (int k = 1; k <= 9; k++) {
queue[end++] = k;
}
while (begin < end) {
int n = queue[begin++];
for (int k = n % 10 + 1; k <= 9; k++) {
queue[end++] = n * 10 + k;
}
}
// We can use a parallel stream (and then sort the results)
// to use multiple cores.
//
System.out.println(Arrays.stream(queue).filter(this::isPrime).boxed().toList());
}
private boolean isPrime(int n) {
if (n == 2) {
return true;
}
if (n == 1 || n % 2 == 0) {
return false;
}
int root = (int) Math.sqrt(n);
for (int k = 3; k <= root; k += 2) {
if (n % k == 0) {
return false;
}
}
return true;
}
}
- Output:
[2, 3, 5, 7, 13, 17, 19, 23, 29, 37, 47, 59, 67, 79, 89, 127, 137, 139, 149, 157, 167, 179, 239, 257, 269, 347, 349, 359, 367, 379, 389, 457, 467, 479, 569, 1237, 1249, 1259, 1279, 1289, 1367, 1459, 1489, 1567, 1579, 1789, 2347, 2357, 2389, 2459, 2467, 2579, 2689, 2789, 3457, 3467, 3469, 4567, 4679, 4789, 5689, 12347, 12379, 12457, 12479, 12569, 12589, 12689, 13457, 13469, 13567, 13679, 13789, 15679, 23459, 23567, 23689, 23789, 25679, 34589, 34679, 123457, 123479, 124567, 124679, 125789, 134789, 145679, 234589, 235679, 235789, 245789, 345679, 345689, 1234789, 1235789, 1245689, 1456789, 12356789, 23456789] total time consumed = 4.964799999999999 milliseconds
JavaScript
<!DOCTYPE html>
<html>
<body>
<noscript>
No script, no fun. Turn on Javascript on.
</noscript>
<script>
(()=>{
function isPrime(n) {
if (n == 2)
return true;
if (n == 1 || n % 2 == 0)
return false;
root = Math.sqrt(n)
for (let k = 3; k <= root; k += 2)
if (n % k == 0)
return false;
return true;
}
let queue = [];
let primes = [];
for (let k = 1; k <= 9; k++)
queue.push(k);
while (queue.length != 0)
{
let n = queue.shift();
if (isPrime(n))
primes.push(n);
for (let k = n % 10 + 1; k <= 9; k++)
queue.push(n * 10 + k);
}
document.writeln(primes);
})();
</script>
</body>
</html>
- Output:
2,3,5,7,13,17,19,23,29,37,47,59,67,79,89,127,137,139,149,157,167,179,239,257,269,347,349,359,367,379,389,457,467,479,569,1237,1249,1259,1279,1289,1367,1459,1489,1567,1579,1789,2347,2357,2389,2459,2467,2579,2689,2789,3457,3467,3469,4567,4679,4789,5689,12347,12379,12457,12479,12569,12589,12689,13457,13469,13567,13679,13789,15679,23459,23567,23689,23789,25679,34589,34679,123457,123479,124567,124679,125789,134789,145679,234589,235679,235789,245789,345679,345689,1234789,1235789,1245689,1456789,12356789,23456789
jq
Works with gojq, the Go implementation of jq
See Erdős-primes#jq for a suitable definition of `is_prime` as used here.
# Output: the stream of ascending primes, in order
def ascendingPrimes:
# Generate the stream of primes beginning with the digit .
# and with strictly ascending digits, without regard to order
def generate:
# strings
def g:
. as $first
| tonumber as $n
| select($n <= 9)
| $first,
((range($n + 1;10) | tostring | g) as $x
| $first + $x );
tostring | g | tonumber | select(is_prime);
[range(1;10) | generate] | sort[];
def task:
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
[ascendingPrimes]
| "There are \(length) ascending primes, namely:",
( _nwise(10) | map(lpad(10)) | join(" ") );
task
- Output:
There are 100 ascending primes, namely: 2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Julia
using Combinatorics
using Primes
function ascendingprimes()
return filter(isprime, [evalpoly(10, reverse(x))
for x in powerset([1, 2, 3, 4, 5, 6, 7, 8, 9]) if !isempty(x)])
end
foreach(p -> print(rpad(p[2], 10), p[1] % 10 == 0 ? "\n" : ""), enumerate(ascendingprimes()))
@time ascendingprimes()
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789 0.000150 seconds (2.19 k allocations: 159.078 KiB
Lua
Exactly 511 calls to is_prime
required.
local function is_prime(n)
if n < 2 then return false end
if n % 2 == 0 then return n==2 end
if n % 3 == 0 then return n==3 end
for f = 5, n^0.5, 6 do
if n%f==0 or n%(f+2)==0 then return false end
end
return true
end
local function ascending_primes()
local digits, candidates, primes = {1,2,3,4,5,6,7,8,9}, {0}, {}
for i = 1, #digits do
for j = 1, #candidates do
local value = candidates[j] * 10 + digits[i]
if is_prime(value) then primes[#primes+1] = value end
candidates[#candidates+1] = value
end
end
table.sort(primes)
return primes
end
print(table.concat(ascending_primes(), ", "))
- Output:
2, 3, 5, 7, 13, 17, 19, 23, 29, 37, 47, 59, 67, 79, 89, 127, 137, 139, 149, 157, 167, 179, 239, 257, 269, 347, 349, 359, 367, 379, 389, 457, 467, 479, 569, 1237, 1249, 1259, 1279, 1289, 1367, 1459, 1489, 1567, 1579, 1789, 2347, 2357, 2389, 2459, 2467, 2579, 2689, 2789, 3457, 3467, 3469, 4567, 4679, 4789, 5689, 12347, 12379, 12457, 12479, 12569, 12589, 12689, 13457, 13469, 13567, 13679, 13789, 15679, 23459, 23567, 23689, 23789, 25679, 34589, 34679, 123457, 123479, 124567, 124679, 125789, 134789, 145679, 234589, 235679, 235789, 245789, 345679, 345689, 1234789, 1235789, 1245689, 1456789, 12356789, 23456789
Matlab
queue = 1:9;
j = 1;
while j < length(queue)
n = queue(j);
j = j + 1;
a = n * 10 + mod(n, 10) + 1;
b = n * 10 + 9;
if a <= b
queue = [queue, a:b];
end
end
queue(isprime(queue))
- Output:
ans = Columns 1 through 8 2 3 5 7 13 17 19 23 Columns 9 through 16 29 37 47 59 67 79 89 127 Columns 17 through 24 137 139 149 157 167 179 239 257 Columns 25 through 32 269 347 349 359 367 379 389 457 Columns 33 through 40 467 479 569 1237 1249 1259 1279 1289 Columns 41 through 48 1367 1459 1489 1567 1579 1789 2347 2357 Columns 49 through 56 2389 2459 2467 2579 2689 2789 3457 3467 Columns 57 through 64 3469 4567 4679 4789 5689 12347 12379 12457 Columns 65 through 72 12479 12569 12589 12689 13457 13469 13567 13679 Columns 73 through 80 13789 15679 23459 23567 23689 23789 25679 34589 Columns 81 through 88 34679 123457 123479 124567 124679 125789 134789 145679 Columns 89 through 96 234589 235679 235789 245789 345679 345689 1234789 1235789 Columns 97 through 100 1245689 1456789 12356789 23456789
Mathematica /Wolfram Language
ps=Sort@Select[FromDigits /@ Subsets[Range@9, {1, \[Infinity]}], PrimeQ];
Multicolumn[ps, {Automatic, 6}, Appearance -> "Horizontal"]
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Nim
We build the candidates using a loop by increasing length. Our solution needs only 502 primality tests.
import std/[strutils, sugar]
proc isPrime(n: int): bool =
assert n > 7
if n mod 2 == 0 or n mod 3 == 0: return false
var d = 5
var step = 2
while d * d <= n:
if n mod d == 0:
return false
inc d, step
step = 6 - step
result = true
iterator ascendingPrimes(): int =
# Yield one digit primes.
for n in [2, 3, 5, 7]:
yield n
# Yield other primes by increasing length and in ascending order.
type Item = tuple[val, lastDigit: int]
var items: seq[Item] = collect(for n in 1..9: (n, n))
for ndigits in 2..9:
var nextItems: seq[Item]
for item in items:
for newDigit in (item.lastDigit + 1)..9:
let newVal = 10 * item.val + newDigit
nextItems.add (val: newVal, lastDigit: newDigit)
if newVal.isPrime():
yield newVal
items = move(nextItems)
var rank = 0
for prime in ascendingPrimes():
inc rank
stdout.write ($prime).align(8)
stdout.write if rank mod 10 == 0: '\n' else: ' '
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
OCaml
let is_prime n =
let rec test x =
let q = n / x in x > q || x * q <> n && n mod (x + 2) <> 0 && test (x + 6)
in if n < 5 then n lor 1 = 3 else n land 1 <> 0 && n mod 3 <> 0 && test 5
let ascending_ints =
let rec range10 m d = if d < 10 then m + d :: range10 m (succ d) else [] in
let up n = range10 (n * 10) (succ (n mod 10)) in
let rec next l = if l = [] then [] else l @ next (List.concat_map up l) in
next [0]
let () =
List.filter is_prime ascending_ints
|> List.iter (Printf.printf " %u") |> print_newline
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Pascal
{$mode Delphi}
{ Note that for the program to work properly,
integer variables must be at least 28-bit.
Free Pascal Compiler uses 16-bit integers by default,
so a directive like above is needed. }
program ascendingprimes(output);
const maxsize = 1000;
var
queue, primes : array[1..maxsize] of integer;
b, e, n, k, v : integer;
function isprime(n: integer): boolean;
var
ans : boolean;
root, k : integer;
begin
if n = 2 then
ans := true
else if (n = 1) or (n mod 2 = 0) then
ans := false
else
begin
root := trunc(sqrt(n));
ans := true;
k := 3;
while ans and (k <= root) do
if n mod k = 0 then
ans := false
else
k := k + 2;
end;
isprime := ans
end;
begin
b := 1;
e := 1;
n := 0;
for k := 1 to 9 do
begin
queue[e] := k;
e := e + 1
end;
while b < e do
begin
v := queue[b];
b := b + 1;
if isprime(v) then
begin
n := n + 1;
primes[n] := v
end;
for k := v mod 10 + 1 to 9 do
begin
queue[e] := v * 10 + k;
e := e + 1
end
end;
for k := 1 to n do
write(primes[k], ' ');
writeln()
end.
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Perl
use strict;
use warnings;
use ntheory 'is_prime';
print join( '',
map { sprintf '%10d', $_ }
sort { $a <=> $b }
grep /./ && is_prime $_,
glob join '', map "{$_,}", 1..9
) =~ s/.{50}\K/\n/gr;
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Phix
with javascript_semantics function ascending_primes(sequence res, atom p=0) for d=remainder(p,10)+1 to 9 do integer np = p*10+d if odd(d) and is_prime(np) then res &= np end if res = ascending_primes(res,np) end for return res end function sequence r = apply(true,sprintf,{{"%8d"},sort(ascending_primes({2}))}) printf(1,"There are %,d ascending primes:\n%s\n",{length(r),join_by(r,1,10," ")})
- Output:
There are 100 ascending primes: 2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
powerset
Using a powerset, the basic idea of which was taken from the Factor entry above, here incrementally built, does not need either recursion or a sort, same output
with javascript_semantics function ascending_primes() sequence res = {}, powerset = {0} while length(powerset) do sequence next = {} for i=1 to length(powerset) do for d=remainder(powerset[i],10)+1 to 9 do next &= powerset[i]*10+d end for end for powerset = next res &= filter(powerset,is_prime) end while return res end function sequence r = apply(true,sprintf,{{"%8d"},ascending_primes()}) printf(1,"There are %,d ascending primes:\n%s\n",{length(r),join_by(r,1,10," ")})
By way of explanation, specifically "no sort rqd", if you pp(shorten(powerset,"entries",3))
at the end of each iteration then you get:
{1,2,3, `...`, 7,8,9, ` (9 entries)`} {12,13,14, `...`, 78,79,89, ` (36 entries)`} {123,124,125, `...`, 679,689,789, ` (84 entries)`} {1234,1235,1236, `...`, 5689,5789,6789, ` (126 entries)`} {12345,12346,12347, `...`, 45789,46789,56789, ` (126 entries)`} {123456,123457,123458, `...`, 346789,356789,456789, ` (84 entries)`} {1234567,1234568,1234569, `...`, 2356789,2456789,3456789, ` (36 entries)`} {12345678,12345679,12345689, `...`, 12456789,13456789,23456789, ` (9 entries)`} {123456789} {}
PHP
<?php
function isPrime($n)
{
if ($n == 2)
return true;
if ($n == 1 || $n % 2 == 0)
return false;
$root = intval(sqrt($n));
for ($k = 3; $k <= $root; $k += 2)
if ($n % $k == 0)
return false;
return true;
}
$queue = [];
$primes = [];
$begin = 0;
$end = 0;
for ($k = 1; $k <= 9; $k++)
$queue[$end++] = $k;
while ($begin < $end)
{
$n = $queue[$begin++];
if (isPrime($n))
$primes[] = $n;
for ($k = $n % 10 + 1; $k <= 9; $k++)
$queue[$end++] = $n * 10 + $k;
}
foreach($primes as $p)
echo "$p ";
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Picat
import util.
main =>
DP = [N : S in power_set("123456789"), S != [], N = S.to_int, prime(N)].sort,
foreach({P,I} in zip(DP,1..DP.len))
printf("%9d%s",P,cond(I mod 10 == 0,"\n",""))
end,
nl,
println(len=DP.len)
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789 len = 100
PicoLisp
(de prime? (N)
(or
(= N 2)
(and
(> N 1)
(bit? 1 N)
(for (D 3 T (+ D 2))
(T (> D (sqrt N)) T)
(T (=0 (% N D)) NIL) ) ) ) )
(let
(D 2
L (1 2 2 . (4 2 4 2 4 6 2 6 .))
Lst
(make
(while (>= 23456789 D)
(and
(prime? D)
(apply < (chop D))
(link D) )
(inc 'D (++ L)) ) ) )
(let Fmt (need 10 10)
(while (cut 10 'Lst)
(apply tab @ Fmt) ) ) )
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Prolog
© 2023
isPrime(2).
isPrime(N):-
between(3, inf, N),
N /\ 1 > 0, % odd
M is floor(sqrt(N)) - 1, % reverse 2*I+1
Max is M div 2,
forall(between(1, Max, I), N mod (2*I+1) > 0).
combi(0, _, Num, Num).
combi(N, [X|T], Acc, Num):-
N > 0,
N1 is N - 1,
Acc1 is Acc * 10 + X,
combi(N1, T, Acc1, Num).
combi(N, [_|T], Acc, Num):-
N > 0,
combi(N, T, Acc, Num).
ascPrimes(Num):-
between(1, 9, N),
combi(N, [1, 2, 3, 4, 5, 6, 7, 8, 9], 0, Num),
isPrime(Num).
showList(List):-
findnsols(10, DPrim, (member(DPrim, List), writef('%9r', [DPrim])), _),
nl,
fail.
showList(_).
do:-findall(DPrim, ascPrimes(DPrim), DList),
showList(DList).
- Output:
?- do. 2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789 true.
Python
Recursive solution, with a number generator and sorting of results.
from sympy import isprime
def ascending(x=0):
for y in range(x*10 + (x%10) + 1, x*10 + 10):
yield from ascending(y)
yield(y)
print(sorted(x for x in ascending() if isprime(x)))
- Output:
[2, 3, 5, 7, 13, 17, 19, 23, 29, 37, 47, 59, 67, 79, 89, 127, 137, 139, 149, 157, 167, 179, 239, 257, 269, 347, 349, 359, 367, 379, 389, 457, 467, 479, 569, 1237, 1249, 1259, 1279, 1289, 1367, 1459, 1489, 1567, 1579, 1789, 2347, 2357, 2389, 2459, 2467, 2579, 2689, 2789, 3457, 3467, 3469, 4567, 4679, 4789, 5689, 12347, 12379, 12457, 12479, 12569, 12589, 12689, 13457, 13469, 13567, 13679, 13789, 15679, 23459, 23567, 23689, 23789, 25679, 34589, 34679, 123457, 123479, 124567, 124679, 125789, 134789, 145679, 234589, 235679, 235789, 245789, 345679, 345689, 1234789, 1235789, 1245689, 1456789, 12356789, 23456789]
Queue-based solution that does not need sorting.
def isprime(n):
if n == 2: return True
if n == 1 or n % 2 == 0: return False
root1 = int(n**0.5) + 1;
for k in range(3, root1, 2):
if n % k == 0: return False
return True
queue = [k for k in range(1, 10)]
primes = []
while queue:
n = queue.pop(0)
if isprime(n):
primes.append(n)
queue.extend(n * 10 + k for k in range(n % 10 + 1, 10))
print(primes)
- Output:
[2, 3, 5, 7, 13, 17, 19, 23, 29, 37, 47, 59, 67, 79, 89, 127, 137, 139, 149, 157, 167, 179, 239, 257, 269, 347, 349, 359, 367, 379, 389, 457, 467, 479, 569, 1237, 1249, 1259, 1279, 1289, 1367, 1459, 1489, 1567, 1579, 1789, 2347, 2357, 2389, 2459, 2467, 2579, 2689, 2789, 3457, 3467, 3469, 4567, 4679, 4789, 5689, 12347, 12379, 12457, 12479, 12569, 12589, 12689, 13457, 13469, 13567, 13679, 13789, 15679, 23459, 23567, 23689, 23789, 25679, 34589, 34679, 123457, 123479, 124567, 124679, 125789, 134789, 145679, 234589, 235679, 235789, 245789, 345679, 345689, 1234789, 1235789, 1245689, 1456789, 12356789, 23456789]
Quackery
powerset
is defined at Power set#Quackery, and isprime
is defined at Primality by trial division#Quackery.
[ 0 swap witheach
[ swap 10 * + ] ] is digits->n ( [ --> n )
[]
' [ 1 2 3 4 5 6 7 8 9 ] powerset
witheach
[ digits->n dup isprime
iff join else drop ]
sort echo
- Output:
[ 2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789 ]
Raku
put (flat 2, 3, 5, 7, sort +*, gather (1..8).map: &recurse ).batch(10)».fmt("%8d").join: "\n";
sub recurse ($str) {
.take for ($str X~ (3, 7, 9)).grep: { .is-prime && [<] .comb };
recurse $str × 10 + $_ for $str % 10 ^.. 9;
}
printf "%.3f seconds", now - INIT now;
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789 0.075 seconds
Ring
show("ascending primes", sort(cending_primes(seq(1, 9))))
func show(title, itm)
l = len(itm); ? "" + l + " " + title + ":"
for i = 1 to l
see fmt(itm[i], 9)
if i % 5 = 0 and i < l? "" ok
next : ? ""
func seq(b, e)
res = []; d = e - b
s = d / fabs(d)
for i = b to e step s add(res, i) next
return res
func ispr(n)
if n < 2 return 0 ok
if n & 1 = 0 return n = 2 ok
if n % 3 = 0 return n = 3 ok
l = sqrt(n)
for f = 5 to l
if n % f = 0 or n % (f + 2) = 0 return false ok
next : return 1
func cending_primes(digs)
cand = [0]
pr = []
for i in digs
lcand = cand
for j in lcand
v = j * 10 + i
if ispr(v) add(pr, v) ok
add(cand, v)
next
next
return pr
func fmt(x, l)
res = " " + x
return right(res, l)
- Output:
100 ascending primes: 2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
RPL
Thanks to recursion, we have here a compact and efficient code that generates only ascending odd integers with 9 digits and less, and then check their primality.
RPL code | Comment |
---|---|
≪ IF DUP 5 ≤ THEN { 2 3 5 } SWAP POS ELSE IF DUP 2 MOD NOT THEN 2 ELSE DUP √ CEIL → lim ≪ 3 WHILE DUP2 MOD OVER lim ≤ AND REPEAT 2 + END ≫ END MOD END SIGN ≫ 'PRIM?' STO ≪ SWAP 1 - SWAP 10 * LAST MOD 1 + IF 3 PICK NOT THEN DUP 2 MOD NOT + END + LAST DROP 9 4 PICK - + FOR d IF DUP THEN SWAP OVER d APRIM SWAP ELSE IF d PRIM? THEN SWAP d + SWAP END d 1 + 'd' STO END NEXT DROP ≫ 'APRIM' STO |
PRIM? ( n -- boolean) APRIM ( { } n seed -- { asc } ) n ← n-1 preparing loop from ##u to ##v, where ## = seed, u = last digit of seed + 1 (or + 2 if last recursion and seed odd) ; v = 10 - n if not last recursion generate next digits else store in list if prime skip to next odd value . forget n . |
- Input:
≪ { 2 } 1 9 FOR n n 0 APRIM NEXT ≫ EVAL
- Output:
1: { 2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789 }
Ruby
require 'prime'
digits = [9,8,7,6,5,4,3,2,1]
res = 1.upto(digits.size).flat_map do |n|
digits.combination(n).filter_map do |set|
candidate = set.join.to_i
candidate if candidate.prime?
end.reverse
end
puts res.join(",")
- Output:
2,3,5,7,13,17,19,23,29,37,47,59,67,79,89,127,137,139,149,157,167,179,239,257,269,347,349,359,367,379,389,457,467,479,569,1237,1249,1259,1279,1289,1367,1459,1489,1567,1579,1789,2347,2357,2389,2459,2467,2579,2689,2789,3457,3467,3469,4567,4679,4789,5689,12347,12379,12457,12479,12569,12589,12689,13457,13469,13567,13679,13789,15679,23459,23567,23689,23789,25679,34589,34679,123457,123479,124567,124679,125789,134789,145679,234589,235679,235789,245789,345679,345689,1234789,1235789,1245689,1456789,12356789,23456789
Sidef
func primes_with_ascending_digits(base = 10) {
var list = []
var digits = @(1..^base -> flip)
var end_digits = digits.grep { .is_coprime(base) }
list << digits.grep { .is_prime && !.is_coprime(base) }...
for k in (0 .. digits.end) {
digits.combinations(k, {|*a|
var v = a.digits2num(base)
end_digits.each {|d|
var n = (v*base + d)
next if ((n >= base) && (a[0] >= d))
list << n if (n.is_prime)
}
})
}
list.sort
}
var arr = primes_with_ascending_digits()
say "There are #{arr.len} ascending primes.\n"
arr.each_slice(10, {|*a|
say a.map { '%8s' % _ }.join(' ')
})
- Output:
There are 100 ascending primes. 2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
SparForte
#!/usr/local/bin/spar
pragma annotate( summary, "primes_asc" );
pragma annotate( description, "Generate and show all primes with strictly ascending decimal digits" );
pragma annotate( description, "Translation of Pascal" );
pragma annotate( see_also, "https://rosettacode.org/wiki/Ascending_primes" );
pragma annotate( author, "Ken O. Burtch" );
pragma software_model( nonstandard );
pragma restriction( no_external_commands );
procedure primes_asc is
maxsize : constant natural := 1000;
queue : array(1..maxsize) of natural;
primes: array(1..maxsize) of natural;
b : natural;
e : natural;
n : natural;
v : natural;
function is_prime(num: integer) return boolean is
found : boolean;
num_root : natural;
k : natural;
begin
if num = 2 then
found;
elsif (num = 1) or (num mod 2 = 0) then
found := false;
else
num_root := numerics.truncation(numerics.sqrt(num));
found;
k := 3;
while found and (k <= num_root) loop
if num mod k = 0 then
found := false;
else
k := @ + 2;
end if;
end loop;
end if;
return found;
end is_prime;
begin
b := 1;
e := 1;
n := 0;
for k in 1..9 loop
queue(e) := k;
e := e + 1;
end loop;
while b < e loop
v := queue(b);
b := @ + 1;
if is_prime(v) then
n := @ + 1;
primes(n) := v;
end if;
for k in v mod 10 + 1..9 loop
queue(e) := v * 10 + k;
e := @ + 1;
end loop;
end loop;
for k in 1..n loop
put(primes(k), "ZZZZZZZZ9");
if k mod 8 = 0 then
new_line;
end if;
end loop;
new_line;
end primes_asc;
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Visual Basic .NET
Module AscendingPrimes
Function isPrime(n As Integer)
n = Math.Abs(n)
If n = 2 Then
Return True
End If
If n = 1 Or n Mod 2 = 0 Then
Return False
End If
Dim root As Integer = Math.Sqrt(n)
For k = 3 To root Step 2
If n Mod k = 0 Then
Return False
End If
Next
Return True
End Function
Sub Main()
Dim queue As Queue(Of Integer) = New Queue(Of Integer)
Dim primes As List(Of Integer) = New List(Of Integer)
For k = 1 To 9
queue.Enqueue(k)
Next
While queue.Count > 0
Dim n As Integer = queue.Dequeue()
If (isPrime(n)) Then
primes.Add(n)
End If
For k = n Mod 10 + 1 To 9
queue.Enqueue(n * 10 + k)
Next
End While
For Each p As Integer In primes
Console.Write(p)
Console.Write(" ")
Next
Console.WriteLine()
End Sub
End Module
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
V (Vlang)
fn is_prime(n int) bool {
if n < 2 {
return false
} else if n%2 == 0 {
return n == 2
} else if n%3 == 0 {
return n == 3
} else {
mut d := 5
for d*d <= n {
if n%d == 0 {
return false
}
d += 2
if n%d == 0 {
return false
}
d += 4
}
return true
}
}
fn generate(first int, cand int, digits int, mut asc map[int]bool) {
if digits == 0 {
if is_prime(cand) {
asc[cand] = true
}
return
}
for i in first..10 {
next := cand*10 + i
generate(i+1, next, digits-1, mut asc)
}
}
fn main() {
mut asc_primes_set := map[int]bool{} // avoids duplicates
for digits in 1..10 {
generate(1, 0, digits, mut asc_primes_set)
}
le := asc_primes_set.keys().len
mut asc_primes := []int{len: le}
mut i := 0
for k,_ in asc_primes_set {
asc_primes[i] = k
i++
}
asc_primes.sort()
println("There are $le ascending primes, namely:")
for q in 0..le {
print("${asc_primes[q]:8} ")
if (q+1)%10 == 0 {
println('')
}
}
}
- Output:
There are 100 ascending primes, namely: 2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Wren
Version 1 (Sieve)
Although they use a lot of memory, sieves usually produce good results in Wren and here we only need to sieve for primes up to 3456789 as there are just 9 possible candidates with 8 digits and 1 possible candidate with 9 digits which we can test for primality individually. The following runs in around 0.43 seconds.
import "./math" for Int
import "./fmt" for Fmt
var isAscending = Fn.new { |n|
if (n < 10) return true
var digits = Int.digits(n)
for (i in 1...digits.count) {
if (digits[i] <= digits[i-1]) return false
}
return true
}
var higherPrimes = []
var candidates = [
12345678, 12345679, 12345689, 12345789, 12346789,
12356789, 12456789, 13456789, 23456789, 123456789
]
for (cand in candidates) if (Int.isPrime(cand)) higherPrimes.add(cand)
var primes = Int.primeSieve(3456789)
var ascPrimes = []
for (p in primes) if (isAscending.call(p)) ascPrimes.add(p)
ascPrimes.addAll(higherPrimes)
System.print("There are %(ascPrimes.count) ascending primes, namely:")
Fmt.tprint("$8d", ascPrimes, 10)
- Output:
There are 100 ascending primes, namely: 2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
Version 2 (Generator)
Here we generate all possible positive integers with ascending non-zero digits and filter out those that are prime.
Much quicker than the 'sieve' approach at 0.013 seconds. I also tried using a powerset but that was slightly slower at 0.015 seconds.
import "./set" for Set
import "./math" for Int
import "./fmt" for Fmt
var ascPrimes = Set.new() // avoids duplicates
var generate // recursive function
generate = Fn.new { |first, cand, digits|
if (digits == 0) {
if (Int.isPrime(cand)) ascPrimes.add(cand)
return
}
var i = first
while (i <= 9) {
var next = cand * 10 + i
generate.call(i + 1, next, digits - 1)
i = i + 1
}
}
for (digits in 1..9) generate.call(1, 0, digits)
ascPrimes = ascPrimes.toList
ascPrimes.sort()
System.print("There are %(ascPrimes.count) ascending primes, namely:")
Fmt.tprint("$8d", ascPrimes, 10)
- Output:
Same as before.
XPL0
Brute force solution: 4.3 seconds on Pi4.
func IsPrime(N); \Return 'true' if N is prime
int N, I;
[if N <= 2 then return N = 2;
if (N&1) = 0 then \even >2\ return false;
for I:= 3 to sqrt(N) do
[if rem(N/I) = 0 then return false;
I:= I+1;
];
return true;
];
func Ascending(N); \Return 'true' if digits are ascending
int N, D;
[N:= N/10;
D:= rem(0);
while N do
[N:= N/10;
if rem(0) >= D then return false;
D:= rem(0);
];
return true;
];
int Cnt, N;
[Cnt:= 0;
Format(9, 0);
for N:= 2 to 123_456_789 do
if Ascending(N) then
if IsPrime(N) then
[RlOut(0, float(N));
Cnt:= Cnt+1;
if rem(Cnt/10) = 0 then CrLf(0);
];
]
- Output:
2 3 5 7 13 17 19 23 29 37 47 59 67 79 89 127 137 139 149 157 167 179 239 257 269 347 349 359 367 379 389 457 467 479 569 1237 1249 1259 1279 1289 1367 1459 1489 1567 1579 1789 2347 2357 2389 2459 2467 2579 2689 2789 3457 3467 3469 4567 4679 4789 5689 12347 12379 12457 12479 12569 12589 12689 13457 13469 13567 13679 13789 15679 23459 23567 23689 23789 25679 34589 34679 123457 123479 124567 124679 125789 134789 145679 234589 235679 235789 245789 345679 345689 1234789 1235789 1245689 1456789 12356789 23456789
powerset
Aaah! Power set, from Factor. Runs in less than 1 millisecond. A better way of measuring duration than using Linux's time utility gave a more credible 35 milliseconds.
include xpllib; \provides IsPrime and Sort
int I, N, Mask, Digit, A(512), Cnt;
[for I:= 0 to 511 do
[N:= 0; Mask:= I; Digit:= 1;
while Mask do
[if Mask&1 then
N:= N*10 + Digit;
Mask:= Mask>>1;
Digit:= Digit+1;
];
A(I):= N;
];
Sort(A, 512);
Cnt:= 0;
Format(9, 0);
for I:= 1 to 511 do \skip empty set
[N:= A(I);
if IsPrime(N) then
[RlOut(0, float(N));
Cnt:= Cnt+1;
if rem(Cnt/10) = 0 then CrLf(0);
];
];
]
- Output:
Same as before.
- Programming Tasks
- Solutions by Programming Task
- 11l
- ALGOL 68
- ALGOL 68-primes
- ALGOL 68-rows
- ALGOL W
- Arturo
- AWK
- C
- C++
- C sharp
- Delphi
- Windows,SysUtils,StdCtrls
- Dylan
- EasyLang
- F Sharp
- Factor
- Forth
- Fortran
- FreeBASIC
- FutureBasic
- Go
- Go-rcu
- J
- Java
- JavaScript
- Jq
- Julia
- Lua
- Matlab
- Mathematica
- Wolfram Language
- Nim
- OCaml
- Pascal
- Perl
- Ntheory
- Phix
- PHP
- Picat
- PicoLisp
- Prolog
- Python
- Quackery
- Raku
- Ring
- RPL
- Ruby
- Sidef
- SparForte
- Visual Basic .NET
- V (Vlang)
- Wren
- Wren-math
- Wren-seq
- Wren-fmt
- Wren-set
- XPL0