Honaker primes
You are encouraged to solve this task according to the task description, using any language you may know.
A Honaker prime is a prime whose digital sum is equal to the digital sum of its position in the sequence of primes.
- E.G.
If you look at the sequence of positive integer primes the first prime is 2 at position 1. The digital sums of 2 and 1 are not equal, so 2 is not a Honaker prime. The prime at position 32: 131 is a Honaker prime. The digital sum of 32 (5) is equal to the digital sum of 131 (5).
- Task
- Write a routine (procedure, function, filter, whatever it may be called in your language) to identify Honaker primes.
- Use that routine to find the first fifty Honaker primes and display the position and value for each.
- Stretch
- Find and display the ten thousandth Honaker prime (position and value).
- See also
11l
F primes_up_to_limit(Int limit)
[Int] r
I limit >= 2
r.append(2)
V isprime = [1B] * ((limit - 1) I/ 2)
V sieveend = Int(sqrt(limit))
L(i) 0 .< isprime.len
I isprime[i]
Int p = i * 2 + 3
r.append(p)
I i <= sieveend
L(j) ((p * p - 3) >> 1 .< isprime.len).step(p)
isprime[j] = 0B
R r
F digitsum(num)
‘ Digit sum of an integer (base 10) ’
R sum(String(num).map(c -> Int(c)))
F generate_honaker(limit = 5'000'000)
‘ Generate the sequence of Honaker primes with their sequence and primepi values ’
V honaker = enumerate(primes_up_to_limit(limit)).filter((i, p) -> digitsum(p) == digitsum(i + 1)).map((i, p) -> (i + 1, p))
R enumerate(honaker).map((hcount, pp) -> (hcount + 1, pp[0], pp[1]))
print(‘First 50 Honaker primes:’)
L(p) generate_honaker()
I p[0] < 51
print(f:‘{String(p):<16}’, end' I p[0] % 5 == 0 {"\n"} E ‘’)
E I p[0] == 10'000
print(f:"\nThe 10,000th Honaker prime is the {commatize(p[1])}th one, which is {commatize(p[2])}.")
L.break
- Output:
First 50 Honaker primes: (1, 32, 131) (2, 56, 263) (3, 88, 457) (4, 175, 1039) (5, 176, 1049) (6, 182, 1091) (7, 212, 1301) (8, 218, 1361) (9, 227, 1433) (10, 248, 1571) (11, 293, 1913) (12, 295, 1933) (13, 323, 2141) (14, 331, 2221) (15, 338, 2273) (16, 362, 2441) (17, 377, 2591) (18, 386, 2663) (19, 394, 2707) (20, 397, 2719) (21, 398, 2729) (22, 409, 2803) (23, 439, 3067) (24, 446, 3137) (25, 457, 3229) (26, 481, 3433) (27, 499, 3559) (28, 508, 3631) (29, 563, 4091) (30, 571, 4153) (31, 595, 4357) (32, 599, 4397) (33, 635, 4703) (34, 637, 4723) (35, 655, 4903) (36, 671, 5009) (37, 728, 5507) (38, 751, 5701) (39, 752, 5711) (40, 755, 5741) (41, 761, 5801) (42, 767, 5843) (43, 779, 5927) (44, 820, 6301) (45, 821, 6311) (46, 826, 6343) (47, 827, 6353) (48, 847, 6553) (49, 848, 6563) (50, 857, 6653) The 10,000th Honaker prime is the 286,069th one, which is 4,043,749.
ABC
HOW TO RETURN primes.up.to n:
PUT {2..n} IN primes
FOR p IN {2..floor root n}:
PUT p*p IN c
WHILE c <= n:
IF c in primes: REMOVE c FROM primes
PUT c+p IN c
RETURN primes
HOW TO RETURN digit.sum n:
PUT 0 IN sum
WHILE n>0:
PUT sum + (n mod 10) IN sum
PUT floor (n/10) IN n
RETURN sum
HOW TO RETURN honakers.from primes:
PUT 0 IN index
PUT {} IN honakers
FOR prime IN primes:
PUT index+1 IN index
IF digit.sum index = digit.sum (primes item index):
INSERT index IN honakers
RETURN honakers
PUT primes.up.to 4100000 IN primes
PUT honakers.from primes IN honakers
WRITE "First 50 Honaker primes:"/
FOR index IN {1..50}:
PUT honakers item index IN hon.idx
PUT primes item hon.idx IN hon.prime
WRITE hon.prime>>4, " @ ", hon.idx>>3, " "
IF index mod 5 = 0: WRITE/
WRITE/
WRITE "The 10,000th Honaker prime is: "
PUT honakers item 10000 IN index
WRITE (primes item index), "@", index/
QUIT
- Output:
First 50 Honaker primes: 131 @ 32 263 @ 56 457 @ 88 1039 @ 175 1049 @ 176 1091 @ 182 1301 @ 212 1361 @ 218 1433 @ 227 1571 @ 248 1913 @ 293 1933 @ 295 2141 @ 323 2221 @ 331 2273 @ 338 2441 @ 362 2591 @ 377 2663 @ 386 2707 @ 394 2719 @ 397 2729 @ 398 2803 @ 409 3067 @ 439 3137 @ 446 3229 @ 457 3433 @ 481 3559 @ 499 3631 @ 508 4091 @ 563 4153 @ 571 4357 @ 595 4397 @ 599 4703 @ 635 4723 @ 637 4903 @ 655 5009 @ 671 5507 @ 728 5701 @ 751 5711 @ 752 5741 @ 755 5801 @ 761 5843 @ 767 5927 @ 779 6301 @ 820 6311 @ 821 6343 @ 826 6353 @ 827 6553 @ 847 6563 @ 848 6653 @ 857 The 10,000th Honaker prime is: 4043749 @ 286069
ALGOL 68
After experimenting on TIO.RUN, it seems that with ALGOL 68G, calculating the digit sums the "traditional" way is slightly faster than generating a table of digit sums. In the sample below, the digit sum is calculated by first converting the number to a string - this is faster in ALGOL 68G than using MOD and division. For other implementations of Algol 68, using MOD and division may be faster.
BEGIN # find some Honaker primes: primes whose digit-sum equals the #
# digit-sum of the index of the prime in the list of primes #
# e.g.: prime 32 (dsum 5) = 131 (dsum 5) #
INT h count := 0; # number of Honaker primes found so far #
# sieve the primes up to 5 000 000, hopefully enough... #
[ 0 : 5 000 000 ]BOOL prime;
prime[ 0 ] := prime[ 1 ] := FALSE;
prime[ 2 ] := TRUE;
FOR i FROM 3 BY 2 TO UPB prime DO prime[ i ] := TRUE OD;
FOR i FROM 4 BY 2 TO UPB prime DO prime[ i ] := FALSE OD;
FOR i FROM 3 BY 2 TO ENTIER sqrt( UPB prime ) DO
IF prime[ i ] THEN
FOR s FROM i * i BY i + i TO UPB prime DO prime[ s ] := FALSE OD
FI
OD;
# returns the digit sum of n #
PROC dsum = ( INT n )INT:
BEGIN
INT sum := 0;
STRING s = whole( n, 0 );
FOR s pos FROM LWB s TO UPB s DO
sum +:= ABS s[ s pos ] - ABS "0"
OD;
sum
END # digit sum # ;
# attempt to find the Honaker primes #
INT p count := 0;
FOR n FROM LWB prime TO UPB prime DO
IF prime[ n ] THEN
# have the p count'th prime #
p count +:= 1;
IF dsum( n ) = dsum( p count ) THEN
# have a Honaker prime #
IF ( h count +:= 1 ) < 51 THEN
print( ( "(", whole( h count, -2 )
, ": ", whole( p count, -3 )
, " ", whole( n, -4 )
, ") "
)
);
IF h count MOD 5 = 0 THEN print( ( newline ) ) FI
ELIF h count = 10 000 THEN
print( ( newline
, "Honaker prime ", whole( h count, 0 )
, " is prime ", whole( p count, 0 )
, ": ", whole( n, 0 )
, newline
)
)
FI
FI
FI
OD
END
- Output:
( 1: 32 131) ( 2: 56 263) ( 3: 88 457) ( 4: 175 1039) ( 5: 176 1049) ( 6: 182 1091) ( 7: 212 1301) ( 8: 218 1361) ( 9: 227 1433) (10: 248 1571) (11: 293 1913) (12: 295 1933) (13: 323 2141) (14: 331 2221) (15: 338 2273) (16: 362 2441) (17: 377 2591) (18: 386 2663) (19: 394 2707) (20: 397 2719) (21: 398 2729) (22: 409 2803) (23: 439 3067) (24: 446 3137) (25: 457 3229) (26: 481 3433) (27: 499 3559) (28: 508 3631) (29: 563 4091) (30: 571 4153) (31: 595 4357) (32: 599 4397) (33: 635 4703) (34: 637 4723) (35: 655 4903) (36: 671 5009) (37: 728 5507) (38: 751 5701) (39: 752 5711) (40: 755 5741) (41: 761 5801) (42: 767 5843) (43: 779 5927) (44: 820 6301) (45: 821 6311) (46: 826 6343) (47: 827 6353) (48: 847 6553) (49: 848 6563) (50: 857 6653) Honaker prime 10000 is prime 286069: 4043749
Arturo
honaker?: function [n, pos]->
equal? sum digits n sum digits pos
idx: 0
found: 0
honakers: []
loop 2..∞ 'n [
if prime? n [
idx: idx + 1
if honaker? n idx [
found: found + 1
'honakers ++ @[@[found, idx, n]]
]
]
if found = 50 -> break
]
loop split.every: 5 honakers 'x ->
print map x 's -> pad as.code s 14
- Output:
[1 32 131] [2 56 263] [3 88 457] [4 175 1039] [5 176 1049] [6 182 1091] [7 212 1301] [8 218 1361] [9 227 1433] [10 248 1571] [11 293 1913] [12 295 1933] [13 323 2141] [14 331 2221] [15 338 2273] [16 362 2441] [17 377 2591] [18 386 2663] [19 394 2707] [20 397 2719] [21 398 2729] [22 409 2803] [23 439 3067] [24 446 3137] [25 457 3229] [26 481 3433] [27 499 3559] [28 508 3631] [29 563 4091] [30 571 4153] [31 595 4357] [32 599 4397] [33 635 4703] [34 637 4723] [35 655 4903] [36 671 5009] [37 728 5507] [38 751 5701] [39 752 5711] [40 755 5741] [41 761 5801] [42 767 5843] [43 779 5927] [44 820 6301] [45 821 6311] [46 826 6343] [47 827 6353] [48 847 6553] [49 848 6563] [50 857 6653]
BASIC
10 DEFINT A-Z
20 DIM P(7000)
30 FOR P=2 TO SQR(7000)
40 FOR C=P*P TO 7000 STEP P
50 P(C)=-1
60 NEXT C,P
65 N=1: I=0
70 FOR H=1 TO 50
80 N=N+1: IF P(N) THEN 80 ELSE Z=N: GOSUB 200: S=Y
90 I=I+1: Z=I: GOSUB 200: IF S<>Y THEN 80
100 PRINT N;"@";I,
110 NEXT H
120 END
200 Y=0
210 IF Z=0 THEN RETURN
220 Y=Y+Z MOD 10
230 Z=Z\10
240 GOTO 210
- Output:
131 @ 32 263 @ 56 457 @ 88 1039 @ 175 1049 @ 176 1091 @ 182 1301 @ 212 1361 @ 218 1433 @ 227 1571 @ 248 1913 @ 293 1933 @ 295 2141 @ 323 2221 @ 331 2273 @ 338 2441 @ 362 2591 @ 377 2663 @ 386 2707 @ 394 2719 @ 397 2729 @ 398 2803 @ 409 3067 @ 439 3137 @ 446 3229 @ 457 3433 @ 481 3559 @ 499 3631 @ 508 4091 @ 563 4153 @ 571 4357 @ 595 4397 @ 599 4703 @ 635 4723 @ 637 4903 @ 655 5009 @ 671 5507 @ 728 5701 @ 751 5711 @ 752 5741 @ 755 5801 @ 761 5843 @ 767 5927 @ 779 6301 @ 820 6311 @ 821 6343 @ 826 6353 @ 827 6553 @ 847 6563 @ 848 6653 @ 857
C
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <locale.h>
#define LIMIT 5000000
typedef struct {
int x;
int y;
} pair;
int *primeSieve(int limit, int *length) {
int i, p, *primes;
int j, pc = 0;
limit++;
// True denotes composite, false denotes prime.
bool *c = calloc(limit, sizeof(bool)); // all false by default
c[0] = true;
c[1] = true;
for (i = 4; i < limit; i += 2) c[i] = true;
p = 3; // Start from 3.
while (true) {
int p2 = p * p;
if (p2 >= limit) break;
for (i = p2; i < limit; i += 2 * p) c[i] = true;
while (true) {
p += 2;
if (!c[p]) break;
}
}
for (i = 0; i < limit; ++i) {
if (!c[i]) ++pc;
}
primes = (int *)malloc(pc * sizeof(int));
for (i = 0, j = 0; i < limit; ++i) {
if (!c[i]) primes[j++] = i;
}
free(c);
*length = pc;
return primes;
}
int digitSum(int n) {
int sum = 0;
while (n > 0) {
sum += n % 10;
n /= 10;
}
return sum;
}
int main() {
int i, count, length, hc = 0;
int *primes = (int *)primeSieve(LIMIT, &length);
pair h[50], h10000;
for (i = 1, count = 0; count < 10000; ++i) {
if (digitSum(i) == digitSum(primes[i-1])) {
++count;
if (count <= 50) {
h[hc++] = (pair){i, primes[i-1]};
} else if (count == 10000) {
h10000.x = i;
h10000.y = primes[i-1];
}
}
}
setlocale(LC_NUMERIC, "");
printf("The first 50 Honaker primes (index, prime):\n");
for (i = 0; i < 50; ++i) {
printf("(%3d, %'5d) ", h[i].x, h[i].y);
if (!((i+1)%5)) printf("\n");
}
printf("\nand the 10,000th: (%'7d, %'9d)\n", h10000.x, h10000.y);
free(primes);
return 0;
}
- Output:
The first 50 Honaker primes (index, prime): ( 32, 131) ( 56, 263) ( 88, 457) (175, 1,039) (176, 1,049) (182, 1,091) (212, 1,301) (218, 1,361) (227, 1,433) (248, 1,571) (293, 1,913) (295, 1,933) (323, 2,141) (331, 2,221) (338, 2,273) (362, 2,441) (377, 2,591) (386, 2,663) (394, 2,707) (397, 2,719) (398, 2,729) (409, 2,803) (439, 3,067) (446, 3,137) (457, 3,229) (481, 3,433) (499, 3,559) (508, 3,631) (563, 4,091) (571, 4,153) (595, 4,357) (599, 4,397) (635, 4,703) (637, 4,723) (655, 4,903) (671, 5,009) (728, 5,507) (751, 5,701) (752, 5,711) (755, 5,741) (761, 5,801) (767, 5,843) (779, 5,927) (820, 6,301) (821, 6,311) (826, 6,343) (827, 6,353) (847, 6,553) (848, 6,563) (857, 6,653) and the 10,000th: (286,069, 4,043,749)
C#
using System;
using System.Collections.Generic;
using System.Linq;
public class HonakerPrimes
{
private static List<int> primes = new List<int>();
private static int honakerIndex = 0;
private static int primeIndex = 0;
public static void Main(string[] args)
{
SievePrimes(5_000_000);
Console.WriteLine("The first 50 Honaker primes (honaker index: prime index, prime):");
for (int i = 1; i <= 50; i++)
{
Console.Write($"{NextHonakerPrime()}{(i % 5 == 0 ? "\n" : " ")}");
}
for (int i = 51; i < 10_000; i++)
{
NextHonakerPrime();
}
Console.WriteLine();
Console.WriteLine($"The 10,000th Honaker prime is: {NextHonakerPrime()}");
}
private static HonakerPrime NextHonakerPrime()
{
honakerIndex++;
primeIndex++;
while (DigitalSum(primeIndex) != DigitalSum(primes[primeIndex - 1]))
{
primeIndex++;
}
return new HonakerPrime(honakerIndex, primeIndex, primes[primeIndex - 1]);
}
private static int DigitalSum(int number)
{
return number.ToString().Select(c => c - '0').Sum();
}
private static void SievePrimes(int limit)
{
primes.Add(2);
var halfLimit = (limit + 1) / 2;
bool[] composite = new bool[halfLimit];
for (int i = 1, p = 3; i < halfLimit; p += 2, i++)
{
if (!composite[i])
{
primes.Add(p);
for (int a = i + p; a < halfLimit; a += p)
{
composite[a] = true;
}
}
}
}
private class HonakerPrime
{
public int HonakerIndex { get; }
public int PrimeIndex { get; }
public int Prime { get; }
public HonakerPrime(int honakerIndex, int primeIndex, int prime)
{
HonakerIndex = honakerIndex;
PrimeIndex = primeIndex;
Prime = prime;
}
public override string ToString() => $"({HonakerIndex}: {PrimeIndex}, {Prime})";
}
}
- Output:
The first 50 Honaker primes (honaker index: prime index, prime): (1: 32, 131) (2: 56, 263) (3: 88, 457) (4: 175, 1039) (5: 176, 1049) (6: 182, 1091) (7: 212, 1301) (8: 218, 1361) (9: 227, 1433) (10: 248, 1571) (11: 293, 1913) (12: 295, 1933) (13: 323, 2141) (14: 331, 2221) (15: 338, 2273) (16: 362, 2441) (17: 377, 2591) (18: 386, 2663) (19: 394, 2707) (20: 397, 2719) (21: 398, 2729) (22: 409, 2803) (23: 439, 3067) (24: 446, 3137) (25: 457, 3229) (26: 481, 3433) (27: 499, 3559) (28: 508, 3631) (29: 563, 4091) (30: 571, 4153) (31: 595, 4357) (32: 599, 4397) (33: 635, 4703) (34: 637, 4723) (35: 655, 4903) (36: 671, 5009) (37: 728, 5507) (38: 751, 5701) (39: 752, 5711) (40: 755, 5741) (41: 761, 5801) (42: 767, 5843) (43: 779, 5927) (44: 820, 6301) (45: 821, 6311) (46: 826, 6343) (47: 827, 6353) (48: 847, 6553) (49: 848, 6563) (50: 857, 6653) The 10,000th Honaker prime is: (10000: 286069, 4043749)
C++
#include <iomanip>
#include <iostream>
#include <sstream>
#include <utility>
#include <primesieve.hpp>
uint64_t digit_sum(uint64_t n) {
uint64_t sum = 0;
for (; n > 0; n /= 10)
sum += n % 10;
return sum;
}
class honaker_prime_generator {
public:
std::pair<uint64_t, uint64_t> next();
private:
primesieve::iterator pi_;
uint64_t index_ = 0;
};
std::pair<uint64_t, uint64_t> honaker_prime_generator::next() {
for (;;) {
uint64_t prime = pi_.next_prime();
++index_;
if (digit_sum(index_) == digit_sum(prime))
return std::make_pair(index_, prime);
}
}
std::ostream& operator<<(std::ostream& os,
const std::pair<uint64_t, uint64_t>& p) {
std::ostringstream str;
str << '(' << p.first << ", " << p.second << ')';
return os << str.str();
}
int main() {
honaker_prime_generator hpg;
std::cout << "First 50 Honaker primes (index, prime):\n";
int i = 1;
for (; i <= 50; ++i)
std::cout << std::setw(11) << hpg.next() << (i % 5 == 0 ? '\n' : ' ');
for (; i < 10000; ++i)
hpg.next();
std::cout << "\nTen thousandth: " << hpg.next() << '\n';
}
- Output:
First 50 Honaker primes (index, prime): (32, 131) (56, 263) (88, 457) (175, 1039) (176, 1049) (182, 1091) (212, 1301) (218, 1361) (227, 1433) (248, 1571) (293, 1913) (295, 1933) (323, 2141) (331, 2221) (338, 2273) (362, 2441) (377, 2591) (386, 2663) (394, 2707) (397, 2719) (398, 2729) (409, 2803) (439, 3067) (446, 3137) (457, 3229) (481, 3433) (499, 3559) (508, 3631) (563, 4091) (571, 4153) (595, 4357) (599, 4397) (635, 4703) (637, 4723) (655, 4903) (671, 5009) (728, 5507) (751, 5701) (752, 5711) (755, 5741) (761, 5801) (767, 5843) (779, 5927) (820, 6301) (821, 6311) (826, 6343) (827, 6353) (847, 6553) (848, 6563) (857, 6653) Ten thousandth: (286069, 4043749)
Without external libraries
#include <cstdint>
#include <iomanip>
#include <iostream>
#include <string>
#include <vector>
uint32_t honaker_index = 0;
uint32_t prime_index = 0;
std::vector<uint32_t> primes;
struct HonakerPrime {
uint32_t honaker_index, prime_index, prime;
std::string to_string() {
return "(" + std::to_string(honaker_index) + ": "
+ std::to_string(prime_index) + ", "
+ std::to_string(prime) + ")";
}
};
void sieve_primes(const uint32_t& limit) {
primes.emplace_back(2);
const uint32_t half_limit = ( limit + 1 ) / 2;
std::vector<bool> composite(half_limit);
for ( uint32_t i = 1, p = 3; i < half_limit; p += 2, ++i ) {
if ( ! composite[i] ) {
primes.emplace_back(p);
for ( uint32_t a = i + p; a < half_limit; a += p ) {
composite[a] = true;
}
}
}
}
uint32_t digital_sum(uint32_t number) {
uint32_t sum = 0;
while ( number > 0 ) {
sum += number % 10;
number /= 10;
}
return sum;
}
HonakerPrime nextHonakerPrime() {
honaker_index++;
prime_index++;
while ( digital_sum(prime_index) != digital_sum(primes[prime_index - 1]) ) {
prime_index++;
}
return HonakerPrime(honaker_index, prime_index, primes[prime_index - 1]);
}
int main() {
sieve_primes(5'000'000);
std::cout << "The first 50 Honaker primes (honaker index: prime index, prime):" << std::endl;
for ( uint32_t i = 1; i <= 50; ++i ) {
std::cout << std::setw(17) << nextHonakerPrime().to_string() << ( i % 5 == 0 ? "\n" : " " );
}
for ( uint32_t i = 51; i < 10'000; ++i ) {
nextHonakerPrime();
}
std::cout << "\n" << "The 10,000th Honaker prime is: " + nextHonakerPrime().to_string() << std::endl;
}
- Output:
The first 50 Honaker primes (honaker index: prime index, prime): (1: 32, 131) (2: 56, 263) (3: 88, 457) (4: 175, 1039) (5: 176, 1049) (6: 182, 1091) (7: 212, 1301) (8: 218, 1361) (9: 227, 1433) (10: 248, 1571) (11: 293, 1913) (12: 295, 1933) (13: 323, 2141) (14: 331, 2221) (15: 338, 2273) (16: 362, 2441) (17: 377, 2591) (18: 386, 2663) (19: 394, 2707) (20: 397, 2719) (21: 398, 2729) (22: 409, 2803) (23: 439, 3067) (24: 446, 3137) (25: 457, 3229) (26: 481, 3433) (27: 499, 3559) (28: 508, 3631) (29: 563, 4091) (30: 571, 4153) (31: 595, 4357) (32: 599, 4397) (33: 635, 4703) (34: 637, 4723) (35: 655, 4903) (36: 671, 5009) (37: 728, 5507) (38: 751, 5701) (39: 752, 5711) (40: 755, 5741) (41: 761, 5801) (42: 767, 5843) (43: 779, 5927) (44: 820, 6301) (45: 821, 6311) (46: 826, 6343) (47: 827, 6353) (48: 847, 6553) (49: 848, 6563) (50: 857, 6653) The 10,000th Honaker prime is: (10000: 286069, 4043749)
CLU
isqrt = proc (s: int) returns (int)
x0: int := s/2
if x0=0 then return(s) end
x1: int := (x0 + s/x0)/2
while x1<x0 do
x0, x1 := x1, (x1 + s/x1)/2
end
return(x0)
end isqrt
primes = iter (max: int) yields (int)
prime: array[bool] := array[bool]$fill(2, max, true)
p: int
for p in int$from_to(2, isqrt(max)) do
if ~prime[p] then continue end
yield(p)
for c: int in int$from_to_by(p*p, max, p) do
prime[c] := false
end
end
for p in int$from_to(p+1, max) do
if prime[p] then yield(p) end
end
end primes
digit_sum = proc (n: int) returns (int)
sum: int := 0
while n>0 do
sum := sum + n//10
n := n/10
end
return(sum)
end digit_sum
honakers = iter (max: int) yields (int, int)
i: int := 0
for p: int in primes(max) do
i := i+1
if digit_sum(i) = digit_sum(p) then yield (i,p) end
end
end honakers
start_up = proc ()
po: stream := stream$primary_output()
stream$putl(po, "First 50 Honaker primes:")
n: int := 0
for i, p: int in honakers(4100000) do
n := n+1
if n<=50 then
stream$putright(po, int$unparse(p), 4)
stream$puts(po, " @ ")
stream$putright(po, int$unparse(i), 3)
stream$puts(po, " ")
if n//5 = 0 then stream$putl(po, "") end
elseif n=10000 then
stream$putl(po, "\nThe 10000th Honaker prime: "
|| int$unparse(p) || " @ " || int$unparse(i))
break
end
end
end start_up
- Output:
First 50 Honaker primes: 131 @ 32 263 @ 56 457 @ 88 1039 @ 175 1049 @ 176 1091 @ 182 1301 @ 212 1361 @ 218 1433 @ 227 1571 @ 248 1913 @ 293 1933 @ 295 2141 @ 323 2221 @ 331 2273 @ 338 2441 @ 362 2591 @ 377 2663 @ 386 2707 @ 394 2719 @ 397 2729 @ 398 2803 @ 409 3067 @ 439 3137 @ 446 3229 @ 457 3433 @ 481 3559 @ 499 3631 @ 508 4091 @ 563 4153 @ 571 4357 @ 595 4397 @ 599 4703 @ 635 4723 @ 637 4903 @ 655 5009 @ 671 5507 @ 728 5701 @ 751 5711 @ 752 5741 @ 755 5801 @ 761 5843 @ 767 5927 @ 779 6301 @ 820 6311 @ 821 6343 @ 826 6353 @ 827 6553 @ 847 6563 @ 848 6653 @ 857 The 10000th Honaker prime: 4043749 @ 286069
Cowgol
include "cowgol.coh";
var prime: uint8[7000];
typedef N is @indexof prime;
sub Sieve() is
prime[0] := 0;
prime[1] := 0;
var p: N := 2;
while p < @sizeof prime loop
prime[p] := 1;
p := p+1;
end loop;
p := 2;
while p*p < @sizeof prime loop
var c := p*p;
while c < @sizeof prime loop
prime[c] := 0;
c := c+p;
end loop;
p := p+1;
end loop;
end sub;
sub DigitSum(n: N): (sum: N) is
sum := 0;
while n>0 loop
sum := sum + n % 10;
n := n / 10;
end loop;
end sub;
var cur_prime: N := 1;
var i_prime: N := 0;
sub Honaker(): (p: N, i: N) is
loop
loop
cur_prime := cur_prime + 1;
if prime[cur_prime] != 0 then break; end if;
end loop;
i_prime := i_prime + 1;
if DigitSum(i_prime) == DigitSum(cur_prime) then break; end if;
end loop;
p := cur_prime;
i := i_prime;
end sub;
Sieve();
print("First 50 Honaker primes:\n");
var h: uint8 := 1;
while h <= 50 loop
var p: N;
var i: N;
(p, i) := Honaker();
print_i32(i as uint32);
print(": ");
print_i32(p as uint32);
print(" ");
if h % 5 == 0 then
print("\n");
else
print("\t");
end if;
h := h+1;
end loop;
- Output:
First 50 Honaker primes: 32: 131 56: 263 88: 457 175: 1039 176: 1049 182: 1091 212: 1301 218: 1361 227: 1433 248: 1571 293: 1913 295: 1933 323: 2141 331: 2221 338: 2273 362: 2441 377: 2591 386: 2663 394: 2707 397: 2719 398: 2729 409: 2803 439: 3067 446: 3137 457: 3229 481: 3433 499: 3559 508: 3631 563: 4091 571: 4153 595: 4357 599: 4397 635: 4703 637: 4723 655: 4903 671: 5009 728: 5507 751: 5701 752: 5711 755: 5741 761: 5801 767: 5843 779: 5927 820: 6301 821: 6311 826: 6343 827: 6353 847: 6553 848: 6563 857: 6653
Delphi
Modular version of the algorithm, breaks the problem down into simple pieces, which is a standard technique for solving problems. One of the advantages is that the modules can be used in different combination to solve different aspects of the problem. In this case, it is to find the first 50 and then 10,000th Honaker.
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 GetNextPrime(var Start: integer): integer;
{Get the next prime number after Start}
{Start is passed by "reference," so the
{original variable is incremented}
begin
repeat Inc(Start)
until IsPrime(Start);
Result:=Start;
end;
function SumDigits(N: integer): integer;
{Sum the integers in a number}
var T: integer;
begin
Result:=0;
repeat
begin
T:=N mod 10;
N:=N div 10;
Result:=Result+T;
end
until N<1;
end;
function IsHonaker(I,N: integer): boolean;
{A Honaker prime is one where the sums of digits}
{of the prime and its position are equal}
begin
Result:=SumDigits(I) = SumDigits(N);
end;
procedure ShowHonakerPrimes(Memo: TMemo);
{Test Honaker primes}
var I, N,Cnt: integer;
var S: string;
begin
N:=0; Cnt:=0; S:='';
{Test all numbers to see if they are prime}
for I:=1 to High(integer) do
begin
N:=GetNextPrime(N);
{Test the number if it Honaker}
if IsHonaker(I,N) then
begin
{Display if Honaker}
Inc(Cnt);
S:=S+Format('(%2d%5d%5d) ',[Cnt,I,N]);
if (Cnt mod 3)=0 then S:=S+#$0D#$0A;
if Cnt>=50 then break;
end;
end;
Memo.Lines.Add('First 50 Honaker Primes');
Memo.Lines.Add(S);
Memo.Lines.Add('');
{Find the 10,000th Honaker}
Memo.Lines.Add('The 10,000th Honaker Primes');
N:=0; Cnt:=0;
for I:=1 to High(integer) do
begin
N:=GetNextPrime(N);
if IsHonaker(I,N) then
begin
Inc(Cnt);
if Cnt=10000 then
begin
Memo.Lines.Add(Format('(%5d %5d %5d) ',[Cnt,I,N]));
break;
end;
end;
end;
end;
- Output:
First 50 Honaker Primes ( 1 32 131) ( 2 56 263) ( 3 88 457) ( 4 175 1039) ( 5 176 1049) ( 6 182 1091) ( 7 212 1301) ( 8 218 1361) ( 9 227 1433) (10 248 1571) (11 293 1913) (12 295 1933) (13 323 2141) (14 331 2221) (15 338 2273) (16 362 2441) (17 377 2591) (18 386 2663) (19 394 2707) (20 397 2719) (21 398 2729) (22 409 2803) (23 439 3067) (24 446 3137) (25 457 3229) (26 481 3433) (27 499 3559) (28 508 3631) (29 563 4091) (30 571 4153) (31 595 4357) (32 599 4397) (33 635 4703) (34 637 4723) (35 655 4903) (36 671 5009) (37 728 5507) (38 751 5701) (39 752 5711) (40 755 5741) (41 761 5801) (42 767 5843) (43 779 5927) (44 820 6301) (45 821 6311) (46 826 6343) (47 827 6353) (48 847 6553) (49 848 6563) (50 857 6653) The 10,000th Honaker Primes (10000 286069 4043749)
Draco
proc sieve([*]bool prime) void:
word pr, comp, max;
prime[0] := false;
prime[1] := false;
max := dim(prime,1)-1;
for pr from 2 upto max do prime[pr] := true od;
pr := 2;
while pr*pr <= max do
comp := pr * pr;
while comp <= max do
prime[comp] := false;
comp := comp + pr
od;
pr := pr + 1
od
corp
proc dsum(word n) word:
word sum;
sum := 0;
while n>0 do
sum := sum + n % 10;
n := n / 10
od;
sum
corp
proc main() void:
word p, i, h;
[7000]bool prime;
sieve(prime);
writeln("First 50 Honaker primes:");
p := 1;
i := 0;
for h from 1 upto 50 do
while
while p := p+1; not prime[p] do od;
i := i+1; dsum(i) /= dsum(p)
do od;
write(p:4, " @ ", i:3, " ");
if h%5 = 0 then writeln() fi
od
corp
- Output:
First 50 Honaker primes: 131 @ 32 263 @ 56 457 @ 88 1039 @ 175 1049 @ 176 1091 @ 182 1301 @ 212 1361 @ 218 1433 @ 227 1571 @ 248 1913 @ 293 1933 @ 295 2141 @ 323 2221 @ 331 2273 @ 338 2441 @ 362 2591 @ 377 2663 @ 386 2707 @ 394 2719 @ 397 2729 @ 398 2803 @ 409 3067 @ 439 3137 @ 446 3229 @ 457 3433 @ 481 3559 @ 499 3631 @ 508 4091 @ 563 4153 @ 571 4357 @ 595 4397 @ 599 4703 @ 635 4723 @ 637 4903 @ 655 5009 @ 671 5507 @ 728 5701 @ 751 5711 @ 752 5741 @ 755 5801 @ 761 5843 @ 767 5927 @ 779 6301 @ 820 6311 @ 821 6343 @ 826 6353 @ 827 6553 @ 847 6563 @ 848 6653 @ 857
EasyLang
fastfunc nextprim num .
repeat
i = 2
while i <= sqrt num and num mod i <> 0
i += 1
.
until num mod i <> 0
num += 1
.
return num
.
func digsum n .
while n > 0
sum += n mod 10
n = n div 10
.
return sum
.
proc show . .
i = 1
pri = 2
while count < 50
if digsum i = digsum pri
write "(" & i & " " & pri & ") "
count += 1
.
i += 1
pri = nextprim (pri + 1)
.
.
show
F#
This task uses Extensible Prime Generator (F#)
// Honaker primes. Nigel Galloway: September 21st., 2022
let rec fG n g=if n<10 then n+g else fG(n/10)(g+n%10)
let Honaker()=primes32()|>Seq.mapi(fun n g->(n+1,g,fG g 0,fG (n+1) 0))|>Seq.choose(fun(i,g,e,l)->if e=l then Some(i,g) else None)
Honaker()|>Seq.chunkBySize 10|>Seq.take 5|>Seq.iter(fun g->g|>Seq.iter(printf "%A "); printfn "")
printfn "%A" (Seq.item 9999 (Honaker()))
- Output:
(32, 131) (56, 263) (88, 457) (175, 1039) (176, 1049) (182, 1091) (212, 1301) (218, 1361) (227, 1433) (248, 1571) (293, 1913) (295, 1933) (323, 2141) (331, 2221) (338, 2273) (362, 2441) (377, 2591) (386, 2663) (394, 2707) (397, 2719) (398, 2729) (409, 2803) (439, 3067) (446, 3137) (457, 3229) (481, 3433) (499, 3559) (508, 3631) (563, 4091) (571, 4153) (595, 4357) (599, 4397) (635, 4703) (637, 4723) (655, 4903) (671, 5009) (728, 5507) (751, 5701) (752, 5711) (755, 5741) (761, 5801) (767, 5843) (779, 5927) (820, 6301) (821, 6311) (826, 6343) (827, 6353) (847, 6553) (848, 6563) (857, 6653) (286069, 4043749)
Factor
USING: grouping kernel lists lists.lazy math math.primes.lists
prettyprint sequences ;
: sum-digits ( n -- sum )
0 swap [ 10 /mod rot + swap ] until-zero ;
: honaker ( -- list )
1 lfrom lprimes lzip [ first2 [ sum-digits ] same? ] lfilter ;
50 honaker ltake list>array 5 group simple-table.
- Output:
{ 32 131 } { 56 263 } { 88 457 } { 175 1039 } { 176 1049 } { 182 1091 } { 212 1301 } { 218 1361 } { 227 1433 } { 248 1571 } { 293 1913 } { 295 1933 } { 323 2141 } { 331 2221 } { 338 2273 } { 362 2441 } { 377 2591 } { 386 2663 } { 394 2707 } { 397 2719 } { 398 2729 } { 409 2803 } { 439 3067 } { 446 3137 } { 457 3229 } { 481 3433 } { 499 3559 } { 508 3631 } { 563 4091 } { 571 4153 } { 595 4357 } { 599 4397 } { 635 4703 } { 637 4723 } { 655 4903 } { 671 5009 } { 728 5507 } { 751 5701 } { 752 5711 } { 755 5741 } { 761 5801 } { 767 5843 } { 779 5927 } { 820 6301 } { 821 6311 } { 826 6343 } { 827 6353 } { 847 6553 } { 848 6563 } { 857 6653 }
Forth
5000000 constant limit
create sieve limit allot
: prime? ( n -- ? ) sieve + c@ 0= ;
: notprime! ( n -- ) sieve + 1 swap c! ;
: prime_sieve
sieve limit erase
3
begin
dup dup * limit <
while
dup prime? if
limit over dup * do
i notprime!
dup 2* +loop
then
2 +
repeat
drop ;
: digit_sum ( u -- u )
dup 10 < if exit then
10 /mod recurse + ;
: next_odd_prime ( u -- u )
begin
2 + dup prime?
until ;
: next_honaker_prime ( u u -- u u )
begin
swap next_odd_prime swap 1+
2dup digit_sum swap digit_sum =
until ;
: print_pair ( u u -- )
." (" 3 .r ." , " 4 .r ." )" ;
: main
prime_sieve
." First 50 Honaker primes (index, prime):" cr
3 2 0 \ prime prime-index honaker-index
begin
dup 50 <
while
-rot next_honaker_prime
2dup print_pair rot 1+
dup 5 mod 0= if cr else space then
repeat
begin
dup 10000 <
while
-rot next_honaker_prime rot 1+
repeat
drop
cr ." Ten thousandth: " print_pair ;
main cr bye
- Output:
First 50 Honaker primes (index, prime): ( 32, 131) ( 56, 263) ( 88, 457) (175, 1039) (176, 1049) (182, 1091) (212, 1301) (218, 1361) (227, 1433) (248, 1571) (293, 1913) (295, 1933) (323, 2141) (331, 2221) (338, 2273) (362, 2441) (377, 2591) (386, 2663) (394, 2707) (397, 2719) (398, 2729) (409, 2803) (439, 3067) (446, 3137) (457, 3229) (481, 3433) (499, 3559) (508, 3631) (563, 4091) (571, 4153) (595, 4357) (599, 4397) (635, 4703) (637, 4723) (655, 4903) (671, 5009) (728, 5507) (751, 5701) (752, 5711) (755, 5741) (761, 5801) (767, 5843) (779, 5927) (820, 6301) (821, 6311) (826, 6343) (827, 6353) (847, 6553) (848, 6563) (857, 6653) Ten thousandth: (286069, 4043749)
FreeBASIC
' version 20-09-2022
' compile with: fbc -s console
Function dig_sum(n As UInteger) As UInteger
Dim As UInteger sum
While n > 0
sum += n Mod 10
n \= 10
Wend
Return sum
End Function
' ------=< MAIN >=------
#Define max 5 * 10^6
Dim As UInteger x, y, place, rank = 1
Dim Shared As UInteger prime(max)
For x = 3 To max Step 2
If prime(x) = 0 Then
For y = x * x To max Step x + x
prime(y) = 1
Next
End If
Next
For x = 3 To max Step 2
If prime(x) = 0 Then
rank += 1
If rank Mod 9 = x Mod 9 Then
If dig_sum(rank) = dig_sum(x) Then
place += 1
If place <= 50 Then
Print Using " ##: ### #####"; place ; rank ; x;
If (place Mod 5) = 0 Then Print
End If
If place = 10000 Then
Print
Print " 10000th honaker prime is at ";rank; " and is ";x
End If
End If
End If
End If
Next
' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End
- Output:
1: 32 131 2: 56 263 3: 88 457 4: 175 1039 5: 176 1049 6: 182 1091 7: 212 1301 8: 218 1361 9: 227 1433 10: 248 1571 11: 293 1913 12: 295 1933 13: 323 2141 14: 331 2221 15: 338 2273 16: 362 2441 17: 377 2591 18: 386 2663 19: 394 2707 20: 397 2719 21: 398 2729 22: 409 2803 23: 439 3067 24: 446 3137 25: 457 3229 26: 481 3433 27: 499 3559 28: 508 3631 29: 563 4091 30: 571 4153 31: 595 4357 32: 599 4397 33: 635 4703 34: 637 4723 35: 655 4903 36: 671 5009 37: 728 5507 38: 751 5701 39: 752 5711 40: 755 5741 41: 761 5801 42: 767 5843 43: 779 5927 44: 820 6301 45: 821 6311 46: 826 6343 47: 827 6353 48: 847 6553 49: 848 6563 50: 857 6653 10000th honaker prime is at 286069 and is 4043749
FutureBasic
local fn dig_sum( n as NSUInteger )
NSUInteger sum = 0
while ( n > 0 )
sum += n mod 10
n /= 10
wend
end fn = sum
void local fn CalculaterHonakerPrimes
NSUInteger x, y, rank = 1, place = 0
for x = 3 to _limit step 2
if ( prime(x) == 0 )
for y = x * x to _limit step x + x
prime(y) = 1
next
end if
next
printf @"The first %lu Honaker Primes ranked as \"Index: ([position], [value])\" are:\n", 50
for x = 3 to _limit step 2
if ( prime(x) == 0 )
rank++
if ( (rank mod 9) == ( x mod 9 ) )
if ( fn dig_sum(rank) == fn dig_sum(x) )
place++
if ( place <= 50 )
printf @"%4lu: (%3lu, %4lu) \b", place, rank, x
if ( place mod 5 == 0 ) then print
end if
if ( place == 10000 ) then printf @"\n The 10000th Honaker Prime is:\n %lu: (%4lu, %5lu)", place, rank, x
end if
end if
end if
next
end fn
window 1, @"Honakeer Primes", ( 0, 0, 780, 380 )
fn CalculaterHonakerPrimes
HandleEvents
- Output:
The first 50 Honaker Primes ranked as "Index: ([position], [value])" are: 1: ( 32, 131) 2: ( 56, 263) 3: ( 88, 457) 4: (175, 1039) 5: (176, 1049) 6: (182, 1091) 7: (212, 1301) 8: (218, 1361) 9: (227, 1433) 10: (248, 1571) 11: (293, 1913) 12: (295, 1933) 13: (323, 2141) 14: (331, 2221) 15: (338, 2273) 16: (362, 2441) 17: (377, 2591) 18: (386, 2663) 19: (394, 2707) 20: (397, 2719) 21: (398, 2729) 22: (409, 2803) 23: (439, 3067) 24: (446, 3137) 25: (457, 3229) 26: (481, 3433) 27: (499, 3559) 28: (508, 3631) 29: (563, 4091) 30: (571, 4153) 31: (595, 4357) 32: (599, 4397) 33: (635, 4703) 34: (637, 4723) 35: (655, 4903) 36: (671, 5009) 37: (728, 5507) 38: (751, 5701) 39: (752, 5711) 40: (755, 5741) 41: (761, 5801) 42: (767, 5843) 43: (779, 5927) 44: (820, 6301) 45: (821, 6311) 46: (826, 6343) 47: (827, 6353) 48: (847, 6553) 49: (848, 6563) 50: (857, 6653) The 10000th Honaker Prime is: 10000: (286069, 4043749)
Go
package main
import (
"fmt"
"rcu"
)
func main() {
primes := rcu.Primes(5_000_000)
var h [][2]int
var h10000 [2]int
for i, count := 1, 0; count < 10000; i++ {
if rcu.DigitSum(i, 10) == rcu.DigitSum(primes[i-1], 10) {
count++
if count <= 50 {
h = append(h, [2]int{i, primes[i-1]})
} else if count == 10000 {
h10000 = [2]int{i, primes[i-1]}
}
}
}
fmt.Println("The first 50 Honaker primes (index, prime):\n")
for i := 0; i < 50; i++ {
fmt.Printf("(%3d, %5s) ", h[i][0], rcu.Commatize(h[i][1]))
if (i+1)%5 == 0 {
fmt.Println()
}
}
fmt.Printf("\nand the 10,000th: (%7s, %9s)\n", rcu.Commatize(h10000[0]), rcu.Commatize(h10000[1]))
}
- Output:
The first 50 Honaker primes (index, prime): ( 32, 131) ( 56, 263) ( 88, 457) (175, 1,039) (176, 1,049) (182, 1,091) (212, 1,301) (218, 1,361) (227, 1,433) (248, 1,571) (293, 1,913) (295, 1,933) (323, 2,141) (331, 2,221) (338, 2,273) (362, 2,441) (377, 2,591) (386, 2,663) (394, 2,707) (397, 2,719) (398, 2,729) (409, 2,803) (439, 3,067) (446, 3,137) (457, 3,229) (481, 3,433) (499, 3,559) (508, 3,631) (563, 4,091) (571, 4,153) (595, 4,357) (599, 4,397) (635, 4,703) (637, 4,723) (655, 4,903) (671, 5,009) (728, 5,507) (751, 5,701) (752, 5,711) (755, 5,741) (761, 5,801) (767, 5,843) (779, 5,927) (820, 6,301) (821, 6,311) (826, 6,343) (827, 6,353) (847, 6,553) (848, 6,563) (857, 6,653) and the 10,000th: (286,069, 4,043,749)
Haskell
import Control.Monad (join)
import Data.Bifunctor (bimap)
import Data.List.Split (chunksOf)
import Data.Numbers.Primes (primes)
---------------------- HONAKER PRIMES --------------------
honakers :: [(Integer, Integer)]
honakers =
filter
(uncurry (==) . both sumDigits)
(zip [1 ..] primes)
--------------------------- TEST -------------------------
main :: IO ()
main =
putStrLn "First Fifty:\n"
>> mapM_
(putStrLn . unwords)
( chunksOf
5
(take 50 (show <$> honakers))
)
>> putStrLn "\n10Kth:\n"
>> print (honakers !! pred 10000)
------------------------- GENERIC ------------------------
sumDigits :: Integer -> Integer
sumDigits = foldr ((+) . read . pure) 0 . show
both :: (a -> b) -> (a, a) -> (b, b)
both = join bimap
- Output:
First Fifty: (32,131) (56,263) (88,457) (175,1039) (176,1049) (182,1091) (212,1301) (218,1361) (227,1433) (248,1571) (293,1913) (295,1933) (323,2141) (331,2221) (338,2273) (362,2441) (377,2591) (386,2663) (394,2707) (397,2719) (398,2729) (409,2803) (439,3067) (446,3137) (457,3229) (481,3433) (499,3559) (508,3631) (563,4091) (571,4153) (595,4357) (599,4397) (635,4703) (637,4723) (655,4903) (671,5009) (728,5507) (751,5701) (752,5711) (755,5741) (761,5801) (767,5843) (779,5927) (820,6301) (821,6311) (826,6343) (827,6353) (847,6553) (848,6563) (857,6653) 10Kth: (286069,4043749)
J
Implementation:
honk=: >: =&(+/@(10&#.inv))"0 p:
This tests a sequence of prime indices to determine whether the corresponding prime is a honaker prime. Here, >:
adds 1 (since J indices start with 0 and Honaker prime indices start with 1). Also, p:
yields the prime for an index, and +/@(10&#.inv)
computes a digital sum of a number (but not a sequence, so we use "0
to map it onto sequences). So, =&(+/@(10&#.inv))"0
identifies members of a pair of sequences (one on the left, the other on the right) whose digital sums match.
In other words, these are equivalent:
(>: =&(+/@(10&#.inv))"0 p:) 30 31 32
31 32 33 (=&(+/@(10&#.inv))"0) 127 131 137
((+/3 1),(+/3 2),(+/3 3)) = ((+/1 2 7),(+/1 3 1),(+/1 3 7))
((3+1),(3+2),(3+3)) = ((1+2+7),(1+3+1),(1+3+7))
4 5 6 = 10 5 11
0 1 0
Task example:
(>: j. p:) 5 10$I.honk i.1e3
32j131 56j263 88j457 175j1039 176j1049 182j1091 212j1301 218j1361 227j1433 248j1571
293j1913 295j1933 323j2141 331j2221 338j2273 362j2441 377j2591 386j2663 394j2707 397j2719
398j2729 409j2803 439j3067 446j3137 457j3229 481j3433 499j3559 508j3631 563j4091 571j4153
595j4357 599j4397 635j4703 637j4723 655j4903 671j5009 728j5507 751j5701 752j5711 755j5741
761j5801 767j5843 779j5927 820j6301 821j6311 826j6343 827j6353 847j6553 848j6563 857j6653
Here, we test the first thousand primes to see which are prime indices of Honaker primes. Then I.
converts the test results back to index form, and 5 10$I.
organizes those indices in 5 rows of 10 columns (discarding any extra). Finally, we use complex number notation to form pairs of the corresponding honaker index and prime.
Java
import java.util.ArrayList;
import java.util.List;
public final class HonakerPrimes {
public static void main(String[] args) {
sievePrimes(5_000_000);
System.out.println("The first 50 Honaker primes (honaker index: prime index, prime):");
for ( int i = 1; i <= 50; i++ ) {
System.out.print(String.format("%17s%s", nextHonakerPrime(), ( i % 5 == 0 ? "\n" : " " ) ));
}
for ( int i = 51; i < 10_000; i++ ) {
nextHonakerPrime();
}
System.out.println();
System.out.println("The 10,000th Honaker prime is: " + nextHonakerPrime());
}
private static HonakerPrime nextHonakerPrime() {
honakerIndex += 1;
primeIndex += 1;
while ( digitalSum(primeIndex) != digitalSum(primes.get(primeIndex - 1)) ) {
primeIndex += 1;
}
return new HonakerPrime(honakerIndex, primeIndex, primes.get(primeIndex - 1));
}
private static int digitalSum(int number) {
return String.valueOf(number).chars().map( i -> i - (int) '0' ).sum();
}
private static void sievePrimes(int limit) {
primes.add(2);
final int halfLimit = ( limit + 1 ) / 2;
boolean[] composite = new boolean[halfLimit];
for ( int i = 1, p = 3; i < halfLimit; p += 2, i++ ) {
if ( ! composite[i] ) {
primes.add(p);
for ( int a = i + p; a < halfLimit; a += p ) {
composite[a] = true;
}
}
}
}
private static int honakerIndex = 0;
private static int primeIndex = 0;
private static List<Integer> primes = new ArrayList<Integer>();
private static record HonakerPrime(int honakerIndex, int primeIndex, int prime) {
public String toString() {
return "(" + honakerIndex + ": " + primeIndex + ", " + prime + ")";
}
}
}
- Output:
The first 50 Honaker primes (honaker index: prime index, prime): (1: 32, 131) (2: 56, 263) (3: 88, 457) (4: 175, 1039) (5: 176, 1049) (6: 182, 1091) (7: 212, 1301) (8: 218, 1361) (9: 227, 1433) (10: 248, 1571) (11: 293, 1913) (12: 295, 1933) (13: 323, 2141) (14: 331, 2221) (15: 338, 2273) (16: 362, 2441) (17: 377, 2591) (18: 386, 2663) (19: 394, 2707) (20: 397, 2719) (21: 398, 2729) (22: 409, 2803) (23: 439, 3067) (24: 446, 3137) (25: 457, 3229) (26: 481, 3433) (27: 499, 3559) (28: 508, 3631) (29: 563, 4091) (30: 571, 4153) (31: 595, 4357) (32: 599, 4397) (33: 635, 4703) (34: 637, 4723) (35: 655, 4903) (36: 671, 5009) (37: 728, 5507) (38: 751, 5701) (39: 752, 5711) (40: 755, 5741) (41: 761, 5801) (42: 767, 5843) (43: 779, 5927) (44: 820, 6301) (45: 821, 6311) (46: 826, 6343) (47: 827, 6353) (48: 847, 6553) (49: 848, 6563) (50: 857, 6653) The 10,000th Honaker prime is: (10000: 286069, 4043749)
jq
Adapted from Wren
As with several other entries, some care must be used in choosing the size of the prime sieve or basket.
Generic utilities
def digitSum: tostring | explode | map(.-48) | add;
def lpad($len): tostring | ($len - length) as $l | (" " * $l)[:$l] + .;
# Input: a positive integer
# Output: an array, $a, of length .+1 such that
# $a[$i] is $i if $i is prime, and false otherwise.
def primeSieve:
# erase(i) sets .[i*j] to false for integral j > 1
def erase($i):
if .[$i] then
reduce (range(2*$i; length; $i)) as $j (.; .[$j] = false)
else .
end;
(. + 1) as $n
| (($n|sqrt) / 2) as $s
| [null, null, range(2; $n)]
| reduce (2, 1 + (2 * range(1; $s))) as $i (.; erase($i)) ;
The Task
# Output: .h gives details for the first $n Honaker primes, and
# .hmax gives details for the $max-th
def honakers($sieveLength; $n; $max):
($sieveLength|primeSieve|map(select(.))) as $primes
| { i: 1,
count: 0,
h: [],
hmax: null}
| until(.done or .i > $sieveLength;
if (.i|digitSum) == ($primes[.i-1] | digitSum)
then .count += 1
| if .count <= 50
then .h += [[.i, $primes[.i-1]]]
elif .count == $max
then .hmax = [.i, $primes[.i-1]]
| .done = true
else .
end
else .
end
| .i += 1 );
5e6 as $enough
| "The first 50 Honaker primes [index, prime]:",
(honakers($enough; 50; 10000)
| (.h | map( "[\(.[0]|lpad(3)), \(.[1]|lpad(4))]") | _nwise(5) | join(" ")),
"\nand the 10,000th:",
.hmax )
- Output:
The first 50 Honaker primes [index, prime]: [ 32, 131] [ 56, 263] [ 88, 457] [175, 1039] [176, 1049] [182, 1091] [212, 1301] [218, 1361] [227, 1433] [248, 1571] [293, 1913] [295, 1933] [323, 2141] [331, 2221] [338, 2273] [362, 2441] [377, 2591] [386, 2663] [394, 2707] [397, 2719] [398, 2729] [409, 2803] [439, 3067] [446, 3137] [457, 3229] [481, 3433] [499, 3559] [508, 3631] [563, 4091] [571, 4153] [595, 4357] [599, 4397] [635, 4703] [637, 4723] [655, 4903] [671, 5009] [728, 5507] [751, 5701] [752, 5711] [755, 5741] [761, 5801] [767, 5843] [779, 5927] [820, 6301] [821, 6311] [826, 6343] [827, 6353] [847, 6553] [848, 6563] [857, 6653] and the 10,000th: [286069,4043749]
Julia
""" Rosetta code task: rosettacode.org/wiki/Honaker_primes """
using Formatting
using Primes
""" Get the sequence of Honaker primes as tuples with their primepi values first in tuple"""
honaker(lim) = [(i, p) for (i, p) in enumerate(primes(lim)) if sum(digits(p)) == sum(digits(i))]
println("First 50 Honaker primes:")
const a = honaker(5_000_000)
foreach(p -> print(rpad(p[2], 12), p[1] % 5 == 0 ? "\n" : ""), enumerate(a[1:50]))
println("\n$(format(a[10000][2], commas = true)) is the ",
"$(format(a[10000][1], commas = true))th prime and the 10,000th Honaker prime.")
- Output:
First 50 Honaker primes: (32, 131) (56, 263) (88, 457) (175, 1039) (176, 1049) (182, 1091) (212, 1301) (218, 1361) (227, 1433) (248, 1571) (293, 1913) (295, 1933) (323, 2141) (331, 2221) (338, 2273) (362, 2441) (377, 2591) (386, 2663) (394, 2707) (397, 2719) (398, 2729) (409, 2803) (439, 3067) (446, 3137) (457, 3229) (481, 3433) (499, 3559) (508, 3631) (563, 4091) (571, 4153) (595, 4357) (599, 4397) (635, 4703) (637, 4723) (655, 4903) (671, 5009) (728, 5507) (751, 5701) (752, 5711) (755, 5741) (761, 5801) (767, 5843) (779, 5927) (820, 6301) (821, 6311) (826, 6343) (827, 6353) (847, 6553) (848, 6563) (857, 6653) 4,043,749 is the 286,069th prime and the 10,000th Honaker prime.
MAD
NORMAL MODE IS INTEGER
OUTN = 0
INTERNAL FUNCTION(OP, OI)
DIMENSION OUTP(5), OUTI(5)
VECTOR VALUES FMT=$5(I4,5H AT ,I3,S4)*$
ENTRY TO OUT.
OUTP(OUTN)=OP
OUTI(OUTN)=OI
OUTN=OUTN+1
WHENEVER OUTN.L.5, FUNCTION RETURN 0.
OUTN=0
PRINT FORMAT FMT,OUTP(0),OUTI(0),OUTP(1),OUTI(1),
1 OUTP(2),OUTI(2),OUTP(3),OUTI(3),OUTP(4),OUTI(4)
END OF FUNCTION
INTERNAL FUNCTION(N)
ENTRY TO DIGSUM.
SUM=0
THROUGH DIGIT, FOR NN=N, 0, NN.E.0
ND=NN/10
SUM=SUM+(NN-ND*10)
DIGIT NN=ND
FUNCTION RETURN SUM
END OF FUNCTION
BOOLEAN PRIME
DIMENSION PRIME(7000)
PRIME(0)=0B
PRIME(1)=0B
THROUGH PRINIT, FOR I=2, 1, I.GE.7000
PRINIT PRIME(I)=1B
THROUGH SIEVE, FOR P=2, 1, P*P.GE.7000
THROUGH SIEVE, FOR C=P*P, P, C.GE.7000
SIEVE PRIME(C)=0B
P=1
I=0
THROUGH HONAK, FOR H=1, 1, H.G.50
SEARCH P=P+1
WHENEVER .NOT.PRIME(P), TRANSFER TO SEARCH
I=I+1
WHENEVER DIGSUM.(P).NE.DIGSUM.(I), TRANSFER TO SEARCH
HONAK OUT.(P,I)
END OF PROGRAM
- Output:
131 AT 32 263 AT 56 457 AT 88 1039 AT 175 1049 AT 176 1091 AT 182 1301 AT 212 1361 AT 218 1433 AT 227 1571 AT 248 1913 AT 293 1933 AT 295 2141 AT 323 2221 AT 331 2273 AT 338 2441 AT 362 2591 AT 377 2663 AT 386 2707 AT 394 2719 AT 397 2729 AT 398 2803 AT 409 3067 AT 439 3137 AT 446 3229 AT 457 3433 AT 481 3559 AT 499 3631 AT 508 4091 AT 563 4153 AT 571 4357 AT 595 4397 AT 599 4703 AT 635 4723 AT 637 4903 AT 655 5009 AT 671 5507 AT 728 5701 AT 751 5711 AT 752 5741 AT 755 5801 AT 761 5843 AT 767 5927 AT 779 6301 AT 820 6311 AT 821 6343 AT 826 6353 AT 827 6553 AT 847 6563 AT 848 6653 AT 857
Mathematica / Wolfram Language
ClearAll[HonakerPrimeQ, DigitSum, NextHonakerPrime, HonakerPrime];
DigitSum[n_Integer] := Total@IntegerDigits[n]; /; $Version < 14;
HonakerPrimeQ[p_Integer] := PrimeQ[p] && (DigitSum[p] == DigitSum@PrimePi[p]);
NextHonakerPrime[n_Integer?Positive] := NestWhile[NextPrime, n + 1, ! HonakerPrimeQ[#] &]
HonakerPrime[n_Integer?Positive] := Nest[NextHonakerPrime, 1, n];
SetAttributes[{HonakerPrimeQ, NextHonakerPrime, HonakerPrime}, Listable];
(* Output *)
first50HonakerPrimes = HonakerPrime[Range[50]];
honaker10k = HonakerPrime[10^4];
Print["The first 50 Honaker primes are:"];
Grid[
Partition[
Transpose[{Range[50], PrimePi[first50HonakerPrimes],first50HonakerPrimes}],
UpTo[5]],
Alignment -> Right]
Print["The 10,000 Honaker prime is ", {PrimePi[honaker10k], honaker10k}]
- Output:
The first 50 Honaker primes are: {1,32,131} {2,56,263} {3,88,457} {4,175,1039} {5,176,1049} {6,182,1091} {7,212,1301} {8,218,1361} {9,227,1433} {10,248,1571} {11,293,1913} {12,295,1933} {13,323,2141} {14,331,2221} {15,338,2273} {16,362,2441} {17,377,2591} {18,386,2663} {19,394,2707} {20,397,2719} {21,398,2729} {22,409,2803} {23,439,3067} {24,446,3137} {25,457,3229} {26,481,3433} {27,499,3559} {28,508,3631} {29,563,4091} {30,571,4153} {31,595,4357} {32,599,4397} {33,635,4703} {34,637,4723} {35,655,4903} {36,671,5009} {37,728,5507} {38,751,5701} {39,752,5711} {40,755,5741} {41,761,5801} {42,767,5843} {43,779,5927} {44,820,6301} {45,821,6311} {46,826,6343} {47,827,6353} {48,847,6553} {49,848,6563} {50,857,6653} The 10,000 Honaker prime is {286069,4043749}
Miranda
main :: [sys_message]
main = [Stdout "First 50 Honaker primes:\n",
Stdout ((lay . map show . group 5 . take 50) honakers)
]
group :: num->[*]->[[*]]
group s [] = []
group s ls = take s ls : group s (drop s ls)
honakers :: [(num,num)]
honakers = [(i,p) | (i,p) <- zip2 [1..] primes; digsum i = digsum p]
primes :: [num]
primes = sieve [2..] where sieve (p:ns) = p : sieve [n | n<-ns; n mod p>0]
digsum :: num->num
digsum 0 = 0
digsum n = n mod 10 + digsum (n div 10)
- Output:
First 50 Honaker primes: [(32,131),(56,263),(88,457),(175,1039),(176,1049)] [(182,1091),(212,1301),(218,1361),(227,1433),(248,1571)] [(293,1913),(295,1933),(323,2141),(331,2221),(338,2273)] [(362,2441),(377,2591),(386,2663),(394,2707),(397,2719)] [(398,2729),(409,2803),(439,3067),(446,3137),(457,3229)] [(481,3433),(499,3559),(508,3631),(563,4091),(571,4153)] [(595,4357),(599,4397),(635,4703),(637,4723),(655,4903)] [(671,5009),(728,5507),(751,5701),(752,5711),(755,5741)] [(761,5801),(767,5843),(779,5927),(820,6301),(821,6311)] [(826,6343),(827,6353),(847,6553),(848,6563),(857,6653)]
Modula-2
MODULE HonakerPrimes;
FROM InOut IMPORT WriteCard, WriteString, WriteLn;
FROM MathLib IMPORT sqrt;
CONST
MaxPrime = 7000;
VAR
prime: ARRAY [2..MaxPrime] OF BOOLEAN;
cur, idx, hon: CARDINAL;
PROCEDURE Sieve;
VAR pr, co, sqmax: CARDINAL;
BEGIN
sqmax := TRUNC(sqrt(FLOAT(MaxPrime)));
FOR pr := 2 TO MaxPrime DO prime[pr] := TRUE END;
FOR pr := 2 TO sqmax DO
co := pr * pr;
WHILE co <= MaxPrime DO
prime[co] := FALSE;
INC(co, pr)
END
END
END Sieve;
PROCEDURE DigitSum(n: CARDINAL): CARDINAL;
VAR sum: CARDINAL;
BEGIN
sum := 0;
REPEAT
INC(sum, n MOD 10);
n := n DIV 10
UNTIL n=0;
RETURN sum
END DigitSum;
BEGIN
Sieve;
cur := 1;
idx := 0;
FOR hon := 1 TO 50 DO
REPEAT
REPEAT INC(cur) UNTIL prime[cur];
INC(idx)
UNTIL DigitSum(cur) = DigitSum(idx);
WriteCard(cur, 4);
WriteString(" @ ");
WriteCard(idx, 3);
WriteString(" ");
IF hon MOD 5 = 0 THEN WriteLn END
END
END HonakerPrimes.
- Output:
131 @ 32 263 @ 56 457 @ 88 1039 @ 175 1049 @ 176 1091 @ 182 1301 @ 212 1361 @ 218 1433 @ 227 1571 @ 248 1913 @ 293 1933 @ 295 2141 @ 323 2221 @ 331 2273 @ 338 2441 @ 362 2591 @ 377 2663 @ 386 2707 @ 394 2719 @ 397 2729 @ 398 2803 @ 409 3067 @ 439 3137 @ 446 3229 @ 457 3433 @ 481 3559 @ 499 3631 @ 508 4091 @ 563 4153 @ 571 4357 @ 595 4397 @ 599 4703 @ 635 4723 @ 637 4903 @ 655 5009 @ 671 5507 @ 728 5701 @ 751 5711 @ 752 5741 @ 755 5801 @ 761 5843 @ 767 5927 @ 779 6301 @ 820 6311 @ 821 6343 @ 826 6353 @ 827 6553 @ 847 6563 @ 848 6653 @ 857
Nim
import std/[bitops, math, strformat, strutils]
type Sieve = object
data: seq[byte]
func `[]`(sieve: Sieve; idx: Positive): bool =
## Return value of element at index "idx".
let idx = idx shr 1
let iByte = idx shr 3
let iBit = idx and 7
result = sieve.data[iByte].testBit(iBit)
func `[]=`(sieve: var Sieve; idx: Positive; val: bool) =
## Set value of element at index "idx".
let idx = idx shr 1
let iByte = idx shr 3
let iBit = idx and 7
if val: sieve.data[iByte].setBit(iBit)
else: sieve.data[iByte].clearBit(iBit)
func newSieve(lim: Positive): Sieve =
## Create a sieve with given maximal index.
result.data = newSeq[byte]((lim + 16) shr 4)
func initPrimes(lim: Positive): seq[Natural] =
## Initialize the list of primes from 2 to "lim".
var composite = newSieve(lim)
composite[1] = true
for n in countup(3, sqrt(lim.toFloat).int, 2):
if not composite[n]:
for k in countup(n * n, lim, 2 * n):
composite[k] = true
result.add 2
for n in countup(3, lim, 2):
if not composite[n]:
result.add n
let primes = initPrimes(5_000_000)
func digitalSum(n: Natural): int =
## Return the digital sum of "n".
var n = n
while n != 0:
result += n mod 10
n = n div 10
iterator honakerPrimes(primes: seq[Natural]): tuple[pos, val: int] =
## Yield the position and value of Honaker primes from the given list of primes.
for i, n in primes:
if digitalSum(i + 1) == digitalSum(n):
yield (i + 1, n)
echo "List of positions and values of first 50 Honeker primes:"
var count = 0
for (pos, val) in honakerPrimes(primes):
inc count
if count <= 50:
stdout.write &"({pos:>3}, {val:>4})"
stdout.write if count mod 5 == 0: '\n' else: ' '
elif count == 10_000:
echo &"\nThe 10_000th Honeker prime number is {insertSep($val)} at position {insertSep($pos)}."
break
- Output:
List of positions and values of first 50 Honeker primes: ( 32, 131) ( 56, 263) ( 88, 457) (175, 1039) (176, 1049) (182, 1091) (212, 1301) (218, 1361) (227, 1433) (248, 1571) (293, 1913) (295, 1933) (323, 2141) (331, 2221) (338, 2273) (362, 2441) (377, 2591) (386, 2663) (394, 2707) (397, 2719) (398, 2729) (409, 2803) (439, 3067) (446, 3137) (457, 3229) (481, 3433) (499, 3559) (508, 3631) (563, 4091) (571, 4153) (595, 4357) (599, 4397) (635, 4703) (637, 4723) (655, 4903) (671, 5009) (728, 5507) (751, 5701) (752, 5711) (755, 5741) (761, 5801) (767, 5843) (779, 5927) (820, 6301) (821, 6311) (826, 6343) (827, 6353) (847, 6553) (848, 6563) (857, 6653) The 10_000th Honeker prime number is 4_043_749 at position 286_069.
Pascal
Free Pascal
uses primsieve
checking "numbersaplenty.com/set/Honaker_prime" for 30000101111.
{$IFDEF FPC}{$MODE DELPHI}{$OPTIMIZATION ON,ALL}{$ENDIF}
{$IFDEF WINDOWS} {$APPTYPE CONSOLE}{$ENDIF}
uses
primsieve;
function SumOfDecDigits(n:UInt64): Uint32; forward;
const
DgtMod = 10000;
var
{$ALIGN 32}
SumDigits : array[0..DgtMod-1] of byte;
procedure Init;
var
i,
a,b,c,d : NativeUint;
Begin
i := DgtMod-1;
For a := 9 downto 0 do
For b := 9 downto 0 do
For c := 9 downto 0 do
For d := 9 downto 0 do
Begin
SumDigits[i] := a+b+c+d;
dec(i);
end;
end;
procedure OutSpecial(idxH,idxP,p,CntDecDgt:Uint64);
Begin
write('(',idxH:9,idxP:11,p:13);
writeln(' Digitsum :',SumOfDecDigits(p):3,' < ',CntDecDgt:3,' Count of digits )');
end;
procedure OutHonaker(idxH,idxP,p:Uint64);
begin
writeln('(',idxH:9,idxP:11,p:13,')');
end;
function SumOfDecDigits(n:UInt64): Uint32;
var
tmp: Uint64;
digit: Uint32;
Begin
result := 0;
repeat
tmp := n div DgtMod;
digit := n-tmp*DgtMod;
n := tmp;
result +=SumDigits[digit];
until n=0;
end;
var
idxP,p,DecDgtLimit : Uint64;
idxH,lmt,SumDgtPrime,CntDecDgt : UInt32;
Begin
init;
idxP := 0;
idxH := 0;
CntDecDgt := 1;
DecDgtLimit := 10;
Writeln(' First 50 Honaker primes ');
repeat
p := NextPrime;
inc(idxP);
SumDgtPrime := SumOfDecDigits(idxP);
If SumOfDecDigits(idxP) = SumOfDecDigits(p) then
begin
inc(IdxH);
if idxH<= 50 then
Begin
write('(',idxH:3,idxP:4,p:5,')');
if Idxh mod 5=0 then writeln;
end;
end;
until idxH= 50;
lmt := 100;
CntDecDgt := 1;
DecDgtLimit := 10;
while DecDgtLimit < p do
Begin
CntDecDgt += 1;
DecDgtLimit *= 10;
end;
Writeln;
Writeln(' n.th PrimeIdx Prime');
repeat
p := NextPrime;
inc(idxP);
IF p > DecDgtLimit then
Begin
CntDecDgt += 1;
DecDgtLimit *= 10;
end;
SumDgtPrime := SumOfDecDigits(idxP);
If SumOfDecDigits(idxP) = SumOfDecDigits(p) then
begin
inc(IdxH);
while p > DecDgtLimit do
Begin
CntDecDgt += 1;
DecDgtLimit *= 10;
end;
if SumDgtPrime < CntDecDgt then
OutSpecial(idxH,idxP,p,CntDecDgt);
if idxH = lmt then
Begin
OutHonaker(idxH,idxP,p);
lmt *= 10;
end;
end;
until lmt> 100*1000*1000;
end.
- Output:
First 50 Honaker primes ( 1 32 131)( 2 56 263)( 3 88 457)( 4 175 1039)( 5 176 1049) ( 6 182 1091)( 7 212 1301)( 8 218 1361)( 9 227 1433)( 10 248 1571) ( 11 293 1913)( 12 295 1933)( 13 323 2141)( 14 331 2221)( 15 338 2273) ( 16 362 2441)( 17 377 2591)( 18 386 2663)( 19 394 2707)( 20 397 2719) ( 21 398 2729)( 22 409 2803)( 23 439 3067)( 24 446 3137)( 25 457 3229) ( 26 481 3433)( 27 499 3559)( 28 508 3631)( 29 563 4091)( 30 571 4153) ( 31 595 4357)( 32 599 4397)( 33 635 4703)( 34 637 4723)( 35 655 4903) ( 36 671 5009)( 37 728 5507)( 38 751 5701)( 39 752 5711)( 40 755 5741) ( 41 761 5801)( 42 767 5843)( 43 779 5927)( 44 820 6301)( 45 821 6311) ( 46 826 6343)( 47 827 6353)( 48 847 6553)( 49 848 6563)( 50 857 6653) n.th PrimeIdx Prime ( 100 1855 15913) ( 1000 24706 283303) ( 10000 286069 4043749) ( 100000 3066943 51168613) ( 1000000 32836375 630589303) ( 10000000 354922738 7707009643) ( 36181814 1300010120 30000101111 Digitsum : 8 < 11 Count of digits ) (100000000 3784461563 91565150519) real 1m43.381s user 1m43.253s sys 0m0.000s (4,4 GHz Ryzen 5600 G)
PascalABC.NET
function gen_primes: sequence of integer;
begin
yield 2;
var D := new Dictionary<integer, integer>;
var q := 3;
while True do
begin
if q not in D then
begin
if q < maxint.Sqrt.Floor then
D[q * q] := q;
yield q;
end
else
begin
var p := D[q];
D -= q;
var x := q + p + p;
while x in D do x += p + p;
D[x] := p;
end;
q += 2;
end;
end;
function digitalsum(n: integer) := n.ToString.select(x -> x.ToDigit).Sum;
function honakerPrimes: sequence of (integer, integer);
begin
foreach var n in gen_primes index i do
if digitalSum(i + 1) = digitalSum(n) then
yield (i + 1, n)
end;
begin
writeln('First 50 Honaker primes (index, prime):');
foreach var p in honakerPrimes index i do
begin
write(p:11);
if (i + 1) mod 5 = 0 then println;
if i = 49 then break;
end;
println;
print('Ten thousandth:');
honakerPrimes.ElementAt(10_000 - 1).Println;
end.
- Output:
First 50 Honaker primes (index, prime): (32,131) (56,263) (88,457) (175,1039) (176,1049) (182,1091) (212,1301) (218,1361) (227,1433) (248,1571) (293,1913) (295,1933) (323,2141) (331,2221) (338,2273) (362,2441) (377,2591) (386,2663) (394,2707) (397,2719) (398,2729) (409,2803) (439,3067) (446,3137) (457,3229) (481,3433) (499,3559) (508,3631) (563,4091) (571,4153) (595,4357) (599,4397) (635,4703) (637,4723) (655,4903) (671,5009) (728,5507) (751,5701) (752,5711) (755,5741) (761,5801) (767,5843) (779,5927) (820,6301) (821,6311) (826,6343) (827,6353) (847,6553) (848,6563) (857,6653) Ten thousandth: (286069,4043749)
Perl
use v5.36;
use ntheory 'nth_prime';
use List::Util <max sum>;
sub table ($c, @V) { my $t = $c * (my $w = 2 + max map { length } @V); ( sprintf( ('%'.$w.'s')x@V, @V) ) =~ s/.{1,$t}\K/\n/gr }
sub comma { scalar reverse join ',', unpack '(A3)*', reverse shift }
my($n,@honaker);
while () {
my $p = nth_prime(++$n);
push @honaker, [$n, $p] if (sum split '', $p) == sum split '', $n;
last if 10_000 == @honaker;
}
push @res, "First 50 Honaker primes (index, prime):";
push @res, table 5, map { sprintf "(%3d, %4d)", @$_ } @honaker[0..49];
push @res, "Ten thousandth: " . sprintf "(%s, %s)", map { comma $_ } @{$honaker[9999]};
- Output:
First 50 Honaker primes (index, prime): ( 32, 131) ( 56, 263) ( 88, 457) (175, 1039) (176, 1049) (182, 1091) (212, 1301) (218, 1361) (227, 1433) (248, 1571) (293, 1913) (295, 1933) (323, 2141) (331, 2221) (338, 2273) (362, 2441) (377, 2591) (386, 2663) (394, 2707) (397, 2719) (398, 2729) (409, 2803) (439, 3067) (446, 3137) (457, 3229) (481, 3433) (499, 3559) (508, 3631) (563, 4091) (571, 4153) (595, 4357) (599, 4397) (635, 4703) (637, 4723) (655, 4903) (671, 5009) (728, 5507) (751, 5701) (752, 5711) (755, 5741) (761, 5801) (767, 5843) (779, 5927) (820, 6301) (821, 6311) (826, 6343) (827, 6353) (847, 6553) (848, 6563) (857, 6653) Ten thousandth: (286,069, 4,043,749)
Phix
with javascript_semantics function digital_sum(integer i) integer res = 0 while i do res += remainder(i,10) i = floor(i/10) end while return res end function sequence res = {} integer pdx = 1, p while length(res)<10_000 do p = get_prime(pdx) if digital_sum(p)=digital_sum(pdx) then res = append(res,{pdx,p}) end if pdx += 1 end while string r = join_by(apply(true,sprintf,{{"(%3d,%4d)"},res[1..50]}),1,10," ") printf(1,"First 50 Honaker primes (index, prime):\n%s\n",{r}) {pdx,p} = res[10000] printf(1,"The %,d%s prime is %,d which is the 10,000th Honaker prime\n",{pdx,ord(pdx),p})
- Output:
First 50 Honaker primes (index, prime): ( 32, 131) ( 56, 263) ( 88, 457) (175,1039) (176,1049) (182,1091) (212,1301) (218,1361) (227,1433) (248,1571) (293,1913) (295,1933) (323,2141) (331,2221) (338,2273) (362,2441) (377,2591) (386,2663) (394,2707) (397,2719) (398,2729) (409,2803) (439,3067) (446,3137) (457,3229) (481,3433) (499,3559) (508,3631) (563,4091) (571,4153) (595,4357) (599,4397) (635,4703) (637,4723) (655,4903) (671,5009) (728,5507) (751,5701) (752,5711) (755,5741) (761,5801) (767,5843) (779,5927) (820,6301) (821,6311) (826,6343) (827,6353) (847,6553) (848,6563) (857,6653) The 286,069th prime is 4,043,749 which is the 10,000th Honaker prime
PL/I
honaker: procedure options(main);
declare prime(7000) bit;
sieve: procedure;
declare (pr, co) fixed;
prime(1) = '0'b;
do pr = 2 to 7000; prime(pr) = '1'b; end;
do pr = 2 repeat(pr+1) while(pr*pr <= 7000);
do co = pr*pr repeat(co+pr) while(co <= 7000);
prime(co) = '0'b;
end;
end;
end sieve;
digitsum: procedure(n) returns(fixed);
declare (n, t, s) fixed;
s = 0;
do t=n repeat(t/10) while(t>0);
s = s+mod(t,10);
end;
return(s);
end digitsum;
declare (num, iprime, hon) fixed;
call sieve;
put skip list('First 50 Honaker primes:');
put skip;
iprime = 0;
num = 1;
do hon = 1 to 50;
srch: do;
num = num + 1;
if ^prime(num) then goto srch;
iprime = iprime + 1;
if digitsum(iprime) ^= digitsum(num) then goto srch;
end;
put edit(num, ' @ ', iprime, ' ') (F(4),A,F(3),A);
if mod(hon,5) = 0 then put skip;
end;
end honaker;
- Output:
First 50 Honaker primes: 131 @ 32 263 @ 56 457 @ 88 1039 @ 175 1049 @ 176 1091 @ 182 1301 @ 212 1361 @ 218 1433 @ 227 1571 @ 248 1913 @ 293 1933 @ 295 2141 @ 323 2221 @ 331 2273 @ 338 2441 @ 362 2591 @ 377 2663 @ 386 2707 @ 394 2719 @ 397 2729 @ 398 2803 @ 409 3067 @ 439 3137 @ 446 3229 @ 457 3433 @ 481 3559 @ 499 3631 @ 508 4091 @ 563 4153 @ 571 4357 @ 595 4397 @ 599 4703 @ 635 4723 @ 637 4903 @ 655 5009 @ 671 5507 @ 728 5701 @ 751 5711 @ 752 5741 @ 755 5801 @ 761 5843 @ 767 5927 @ 779 6301 @ 820 6311 @ 821 6343 @ 826 6353 @ 827 6553 @ 847 6563 @ 848 6653 @ 857
PL/M
100H:
BDOS: PROCEDURE (FN,ARG); DECLARE FN BYTE, ARG ADDRESS; GO TO 5; END BDOS;
EXIT: PROCEDURE; GO TO 0; END EXIT;
PUT$CHAR: PROCEDURE (CHR); DECLARE CHR BYTE; CALL BDOS(2, CHR); END PUT$CHAR;
PRINT: PROCEDURE (S); DECLARE S ADDRESS; CALL BDOS(9, S); END PRINT;
DECLARE FALSE LITERALLY '0', TRUE LITERALLY '0FFH';
PRINT$NUM: PROCEDURE (N);
DECLARE (N, P) ADDRESS, I BYTE;
DECLARE S (6) BYTE INITIAL ('.....$');
I = 5;
DIGIT:
S(I := I-1) = '0' + N MOD 10;
IF (N := N/10) > 0 THEN GO TO DIGIT;
CALL PRINT(.S(I));
END PRINT$NUM;
SIEVE: PROCEDURE (MAX, PRIME);
DECLARE (MAX, PRIME, PR, CO) ADDRESS;
DECLARE P BASED PRIME BYTE;
P(0) = FALSE;
P(1) = FALSE;
DO PR = 2 TO MAX;
P(PR) = TRUE;
END;
PR = 2;
DO WHILE (CO := PR*PR) <= MAX;
DO WHILE CO <= MAX;
P(CO) = FALSE;
CO = CO + PR;
END;
PR = PR + 1;
END;
END SIEVE;
DIG$SUM: PROCEDURE (N) BYTE;
DECLARE SUM BYTE, N ADDRESS;
SUM = 0;
DO WHILE N>0;
SUM = SUM + N MOD 10;
N = N / 10;
END;
RETURN SUM;
END DIG$SUM;
DECLARE PRIME (7001) BYTE;
CALL SIEVE(LAST(PRIME), .PRIME);
CALL PRINT(.('FIRST 50 HONAKER PRIMES:',13,10,'$'));
DECLARE (N, NPRIME) ADDRESS, HON BYTE;
N = 0;
NPRIME = 0;
DO HON = 1 TO 50;
SRCH$HON: DO;
IF NOT PRIME(N := N+1) THEN GO TO SRCH$HON;
IF DIG$SUM(N) <> DIG$SUM(NPRIME := NPRIME+1) THEN GO TO SRCH$HON;
END;
CALL PRINT$NUM(NPRIME);
CALL PRINT(.': $');
CALL PRINT$NUM(N);
CALL PRINT(.' $');
IF HON MOD 5 = 0
THEN CALL PRINT(.(13,10,'$'));
ELSE CALL PUT$CHAR(9);
END;
CALL EXIT;
EOF
- Output:
FIRST 50 HONAKER PRIMES: 32: 131 56: 263 88: 457 175: 1039 176: 1049 182: 1091 212: 1301 218: 1361 227: 1433 248: 1571 293: 1913 295: 1933 323: 2141 331: 2221 338: 2273 362: 2441 377: 2591 386: 2663 394: 2707 397: 2719 398: 2729 409: 2803 439: 3067 446: 3137 457: 3229 481: 3433 499: 3559 508: 3631 563: 4091 571: 4153 595: 4357 599: 4397 635: 4703 637: 4723 655: 4903 671: 5009 728: 5507 751: 5701 752: 5711 755: 5741 761: 5801 767: 5843 779: 5927 820: 6301 821: 6311 826: 6343 827: 6353 847: 6553 848: 6563 857: 6653
Python
''' Rosetta code task: rosettacode.org/wiki/Honaker_primes '''
from pyprimesieve import primes
def digitsum(num):
''' Digit sum of an integer (base 10) '''
return sum(int(c) for c in str(num))
def generate_honaker(limit=5_000_000):
''' Generate the sequence of Honaker primes with their sequence and primepi values '''
honaker = [(i + 1, p) for i, p in enumerate(primes(limit)) if digitsum(p) == digitsum(i + 1)]
for hcount, (ppi, pri) in enumerate(honaker):
yield hcount + 1, ppi, pri
print('First 50 Honaker primes:')
for p in generate_honaker():
if p[0] < 51:
print(f'{str(p):16}', end='\n' if p[0] % 5 == 0 else '')
elif p[0] == 10_000:
print(f'\nThe 10,000th Honaker prime is the {p[1]:,}th one, which is {p[2]:,}.')
break
- Output:
First 50 Honaker primes: (1, 32, 131) (2, 56, 263) (3, 88, 457) (4, 175, 1039) (5, 176, 1049) (6, 182, 1091) (7, 212, 1301) (8, 218, 1361) (9, 227, 1433) (10, 248, 1571) (11, 293, 1913) (12, 295, 1933) (13, 323, 2141) (14, 331, 2221) (15, 338, 2273) (16, 362, 2441) (17, 377, 2591) (18, 386, 2663) (19, 394, 2707) (20, 397, 2719) (21, 398, 2729) (22, 409, 2803) (23, 439, 3067) (24, 446, 3137) (25, 457, 3229) (26, 481, 3433) (27, 499, 3559) (28, 508, 3631) (29, 563, 4091) (30, 571, 4153) (31, 595, 4357) (32, 599, 4397) (33, 635, 4703) (34, 637, 4723) (35, 655, 4903) (36, 671, 5009) (37, 728, 5507) (38, 751, 5701) (39, 752, 5711) (40, 755, 5741) (41, 761, 5801) (42, 767, 5843) (43, 779, 5927) (44, 820, 6301) (45, 821, 6311) (46, 826, 6343) (47, 827, 6353) (48, 847, 6553) (49, 848, 6563) (50, 857, 6653) The 10,000th Honaker prime is the 286,069th one, which is 4,043,749.
Or, defining an infinite series of Honaker primes, writing our own primes function,
and displaying with flexible column widths, for variable sample sizes:
'''Honaker primes'''
from itertools import count, islice
from functools import reduce
# honakers :: [Int]
def honakers():
'''Infinite stream of Honaker primes,
tupled with their 1-based indices
in the series of prime integers.
'''
def p(ip):
return digitSum(ip[0]) == digitSum(ip[1])
return filter(
p, enumerate(primes(), 1)
)
# digitSum :: Int -> Int
def digitSum(n):
'''Sum of the decimal digits of the given integer.
'''
return reduce(
lambda a, c: a + int(c),
str(n),
0
)
# ------------------------- TEST -------------------------
# main :: IO ()
def main():
'''First 50 Honaker primes, and ten thousandth.'''
print ("First 50 (prime index, Honaker) pairs:")
print(
table(5)([
str(n) for n in
islice(honakers(), 50)
])
)
print("\n10Kth:\n")
print(
next(islice(honakers(), 10000-1, None))
)
# ----------------------- GENERIC ------------------------
# chunksOf :: Int -> [a] -> [[a]]
def chunksOf(n):
'''A series of lists of length n, subdividing the
contents of xs. Where the length of xs is not evenly
divisible, the final list will be shorter than n.
'''
def go(xs):
return (
xs[i:n + i] for i in range(0, len(xs), n)
) if 0 < n else None
return go
# primes :: [Int]
def primes():
'''An infinite stream of primes.
'''
seen = {}
p = None
yield 2
for q in count(3, 2):
p = seen.pop(q, None)
if p is None:
seen[q ** 2] = q
yield q
else:
seen[
until(
lambda x: x not in seen,
lambda x: x + 2 * p,
q + 2 * p
)
] = p
# table :: Int -> [String] -> String
def table(n):
'''A list of strings formatted as
right-justified rows of n columns.
'''
def go(xs):
w = len(max(xs, key=len))
return '\n'.join(
' '.join(row) for row in chunksOf(n)([
s.rjust(w, ' ') for s in xs
])
)
return go
# until :: (a -> Bool) -> (a -> a) -> a -> a
def until(p, f, x):
'''The result of repeatedly applying f until p holds.
The initial seed value is x.
'''
v = x
while not p(v):
v = f(v)
return v
# MAIN ---
if __name__ == '__main__':
main()
- Output:
First 50 (prime index, Honaker) pairs: (32, 131) (56, 263) (88, 457) (175, 1039) (176, 1049) (182, 1091) (212, 1301) (218, 1361) (227, 1433) (248, 1571) (293, 1913) (295, 1933) (323, 2141) (331, 2221) (338, 2273) (362, 2441) (377, 2591) (386, 2663) (394, 2707) (397, 2719) (398, 2729) (409, 2803) (439, 3067) (446, 3137) (457, 3229) (481, 3433) (499, 3559) (508, 3631) (563, 4091) (571, 4153) (595, 4357) (599, 4397) (635, 4703) (637, 4723) (655, 4903) (671, 5009) (728, 5507) (751, 5701) (752, 5711) (755, 5741) (761, 5801) (767, 5843) (779, 5927) (820, 6301) (821, 6311) (826, 6343) (827, 6353) (847, 6553) (848, 6563) (857, 6653) 10Kth: (286069, 4043749)
Quackery
isprime
is defined at Primality by trial division#Quackery.
[ 0 swap
[ 10 /mod
rot + swap
dup 0 = until ]
drop ] is digitsum ( n --> n )
[ digitsum swap digitsum = ] is ds= ( n n --> b )
[ 0 temp put
[] 0
[ 1+
dup isprime if
[ 1 temp tally
dup temp share
ds= if
[ dup dip
[ temp share
swap join
nested join ] ] ]
dip [ 2dup size = ]
swap until ]
drop nip temp release ] is honakers ( n --> [ )
50 honakers
witheach
[ echo
i^ 5 mod 4 =
if cr else sp ]
cr cr
10000 honakers -1 peek echo
- Output:
[ 32 131 ][ 56 263 ][ 88 457 ][ 175 1039 ][ 176 1049 ] [ 182 1091 ][ 212 1301 ][ 218 1361 ][ 227 1433 ][ 248 1571 ] [ 293 1913 ][ 295 1933 ][ 323 2141 ][ 331 2221 ][ 338 2273 ] [ 362 2441 ][ 377 2591 ][ 386 2663 ][ 394 2707 ][ 397 2719 ] [ 398 2729 ][ 409 2803 ][ 439 3067 ][ 446 3137 ][ 457 3229 ] [ 481 3433 ][ 499 3559 ][ 508 3631 ][ 563 4091 ][ 571 4153 ] [ 595 4357 ][ 599 4397 ][ 635 4703 ][ 637 4723 ][ 655 4903 ] [ 671 5009 ][ 728 5507 ][ 751 5701 ][ 752 5711 ][ 755 5741 ] [ 761 5801 ][ 767 5843 ][ 779 5927 ][ 820 6301 ][ 821 6311 ] [ 826 6343 ][ 827 6353 ][ 847 6553 ][ 848 6563 ][ 857 6653 ] [ 286069 4043749 ]
Raku
my @honaker = lazy (^∞).hyper.grep(&is-prime).kv.grep: (1 + *).comb.sum == *.comb.sum;
say "First 50 Honaker primes (index, prime):\n" ~ @honaker[^50].map(&format).batch(5).join: "\n";
say "\nTen thousandth: " ~ @honaker[9999].&format;
sub format ($_) { sprintf "(%3d, %4d)", 1 + .[0], .[1] }
- Output:
First 50 Honaker primes (index, prime): ( 32, 131) ( 56, 263) ( 88, 457) (175, 1039) (176, 1049) (182, 1091) (212, 1301) (218, 1361) (227, 1433) (248, 1571) (293, 1913) (295, 1933) (323, 2141) (331, 2221) (338, 2273) (362, 2441) (377, 2591) (386, 2663) (394, 2707) (397, 2719) (398, 2729) (409, 2803) (439, 3067) (446, 3137) (457, 3229) (481, 3433) (499, 3559) (508, 3631) (563, 4091) (571, 4153) (595, 4357) (599, 4397) (635, 4703) (637, 4723) (655, 4903) (671, 5009) (728, 5507) (751, 5701) (752, 5711) (755, 5741) (761, 5801) (767, 5843) (779, 5927) (820, 6301) (821, 6311) (826, 6343) (827, 6353) (847, 6553) (848, 6563) (857, 6653) Ten thousandth: (286069, 4043749)
RPL
≪ →STR → digits ≪ 0 1 digits SIZE FOR j digits j DUP SUB STR→ + NEXT ≫ ≫ 'DIGSUM' STO ≪ 1 { } → max primepos result ≪ 2 1 max FOR j DO NEXTPRIME UNTIL 'primepos' INCR DIGSUM OVER DIGSUM == END 'result' j primepos 4 PICK →V3 STO+ NEXT result ≫ ≫ 'HONAKER' STO
50 HONAKER
- Output:
1: {[1. 32. 131.] [2. 56. 263.] [3. 88. 457.] [4. 175. 1039.] [5. 176. 1049.] [6. 182. 1091.] [7. 212. 1301.] [8. 218. 1361.] [9. 227. 1433.] [10. 248. 1571.] [11. 293. 1913.] [12. 295. 1933.] [13. 323. 2141.] [14. 331. 2221.] [15. 338. 2273.] [16. 362. 2441.] [17. 377. 2591.] [18. 386. 2663.] [19. 394. 2707.] [20. 397. 2719.] [21. 398. 2729.] [22. 409. 2803.] [23. 439. 3067.] [24. 446. 3137.] [25. 457. 3229.] [26. 481. 3433.] [27. 499. 3559.] [28. 508. 3631.] [29. 563. 4091.] [30. 571. 4153.] [31. 595. 4357.] [32. 599. 4397.] [33. 635. 4703.] [34. 637. 4723.] [35. 655. 4903.] [36. 671. 5009.] [37. 728. 5507.] [38. 751. 5701.] [39. 752. 5711.] [40. 755. 5741.] [41. 761. 5801.] [42. 767. 5843.] [43. 779. 5927.] [44. 820. 6301.] [45. 821. 6311.] [46. 826. 6343.] [47. 827. 6353.] [48. 847. 6553.] [49. 848. 6563.] [50. 857. 6653.]}
Ruby
require 'prime'
honakers = Prime.each.with_index(1).lazy.select{|pr, i| pr.digits.sum == i.digits.sum}
ar = honakers.take(10_000).to_a
puts "The first 50 Honaker primes and their position:"
ar.first(50).each_slice(5){|slice| puts "%15s"*slice.size % slice}
puts "\nHonaker prime 10000 is %d on position %d." % ar.last
- Output:
The first 50 Honaker primes: [131, 32] [263, 56] [457, 88] [1039, 175] [1049, 176] [1091, 182] [1301, 212] [1361, 218] [1433, 227] [1571, 248] [1913, 293] [1933, 295] [2141, 323] [2221, 331] [2273, 338] [2441, 362] [2591, 377] [2663, 386] [2707, 394] [2719, 397] [2729, 398] [2803, 409] [3067, 439] [3137, 446] [3229, 457] [3433, 481] [3559, 499] [3631, 508] [4091, 563] [4153, 571] [4357, 595] [4397, 599] [4703, 635] [4723, 637] [4903, 655] [5009, 671] [5507, 728] [5701, 751] [5711, 752] [5741, 755] [5801, 761] [5843, 767] [5927, 779] [6301, 820] [6311, 821] [6343, 826] [6353, 827] [6553, 847] [6563, 848] [6653, 857] Honaker prime 10000 is 4043749 on position 286069.
Rust
//includes primal = "0.2" in dependencies
fn digit_sum( mut number: usize) -> usize {
let mut sum : usize = 0 ;
while number != 0 {
sum += number % 10 ;
number /= 10 ;
}
sum
}
fn main() {
let mut count : i32 = 0 ;
let mut pos : i32 = 1 ;
println!("The first 50 Honaker primes:") ;
primal::Primes::all( ).enumerate( ).map( |( i , w )| (i + 1 , w) ).
filter( |(i , w)| digit_sum( *i ) == digit_sum( *w ) ).take( 50 ).
for_each( |(i , w )| {
count += 1 ;
print!("(p:{} ,ind:{} ,val:{}) " , pos , i, w ) ;
pos += 1 ;
if count % 3 == 0 {
println!( ) ;
}
}) ;
println!( ) ;
}
- Output:
The first 50 Honaker primes: (p:1 ,ind:32 ,val:131) (p:2 ,ind:56 ,val:263) (p:3 ,ind:88 ,val:457) (p:4 ,ind:175 ,val:1039) (p:5 ,ind:176 ,val:1049) (p:6 ,ind:182 ,val:1091) (p:7 ,ind:212 ,val:1301) (p:8 ,ind:218 ,val:1361) (p:9 ,ind:227 ,val:1433) (p:10 ,ind:248 ,val:1571) (p:11 ,ind:293 ,val:1913) (p:12 ,ind:295 ,val:1933) (p:13 ,ind:323 ,val:2141) (p:14 ,ind:331 ,val:2221) (p:15 ,ind:338 ,val:2273) (p:16 ,ind:362 ,val:2441) (p:17 ,ind:377 ,val:2591) (p:18 ,ind:386 ,val:2663) (p:19 ,ind:394 ,val:2707) (p:20 ,ind:397 ,val:2719) (p:21 ,ind:398 ,val:2729) (p:22 ,ind:409 ,val:2803) (p:23 ,ind:439 ,val:3067) (p:24 ,ind:446 ,val:3137) (p:25 ,ind:457 ,val:3229) (p:26 ,ind:481 ,val:3433) (p:27 ,ind:499 ,val:3559) (p:28 ,ind:508 ,val:3631) (p:29 ,ind:563 ,val:4091) (p:30 ,ind:571 ,val:4153) (p:31 ,ind:595 ,val:4357) (p:32 ,ind:599 ,val:4397) (p:33 ,ind:635 ,val:4703) (p:34 ,ind:637 ,val:4723) (p:35 ,ind:655 ,val:4903) (p:36 ,ind:671 ,val:5009) (p:37 ,ind:728 ,val:5507) (p:38 ,ind:751 ,val:5701) (p:39 ,ind:752 ,val:5711) (p:40 ,ind:755 ,val:5741) (p:41 ,ind:761 ,val:5801) (p:42 ,ind:767 ,val:5843) (p:43 ,ind:779 ,val:5927) (p:44 ,ind:820 ,val:6301) (p:45 ,ind:821 ,val:6311) (p:46 ,ind:826 ,val:6343) (p:47 ,ind:827 ,val:6353) (p:48 ,ind:847 ,val:6553) (p:49 ,ind:848 ,val:6563) (p:50 ,ind:857 ,val:6653)
Scala
import scala.collection.mutable.ListBuffer
object HonakerPrimes {
def main(args: Array[String]): Unit = {
sievePrimes(5000000)
println("The first 50 Honaker primes (honaker index: prime index, prime):")
for (i <- 1 to 50) {
print(f"${nextHonakerPrime()}%17s${if (i % 5 == 0) "\n" else " "}")
}
for (i <- 51 until 10000) {
nextHonakerPrime()
}
println()
println(s"The 10,000th Honaker prime is: ${nextHonakerPrime()}")
}
private def nextHonakerPrime(): HonakerPrime = {
honakerIndex += 1
primeIndex += 1
while (digitalSum(primeIndex) != digitalSum(primes(primeIndex - 1))) {
primeIndex += 1
}
HonakerPrime(honakerIndex, primeIndex, primes(primeIndex - 1))
}
private def digitalSum(number: Int): Int = {
number.toString.map(_.asDigit).sum
}
private def sievePrimes(limit: Int): Unit = {
primes += 2
val halfLimit = (limit + 1) / 2
val composite = Array.fill(halfLimit)(false)
var i = 1
var p = 3
while (i < halfLimit) {
if (!composite(i)) {
primes += p
var a = i + p
while (a < halfLimit) {
composite(a) = true
a += p
}
}
i += 1
p += 2
}
}
private var honakerIndex = 0
private var primeIndex = 0
private val primes = ListBuffer[Int]()
case class HonakerPrime(honakerIndex: Int, primeIndex: Int, prime: Int) {
override def toString: String = s"($honakerIndex: $primeIndex, $prime)"
}
}
- Output:
The first 50 Honaker primes (honaker index: prime index, prime): (1: 32, 131) (2: 56, 263) (3: 88, 457) (4: 175, 1039) (5: 176, 1049) (6: 182, 1091) (7: 212, 1301) (8: 218, 1361) (9: 227, 1433) (10: 248, 1571) (11: 293, 1913) (12: 295, 1933) (13: 323, 2141) (14: 331, 2221) (15: 338, 2273) (16: 362, 2441) (17: 377, 2591) (18: 386, 2663) (19: 394, 2707) (20: 397, 2719) (21: 398, 2729) (22: 409, 2803) (23: 439, 3067) (24: 446, 3137) (25: 457, 3229) (26: 481, 3433) (27: 499, 3559) (28: 508, 3631) (29: 563, 4091) (30: 571, 4153) (31: 595, 4357) (32: 599, 4397) (33: 635, 4703) (34: 637, 4723) (35: 655, 4903) (36: 671, 5009) (37: 728, 5507) (38: 751, 5701) (39: 752, 5711) (40: 755, 5741) (41: 761, 5801) (42: 767, 5843) (43: 779, 5927) (44: 820, 6301) (45: 821, 6311) (46: 826, 6343) (47: 827, 6353) (48: 847, 6553) (49: 848, 6563) (50: 857, 6653) The 10,000th Honaker prime is: (10000: 286069, 4043749)
SETL
program honaker_primes;
init primes := sieve(4100000);
init honaker := [p in [1..#primes] | digit_sum p = digit_sum primes(p)];
print("First 50 Honaker primes: ");
loop for h in honaker(1..50) do
nprint(lpad(str primes(h), 4) + " @ " + lpad(str h, 3) + " ");
if (col +:= 1) mod 5 = 0 then
print;
end if;
end loop;
print;
print("10,000th Honaker prime: " + str primes(h := honaker(10000)) +
" @ " + str h);
proc sieve(size);
prime := [False, True] + [True, False] * (size div 2);
loop for p in [3, 5..floor sqrt size] do
loop for c in [p*p, p*p+p..size] do
prime(c) := False;
end loop;
end loop;
return [p in [2..size] | prime(p)];
end proc;
op digit_sum(n);
return 0 +/[[n mod 10, n div:= 10](1) : until n=0];
end op;
end program;
- Output:
First 50 Honaker primes: 131 @ 32 263 @ 56 457 @ 88 1039 @ 175 1049 @ 176 1091 @ 182 1301 @ 212 1361 @ 218 1433 @ 227 1571 @ 248 1913 @ 293 1933 @ 295 2141 @ 323 2221 @ 331 2273 @ 338 2441 @ 362 2591 @ 377 2663 @ 386 2707 @ 394 2719 @ 397 2729 @ 398 2803 @ 409 3067 @ 439 3137 @ 446 3229 @ 457 3433 @ 481 3559 @ 499 3631 @ 508 4091 @ 563 4153 @ 571 4357 @ 595 4397 @ 599 4703 @ 635 4723 @ 637 4903 @ 655 5009 @ 671 5507 @ 728 5701 @ 751 5711 @ 752 5741 @ 755 5801 @ 761 5843 @ 767 5927 @ 779 6301 @ 820 6311 @ 821 6343 @ 826 6353 @ 827 6553 @ 847 6563 @ 848 6653 @ 857 10,000th Honaker prime: 4043749 @ 286069
Sidef
func is_honaker_prime (n) {
n.is_prime && (n.sumdigits == n.prime_count.sumdigits)
}
say "The first 50 Honaker primes and their position:"
is_honaker_prime.first(50).each_slice(5, {|*slice|
say ("%15s"*slice.len % slice.map{ [_, .prime_count] }...)
})
printf("\nHonaker prime 10000 is %s on position %s.\n",
with (is_honaker_prime.nth(1e4)) {|k| (k, k.prime_count) })
- Output:
The first 50 Honaker primes and their position: [131, 32] [263, 56] [457, 88] [1039, 175] [1049, 176] [1091, 182] [1301, 212] [1361, 218] [1433, 227] [1571, 248] [1913, 293] [1933, 295] [2141, 323] [2221, 331] [2273, 338] [2441, 362] [2591, 377] [2663, 386] [2707, 394] [2719, 397] [2729, 398] [2803, 409] [3067, 439] [3137, 446] [3229, 457] [3433, 481] [3559, 499] [3631, 508] [4091, 563] [4153, 571] [4357, 595] [4397, 599] [4703, 635] [4723, 637] [4903, 655] [5009, 671] [5507, 728] [5701, 751] [5711, 752] [5741, 755] [5801, 761] [5843, 767] [5927, 779] [6301, 820] [6311, 821] [6343, 826] [6353, 827] [6553, 847] [6563, 848] [6653, 857] Honaker prime 10000 is 4043749 on position 286069.
Wren
import "./math" for Int
import "./fmt" for Fmt
var primes = Int.primeSieve(5 * 1e6)
var i = 1
var count = 0
var h = []
var h10000
while (true) {
if (Int.digitSum(i) == Int.digitSum(primes[i-1])) {
count = count + 1
if (count <= 50) {
h.add([i, primes[i-1]])
} else if (count == 10000) {
h10000 = [i, primes[i-1]]
break
}
}
i = i + 1
}
System.print("The first 50 Honaker primes (index, prime):")
for (i in 0..49) {
Fmt.write("($3d, $,5d) ", h[i][0], h[i][1])
if ((i + 1) % 5 == 0) System.print()
}
Fmt.print("\nand the 10,000th: ($,7d, $,9d)", h10000[0], h10000[1])
- Output:
The first 50 Honaker primes (index, prime): ( 32, 131) ( 56, 263) ( 88, 457) (175, 1,039) (176, 1,049) (182, 1,091) (212, 1,301) (218, 1,361) (227, 1,433) (248, 1,571) (293, 1,913) (295, 1,933) (323, 2,141) (331, 2,221) (338, 2,273) (362, 2,441) (377, 2,591) (386, 2,663) (394, 2,707) (397, 2,719) (398, 2,729) (409, 2,803) (439, 3,067) (446, 3,137) (457, 3,229) (481, 3,433) (499, 3,559) (508, 3,631) (563, 4,091) (571, 4,153) (595, 4,357) (599, 4,397) (635, 4,703) (637, 4,723) (655, 4,903) (671, 5,009) (728, 5,507) (751, 5,701) (752, 5,711) (755, 5,741) (761, 5,801) (767, 5,843) (779, 5,927) (820, 6,301) (821, 6,311) (826, 6,343) (827, 6,353) (847, 6,553) (848, 6,563) (857, 6,653) and the 10,000th: (286,069, 4,043,749)
XPL0
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 DigSum(N); \Return sum of digits in N
int N, S;
[S:= 0;
while N do
[N:= N/10;
S:= S + rem(0);
];
return S;
];
int N, C, H;
[Format(5, 0);
N:= 3; C:= 1; H:= 0;
loop [if IsPrime(N) then
[C:= C+1;
if DigSum(N) = DigSum(C) then
[H:= H+1;
if H<=50 or H=10000 then
[RlOut(0, float(C));
Text(0, ": ");
RlOut(0, float(N));
if rem(H/5) = 0 then CrLf(0) else Text(0, " ");
if H = 10000 then quit;
];
];
];
N:= N+2;
];
]
- Output:
32: 131 56: 263 88: 457 175: 1039 176: 1049 182: 1091 212: 1301 218: 1361 227: 1433 248: 1571 293: 1913 295: 1933 323: 2141 331: 2221 338: 2273 362: 2441 377: 2591 386: 2663 394: 2707 397: 2719 398: 2729 409: 2803 439: 3067 446: 3137 457: 3229 481: 3433 499: 3559 508: 3631 563: 4091 571: 4153 595: 4357 599: 4397 635: 4703 637: 4723 655: 4903 671: 5009 728: 5507 751: 5701 752: 5711 755: 5741 761: 5801 767: 5843 779: 5927 820: 6301 821: 6311 826: 6343 827: 6353 847: 6553 848: 6563 857: 6653 286069: 4043749
Yabasic
// Rosetta Code problem: http://rosettacode.org/wiki/Honaker_primes
// by Jjuanhdez, 09/2022
limit = 5 * 10^6
//place = 0
rank = 1
dim prime(limit)
for x = 3 to limit step 2
if prime(x) = 0 then
for y = x * x to limit step x + x
prime(y) = 1
next y
end if
next x
print "First 50 Honaker primes:"
for x = 3 to limit step 2
if prime(x) = 0 then
rank = rank + 1
if mod(rank, 9) = mod(x, 9) then
if dig_sum(rank) = dig_sum(x) then
place = place + 1
if place <= 50 then
print " ", place using("##"), ": (", rank using("###"), ",", x using("#####"), ")";
if mod(place, 5) = 0 print
end if
if place = 10000 print "\n 10000th honaker prime is at ", rank, " and is ", x
end if
end if
end if
next x
sub dig_sum(n)
local sum
while n > 0
sum = sum + mod(n, 10)
n = int(n / 10)
end while
return sum
end sub
- Output:
Same as FreeBASIC entry.
- Programming Tasks
- Solutions by Programming Task
- 11l
- ABC
- ALGOL 68
- Arturo
- BASIC
- C
- C sharp
- C++
- Primesieve
- CLU
- Cowgol
- Delphi
- Classes,SysUtils,StdCtrls
- Draco
- EasyLang
- F Sharp
- Factor
- Forth
- FreeBASIC
- FutureBasic
- Go
- Go-rcu
- Haskell
- J
- Java
- Jq
- Julia
- MAD
- Mathematica
- Wolfram Language
- Miranda
- Modula-2
- Nim
- Pascal
- Free Pascal
- PascalABC.NET
- Perl
- Ntheory
- Phix
- PL/I
- PL/M
- Python
- Quackery
- Raku
- RPL
- Ruby
- Rust
- Scala
- SETL
- Sidef
- Wren
- Wren-math
- Wren-fmt
- XPL0
- Yabasic