Blum integer

From Rosetta Code
Revision as of 15:18, 21 May 2023 by Boreal (talk | contribs) (Added XPL0 example.)
Blum integer is a draft programming task. It is not yet considered ready to be promoted as a complete task, for reasons that should be found in its talk page.
Definition

A positive integer n is a Blum integer if n = p x q is a semi-prime for which p and q are distinct primes congruent to 3 mod 4. In other words, p and q must be of the form 4t + 3 where t is some non-negative integer.

Example

21 is a Blum integer because it has two prime factors: 3 (= 4 x 0 + 3) and 7 (= 4 x 1 + 3).

Task

Find and show on this page the first 50 Blum integers.

Also show the 26,828th.

Stretch

Find and show the 100,000th, 200,000th, 300,000th and 400,000th Blum integers.

For the first 400,000 Blum integers, show the percentage distribution by final decimal digit (to 3 decimal places). Clearly, such integers can only end in 1, 3, 7 or 9.

Related task
References


C

Translation of: Wren
#include <stdio.h>
#include <stdbool.h>
#include <locale.h>

int inc[8] = {4, 2, 4, 2, 4, 6, 2, 6};

bool isPrime(int n) {
    if (n < 2) return false;
    if (n%2 == 0) return n == 2;
    if (n%3 == 0) return n == 3;
    int d = 5;
    while (d*d <= n) {
        if (n%d == 0) return false;
        d += 2;
        if (n%d == 0) return false;
        d += 4;
    }
    return true;
}

// Assumes n is odd.
int firstPrimeFactor(int n) {
    if (n == 1) return 1;
    if (!(n%3)) return 3;
    if (!(n%5)) return 5;
    for (int k = 7, i = 0; k*k <= n; ) {
        if (!(n%k)) {
            return k;
        } else {
            k += inc[i];
            i = (i + 1) % 8;
        }
    }
    return n;
}

int main() {
    int i = 1, j, bc = 0, p, q;
    int blum[50], counts[4] = {0}, digits[4] = {1, 3, 5, 7};
    setlocale(LC_NUMERIC, "");
    while (true) {
        p = firstPrimeFactor(i);
        if (p % 4 == 3) {
            q = i / p;
            if (q != p && q % 4 == 3 && isPrime(q)) {
                if (bc < 50) blum[bc] = i;
                ++counts[i % 10 / 3];
                ++bc;
                if (bc == 50) {
                    printf("First 50 Blum integers:\n");
                    for (j = 0; j < 50; ++j) {
                        printf("%3d ", blum[j]);
                        if (!((j+1) % 10)) printf("\n");
                    }
                    printf("\n");
                } else if (bc == 26828 || !(bc % 100000)) {
                    printf("The %'7dth Blum integer is: %'9d\n", bc, i);
                    if (bc == 400000) {
                        printf("\n%% distribution of the first 400,000 Blum integers:\n");
                        for (j = 0; j < 4; ++j) {
                            printf("  %6.3f%% end in %d\n", counts[j]/4000.0, digits[j]);
                        }
                        break;
                    }
                }
            }
        }
        i += (i % 5 == 3) ? 4 : 2;
    }
    return 0;
}
Output:
Same as Wren example.

Go

Translation of: Wren
Library: Go-rcu
package main

import (
    "fmt"
    "rcu"
)

var inc = []int{4, 2, 4, 2, 4, 6, 2, 6}

// Assumes n is odd.
func firstPrimeFactor(n int) int {
    if n == 1 {
        return 1
    }
    if n%3 == 0 {
        return 3
    }
    if n%5 == 0 {
        return 5
    }
    for k, i := 7, 0; k*k <= n; {
        if n%k == 0 {
            return k
        } else {
            k += inc[i]
            i = (i + 1) % 8
        }
    }
    return n
}

func main() {
    blum := make([]int, 50)
    bc := 0
    counts := make([]int, 4)
    i := 1
    for {
        p := firstPrimeFactor(i)
        if p%4 == 3 {
            q := i / p
            if q != p && q%4 == 3 && rcu.IsPrime(q) {
                if bc < 50 {
                    blum[bc] = i
                }
                counts[i%10/3]++
                bc++
                if bc == 50 {
                    fmt.Println("First 50 Blum integers:")
                    rcu.PrintTable(blum, 10, 3, false)
                    fmt.Println()
                } else if bc == 26828 || bc%100000 == 0 {
                    fmt.Printf("The %7sth Blum integer is: %9s\n", rcu.Commatize(bc), rcu.Commatize(i))
                    if bc == 400000 {
                        fmt.Println("\n% distribution of the first 400,000 Blum integers:")
                        digits := []int{1, 3, 7, 9}
                        for j := 0; j < 4; j++ {
                            fmt.Printf("  %6.3f%% end in %d\n", float64(counts[j])/4000, digits[j])
                        }
                        return
                    }
                }
            }
        }
        if i%5 == 3 {
            i += 4
        } else {
            i += 2
        }
    }
}
Output:
Same as Wren example.

Wren

Library: Wren-math
Library: Wren-fmt
import "./math" for Int
import "./fmt" for Fmt

var inc = [4, 2, 4, 2, 4, 6, 2, 6]

// Assumes n is odd.
var firstPrimeFactor = Fn.new { |n|
    if (n == 1) return 1
    if (n%3 == 0) return 3
    if (n%5 == 0) return 5
    var k = 7
    var i = 0
    while (k * k <= n) {
        if (n%k == 0)  {
            return k
        } else {
            k = k + inc[i]
            i = (i + 1) % 8
        }
    }
    return n
}

var blum = List.filled(50, 0)
var bc = 0
var counts = { 1: 0, 3: 0, 7: 0, 9: 0 }
var i = 1
while (true) {
    var p = firstPrimeFactor.call(i)
    if (p % 4 == 3) {
        var q = i / p
        if (q != p && q % 4 == 3 && Int.isPrime(q)) {
            if (bc < 50) blum[bc] = i
            counts[i % 10] = counts[i % 10] + 1
            bc = bc + 1
            if (bc == 50) {
                System.print("First 50 Blum integers:")
                Fmt.tprint("$3d ", blum, 10)
                System.print()
            } else if (bc == 26828 || bc % 1e5 == 0) {
                Fmt.print("The $,9r Blum integer is: $,9d", bc, i)
                if (bc == 400000) {
                    System.print("\n\% distribution of the first 400,000 Blum integers:")
                    for (i in [1, 3, 7, 9]) {
                        Fmt.print("  $6.3f\% end in $d", counts[i]/4000, i)
                    }
                    return
                }
            }
        }
    }
    i = (i % 5 == 3) ? i + 4 : i + 2
}
Output:
First 50 Blum integers:
 21   33   57   69   77   93  129  133  141  161 
177  201  209  213  217  237  249  253  301  309 
321  329  341  381  393  413  417  437  453  469 
473  489  497  501  517  537  553  573  581  589 
597  633  649  669  681  713  717  721  737  749 

The  26,828th Blum integer is:   524,273
The 100,000th Blum integer is: 2,075,217
The 200,000th Blum integer is: 4,275,533
The 300,000th Blum integer is: 6,521,629
The 400,000th Blum integer is: 8,802,377

% distribution of the first 400,000 Blum integers is:
  25.001% end in 1
  25.017% end in 3
  24.997% end in 7
  24.985% end in 9

XPL0

Simple minded brute force takes 93 seconds on Pi4.

int Prime1;

func Semiprime(N);      \Return 'true' if N is semiprime
int  N, F, C;
[C:= 0;  F:= 2;
repeat  if rem(N/F) = 0 then
                [C:= C+1;
                Prime1:= N;
                N:= N/F;
                ]
        else    F:= F+1;
until   F > N;
return C = 2;
];

int N, C, Prime2;
[Format(4,0);
N:= 3;  C:= 0;
loop    [if Semiprime(N) then
            [if rem(Prime1/4) = 3 then
                [Prime2:= N/Prime1;
                if Prime2 # Prime1 and rem(Prime2/4) = 3 then
                    [C:= C+1;
                    if C <= 50 then
                        [RlOut(0, float(N));
                        if rem(C/10) = 0 then CrLf(0);
                        ];
                    if rem(C/1000)=0 then ChOut(0, ^.);
                    if C >= 26828 then 
                        [Text(0, "^m^jThe 26828th Blum integer is: ");
                        IntOut(0, N);  CrLf(0);
                        quit;
                        ];
                    ];
                ];
        ];
    N:= N+2;
    ];
]
Output:
  21  33  57  69  77  93 129 133 141 161
 177 201 209 213 217 237 249 253 301 309
 321 329 341 381 393 413 417 437 453 469
 473 489 497 501 517 537 553 573 581 589
 597 633 649 669 681 713 717 721 737 749
..........................
The 26828th Blum integer is: 524273