Task: Extra primes




Go: package main

import "fmt"

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

func main() {
    digits := [4]int{2, 3, 5, 7}                      
    digits2 := [2]int{3, 7}                           
    cands := [][2]int{{2, 2}, {3, 3}, {5, 5}, {7, 7}} 

    for _, a := range digits {
        for _, b := range digits2 {
            cands = append(cands, [2]int{10*a + b, a + b})
        }
    }

    for _, a := range digits {
        for _, b := range digits {
            for _, c := range digits2 {
                cands = append(cands, [2]int{100*a + 10*b + c, a + b + c})
            }
        }
    }

    for _, a := range digits {
        for _, b := range digits {
            for _, c := range digits {
                for _, d := range digits2 {
                    cands = append(cands, [2]int{1000*a + 100*b + 10*c + d, a + b + c + d})
                }
            }
        }
    }

    fmt.Println("The extra primes under 10,000 are:")
    count := 0
    for _, cand := range cands {
        if isPrime(cand[0]) && isPrime(cand[1]) {
            count++
            fmt.Printf("%2d: %4d\n", count, cand[0])
        }
    }
}








Ada: with Ada.Text_Io;

procedure Extra_Primes is

   type Number   is new Long_Integer range 0 .. Long_Integer'Last;

   package Number_Io is new Ada.Text_Io.Integer_Io (Number);

   function Is_Prime (A : Number) return Boolean is
      D : Number;
   begin
      if A < 2       then return False; end if;
      if A in 2 .. 3 then return True;  end if;
      if A mod 2 = 0 then return False; end if;
      if A mod 3 = 0 then return False; end if;
      D := 5;
      while D * D <= A loop
         if A mod D = 0 then
            return False;
         end if;
         D := D + 2;
         if A mod D = 0 then
            return False;
         end if;
         D := D + 4;
      end loop;
      return True;
   end Is_Prime;

   subtype Digit is Number range 0 .. 9;
   type Digit_Array is array (Positive range <>) of Digit;

   function To_Digits (N : Number) return Digit_Array is
      Image : constant String := Number'Image (N);
      Res   : Digit_Array (2 .. Image'Last);
   begin
      for A in Image'First + 1 .. Image'Last loop
         Res (A) := Character'Pos (Image (A)) - Character'Pos ('0');
      end loop;
      return Res;
   end To_Digits;

   function All_Prime (Dig : Digit_Array) return Boolean is
     (for all D of Dig => Is_Prime (D));

   function Sum_Of (Dig : Digit_Array) return Number is
      Sum : Number := 0;
   begin
      for D of Dig loop
         Sum := Sum + D;
      end loop;
      return Sum;
   end Sum_Of;

   use Ada.Text_Io;
   Count : Natural := 0;
begin
   for N in Number range 1 .. 9_999 loop
      if Is_Prime (N) then
         declare
            Dig : constant Digit_Array := To_Digits (N);
         begin
            if All_Prime (Dig) and Is_Prime (Sum_Of (Dig)) then
               Count := Count + 1;
               Number_Io.Put (N, Width => 4); Put ("  ");
               if Count mod 8 = 0 then
                  New_Line;
               end if;
            end if;
         end;
      end if;
   end loop;
   New_Line;
   Put_Line (Count'Image & " extra primes.");
end Extra_Primes;