MODULE SelfDescribingNumber;

FROM WholeStr IMPORT
  CardToStr;
FROM STextIO IMPORT
  WriteString, WriteLn;
FROM SWholeIO IMPORT
  WriteCard;

PROCEDURE Check(Number: CARDINAL): BOOLEAN;
VAR
  I, D: CARDINAL;
  A: ARRAY [0 .. 9] OF CHAR;
  Count, W: ARRAY [0 .. 9] OF CARDINAL;
  Result: BOOLEAN;
BEGIN
  CardToStr(Number, A);
  FOR I := 0 TO 9 DO
    Count[I] := 0;
    W[I] := 0;
  END;
  FOR I := 0 TO LENGTH(A) - 1 DO
    D := ORD(A[I]) - ORD("0");
    INC(Count[D]);
    W[I] := D;
  END;
  Result := TRUE;
  I := 0;
  WHILE Result AND (I <= 9) DO
    Result := (Count[I] = W[I]);
    INC(I);
  END;
  RETURN Result;
END Check;

VAR
  X: CARDINAL;

BEGIN
  WriteString("Autodescriptive numbers from 1 to 100000000:");
  WriteLn;
  FOR X := 1 TO 100000000 DO
    IF Check(X) THEN
      WriteString(" ");
      WriteCard(X, 1);
      WriteLn;
    END;
  END;
  WriteString("Job done.");
  WriteLn;
END SelfDescribingNumber.


import algorithm, sequtils, std/monotimes, times

type Digit = 0..9

var digits = newSeqOfCap[Digit](10)

proc getDigits(n: Positive) =
  digits.setLen(0)
  var n = n.int
  while n != 0:
    digits.add n mod 10
    n = n div 10
  digits.reverse()

proc isSelfDescribing(n: Natural): bool =
  n.getDigits()
  for i, d in digits:
    if digits.count(i) != d:
      return false
  result = true

let t0 = getMonoTime()
for n in 1 .. 1_000_000_000:
  if n.isSelfDescribing:
    echo n, " in ", getMonoTime() - t0

echo "\nTotal time: ", getMonoTime() - t0


-- REXX program to check if a number (base 10) is self-describing.
parse arg x y .
if x=='' then exit
if y=='' then y=x
-- 10 digits is the maximum size number that works here, so cap it
numeric digits 10
y=min(y, 9999999999)

loop number = x to y
  loop i = 1 to number~length
      digit = number~subchar(i)
      -- return on first failure
      if digit \= number~countstr(i - 1) then iterate number
   end
   say number "is a self describing number"
end


Program SelfDescribingNumber;

uses
  SysUtils;

function check(number: longint): boolean;
  var
    i, d: integer;
    a: string;
    count, w : array [0..9] of integer;

  begin
    a := intToStr(number);
    for i := 0 to 9 do
    begin
      count[i] := 0;
      w[i] := 0;
    end;
    for i := 1 to length(a) do
    begin
      d := ord(a[i]) - ord('0');
      inc(count[d]);
      w[i - 1] := d;
    end;
    check := true;
    i := 0;
    while check and (i <= 9) do
    begin
      check := count[i] = w[i];
      inc(i);
    end;
  end;

var
  x: longint;

begin
  writeln ('Autodescriptive numbers from 1 to 100000000:');
  for x := 1 to 100000000 do
    if check(x) then
      writeln (' ', x);
  writeln('Job done.');
end.


sub is_selfdesc
{
	local $_ = shift;
	my @b = (0) x length;
	$b[$_]++ for my @a = split //;
	return "@a" eq "@b";
}

# check all numbers from 0 to 100k plus two 'big' ones
for (0 .. 100000, 3211000, 42101000) {
	print "$_\n" if is_selfdesc($_);
}


with javascript_semantics
function self_desc(integer i)
    sequence digits = repeat(0,10),
             counts = repeat(0,10)
    integer n = 0, digit
    while 1 do
        digit := mod(i,10)
        digits[10-n] := digit
        digit += 1
        counts[digit] += 1
        i = floor(i/10)
        if i=0 then exit end if
        n += 1
    end while
    return digits[10-n..10] = counts[1..n+1]
end function

atom t0 = time()
for i=10 to 100_000_000 by 10 do
    if self_desc(i) then ?i end if
end for
printf(1,"done (%s)\n",{elapsed(time()-t0)})


<?php

function is_describing($number) {
    foreach (str_split((int) $number) as $place => $value) {
        if (substr_count($number, $place) != $value) {
            return false;
        }
    }
    return true;
}

for ($i = 0; $i <= 50000000; $i += 10) {
    if (is_describing($i)) {
        echo $i . PHP_EOL;
    }
}

?>


self_desc(Num,L) =>
  L = [ I.to_integer() : I in Num.to_string()],
  Len = L.len,
  if sum(L) != Len then fail end,
  foreach(J in L)
    % cannot be a digit larger than the length of Num
    if J >= Len then fail end
  end,
  foreach(I in 0..Len-1)
   if sum([1 : J in L, I==J]) != L[I+1] then
      fail
   end
  end.


(de selfDescribing (N)
   (fully '((D I) (= D (cnt = N (circ I))))
      (setq N (mapcar format (chop N)))
      (range 0 (length N)) ) )


function Test-SelfDescribing ([int]$Number)
{
    [int[]]$digits = $Number.ToString().ToCharArray() | ForEach-Object {[Char]::GetNumericValue($_)}
    [int]$sum = 0

    for ($i = 0; $i -lt $digits.Count; $i++)
    {
        $sum += $i * $digits[$i]
    }

    $sum -eq $digits.Count
}


:- use_module(library(clpfd)).

self_describling :-
	forall(between(1, 10, I),
	       (findall(N, self_describling(I,N), L),
		format('Len ~w, Numbers ~w~n', [I, L]))).

% search of the self_describling numbers of a given len
self_describling(Len, N) :-
	length(L, Len),
	Len1 is Len - 1,
	L = [H|T],

	% the first figure is greater than 0
	H in 1..Len1,

	% there is a least to figures so the number of these figures
	% is at most Len - 2
	Len2 is Len - 2,
	T ins 0..Len2,

	% the sum of the figures is equal to the len of the number
	sum(L, #=, Len),

	% There is at least one figure corresponding to the number of zeros
	H1 #= H+1,
	element(H1, L, V),
	V #> 0,

	% create the list
	label(L),

	% test the list
	msort(L, LNS),
	packList(LNS,LNP),
	numlist(0, Len1, NumList),
	verif(LNP,NumList, L),

	% list is OK, create the number
	maplist(atom_number, LA, L),
	number_chars(N, LA).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% testing a number (not use in this program)
self_describling(N) :-
	number_chars(N, L),
	maplist(atom_number, L, LN),
	msort(LN, LNS),
	packList(LNS,LNP), !,
	length(L, Len),
	Len1 is Len - 1,
	numlist(0, Len1, NumList),
	verif(LNP,NumList, LN).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% verif(PackList, Order_of_Numeral, Numeral_of_the_nuber_to_test)
%  Packlist is of the form [[Number_of_Numeral, Order_of_Numeral]|_]
%  Test succeed when

%  All lists are empty
verif([], [], []).

% Packlist is empty and all lasting numerals are 0
verif([], [_N|S], [0|T]) :-
	verif([], S, T).

% Number of numerals N is V
verif([[V, N]|R], [N|S], [V|T]) :-
	verif(R, S, T).

% Number of numerals N is 0
verif([[V, N1]|R], [N|S], [0|T]) :-
	N #< N1,
	verif([[V,N1]|R], S, T).

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% ?- packList([a,a,a,b,c,c,c,d,d,e], L).
%  L = [[3,a],[1,b],[3,c],[2,d],[1,e]] .
% ?- packList(R,  [[3,a],[1,b],[3,c],[2,d],[1,e]]).
% R = [a,a,a,b,c,c,c,d,d,e] .
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
packList([],[]).

packList([X],[[1,X]]) :- !.

packList([X|Rest],[XRun|Packed]):-
    run(X,Rest, XRun,RRest),
    packList(RRest,Packed).

run(Var,[],[1, Var],[]).

run(Var,[Var|LRest],[N1, Var],RRest):-
    N #> 0,
    N1 #= N + 1,
    run(Var,LRest,[N, Var],RRest).

run(Var,[Other|RRest], [1, Var],[Other|RRest]):-
    dif(Var,Other).


Procedure isSelfDescribing(x.q)
  ;returns 1 if number is self-describing, otherwise it returns 0
  Protected digitCount, digit, i, digitSum
  Dim digitTally(10)
  Dim digitprediction(10)

  If x <= 0
    ProcedureReturn 0 ;number must be positive and non-zero
  EndIf

  While x > 0 And i < 10
    digit = x % 10
    digitSum + digit
    If digitSum > 10
      ProcedureReturn 0 ;sum of digits' values exceeds maximum possible
    EndIf
    digitprediction(i) = digit
    digitTally(digit) + 1
    x / 10
    i + 1
  Wend
  digitCount = i - 1

  If digitSum < digitCount Or x > 0
    ProcedureReturn 0  ;sum of digits' values is too small or number has more than 10 digits
  EndIf

  For i = 0 To digitCount
    If digitTally(i) <> digitprediction(digitCount - i)
      ProcedureReturn 0 ;number is not self-describing
    EndIf
  Next
  ProcedureReturn 1 ;number is self-describing
EndProcedure

Procedure displayAll()
  Protected i, j, t
  PrintN("Starting search for all self-describing numbers..." + #CRLF$)
  For j = 0 To 9
    PrintN(#CRLF$ + "Searching possibilites " + Str(j * 1000000000) + " -> " + Str((j + 1) * 1000000000 - 1)+ "...")
    t = ElapsedMilliseconds()
    For i = 0 To 999999999
      If isSelfDescribing(j * 1000000000 + i)
        PrintN(Str(j * 1000000000 + i))
      EndIf
    Next
    PrintN("Time to search this range of possibilities: " + Str((ElapsedMilliseconds() - t) / 1000) + "s.")
  Next
  PrintN(#CRLF$ + "Search complete.")
EndProcedure

If OpenConsole()

  DataSection
    Data.q 1210, 2020, 21200, 3211000, 42101000, 521001000, 6210001000, 3214314
  EndDataSection

  Define i, x.q
  For i = 1 To 8
    Read.q x
    Print(Str(x) + " is ")
    If Not isSelfDescribing(x)
      Print("not ")
    EndIf
    PrintN("selfdescribing.")
  Next
  PrintN(#CRLF$)

  displayAll()

  Print(#CRLF$ + #CRLF$ + "Press ENTER to exit"): Input()
  CloseConsole()
EndIf


  [ tuck over peek
    1+ unrot poke ]        is item++    ( n [ --> [ )

  [ [] 10 times [ 0 join ]
    swap
    [ 10 /mod rot item++
      swap dup 0 = until ]
    drop ]                 is digitcount (  n --> [ )

  [ 0 swap witheach + ]    is sum       (   [ --> n )

  [ 0 swap
    witheach
      [ swap 10 * + ] ]    is digits->n (   [ --> n )

  [ dup digitcount
    dup sum split drop
    digits->n = ]          is self-desc (   n --> b )

  4000000 times
    [ i^ self-desc if
        [ i^ echo cr ] ]


#lang racket
(define (get-digits number (lst null))
  (if (zero? number)
      lst
      (get-digits (quotient number 10) (cons (remainder number 10) lst))))

(define (self-describing? number)
  (if (= number 0) #f
      (let ((digits (get-digits number)))
        (for/fold ((bool #t))
          ((i (in-range (length digits))))
          (and bool
               (= (count (lambda (x) (= x i)) digits)
                  (list-ref digits i)))))))


my @values = <1210 2020 21200 3211000
42101000 521001000 6210001000 27 115508>;

for @values -> $test {
    say "$test is {sdn($test) ?? '' !! 'NOT ' }a self describing number.";
}

sub sdn($n) {
    my $s = $n.Str;
    my $chars = $s.chars;
    my @a = +«$s.comb;
    my @b;
    for @a -> $i {
        return False if $i >= $chars;
        ++@b[$i];
    }
    @b[$_] //= 0 for ^$chars;
    @a eqv @b;
}

.say if .&sdn for ^9999999;


Red []

;;-------------------------------------
count-dig: func ["count occurence of digit in number"
;;-------------------------------------
  s [string!] "number as string"
  sdig [char!] "search number as char"
][
cnt: #"0" ;; counter as char for performance optimization

while [s: find/tail s sdig][cnt: cnt + 1]
return cnt
]

;;-------------------------------------
isSDN?: func ["test if number is self describing number"
  s [string!] "number to test as string "
  ][
;;-------------------------------------

ind: #"0" ;; use digit as char for performance optimization

foreach ele s [
  if ele <> count-dig s ind [return false]
  ind: ind + 1
]
return true
]

repeat i 4000000 [  if isSDN? to-string i [print i] ]


/*REXX program determines if a number (in base 10)  is a  self─describing,              */
/*──────────────────────────────────────────────────────  self─descriptive,             */
/*──────────────────────────────────────────────────────  autobiographical,   or a      */
/*──────────────────────────────────────────────────────  curious  number.              */
parse arg x y .                                  /*obtain optional arguments from the CL*/
if x=='' | x==","  then exit                     /*Not specified?  Then get out of Dodge*/
if y=='' | y==","  then y=x                      /* "      "       Then use the X value.*/
w=length(y)                                      /*use  Y's  width for aligned output.  */
numeric digits max(9, w)                         /*ensure we can handle larger numbers. */
if x==y  then do                                 /*handle the case of a single number.  */
              noYes=test_SDN(y)                  /*is it  or  ain't it?                 */
              say y  word("is isn't", noYes+1)  'a self-describing number.'
              exit
              end

         do n=x  to  y
         if test_SDN(n)  then iterate            /*if not self─describing,  try again.  */
         say  right(n,w)  'is a self-describing number.'                       /*is it? */
         end   /*n*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
test_SDN: procedure; parse arg ?;    L=length(?) /*obtain the argument  and  its length.*/
                    do j=L  to 1  by -1          /*parsing backwards is slightly faster.*/
                    if substr(?,j,1)\==L-length(space(translate(?,,j-1),0))  then return 1
                    end   /*j*/
          return 0                               /*faster if used inverted truth table. */


# Project : Self-describing numbers

for num = 1 to 45000000
     res = 0
     for n=1 to len(string(num))
          temp = string(num)
          pos = number(temp[n])
          cnt = count(temp,string(n-1))
          if cnt = pos
             res = res + 1
          ok
      next
      if res = len(string(num))
         see num + nl
      ok
next

func count(cString,dString)
       sum = 0
       while substr(cString,dString) > 0
               sum = sum + 1
               cString = substr(cString,substr(cString,dString)+len(string(sum)))
       end
       return sum


def self_describing?(n)
  digits = n.digits.reverse
  digits.each_with_index.all?{|digit, idx| digits.count(idx) == digit}
end

3_300_000.times {|n| puts n if self_describing?(n)}


for i = 0 to 50000000 step 10
   a$ = str$(i)
   for c = 1 TO len(a$)
      d      = val(mid$(a$, c, 1))
      j(d)   = j(d) + 1
      k(c-1) = d
   next c
   r = 0
   for n = 0 to 10
      r    = r + (j(n) = k(n))
      j(n) = 0
      k(n) = 0
   next n
   if r = 11 then print i
next i
print "== End =="
end


fn is_self_desc(xx: u64) -> bool
{
    let s: String = xx.to_string();
    let mut count_vec = vec![0; 10];
    for c in s.chars() {
        count_vec[c.to_digit(10).unwrap() as usize] += 1;
    }
    for (i, c) in s.chars().enumerate() {
        if count_vec[i] != c.to_digit(10).unwrap() as usize {
            return false;
        }
    }
    return true;
}

fn main() {
    for i in 1..100000000 {
        if is_self_desc(i) {
            println!("{}", i)
        }
    }
}


object SelfDescribingNumbers extends App {
  def isSelfDescribing(a: Int): Boolean = {
    val s = Integer.toString(a)

    (0 until s.length).forall(i => s.count(_.toString.toInt == i) == s(i).toString.toInt)
  }

  println("Curious numbers n = x0 x1 x2...x9 such that xi is the number of digits equal to i in n.")

  for (i <- 0 to 42101000 by 10
       if isSelfDescribing(i)) println(i)

  println("Successfully completed without errors.")
}


$ include "seed7_05.s7i";

const func boolean: selfDescr (in string: stri) is func
  result
    var boolean: check is TRUE;
  local
    var integer: idx is 0;
    var array integer: count is [0 .. 9] times 0;
  begin
    for idx range 1 to length(stri) do
      incr(count[ord(stri[idx]) - ord('0')]);
    end for;
    idx := 1;
    while check and idx <= length(stri) do
      check := count[pred(idx)] = ord(stri[idx]) - ord('0');
      incr(idx);
    end while;
  end func;

const proc: gen (in integer: n) is func
  local
    var array integer : digits is 0 times 0;
    var string: stri is "";
    var integer: numberOfOneDigits is 0;
    var integer: idx is 0;
  begin
    while numberOfOneDigits <= 2 and numberOfOneDigits < n - 2 do
      digits := n times 0;
      digits[1] := n - 2 - numberOfOneDigits;
      if digits[1] <> 2 then
        digits[digits[1] + 1] := 1;
        digits[2] := 2;
        digits[3] := 1;
      else
        digits[2] := ord(numberOfOneDigits <> 0);
        digits[3] := 2;
      end if;
      stri := "";
      for idx range 1 to n do
        stri &:= chr(ord(digits[idx]) + ord('0'));
      end for;
      if selfDescr(stri) then
        writeln(stri);
      end if;
      incr(numberOfOneDigits);
    end while;
  end func;

const proc: main is func
  local
    const array integer: nums is [] (1210, 1337, 2020, 21200, 3211000, 42101000);
    var integer: number is 0;
  begin
    for number range nums do
      write(number <& " is ");
      if not selfDescr(str(number)) then
        write("not ");
      end if;
      writeln("self describing");
    end for;
    writeln;
    writeln("All autobiograph numbers:");
    for number range 1 to 10 do
      gen(number);
    end for;
  end func;


func sdn(Number n) {
    var b = [0]*n.len
    var a = n.digits.flip
    a.each { |i| b[i] := 0 ++ }
    a == b
}

var values = [1210, 2020, 21200, 3211000,
42101000, 521001000, 6210001000, 27, 115508]

values.each { |test|
    say "#{test} is #{sdn(test) ? '' : 'NOT ' }a self describing number."
}

say "\nSelf-descriptive numbers less than 1e5 (in base 10):"
^1e5 -> each { |i| say i if sdn(i) }


import Foundation

extension BinaryInteger {
  @inlinable
  public var isSelfDescribing: Bool {
    let stringChars = String(self).map({ String($0) })
    let counts = stringChars.reduce(into: [Int: Int](), {res, char in res[Int(char), default: 0] += 1})

    for (i, n) in stringChars.enumerated() where counts[i, default: 0] != Int(n) {
      return false
    }

    return true
  }
}

print("Self-describing numbers less than 100,000,000:")

DispatchQueue.concurrentPerform(iterations: 100_000_000) {i in
  defer {
    if i == 100_000_000 - 1 {
      exit(0)
    }
  }

  guard i.isSelfDescribing else {
    return
  }

  print(i)
}

dispatchMain()


package require Tcl 8.5
proc isSelfDescribing num {
    set digits [split $num ""]
    set len [llength $digits]
    set count [lrepeat $len 0]
    foreach d $digits {
	if {$d >= $len} {return false}
	lset count $d [expr {[lindex $count $d] + 1}]
    }
    foreach d $digits c $count {if {$c != $d} {return false}}
    return true
}

for {set i 0} {$i < 100000000} {incr i} {
    if {[isSelfDescribing $i]} {puts $i}
}


selfdescribing() {
    local n=$1
    local count=()
    local i
    for ((i=0; i<${#n}; i++)); do
        ((count[${n:i:1}]++))
    done
    for ((i=0; i<${#n}; i++)); do
        (( ${n:i:1} == ${count[i]:-0} )) || return 1
    done
    return 0
}

for n in 0 1 10 11 1210 2020 21200 3211000 42101000; do
    if selfdescribing $n; then
        printf "%d\t%s\n" $n yes
    else
        printf "%d\t%s\n" $n no
    fi
done


Function IsSelfDescribing(n)
	IsSelfDescribing = False
	Set digit = CreateObject("Scripting.Dictionary")
	For i = 1 To Len(n)
		k = Mid(n,i,1)
		If digit.Exists(k) Then
			digit.Item(k) = digit.Item(k) + 1
		Else
			digit.Add k,1
		End If
	Next
	c = 0
	For j = 0 To Len(n)-1
		l = Mid(n,j+1,1)
		If digit.Exists(CStr(j)) Then
			If digit.Item(CStr(j)) = CInt(l) Then
				c = c + 1
			End If
		ElseIf l = 0 Then
			c = c + 1
		Else
			Exit For
		End If
	Next
	If c = Len(n) Then
		IsSelfDescribing = True
	End If
End Function

'testing
start_time = Now
s = ""
For m = 1 To 100000000
	If 	IsSelfDescribing(m) Then
		WScript.StdOut.WriteLine m
	End If
Next
end_time = Now
WScript.StdOut.WriteLine "Elapse Time: " & DateDiff("s",start_time,end_time) & " seconds"


var selfDesc = Fn.new { |n|
    var ns = "%(n)"
    var nc = ns.count
    var count = List.filled(nc, 0)
    var sum = 0
    while (n > 0) {
        var d = n % 10
        if (d >= nc) return false  // can't have a digit >= number of digits
        sum = sum + d
        if (sum > nc) return false
        count[d] = count[d] + 1
        n = (n/10).floor
    }
    // to be self-describing sum of digits must equal number of digits
    if (sum != nc) return false
    return ns == count.join() // there must always be at least one zero
}

var start = System.clock
System.print("The self-describing numbers are:")
var i = 10   // self-describing number must end in 0
var pw = 10  // power of 10
var fd = 1   // first digit
var sd = 1   // second digit
var dg = 2   // number of digits
var mx = 11  // maximum for current batch
var lim = 9.1 * 1e9 + 1 // sum of digits can't be more than 10
while (i < lim) {
    if (selfDesc.call(i)) {
        var secs = ((System.clock - start) * 10).round / 10
        System.print("%(i) (in %(secs) secs)")
    }
    i = i + 10
    if (i > mx) {
        fd = fd + 1
        sd = sd - 1
        if (sd >= 0) {
            i = fd * pw
        } else {
            pw = pw * 10
            dg = dg + 1
            i = pw
            fd = 1
            sd = dg - 1
        }
        mx = i + sd*pw/10
    }
}
var osecs = ((System.clock - start) * 10).round / 10
System.print("\nTook %(osecs) secs overall")


code ChOut=8, IntOut=11;

func SelfDesc(N);               \Returns 'true' if N is self-describing
int N;
int Len,        \length = number of digits in N
    I, D;
char Digit(10), Count(10);

        proc Num2Str(N);        \Convert integer N to string in Digit
        int N;
        int R;
        [N:= N/10;
        R:= rem(0);
        if N then Num2Str(N);
        Digit(Len):= R;
        Len:= Len+1;
        ];

[Len:= 0;
Num2Str(N);
for I:= 0 to Len-1 do Count(I):= 0;
for I:= 0 to Len-1 do
        [D:= Digit(I);
        if D >= Len then return false;
        Count(D):= Count(D)+1;
        ];
for I:= 0 to Len-1 do
        if Count(I) # Digit(I) then return false;
return true;
]; \SelfDesc

int N;
for N:= 0 to 100_000_000-1 do
        if SelfDesc(N) then [IntOut(0, N);  ChOut(0, ^ )]


FOR N = 1 TO 5E7
    IF FNselfdescribing(N) PRINT N
NEXT

sub FNselfdescribing(N)
    LOCAL D(9), I, L, O

    O = N
    L = INT(LOG(N, 10))
    WHILE(N)
        I = MOD(N, 10)
        D(I) = D(I) + 10^(L-I)
        N = INT(N / 10)
    WEND

    L = 0
    FOR I = 0 TO 8 : L = L + D(I) : NEXT
    RETURN O = L
END SUB


fcn isSelfDescribing(n){
   if (n.bitAnd(1)) return(False); // Wikipedia: last digit must be zero
   nu:= n.toString();
   ns:=["0".."9"].pump(String,nu.inCommon,"len"); //"12233".inCommon("2")-->"22"
   (nu+"0000000000")[0,10] == ns;  //"2020","2020000000"
}


BEGIN # find some self numbers numbers n such that there is no g such that g + sum of g's digits = n #
    INT max number = 1 999 999 999 + 82; # maximum n plus g we will condifer #
    # sieve the self numbers up to 1 999 999 999 #
    [ 0 : max number ]BOOL self; FOR i TO UPB self DO self[ i ] := TRUE OD;
    INT n := 0;
    FOR s0 FROM 0 TO 1 DO
        FOR d1 FROM 0 TO 9 DO
            INT s1 = s0 + d1;
            FOR d2 FROM 0 TO 9 DO
                INT s2 = s1 + d2;
                FOR d3 FROM 0 TO 9 DO
                    INT s3 = s2 + d3;
                    FOR d4 FROM 0 TO 9 DO
                        INT s4 = s3 + d4;
                        FOR d5 FROM 0 TO 9 DO
                            INT s5 = s4 + d5;
                            FOR d6 FROM 0 TO 9 DO
                                INT s6 = s5 + d6;
                                FOR d7 FROM 0 TO 9 DO
                                    INT s7 = s6 + d7;
                                    FOR d8 FROM 0 TO 9 DO
                                        INT s8 = s7 + d8;
                                        FOR d9 FROM 0 TO 9 DO
                                            INT s9 = s8 + d9;
                                            self[ s9 + n ] := FALSE;
                                            n +:= 1
                                        OD
                                    OD
                                OD
                            OD
                        OD
                    OD
                OD
            OD
        OD
    OD;
    # show the first 50 self numbers #
    INT s count := 0;
    FOR i TO UPB self WHILE s count < 50 DO
        IF self[ i ] THEN
            print( ( " ", whole( i, -3 ) ) );
            IF ( s count +:= 1 ) MOD 18 = 0 THEN print( ( newline ) ) FI
        FI
    OD;
    print( ( newline ) );
    # show the self numbers with power-of-10 indxes #
    INT s show := 1;
    s count    := 0;
    print( ( "              nth self", newline ) );
    print( ( "        n       number", newline ) );
    FOR i TO UPB self DO
        IF self[ i ] THEN
            s count +:= 1;
            IF s count = s show THEN
                print( ( whole( s show, -9 ), "  ", whole( i, -11 ), newline ) );
                s show *:= 10
            FI
        FI
    OD
END


(*
    Base-10 self numbers by index (single or range).
    Follows an observed sequence pattern whereby, after the initial single-digit odd numbers, self numbers are
    grouped in runs whose members occur at numeric intervals of 11. Runs after the first one come in blocks of
    ten: eight runs of ten numbers followed by two shorter runs. The numeric interval between runs is usually 2,
    but that between shorter runs, and their length, depend on the highest-order digit change occurring in them.
    This connection with significant digit change means every ten blocks form a higher-order block, every ten
    of these a higher-order-still block, and so on.

    The code below appears to be good up to the last self number before 10^12 — ie. 999,999,999,997, which is
    returned as the 97,777,777,792nd such number. After this, instead of zero-length shorter runs, the actual
    pattern apparently starts again with a single run of 10, like the one at the beginning.
*)
on selfNumbers(indexRange)
    set indexRange to indexRange as list
    -- Script object with subhandlers and associated properties.
    script |subscript|
        property startIndex : beginning of indexRange
        property endIndex : end of indexRange
        property counter : 0
        property currentSelf : -1
        property output : {}

        -- Advance to the next self number in the sequence, append it to the output if required, indicate if finished.
        on doneAfterAdding(interval)
            set currentSelf to currentSelf + interval
            set counter to counter + 1
            if (counter < startIndex) then return false
            set end of my output to currentSelf
            return (counter = endIndex)
        end doneAfterAdding

        -- If necessary, fast forward to the last self number before the lowest-order block containing the first number required.
        on fastForward()
            if (counter ≥ startIndex) then return
            -- The highest-order blocks whose ends this script handles correctly contain 9,777,777,778 self numbers.
            -- The difference between equivalently positioned numbers in these blocks is 100,000,000,001.
            -- The figures for successively lower-order blocks have successively fewer 7s and 0s!
            set indexDiff to 9.777777778E+9
            set numericDiff to 1.00000000001E+11
            repeat until ((indexDiff < 98) or (counter = startIndex))
                set test to counter + indexDiff
                if (test < startIndex) then
                    set counter to test
                    set currentSelf to (currentSelf + numericDiff)
                else
                    set indexDiff to (indexDiff + 2) div 10
                    set numericDiff to numericDiff div 10 + 1
                end if
            end repeat
        end fastForward

        -- Work out a shorter run length based on the most significant digit change about to happen.
        on getShorterRunLength()
            set shorterRunLength to 9
            set temp to (|subscript|'s currentSelf) div 1000
            repeat while (temp mod 10 is 9)
                set shorterRunLength to shorterRunLength - 1
                set temp to temp div 10
            end repeat
            return shorterRunLength
        end getShorterRunLength
    end script

    -- Main process. Start with the single-digit odd numbers and first run.
    repeat 5 times
        if (|subscript|'s doneAfterAdding(2)) then return |subscript|'s output
    end repeat
    repeat 9 times
        if (|subscript|'s doneAfterAdding(11)) then return |subscript|'s output
    end repeat
    -- Fast forward if the start index hasn't yet been reached.
    tell |subscript| to fastForward()

    -- Sequencing loop, per lowest-order block.
    repeat
        -- Eight ten-number runs, each at a numeric interval of 2 from the end of the previous one.
        repeat 8 times
            if (|subscript|'s doneAfterAdding(2)) then return |subscript|'s output
            repeat 9 times
                if (|subscript|'s doneAfterAdding(11)) then return |subscript|'s output
            end repeat
        end repeat
        -- Two shorter runs, the second at an interval inversely related to their length.
        set shorterRunLength to |subscript|'s getShorterRunLength()
        repeat with interval in {2, 2 + (10 - shorterRunLength) * 13}
            if (|subscript|'s doneAfterAdding(interval)) then return |subscript|'s output
            repeat (shorterRunLength - 1) times
                if (|subscript|'s doneAfterAdding(11)) then return |subscript|'s output
            end repeat
        end repeat
    end repeat
end selfNumbers

-- Demo calls:
-- First to fiftieth self numbers.
selfNumbers({1, 50})
--> {1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, 97, 108, 110, 121, 132, 143, 154, 165, 176, 187, 198, 209, 211, 222, 233, 244, 255, 266, 277, 288, 299, 310, 312, 323, 334, 345, 356, 367, 378, 389, 400, 411, 413, 424, 435, 446, 457, 468}

-- One hundred millionth:
selfNumbers(100000000)
--> {1.022727208E+9}

-- 97,777,777,792nd:
selfNumbers(9.7777777792E+10)
--> {9.99999999997E+11}


awk 'BEGIN { RS = "" ; ORS = "\n----------------\n" } /Traceback/ && /SystemError/ { print substr($0,index($0,"Traceback")) }' Traceback.txt


NB. read file, separate on blank lines
paragraphs=: ((LF,LF)&E. <;.2 ])fread 'traceback.txt'

NB. ignore text preceding 'Traceback (most recent call last)'
cleaned=:  {{y}.~{.I.'Traceback (most recent call last)'&E.y}}each paragraphs

NB. limit to paragraphs containing 'SystemError'
searched=: (#~ (1 e.'SystemError'&E.)every) cleaned

NB. add "paragraph 'separator'" and display
echo ;searched ,L:0 '----------------',LF


def p1: "Traceback (most recent call last):";
def p2: "SystemError";
def sep: "----------------";

split("\n\n")[]
| index(p1) as $ix
| select( $ix and index(p2) )
| .[$ix:], sep


const filename = "traceback.txt"
const pmarker, target = "Traceback (most recent call last):", "SystemError"

foreach(
    p -> println(p, p[end] == '\n' ? "" : "\n", "-"^16),
    [
        p[findfirst(pmarker, p).start:end] for
        p in split(read(filename, String), r"\r?\n\r?\n") if
        contains(p, pmarker) && contains(p, target)
    ],
)


with javascript_semantics
--constant text = get_text("Traceback.txt") -- (not js!)
constant text = """
2018-06-19 23:19:34,877 ERROR Processes plugin raised an exception.
<snip>
    }""",
paras = split(text,"\n\n"),
tmrcl = "Traceback (most recent call last)"
for i=1 to length(paras) do
    string para = paras[i]
    integer tdx = match(tmrcl,para)
    if tdx then
        para = para[tdx..$]
        if match("SystemError",para) then
            printf(1,"%s\n----------------\n",{para})
        end if
    end if
end for


# syntax: GAWK -f SELF_NUMBERS.AWK
# converted from Go (low memory example)
BEGIN {
    print("HH:MM:SS      INDEX       SELF")
    print("-------- ---------- ----------")
    count = 0
    digits = 1
    i = 1
    last_self = 0
    offset = 9
    pow = 10
    while (count < 1E8) {
      is_self = 1
      start = max(i-offset,0)
      sum = sum_digits(start)
      for (j=start; j<i; j++) {
        if (j + sum == i) {
          is_self = 0
          break
        }
        sum = ((j+1) % 10 != 0) ? ++sum : sum_digits(j+1)
      }
      if (is_self) {
        last_self = i
        if (++count <= 50) {
          selfs = selfs i " "
        }
      }
      if (++i % pow == 0) {
        pow *= 10
        digits++
        offset = digits * 9
      }
      if (count ~ /^10*$/ && arr[count]++ == 0) {
        printf("%8s %10s %10s\n",strftime("%H:%M:%S"),count,last_self)
      }
    }
    printf("\nfirst 50 self numbers:\n%s\n",selfs)
    exit(0)
}
function sum_digits(x,  sum,y) {
    while (x) {
      y = x % 10
      sum += y
      x = int(x/10)
    }
    return(sum)
}
function max(x,y) { return((x > y) ? x : y) }


#include <stdio.h>
#include <stdlib.h>
#include <time.h>

typedef unsigned char bool;

#define TRUE 1
#define FALSE 0
#define MILLION 1000000
#define BILLION 1000 * MILLION
#define MAX_COUNT 2*BILLION + 9*9 + 1

void sieve(bool *sv) {
    int n = 0, s[8], a, b, c, d, e, f, g, h, i, j;
    for (a = 0; a < 2; ++a) {
        for (b = 0; b < 10; ++b) {
            s[0] = a + b;
            for (c = 0; c < 10; ++c) {
                s[1] = s[0] + c;
                for (d = 0; d < 10; ++d) {
                    s[2] = s[1] + d;
                    for (e = 0; e < 10; ++e) {
                        s[3] = s[2] + e;
                        for (f = 0; f < 10; ++f) {
                            s[4] = s[3] + f;
                            for (g = 0; g < 10; ++g) {
                                s[5] = s[4] + g;
                                for (h = 0; h < 10; ++h) {
                                    s[6] = s[5] + h;
                                    for (i = 0; i < 10; ++i) {
                                        s[7] = s[6] + i;
                                        for (j = 0; j < 10; ++j) {
                                            sv[s[7] + j+ n++] = TRUE;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}

int main() {
    int count = 0;
    clock_t begin = clock();
    bool *p, *sv = (bool*) calloc(MAX_COUNT, sizeof(bool));
    sieve(sv);
    printf("The first 50 self numbers are:\n");
    for (p = sv; p < sv + MAX_COUNT; ++p) {
        if (!*p) {
            if (++count <= 50) printf("%ld ", p-sv);
            if (count == 100 * MILLION) {
                printf("\n\nThe 100 millionth self number is %ld\n", p-sv);
                break;
            }
        }
    }
    free(sv);
    printf("Took %lf seconds.\n", (double)(clock() - begin) / CLOCKS_PER_SEC);
    return 0;
}


with open('Traceback.txt', 'r' ) as f:
    rawText = f.read()

paragraphs = rawText.split( "\n\n" )

for p in paragraphs:
    if "SystemError" in p:

        index = p.find( "Traceback (most recent call last):" )

        if -1 != index:
            print( p[index:] )
            print( "----------------" )


unit sub MAIN ( :$for, :$at = 0 );

put slurp.split( /\n\n+/ ).grep( { .contains: $for } )
         .map( { .substr: .index: $at } )
         .join: "\n----------------\n"


import "io" for File
import "./pattern" for Pattern

var fileName = "Traceback.txt"
var p1 = Pattern.new("Traceback (most recent call last):")
var p2 = Pattern.new("SystemError")
var sep = "----------------"

File.read(fileName)
    .split("\n\n")
    .where { |para| p1.isMatch(para) && p2.isMatch(para) }
    .each { |para|
        var ix = p1.find(para).index
        System.print(para[ix..-1])
        System.print(sep)
    }


#include <array>
#include <iomanip>
#include <iostream>

const int MC = 103 * 1000 * 10000 + 11 * 9 + 1;
std::array<bool, MC + 1> SV;

void sieve() {
    std::array<int, 10000> dS;
    for (int a = 9, i = 9999; a >= 0; a--) {
        for (int b = 9; b >= 0; b--) {
            for (int c = 9, s = a + b; c >= 0; c--) {
                for (int d = 9, t = s + c; d >= 0; d--) {
                    dS[i--] = t + d;
                }
            }
        }
    }
    for (int a = 0, n = 0; a < 103; a++) {
        for (int b = 0, d = dS[a]; b < 1000; b++, n += 10000) {
            for (int c = 0, s = d + dS[b] + n; c < 10000; c++) {
                SV[dS[c] + s++] = true;
            }
        }
    }
}

int main() {
    sieve();

    std::cout << "The first 50 self numbers are:\n";
    for (int i = 0, count = 0; count <= 50; i++) {
        if (!SV[i]) {
            count++;
            if (count <= 50) {
                std::cout << i << ' ';
            } else {
                std::cout << "\n\n       Index     Self number\n";
            }
        }
    }
    for (int i = 0, limit = 1, count = 0; i < MC; i++) {
        if (!SV[i]) {
            if (++count == limit) {
                //System.out.printf("%,12d   %,13d%n", count, i);
                std::cout << std::setw(12) << count << "   " << std::setw(13) << i << '\n';
                limit *= 10;
            }
        }
    }

    return 0;
}


F is_semiprime(=c)
   V a = 2
   V b = 0
   L b < 3 & c != 1
      I c % a == 0
         c /= a
         b++
      E
         a++
   R b == 2

print((1..100).filter(n -> is_semiprime(n)))


using System;
using static System.Console;

class Program {

  const int mc = 103 * 1000 * 10000 + 11 * 9 + 1;

  static bool[] sv = new bool[mc + 1];

  static void sieve() { int[] dS = new int[10000];
    for (int a = 9, i = 9999; a >= 0; a--)
      for (int b = 9; b >= 0; b--)
        for (int c = 9, s = a + b; c >= 0; c--)
          for (int d = 9, t = s + c; d >= 0; d--)
            dS[i--] = t + d;
    for (int a = 0, n = 0; a < 103; a++)
      for (int b = 0, d = dS[a]; b < 1000; b++, n += 10000)
        for (int c = 0, s = d + dS[b] + n; c < 10000; c++)
          sv[dS[c] + s++] = true; }

  static void Main() { DateTime st = DateTime.Now; sieve();
    WriteLine("Sieving took {0}s", (DateTime.Now - st).TotalSeconds);
    WriteLine("\nThe first 50 self numbers are:");
    for (int i = 0, count = 0; count <= 50; i++) if (!sv[i]) {
        count++; if (count <= 50) Write("{0} ", i);
        else WriteLine("\n\n       Index     Self number"); }
    for (int i = 0, limit = 1, count = 0; i < mc; i++)
      if (!sv[i]) if (++count == limit) {
          WriteLine("{0,12:n0}   {1,13:n0}", count, i);
          if (limit == 1e9) break; limit *= 10; }
    WriteLine("\nOverall took {0}s", (DateTime.Now - st). TotalSeconds);
  }
}


*        Semiprime                 14/03/2017
SEMIPRIM CSECT
         USING  SEMIPRIM,R13       base register
         B      72(R15)            skip savearea
         DC     17F'0'             savearea
         STM    R14,R12,12(R13)    save previous context
         ST     R13,4(R15)         link backward
         ST     R15,8(R13)         link forward
         LR     R13,R15            set addressability
         LA     R10,PG             pgi=0
         LA     R8,0               m=0
         L      R6,=F'2'           i=2
       DO WHILE=(C,R6,LE,=F'100')  do i=2 to 100
         ST     R6,N                 n=i
         LA     R9,0                 f=0
         LA     R7,2                 j=2
LOOPJ    EQU    *                    do j=2 while f<2 and j*j<=n
         C      R9,=F'2'               if f<2
         BNL    EXITJ                  then exit do j
         LR     R5,R7                  j
         MR     R4,R7                  *j
         C      R5,N                   if j*j<=n
         BH     EXITJ                  then exit do j
LOOPK    EQU    *                      do while n mod j=0
         L      R4,N                     n
         SRDA   R4,32                    ~
         DR     R4,R7                    /j
         LTR    R4,R4                    if n mod <>0
         BNZ    EXITK                    then exit do j
         ST     R5,N                     n=n/j
         LA     R9,1(R9)                 f=f+1
         B      LOOPK                  enddo k
EXITK    LA     R7,1(R7)               j++
         B      LOOPJ                enddo j
EXITJ    L      R4,N                 n
       IF C,R4,GT,=F'1' THEN         if n>1 then
         LA     R2,1                   g=1
       ELSE     ,                    else
         LA     R2,0                   g=0
       ENDIF    ,                    endif
         AR     R2,R9                +f
       IF C,R2,EQ,=F'2' THEN         if f+(n>1)=2 then
         XDECO  R6,XDEC                edit i
         MVC    0(5,R10),XDEC+7        output i
         LA     R10,5(R10)             pgi=pgi+10
         LA     R8,1(R8)               m=m+1
         LR     R4,R8                  m
         SRDA   R4,32                  ~
         D      R4,=F'16'              m/16
       IF LTR,R4,Z,R4 THEN             if m mod 16=0 then
         XPRNT  PG,L'PG                  print buffer
         MVC    PG,=CL80' '              clear buffer
         LA     R10,PG                   pgi=0
       ENDIF    ,                      endif
       ENDIF    ,                    endif
         LA     R6,1(R6)             i++
       ENDDO    ,                  enddo i
         XPRNT  PG,L'PG            print buffer
         MVC    PG,=CL80'..... semiprimes'  init buffer
         XDECO  R8,XDEC            edit m
         MVC    PG(5),XDEC+7       output m
         XPRNT  PG,L'PG            print buffer
         L      R13,4(0,R13)       restore previous savearea pointer
         LM     R14,R12,12(R13)    restore previous context
         XR     R15,R15            rc=0
         BR     R14                exit
N        DS     F                  n
PG       DC     CL80' '            buffer
XDEC     DS     CL12               temp
         YREGS
         END    SEMIPRIM


BYTE FUNC IsSemiPrime(INT n)
  INT a,b

  a=2 b=0
  WHILE b<3 AND n#1
  DO
    IF n MOD a=0 THEN
      n==/a b==+1
    ELSE
      a==+1
    FI
  OD
  IF b=2 THEN
    RETURN(1)
  FI
RETURN(0)

PROC Main()
  INT i

  PrintE("Semiprimes:")
  FOR i=1 TO 500
  DO
    IF IsSemiPrime(i) THEN
      PrintI(i) Put(32)
    FI
  OD
RETURN


with Prime_Numbers, Ada.Text_IO;

procedure Test_Semiprime is

   package Integer_Numbers is new
     Prime_Numbers (Natural, 0, 1, 2);
   use Integer_Numbers;

begin
   for N in 1 .. 100 loop
      if Decompose(N)'Length = 2 then -- N is a semiprime;
	 Ada.Text_IO.Put(Integer'Image(Integer(N)));
      end if;
   end loop;
   Ada.Text_IO.New_Line;
   for N in 1675 .. 1680 loop
      if Decompose(N)'Length = 2 then -- N is a semiprime;
	 Ada.Text_IO.Put(Integer'Image(Integer(N)));
      end if;
   end loop;
end Test_Semiprime;


# returns TRUE if n is semi-prime, FALSE otherwise            #
#         n is semi prime if it has exactly two prime factors #
PROC is semiprime = ( INT n )BOOL:
     BEGIN
         # We only need to consider factors between 2 and     #
         # sqrt( n ) inclusive. If there is only one of these #
         # then it must be a prime factor and so the number   #
         # is semi prime                                      #
         INT factor count := 0;
         FOR factor FROM 2 TO ENTIER sqrt( ABS n )
         WHILE IF n MOD factor = 0 THEN
                   factor count +:= 1;
                   # check the factor isn't a repeated factor #
                   IF n /= factor * factor THEN
                       # the factor isn't the square root     #
                       INT other factor = n OVER factor;
                       IF other factor MOD factor = 0 THEN
                           # have a repeated factor           #
                           factor count +:= 1
                       FI
                   FI
               FI;
               factor count < 2
         DO SKIP OD;
         factor count = 1
     END # is semiprime # ;

# determine the first few semi primes                          #
print( ( "semi primes below 100: " ) );
FOR i TO 99 DO
    IF is semi prime( i ) THEN print( ( whole( i, 0 ), " " ) ) FI
OD;
print( ( newline ) );
print( ( "semi primes below between 1670 and 1690: " ) );
FOR i FROM 1670 TO 1690 DO
    IF is semi prime( i ) THEN print( ( whole( i, 0 ), " " ) ) FI
OD;
print( ( newline ) )


defmodule SelfNums do

  def digAndSum(number) when is_number(number) do
    Integer.digits(number) |>
    Enum.reduce( 0, fn(num, acc) -> num + acc end ) |>
    (fn(x) -> x + number end).()
  end

  def selfFilter(list, firstNth) do
    numRange = Enum.to_list 1..firstNth
    numRange -- list
  end

end

defmodule SelfTest do

  import SelfNums
  stop = 1000
  Enum.to_list 1..stop |>
  Enum.map(&digAndSum/1) |>
  SelfNums.selfFilter(stop) |>
  Enum.take(50) |>
  IO.inspect

end


// Self numbers. Nigel Galloway: October 6th., 2020
let fN g=let rec fG n g=match n/10 with 0->n+g |i->fG i (g+(n%10)) in fG g g
let Self=let rec Self n i g=seq{let g=[email protected]([n..i]|>List.map fN) in yield! List.except g [n..i]; yield! Self (n+100) (i+100) (List.filter(fun n->n>i) g)} in Self 0 99 []

Self |> Seq.take 50 |> Seq.iter(printf "%d "); printfn ""
printfn "\n%d" (Seq.item 99999999 Self)


Print "The first 50 self numbers are:"
Dim As Boolean flag
Dim As Ulong m, p, sum, number(), sum2
Dim As Ulong n = 0
Dim As Ulong num = 0
Dim As Ulong limit = 51
Dim As Ulong limit2 = 100000000
Dim As String strnum

Do
    n += 1
    For m = 1 To n
        flag = True
        sum = 0
        strnum = Str(m)
        For p = 1 To Len(strnum)
            sum += Val(Mid(strnum,p,1))
        Next p
        sum2 = m + sum
        If sum2 = n Then
            flag = False
            Exit For
        Else
            flag = True
        End If
    Next m
    If flag = True Then
        num += 1
        If num < limit Then Print ""; num; ". "; n
        If num >= limit2 Then
            Print "The "; limit2; "th self number is: "; n
            Exit Do
        End If
    End If
Loop
Sleep


semiPrime?: function [x][
    2 = size factors.prime x
]

print select 1..100 => semiPrime?


package main

import (
    "fmt"
    "time"
)

func sumDigits(n int) int {
    sum := 0
    for n > 0 {
        sum += n % 10
        n /= 10
    }
    return sum
}

func max(x, y int) int {
    if x > y {
        return x
    }
    return y
}

func main() {
    st := time.Now()
    count := 0
    var selfs []int
    i := 1
    pow := 10
    digits := 1
    offset := 9
    lastSelf := 0
    for count < 1e8 {
        isSelf := true
        start := max(i-offset, 0)
        sum := sumDigits(start)
        for j := start; j < i; j++ {
            if j+sum == i {
                isSelf = false
                break
            }
            if (j+1)%10 != 0 {
                sum++
            } else {
                sum = sumDigits(j + 1)
            }
        }
        if isSelf {
            count++
            lastSelf = i
            if count <= 50 {
                selfs = append(selfs, i)
                if count == 50 {
                    fmt.Println("The first 50 self numbers are:")
                    fmt.Println(selfs)
                }
            }
        }
        i++
        if i%pow == 0 {
            pow *= 10
            digits++
            offset = digits * 9
        }
    }
    fmt.Println("\nThe 100 millionth self number is", lastSelf)
    fmt.Println("Took", time.Since(st))
}


import Control.Monad (forM_)
import Text.Printf

selfs :: [Integer]
selfs = sieve (sumFs [0..]) [0..]
  where
    sumFs = zipWith (+) [ a+b+c+d+e+f+g+h+i+j
                        | a <- [0..9] , b <- [0..9]
                        , c <- [0..9] , d <- [0..9]
                        , e <- [0..9] , f <- [0..9]
                        , g <- [0..9] , h <- [0..9]
                        , i <- [0..9] , j <- [0..9] ]

    -- More idiomatic list generator is about three times slower
    --  sumFs = zipWith (+) $ sum <$> replicateM  10 [0..9]

    sieve (f:fs) (n:ns)
      | n > f = sieve fs (n:ns)
      | n `notElem` take 81 (f:fs) = n : sieve (f:fs) ns
      | otherwise = sieve (f:fs) ns

main = do
  print $ take 50 selfs
  forM_ [1..8] $ \i ->
    printf "1e%v\t%v\n" (i :: Int) (selfs !! (10^i-1))


# syntax: GAWK -f SEMIPRIME.AWK
BEGIN {
    main(0,100)
    main(1675,1680)
    exit(0)
}
function main(lo,hi,  i) {
    printf("%d-%d:",lo,hi)
    for (i=lo; i<=hi; i++) {
      if (is_semiprime(i)) {
        printf(" %d",i)
      }
    }
    printf("\n")
}
function is_semiprime(n,  i,nf) {
    nf = 0
    for (i=2; i<=n; i++) {
      while (n % i == 0) {
        if (nf == 2) {
          return(0)
        }
        nf++
        n /= i
      }
    }
    return(nf == 2)
}


REM Semiprime
PRINT "Enter an integer ";
INPUT N
N = ABS(N)

Count = 0
IF N >= 2 THEN
  FOR Factor = 2 TO N
    NModFactor = N MOD Factor
    WHILE NModFactor = 0
      Count = Count + 1
      N = N / Factor
      NModFactor = N MOD Factor
    WEND
  NEXT Factor
ENDIF

IF Count = 2 THEN
  PRINT "It is a semiprime."
ELSE
  PRINT "It is not a semiprime."
ENDIF
END


#include <stdio.h>

int semiprime(int n)
{
	int p, f = 0;
	for (p = 2; f < 2 && p*p <= n; p++)
		while (0 == n % p)
			n /= p, f++;

	return f + (n > 1) == 2;
}

int main(void)
{
	int i;
	for (i = 2; i < 100; i++)
		if (semiprime(i)) printf(" %d", i);
	putchar('\n');

	return 0;
}


public class SelfNumbers {
    private static final int MC = 103 * 1000 * 10000 + 11 * 9 + 1;
    private static final boolean[] SV = new boolean[MC + 1];

    private static void sieve() {
        int[] dS = new int[10_000];
        for (int a = 9, i = 9999; a >= 0; a--) {
            for (int b = 9; b >= 0; b--) {
                for (int c = 9, s = a + b; c >= 0; c--) {
                    for (int d = 9, t = s + c; d >= 0; d--) {
                        dS[i--] = t + d;
                    }
                }
            }
        }
        for (int a = 0, n = 0; a < 103; a++) {
            for (int b = 0, d = dS[a]; b < 1000; b++, n += 10000) {
                for (int c = 0, s = d + dS[b] + n; c < 10000; c++) {
                    SV[dS[c] + s++] = true;
                }
            }
        }
    }

    public static void main(String[] args) {
        sieve();
        System.out.println("The first 50 self numbers are:");
        for (int i = 0, count = 0; count <= 50; i++) {
            if (!SV[i]) {
                count++;
                if (count <= 50) {
                    System.out.printf("%d ", i);
                } else {
                    System.out.printf("%n%n       Index     Self number%n");
                }
            }
        }
        for (int i = 0, limit = 1, count = 0; i < MC; i++) {
            if (!SV[i]) {
                if (++count == limit) {
                    System.out.printf("%,12d   %,13d%n", count, i);
                    limit *= 10;
                }
            }
        }
    }
}


static void Main(string[] args)
{
    //test some numbers
    for (int i = 0; i < 50; i++)
    {
        Console.WriteLine("{0}\t{1} ", i,isSemiPrime(i));
    }
    Console.ReadLine();
}

//returns true or false depending if input was considered semiprime
private static bool isSemiPrime(int c)
{
    int a = 2, b = 0;
    while (b < 3 && c != 1)
    {
        if ((c % a) == 0)
        {
            c /= a;
            b++;
        }
        else
        {
            a++;
        };
    }
    return b == 2;
}


#include <iostream>

bool isSemiPrime( int c )
{
    int a = 2, b = 0;
    while( b < 3 && c != 1 )
    {
	if( !( c % a ) )
	{ c /= a; b++; }
	else a++;
    }
    return b == 2;
}
int main( int argc, char* argv[] )
{
    for( int x = 2; x < 100; x++ )
	if( isSemiPrime( x ) )
	    std::cout << x << " ";

    return 0;
}


(ns example
  (:gen-class))

(defn semi-prime? [n]
  (loop [a 2
         b 0
         c n]
    (cond
      (> b 2) false
      (<= c 1) (= b 2)
      (= 0 (rem c a)) (recur a (inc b) (int (/ c a)))
      :else (recur (inc a) b c))))

(println (filter semi-prime? (range 1 100)))


def sumdigits: tostring | explode | map([.]|implode|tonumber) | add;

def gsum: . + sumdigits;

def isnonself:
  def ndigits: tostring|length;
  . as $i
  | ($i - ($i|ndigits)*9) as $n
  | any( range($i-1; [0,$n]|max; -1);
          gsum == $i);

# an array
def last81:
  [limit(81; range(1; infinite) | select(isnonself))];

# output an unbounded stream
def selfnumbers:
  foreach range(1; infinite) as $i ( [0, last81];
    .[0] = false
    | .[1] as $last81
    | if $last81 | bsearch($i) < 0
      then .[0] = $i
      | if $i > $last81[-1] then .[1] = $last81[1:] + [$i | gsum ] else . end
      else .
      end;
      .[0] | select(.) );

"The first 50 self numbers are:", last81[:50],
"",
(nth(100000000 - 1;  selfnumbers)
 | if . == 1022727208
   then "Yes, \(.) is the 100,000,000th self number."
   else "No,  \(.i) is actually the 100,000,000th self number."
   end)


gsum(i) = sum(digits(i)) + i
isnonself(i) = any(x -> gsum(x) == i, i-1:-1:i-max(1, ndigits(i)*9))
const last81 = filter(isnonself, 1:5000)[1:81]

function checkselfnumbers()
    i, selfcount = 1, 0
    while selfcount <= 100_000_000 && i <= 1022727208
        if !(i in last81)
            selfcount += 1
            if selfcount < 51
                print(i, " ")
            elseif selfcount == 51
                println()
            elseif selfcount == 100_000_000
                println(i == 1022727208 ?
                    "Yes, $i is the 100,000,000th self number." :
                    "No, instead $i is the 100,000,000th self number.")
            end
        end
        popfirst!(last81)
        push!(last81, gsum(i))
        i += 1
    end
end

checkselfnumbers()


private const val MC = 103 * 1000 * 10000 + 11 * 9 + 1
private val SV = BooleanArray(MC + 1)

private fun sieve() {
    val dS = IntArray(10000)
    run {
        var a = 9
        var i = 9999
        while (a >= 0) {
            for (b in 9 downTo 0) {
                var c = 9
                val s = a + b
                while (c >= 0) {
                    var d = 9
                    val t = s + c
                    while (d >= 0) {
                        dS[i--] = t + d
                        d--
                    }
                    c--
                }
            }
            a--
        }
    }
    var a = 0
    var n = 0
    while (a < 103) {
        var b = 0
        val d = dS[a]
        while (b < 1000) {
            var c = 0
            var s = d + dS[b] + n
            while (c < 10000) {
                SV[dS[c] + s++] = true
                c++
            }
            b++
            n += 10000
        }
        a++
    }
}

fun main() {
    sieve()
    println("The first 50 self numbers are:")
    run {
        var i = 0
        var count = 0
        while (count <= 50) {
            if (!SV[i]) {
                count++
                if (count <= 50) {
                    print("$i ")
                } else {
                    println()
                    println()
                    println("       Index     Self number")
                }
            }
            i++
        }
    }
    var i = 0
    var limit = 1
    var count = 0
    while (i < MC) {
        if (!SV[i]) {
            if (++count == limit) {
                println("%,12d   %,13d".format(count, i))
                limit *= 10
            }
        }
        i++
    }
}


(defun semiprimep (n &optional (a 2))
  (cond ((> a (isqrt n)) nil)
        ((zerop (rem n a)) (and (primep a) (primep (/ n a))))
        (t (semiprimep n (+ a 1)))))

(defun primep (n &optional (a 2))
  (cond ((> a (isqrt n)) t)
        ((zerop (rem n a)) nil)
        (t (primep n (+ a 1)))))


def semiprime(n)
  nf = 0
  (2..n).each do |i|
    while n % i == 0
      return false if nf == 2
      nf += 1
      n  /= i
    end
  end
  nf == 2
end

(1675..1681).each { |n| puts "#{n} -> #{semiprime(n)}" }


bool semiprime(long n) pure nothrow @safe @nogc {
    auto nf = 0;
    foreach (immutable i; 2 .. n + 1) {
        while (n % i == 0) {
            if (nf == 2)
                return false;
            nf++;
            n /= i;
        }
    }
    return nf == 2;
}

void main() {
    import std.stdio;

    foreach (immutable n; 1675 .. 1681)
        writeln(n, " -> ", n.semiprime);
}


sum[g_] := g + [email protected]@g

ming[n_] := n - IntegerLength[n]*9

self[n_] := NoneTrue [Range[ming[n], n - 1], sum[#] == n &]

Module[{t = 1, x = 1},
 Reap[
   While[t <= 50,
    If[self[x], Sow[x]; t++]; x++]
   ][[2, 1]]]


import bitops, strutils, std/monotimes, times

const MaxCount = 2 * 1_000_000_000 + 9 * 9

# Bit string used to represent an array of booleans.
type BitString = object
  len: Natural        # length in bits.
  values: seq[byte]   # Sequence containing the bits.

proc newBitString(n: Natural): BitString =
  ## Return a new bit string of length "n" bits.
  result.len = n
  result.values.setLen((n + 7) shr 3)

template checkIndex(i, length: Natural) {.used.} =
  ## Check if index "i" is less than the array length.
  if i >= length:
    raise newException(IndexDefect, "index $1 not in 0 .. $2".format(i, length))

proc `[]`(bs: BitString; i: Natural): bool =
  ## Return the value of bit at index "i" as a boolean.
  when compileOption("boundchecks"):
    checkIndex(i, bs.len)
  result = bs.values[i shr 3].testbit(i and 0x07)

proc `[]=`(bs: var BitString; i: Natural; value: bool) =
  ## Set the bit at index "i" to the given value.
  when compileOption("boundchecks"):
    checkIndex(i, bs.len)
  if value: bs.values[i shr 3].setBit(i and 0x07)
  else: bs.values[i shr 3].clearBit(i and 0x07)

proc fill(sieve: var BitString) =
  ## Fill a sieve.
  var n = 0
  for a in 0..1:
    for b in 0..9:
      for c in 0..9:
        for d in 0..9:
          for e in 0..9:
            for f in 0..9:
              for g in 0..9:
                for h in 0..9:
                  for i in 0..9:
                    for j in 0..9:
                      sieve[a + b + c + d + e + f + g + h + i + j + n] = true
                      inc n

let t0 = getMonoTime()

var sieve = newBitString(MaxCount + 1)
sieve.fill()
echo "Sieve time: ", getMonoTime() - t0

# Find first 50.
echo "\nFirst 50 self numbers:"
var count = 0
var line = ""
for n in 0..MaxCount:
  if not sieve[n]:
    inc count
    line.addSep(" ")
    line.add $n
    if count == 50: break
echo line

# Find 1st, 10th, 100th, ..., 100_000_000th.
echo "\n      Rank       Value"
var limit = 1
count = 0
for n in 0..MaxCount:
  if not sieve[n]: inc count
  if count == limit:
    echo ($count).align(10), ($n).align(12)
    limit *= 10
echo "Total time: ", getMonoTime() - t0


program selfnumb;
{$IFDEF FPC}
  {$MODE Delphi}
  {$Optimization ON,ALL}
{$IFEND}
{$IFDEF DELPHI} {$APPTYPE CONSOLE} {$IFEND}
uses
  sysutils;
const
  MAXCOUNT =103*10000*10000+11*9+ 1;
type
  tDigitSum9999 = array[0..9999] of Uint8;
  tpDigitSum9999 = ^tDigitSum9999;
var
  DigitSum9999 : tDigitSum9999;
  sieve : array of boolean;

procedure dosieve;
var
  pSieve : pBoolean;
  pDigitSum :tpDigitSum9999;
  n,c,b,a,s : NativeInt;
Begin
  pSieve := @sieve[0];
  pDigitSum := @DigitSum9999[0];
  n := 0;
  for a := 0 to 102 do
    for b := 0 to 9999 do
    Begin
      s := pDigitSum^[a]+pDigitSum^[b]+n;
      for c := 0 to 9999 do
      Begin
        pSieve[pDigitSum^[c]+s] := true;
        s+=1;
      end;
      inc(n,10000);
    end;
end;

procedure InitDigitSum;
var
  i,d,c,b,a : NativeInt;
begin
  i := 9999;
  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
          DigitSum9999[i] := a+b+c+d;
          dec(i);
        end;
end;

procedure OutPut(cnt,i:NativeUint);
Begin
  writeln(cnt:10,i:12);
end;

var
  pSieve : pboolean;
  T0 : Uint64;
  i,cnt,limit,One: NativeUInt;
BEGIN
  setlength(sieve,MAXCOUNT);
  pSieve := @sieve[0];
  T0 := GetTickCount64;
  InitDigitSum;
  dosieve;
  writeln('Sievetime : ',(GetTickCount64-T0 )/1000:8:3,' sec');
  //find first 50
  cnt := 0;
  for i := 0 to MAXCOUNT do
  Begin
    if NOT(pSieve[i]) then
    Begin
      inc(cnt);
      if cnt <= 50 then
        write(i:4)
      else
        BREAK;
    end;
  end;
  writeln;
  One := 1;
  limit := One;
  cnt := 0;
  for i := 0 to MAXCOUNT do
  Begin
    inc(cnt,One-Ord(pSieve[i]));
    if cnt = limit then
    Begin
      OutPut(cnt,i);
      limit := limit*10;
    end;
  end;
END.


$ p1 = f$integer( p1 )
$ if p1 .lt. 2
$ then
$  write sys$output "out of range 2 thru 2^31-1"
$  exit
$ endif
$
$ close /nolog primes
$ on control_y then $ goto clean
$ open primes primes.txt
$
$ loop1:
$  read /end_of_file = prime primes prime
$  prime = f$integer( prime )
$  loop2:
$   t = p1 / prime
$   if t * prime .eq. p1
$   then
$    if f$type( factorization ) .eqs. ""
$    then
$     factorization = f$string( prime )
$    else
$     factorization = factorization + "*" + f$string( prime )
$    endif
$    if t .eq. 1 then $ goto done
$    p1 = t
$    goto loop2
$   else
$    goto loop1
$   endif
$ prime:
$ if f$type( factorization ) .eqs. ""
$ then
$  factorization = f$string( p1 )
$ else
$  factorization = factorization + "*" + f$string( p1 )
$ endif
$ done:
$ show symbol factorization
$ if f$locate( "*", factorization ) .eq. f$length( factorization )
$ then
$  write sys$output "so, it is prime"
$ else
$  if f$element( 2, "*", factorization ) .eqs. "*" then $ write sys$output "so, it is semiprime"
$ endif
$
$ clean:
$ close primes


use strict;
use warnings;
use feature 'say';
use List::Util qw(max sum);

my ($i, $pow, $digits, $offset, $lastSelf, @selfs)
 = ( 1,   10,       1,       9,         0,       );

my $final = 50;

while () {
   my $isSelf = 1;
   my $sum = my $start = sum split //, max(($i-$offset), 0);
   for ( my $j = $start; $j < $i; $j++ ) {
      if ($j+$sum == $i) { $isSelf = 0 ; last }
      ($j+1)%10 != 0 ? $sum++ : ( $sum = sum split '', ($j+1) );
   }

   if ($isSelf) {
      push @selfs, $lastSelf = $i;
      last if @selfs == $final;
   }

   next unless ++$i % $pow == 0;
   $pow *= 10;
   $offset = 9 * $digits++
}

say "The first 50 self numbers are:\n" . join ' ', @selfs;


--
--  Base-10 self numbers by index (single or range).
--  Follows an observed sequence pattern whereby, after the initial single-digit odd numbers, self numbers are
--  grouped in runs whose members occur at numeric intervals of 11. Runs after the first one come in blocks of
--  ten: eight runs of ten numbers followed by two shorter runs. The numeric interval between runs is usually 2,
--  but that between shorter runs, and their length, depend on the highest-order digit change occurring in them.
--  This connection with significant digit change means every ten blocks form a higher-order block, every ten
--  of these a higher-order-still block, and so on.
--
--  The code below appears to be good up to the last self number before 10^12 — ie. 999,999,999,997, which is
--  returned as the 97,777,777,792nd such number. After this, instead of zero-length shorter runs, the actual
--  pattern apparently starts again with a single run of 10, like the one at the beginning.
--
integer startIndex, endIndex, counter
atom currentSelf
sequence output

function doneAfterAdding(integer interval, n)
-- Advance to the next self number in the sequence, append it to the output if required, indicate if finished.
    for i=1 to n do
        currentSelf += interval
        counter += 1
        if counter >= startIndex then
            output &= currentSelf
        end if
        if counter = endIndex then return true end if
    end for
    return false
end function

function selfNumbers(sequence indexRange)
    startIndex = indexRange[1]
    endIndex = indexRange[$]
    counter = 0
    currentSelf = -1
    output = {}

    -- Main process. Start with the single-digit odd numbers and first run.
    if doneAfterAdding(2,5) then return output end if
    if doneAfterAdding(11,9) then return output end if

    -- If necessary, fast forward to last self number before the lowest-order block containing first number rqd.
    if counter<startIndex then
        -- The highest-order blocks whose ends this handles correctly contain 9,777,777,778 self numbers.
        -- The difference between equivalently positioned numbers in these blocks is 100,000,000,001.
        -- The figures for successively lower-order blocks have successively fewer 7s and 0s!
        atom indexDiff = 9777777778,
             numericDiff = 100000000001
        while indexDiff>=98 and counter!=startIndex do
            if counter+indexDiff < startIndex then
                counter += indexDiff
                currentSelf += numericDiff
            else
                indexDiff = (indexDiff+2)/10    -- (..78->80->8)
                numericDiff = (numericDiff+9)/10 -- (..01->10->1)
            end if
        end while
    end if

    -- Sequencing loop, per lowest-order block.
    while true do
        -- Eight ten-number runs, each at a numeric interval of 2 from the end of the previous one.
        for i=1 to 8 do
            if doneAfterAdding(2,1) then return output end if
            if doneAfterAdding(11,9) then return output end if
        end for
        -- Two shorter runs, the second at an interval inversely related to their length.
        integer shorterRunLength = 8,
                temp = floor(currentSelf/1000)
        -- Work out a shorter run length based on the most significant digit change about to happen.
        while remainder(temp,10)=9 do
            shorterRunLength -= 1
            temp = floor(temp/10)
        end while

        integer interval = 2
        for i=1 to 2 do
            if doneAfterAdding(interval,1) then return output end if
            if doneAfterAdding(11,shorterRunLength) then return output end if
            interval += (9-shorterRunLength)*13
        end for
    end while
end function

atom t0 = time()
printf(1,"The first 50 self numbers are:\n")
pp(selfNumbers({1, 50}),{pp_IntFmt,"%3d",pp_IntCh,false})
for p=8 to 9 do
    integer n = power(10,p)
    printf(1,"The %,dth safe number is %,d\n",{n,selfNumbers({n})[1]})
end for
printf(1,"completed in %s\n",elapsed(time()-t0))


defmodule Prime do
  def semiprime?(n), do: length(decomposition(n)) == 2

  def decomposition(n), do: decomposition(n, 2, [])

  defp decomposition(n, k, acc) when n < k*k, do: Enum.reverse(acc, [n])
  defp decomposition(n, k, acc) when rem(n, k) == 0, do: decomposition(div(n, k), k, [k | acc])
  defp decomposition(n, k, acc), do: decomposition(n, k+1, acc)
end

IO.inspect Enum.filter(1..100, &Prime.semiprime?(&1))
Enum.each(1675..1680, fn n ->
  :io.format "~w -> ~w\t~s~n", [n, Prime.semiprime?(n), Prime.decomposition(n)|>Enum.join(" x ")]
end)


-module(factors).
-export([factors/1,kthfactor/2]).

factors(N) ->
     factors(N,2,[]).

factors(1,_,Acc) -> Acc;
factors(N,K,Acc) when N rem K == 0 ->
    factors(N div K,K, [K|Acc]);
factors(N,K,Acc) ->
    factors(N,K+1,Acc).

% is integer N factorable into M primes?
kthfactor(N,M) ->
    case length(factors(N)) of M ->
      factors(N);
      _ ->
      false end.


PROGRAM SEMIPRIME_NUMBER

!VAR I%

PROCEDURE SEMIPRIME(N%->RESULT%)
   LOCAL F%,P%
   P%=2
   LOOP
       EXIT IF NOT(F%<2 AND P%*P%<=N%)
       WHILE (N% MOD P%)=0 DO
            N%=N% DIV P%
            F%+=1
       END WHILE
       P%+=1
    END LOOP
    RESULT%=F%-(N%>1)=2
END PROCEDURE

BEGIN
    PRINT(CHR$(12);) !CLS
    FOR I%=2 TO 100 DO
         SEMIPRIME(I%->RESULT%)
         IF RESULT% THEN PRINT(I%;) END IF
    END FOR
    PRINT
END PROGRAM


let isSemiprime (n: int) =
    let rec loop currentN candidateFactor numberOfFactors =
        if numberOfFactors > 2 then numberOfFactors
        elif currentN = candidateFactor then numberOfFactors+1
        elif currentN % candidateFactor = 0 then loop (currentN/candidateFactor) candidateFactor (numberOfFactors+1)
        else loop currentN (candidateFactor+1) numberOfFactors
    if n < 2 then false else 2 = loop n 2 0

seq { 1 .. 100 } |> Seq.choose (fun n -> if isSemiprime n then Some(n) else None)
|> Seq.toList |> printfn "%A"

seq { 1675 .. 1680 }
|> Seq.choose (fun n -> if isSemiprime n then Some(n) else None)
|> Seq.toList
|> printfn "%A"


class DigitSumer :
    def __init__(self):
        sumdigit = lambda n : sum( map( int,str( n )))
        self.t = [sumdigit( i ) for i in xrange( 10000 )]
    def __call__ ( self,n ):
        r = 0
        while n >= 10000 :
            n,q = divmod( n,10000 )
            r += self.t[q]
        return r + self.t[n]

def self_numbers ():
    d = DigitSumer()
    s = set([])
    i = 1
    while 1 :
        n = i + d( i )
        if i in s :
            s.discard( i )
        else:
            yield i
        s.add( n )
        i += 1

import time
p = 100
t = time.time()
for i,s in enumerate( self_numbers(),1 ):
    if i <= 50 :
        print s,
        if i == 50 : print
    if i == p :
        print '%7.1f sec  %9dth = %d'%( time.time()-t,i,s )
        p *= 10


# 20201127 Raku programming solution

my ( $st, $count, $i, $pow, $digits, $offset, $lastSelf, $done, @selfs) =
     now,      0,  1,   10,       1,       9,         0, False;

# while ( $count < 1e8 ) {
until $done {
   my $isSelf = True;
   my $sum    = (my $start = max ($i-$offset), 0).comb.sum;
   loop ( my $j = $start; $j < $i; $j+=1 ) {
      if $j+$sum == $i { $isSelf = False and last }
      ($j+1)%10 != 0 ?? ( $sum+=1 ) !! ( $sum = ($j+1).comb.sum ) ;
   }
   if $isSelf {
      $count+=1;
      $lastSelf = $i;
      if $count ≤ 50 {
         @selfs.append: $i;
         if $count == 50 {
            say "The first 50 self numbers are:\n", @selfs;
            $done = True;
         }
      }
   }
   $i+=1;
   if $i % $pow == 0 {
      $pow *= 10;
      $digits+=1 ;
      $offset = $digits * 9
   }
}

# say "The 100 millionth self number is ", $lastSelf;
# say "Took ", now - $st, " seconds."


USING: io kernel math.primes.factors prettyprint sequences ;

: semiprime? ( n -- ? ) factors length 2 = ;


: semiprime?
  0 swap dup 2 do
    begin dup i mod 0= while i / swap 1+ swap repeat
    over 1 > over i dup * < or if leave then
  loop 1 > abs + 2 =
;

: test 100 2 do i semiprime? if i . then loop cr ;


isSemiprime[n] :=
{
   factors = factor[n]
   sum = 0
   for [num, power] = factors
      sum = sum + power

   return sum == 2
}


package main

import "fmt"

func semiprime(n int) bool {
    nf := 0
    for i := 2; i <= n; i++ {
        for n%i == 0 {
            if nf == 2 {
                return false
            }
            nf++
            n /= i
        }
    }
    return nf == 2
}

func main() {
    for v := 1675; v <= 1680; v++ {
        fmt.Println(v, "->", semiprime(v))
    }
}


/*REXX program displays  N  self numbers (aka Colombian or Devlali numbers). OEIS A3052.*/
parse arg n .                                    /*obtain optional argument from the CL.*/
if n=='' | n==","  then n= 50                    /*Not specified?  Then use the default.*/
tell = n>0;             n= abs(n)                /*TELL:  show the self numbers if  N>0 */
@.= .                                            /*initialize the array of self numbers.*/
           do j=1  for n*10                      /*scan through ten times the #s wanted.*/
           $= j                                  /*1st part of sum is the number itself.*/
                 do k=1  for length(j)           /*sum the decimal digits in the number.*/
                 $= $ + substr(j, k, 1)          /*add a particular digit to the sum.   */
                 end   /*k*/
           @.$=                                  /*mark  J  as not being a self number. */
           end         /*j*/                     /*            ───                      */
list= 1                                          /*initialize the list to the 1st number*/
                 #= 1                            /*the count of self numbers  (so far). */
   do i=3  until #==n;  if @.i=='' then iterate  /*Not a self number?   Then skip it.   */
   #= # + 1;            list= list i             /*bump counter of self #'s; add to list*/
   end   /*i*/
                                                 /*stick a fork in it,  we're all done. */
say   n     " self numbers were found."          /*display the title for the output list*/
if tell  then say list                           /*display list of self numbers ──►term.*/


load "stdlib.ring"

see "working..." + nl
see "The first 50 self numbers are:" + nl

n = 0
num = 0
limit = 51
limit2 = 10000000

while true
    n = n + 1
    for m = 1 to n
        flag = 1
        sum = 0
        strnum = string(m)
        for p = 1 to len(strnum)
            sum = sum + number(strnum[p])
        next
        sum2 = m + sum
        if sum2 = n
           flag = 0
           exit
        else
           flag = 1
        ok
     next
     if flag = 1
        num = num + 1
        if num < limit
           see "" + num + ". " + n + nl
        ok
        if num = limit2
           see "The " + limit2 + "th self number is: " + n + nl
        ok
        if num > limit2
           exit
        ok
     ok
end

see "done..." + nl


func is_self_number(n) {

    if (n < 30) {
        return (((n < 10) && (n.is_odd)) || (n == 20))
    }

    var qd = (1 + n.ilog10)
    var r  = (1 + (n-1)%9)
    var h  = (r + 9*(r%2))/2
    var ld = 10

    while (h + 9*qd >= n%ld) {
        ld *= 10
    }

    var vs = idiv(n, ld).sumdigits
    n %= ld

    0..qd -> none { |i|
        vs + sumdigits(n - h - 9*i) == (h + 9*i)
    }
}

say is_self_number.first(50).join(' ')


isSemiprime :: Int -> Bool
isSemiprime n = (length factors) == 2 && (product factors) == n ||
                (length factors) == 1 && (head factors) ^ 2 == n
                    where factors = primeFactors n


link "factors"

procedure main(A)
    every nf := semiprime(n := !A) do write(n," = ",nf[1]," * ",nf[2])
end

procedure semiprime(n)  # Succeeds and produces the factors only if n is semiprime.
    return (2 = *(nf := factors(n)), nf)
end


import java.math.BigInteger;
import java.util.ArrayList;
import java.util.List;

public class SemiPrime{
	private static final BigInteger TWO = BigInteger.valueOf(2);

	public static List<BigInteger> primeDecomp(BigInteger a){
	    // impossible for values lower than 2
	    if(a.compareTo(TWO) < 0){
	        return null;
	    }

	    //quickly handle even values
	    List<BigInteger> result = new ArrayList<BigInteger>();
	    while(a.and(BigInteger.ONE).equals(BigInteger.ZERO)){
	        a = a.shiftRight(1);
	        result.add(TWO);
	    }

	    //left with odd values
	    if(!a.equals(BigInteger.ONE)){
	        BigInteger b = BigInteger.valueOf(3);
	        while(b.compareTo(a) < 0){
	            if(b.isProbablePrime(10)){
	                BigInteger[] dr = a.divideAndRemainder(b);
	                if(dr[1].equals(BigInteger.ZERO)){
	                    result.add(b);
	                    a = dr[0];
	                }
	            }
	            b = b.add(TWO);
	        }
	        result.add(b); //b will always be prime here...
	    }
	    return result;
	}

	public static boolean isSemi(BigInteger x){
		List<BigInteger> decomp = primeDecomp(x);
		return decomp != null && decomp.size() == 2;
	}

	public static void main(String[] args){
		for(int i = 2; i <= 100; i++){
			if(isSemi(BigInteger.valueOf(i))){
				System.out.print(i + " ");
			}
		}
		System.out.println();
		for(int i = 1675; i <= 1680; i++){
			if(isSemi(BigInteger.valueOf(i))){
				System.out.print(i + " ");
			}
		}
	}
}


open List;

val rec selfNumberNr = fn NR =>
let
  val rec sumdgt = fn 0 => 0 | n => Int.rem (n, 10) + sumdgt (Int.quot(n ,10));
  val rec isSelf  = fn ([],l1,l2) => []
   | (x::tt,l1,l2) => if exists (fn i=>i=x) l1 orelse exists (fn i=>i=x) l2
			  then ( isSelf (tt,l1,l2)) else x::isSelf (tt,l1,l2) ;

  val rec partcount =  fn  (n, listIn , count , selfs) =>
         if count >= NR then  nth (selfs, length selfs + NR - count -1)
           else
         let
          val range   = tabulate (81 , fn i => 81*n +i+1) ;
          val listOut = map (fn i => i + sumdgt i ) range ;
          val selfs   = isSelf (range,listIn,listOut)
         in
          partcount ( n+1 , listOut , count+length (selfs) , selfs )
       end;
in
  partcount (0,[],0,[])
end;

app  ((fn s => print (s ^ " ")) o Int.toString o selfNumberNr)  (tabulate (50,fn i=>i+1)) ;
selfNumberNr 100000000 ;


var sieve = Fn.new {
    var sv = List.filled(2*1e9+9*9+1, false)
    var n = 0
    var s = [0] * 8
    for (a in 0..1) {
        for (b in 0..9) {
            s[0] = a + b
            for (c in 0..9) {
                s[1] = s[0] + c
                for (d in 0..9) {
                   s[2] = s[1] + d
                   for (e in 0..9) {
                        s[3] = s[2] + e
                        for (f in 0..9) {
                            s[4] = s[3] + f
                            for (g in 0..9) {
                                s[5] = s[4] + g
                                for (h in 0..9) {
                                    s[6] = s[5] + h
                                    for (i in 0..9) {
                                        s[7] = s[6] + i
                                        for (j in 0..9) {
                                           sv[s[7] + j + n] = true
                                           n = n + 1
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    return sv
}

var st = System.clock
var sv = sieve.call()
var count = 0
System.print("The first 50 self numbers are:")
for (i in 0...sv.count) {
    if (!sv[i]) {
        count = count + 1
        if (count <= 50) System.write("%(i) ")
        if (count == 1e8) {
            System.print("\n\nThe 100 millionth self number is %(i)")
            break
        }
    }
}
System.print("Took %(System.clock-st) seconds.")


# Output: a stream of proper factors (probably unsorted)
def proper_factors:
  range(2; 1 + sqrt|floor) as $i
  | if (. % $i) == 0
    then (. / $i) as $r
    | if $i == $r then $i else $i, $r end
    else empty
    end;

def is_semiprime:
  . as $n
  | any(proper_factors;
        is_prime and (($n / .) | (. == $n or is_prime) );


using Primes
issemiprime(n::Integer) = sum(values(factor(n))) == 2
@show filter(issemiprime, 1:100)


// version 1.1.2

fun isSemiPrime(n: Int): Boolean {
    var nf = 0
    var nn = n
    for (i in 2..nn)
        while (nn % i == 0) {
            if (nf == 2) return false
            nf++
            nn /= i
        }
    return nf == 2
}

fun main(args: Array<String>) {
    for (v in 1675..1680)
        println("$v ${if (isSemiPrime(v)) "is" else "isn't"} semi-prime")
}


#!/bin/ksh

# Semiprime - As translated from C

#	# Variables:
#

#	# Functions:
#
# Function _issemiprime(p2) - return 1 if p2 semiprime, 0 if not
#
function _issemiprime {
	typeset _p2 ; integer _p2=$1
	typeset _p _f ; integer _p _f=0

	for ((_p=2; (_f<2 && _p*_p<=_p2); _p++)); do
		while (( _p2 % _p == 0 )); do
			(( _p2 /= _p ))
			(( _f++ ))
		done
	done

	return $(( _f + (_p2 > 1) == 2 ))
}

 ######
# main #
 ######

integer i
for ((i=2; i<100; i++)); do
	_issemiprime ${i}
	(( $? )) && printf " %d" ${i}
done
echo


on isSemiPrime (n)
    div = 2
    cnt = 0
    repeat while cnt < 3 and n <> 1
        if n mod div = 0 then
            n = n / div
            cnt = cnt + 1
        else
            div = div + 1
        end if
    end repeat
    return cnt=2
end


function semiprime (n)
	local divisor, count = 2, 0
	while count < 3 and n ~= 1 do
		if n % divisor == 0 then
			n = n / divisor
			count = count + 1
		else
			divisor = divisor + 1
		end
	end
	return count == 2
end

for n = 1675, 1680 do
	print(n, semiprime(n))
end


SemiPrimes := proc( n )
    local fact;
    fact := NumberTheory:-Divisors( n ) minus {1, n};
    if numelems( fact ) in {1,2} and not( member( 'false', isprime ~ ( fact ) ) ) then
        return n;
    else
        return NULL;
    end if;
end proc:
{ seq( SemiPrimes( i ), i = 1..100 ) };


semiPrimeQ[n_Integer] := Module[{factors, numfactors},
  factors = FactorInteger[n] // Transpose;
  numfactors = factors[[2]] // Total  ;
  numfactors == 2
  ]


isSemiprime = function(num)
    divisor = 2
    primes = 0
    while primes < 3 and num != 1
        if num % divisor == 0 then
            num = num / divisor;
            primes = primes + 1
        else
            divisor = divisor + 1
        end if
    end while
    return primes == 2
end function

print "Semiprimes up to 100:"
results = []
for i in range(2, 100)
    if isSemiprime(i) then results.push i
end for
print results


;;;	Practically identical to the EchoLisp solution
(define (semiprime? n)
	(= (length (factor n)) 2))
;
;;;	Example (sadly factor doesn't accept bigints)
(println (filter semiprime? (sequence 2 100)))
(setq x 9223372036854775807)
(while (not (semiprime? x)) (-- x))
(println "Biggest semiprime reachable: " x " = " ((factor x) 0) " x " ((factor x) 1))


proc isSemiPrime(k: int): bool =
 var
  i = 2
  count = 0
  x = k
 while i <= x and count < 3:
  if x mod i == 0:
   x = x div i
   inc count
  else:
   inc i
 result = count == 2

for k in 1675..1680:
 echo k, (if k.isSemiPrime(): " is" else: " isn’t"), " semi-prime"


class SemiPrime {
  function : Main(args : String[]) ~ Nil {
    for(i := 0; i < 100; i+=1;) {
      if(SemiPrime(i)) {
        "{$i} "->Print();
      };
    };
    IO.Console->PrintLine();
  }

  function : native : SemiPrime(n : Int) ~ Bool {
    nf := 0;
    for(i := 2; i <= n; i+=1;) {
      while(n%i = 0) {
        if(nf = 2) {
          return false;
        };
        nf+=1;
        n /= i;
      };
    };

    return nf = 2;
  }
}


func: semiprime(n)
| i |
   0 2 n sqrt asInteger for: i [ while(n i /mod swap 0 &=) [ ->n 1+ ] drop ]
   n 1 > ifTrue: [ 1+ ] 2 == ;


program SemiPrime;
{$IFDEF FPC}
  {$Mode objfpc}// compiler switch to use result
{$ELSE}
  {$APPTYPE CONSOLE} // for Delphi
{$ENDIF}
uses
  primTrial;

function isSemiprime(n: longWord;doWrite:boolean): boolean;
var
  fac1 : LongWord;
begin
  //a simple isAlmostPrime(n,2) would do without output;
  fac1 := SmallFactor(n);
  IF fac1 < n then
  Begin
    n := n div fac1;
    result := SmallFactor(n) = n;
    if result AND doWrite then
      write(fac1:10,'*',n:11)
  end
  else
    result := false;
end;
var
  i,k : longWord;
BEGIN
  For i := 2 to 97 do
    IF isSemiPrime(i,false) then
      write(i:3);
  writeln;
  //test for big numbers
  k := 4000*1000*1000;
  i := k-100;
  repeat
    IF isSemiPrime(i,true) then
      writeln(' = ',i:10);
    inc(i);
  until i> k;
END.


with Ada.Text_Io; use Ada.Text_Io;

procedure Temp_File is
   Temp : File_Type;
   Contents : String(1..80);
   Length : Natural;
begin
   -- Create a temporary file
   Create(File => Temp);
   Put_Line(File => Temp, Item => "Hello World");
   Reset(File => Temp, Mode => In_File);
   Get_Line(File => Temp, Item => Contents, Last => Length);
   Put_Line(Contents(1..Length));
end Temp_File;


      file% = FNopentempfile
      IF file% = 0 ERROR 100, "Failed to open temp file"
      PRINT #file%, "Hello world!"
      PTR#file% = 0
      INPUT #file%, message$
      CLOSE #file%
      PRINT message$
      END

      DEF FNopentempfile
      LOCAL pname%, hfile%, chan%
      OPEN_EXISTING = 3
      FILE_FLAG_DELETE_ON_CLOSE = &4000000
      GENERIC_READ = &80000000
      GENERIC_WRITE = &40000000
      INVALID_HANDLE_VALUE = -1
      DIM pname% LOCAL 260
      FOR chan% = 5 TO 12
        IF @hfile%(chan%) = 0 EXIT FOR
      NEXT
      IF chan% > 12 THEN = 0
      SYS "GetTempFileName", @tmp$, "BBC", 0, pname%
      SYS "CreateFile", $$pname%, GENERIC_READ OR GENERIC_WRITE, 0, 0, \
      \                 OPEN_EXISTING, FILE_FLAG_DELETE_ON_CLOSE, 0 TO hfile%
      IF hfile% = INVALID_HANDLE_VALUE THEN = 0
      @hfile%(chan%) = hfile%
      = chan%


function semiprime(integer n)
    return length(prime_factors(n,true))==2
end function
pp(filter(tagset(100)&tagset(1680,1675),semiprime),{pp_IntCh,false})


(de factor (N)
   (make
      (let
         (D 2
            L (1 2 2 . (4 2 4 2 4 6 2 6 .))
            M (sqrt N) )
         (while (>= M D)
            (if (=0 (% N D))
               (setq M
                  (sqrt (setq N (/ N (link D)))) )
               (inc 'D (pop 'L)) ) )
         (link N) ) ) )

(println
   (filter
      '((X)
         (let L (factor X)
            (and (cdr L) (not (cddr L))) ) )
      (conc (range 1 100) (range 1675 1680)) ) )

(bye)


*process source attributes xref nest or(!);
 /*--------------------------------------------------------------------
 * 22.02.2014 Walter Pachl using the is_prime code from
 *                         PL/I 'prime decomposition'
 * 23.02.  WP start test for second prime with 2 or first prime found
 *-------------------------------------------------------------------*/
 spb: Proc options(main);
 Dcl a(10) Bin Fixed(31)
          Init(900660121,2,4,1679,1234567,32768,99,9876543,100,5040);
 Dcl (x,n,nf,i,j) Bin Fixed(31) Init(0);
 Dcl f(3) Bin Fixed(31);
 Dcl txt Char(30) Var;
 Dcl bit Bit(1);
 Do i=1 To hbound(a);
   bit=is_semiprime(a(i));
   Select(nf);
     When(0,1) txt=' is prime';
     When(2)   txt=' is     semiprime '!!factors(a(i));
     Otherwise txt=' is NOT semiprime '!!factors(a(i));
     End;
   Put Edit(a(i),bit,txt)(Skip,f(10),x(1),b(1),a);
   End;

 is_semiprime: Proc(x) Returns(bit(1));
 /*--------------------------------------------------------------------
 * Returns '1'b if x is semiprime, '0'b otherwise
 * in addition
 * it sets f(1) and f(2) to the first (or only) prime factor(s)
 *-------------------------------------------------------------------*/
   Dcl x Bin Fixed(31);
   nf=0;
   f=0;
   x=a(i);
   n=x;
   f(1)=2;
 loop:
   Do While(nf<=2 & n>1);
     If is_prime(n) Then Do;
       Call mem(n);
       Leave loop;
       End;
     Else Do;
 loop2:
       Do j=f(1) By 1 While(j*j<=n);
         If is_prime(j)&mod(n,j)=0 Then Do;
           Call mem(j);
           n=n/j;
           Leave loop2;
           End;
         End;
       End;
     End;
   Return(nf=2);
 End;

 is_prime: Proc(n) Returns(bit(1));
 Dcl n Bin Fixed(31);
 Dcl i Bin Fixed(31);
   If n < 2 Then Return('0'b);
   If n = 2 Then Return('1'b);
   If mod(n,2)=0 Then Return('0'b);
   Do i = 3 by 2 While(i*i<=n);
     If mod(n,i)=0 Then Return('0'b);
     End;
   Return('1'b);
 End is_prime;

 mem: Proc(x);
 Dcl x Bin Fixed(31);
   nf+=1;
   f(nf)=x;
 End;

 factors: Proc(x) Returns(Char(150) Var);
 Dcl x Bin Fixed(31);
 Dcl (res,net) Char(150) Var Init('');
 Dcl (i,f3) Bin Fixed(31);
 res=f(1)!!'*'!!f(2);
 f3=x/(f(1)*f(2));
 If f3>1 Then
   res=res!!'*'!!f3;
 Do i=1 To length(res);
   If substr(res,i,1)>' ' Then
     net=net!!substr(res,i,1);
   End;
 Return(net);
 End;

 End spb;


#include <stdlib.h>
#include <stdio.h>

int main(void)
{
  FILE *fh = tmpfile(); /* file is automatically deleted when program exits */
  /* do stuff with stream "fh" */
  fclose(fh);
  /* The C standard library also has a tmpnam() function to create a file
    for you to open later. But you should not use it because someone else might
    be able to open the file from the time it is created by this function to the
    time you open it. */
  return 0;
}


using System;
using System.IO;

Console.WriteLine(Path.GetTempFileName());


(let [temp-file (java.io.File/createTempFile "pre" ".suff")]
  ; insert logic here that would use temp-file
  (.delete temp-file))


module tempfile ;
import tango.io.TempFile, tango.io.Stdout ;

void main(char[][] args) {

  // create a temporary file that will be deleted automatically when out of scope
  auto tempTransient = new TempFile(TempFile.Transient) ;
  Stdout(tempTransient.path()).newline ;

  // create a temporary file, still persist after the TempFile object has been destroyed
  auto tempPermanent = new TempFile(TempFile.Permanent) ;
  Stdout(tempPermanent.path()).newline ;

  // both can only be accessed by the current user (the program?).
}


program Secure_temporary_file;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.IOUtils;

var
  FileName, buf: string;

begin
  FileName := TPath.GetTempFileName;
  with TFile.Open(FileName, TFileMode.fmCreate, TFileAccess.faReadWrite,
    Tfileshare.fsNone) do
  begin
    buf := 'This is a exclusive temp file';
    Write(buf[1], buf.Length * sizeof(char));
    Free;
  end;

  writeln(FileName);
  Readln;
end.


function isPrime ($n) {
    if ($n -le 1) {$false}
    elseif (($n -eq 2) -or ($n -eq 3)) {$true}
    else{
        $m = [Math]::Floor([Math]::Sqrt($n))
        (@(2..$m | where {($_ -lt $n)  -and ($n % $_ -eq 0) }).Count -eq 0)
    }
}
function semiprime ($n) {
    if($n -gt 3) {
        $lim = [Math]::Floor($n/2)+1
        $i = 2
        while(($i -lt $lim) -and ($n%$i -ne 0)){ $i += 1}
        if($i -eq $lim){@()}
        elseif(-not (isPrime ($n/$i))){@()}
        else{@($i,($n/$i))}
    } else {@()}
}
$OFS = " x "
"1679: $(semiprime 1679)"
"87: $(semiprime   87)"
"25: $(semiprime 25)"
"12: $(semiprime   12)"
"6: $(semiprime   6)"
$OFS = " "
"semiprime form 1 to 100: $(1..100 | where {semiprime $_})"


from prime_decomposition import decompose

def semiprime(n):
    d = decompose(n)
    try:
        return next(d) * next(d) == n
    except StopIteration:
        return False


  [ factors size dup 3 4 clamp = ] is semiprime ( n --> b )

  say "Semiprimes less than 100:" cr
  100 times [ i^ semiprime if [ i^ echo sp ] ]


(make-temp-file "prefix")
;; => "/tmp/prefix25452LPe"


OPEN (F,STATUS = 'SCRATCH')   !Temporary disc storage.


package main

import (
	"fmt"
	"io/ioutil"
	"log"
	"os"
)

func main() {
	f, err := ioutil.TempFile("", "foo")
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()

	// We need to make sure we remove the file
	// once it is no longer needed.
	defer os.Remove(f.Name())

	// … use the file via 'f' …
	fmt.Fprintln(f, "Using temporary file:", f.Name())
	f.Seek(0, 0)
	d, err := ioutil.ReadAll(f)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Printf("Wrote and read: %s\n", d)

        // The defer statements above will close and remove the
        // temporary file here (or on any return of this function).
}


def file = File.createTempFile( "xxx", ".txt" )

// There is no requirement in the instructions to delete the file.
//file.deleteOnExit()

println file


import System.IO

main = do (pathOfTempFile, h) <- openTempFile "." "prefix.suffix" -- first argument is path to directory where you want to put it
          -- do stuff with it here; "h" is the Handle to the opened file
          return ()


! The "scratch" option opens a file exclusively for the current process.
! A scratch file is automatically deleted upon process termination.

OPEN( FIle='TemporaryAndExclusive', SCRatch, IOStat=ErrNr)
WRITE(FIle='TemporaryAndExclusive') "something"
WRITE(FIle='TemporaryAndExclusive', CLoSe=1) ! explicit "close" deletes file

! Without "scratch" access can be controlled by "denyread", "denywrite", "denyreadwrite" options.

OPEN( FIle='DenyForOthers', DenyREAdWRIte, IOStat=ErrNr)
WRITE(FIle='DenyForOthers') "something"
WRITE(FIle='DenyForOthers', DELETE=1)


#lang racket
(require math)

(define (pair-factorize n)
  "Return all two-number factorizations of a number"
  (let ([up-limit (integer-sqrt n)])
    (map (λ (x) (list x (/ n x)))
	 (filter (λ (x) (<= x up-limit)) (divisors n)))))

(define (semiprime n)
  "Determine if a number is semiprime i.e. a product of two primes.
Check if any pair of complete factors consists of primes."
  (for/or ((pair (pair-factorize n)))
    (for/and ((el pair))
      (prime? el))))


sub is-semiprime (Int $n --> Bool) {
    not $n.is-prime and
        .is-prime given
        $n div first $n %% *, flat grep &is-prime, 2 .. *;
}

use Test;
my @primes = flat grep &is-prime, 2 .. 100;
for ^5 {
    nok is-semiprime([*] my @f1 = @primes.roll(1)), ~@f1;
    ok  is-semiprime([*] my @f2 = @primes.roll(2)), ~@f2;
    nok is-semiprime([*] my @f3 = @primes.roll(3)), ~@f3;
    nok is-semiprime([*] my @f4 = @primes.roll(4)), ~@f4;
}


/* REXX ---------------------------------------------------------------
* 20.02.2014 Walter Pachl  relying on 'prime decomposition'
* 21.02.2014 WP Clarification: I copied the algorithm created by
*            Gerard Schildberger under the task referred to above
* 21.02.2014 WP Make sure that factr is not called illegally
*--------------------------------------------------------------------*/
Call test 4
Call test 9
Call test 10
Call test 12
Call test 1679
Exit

test:
Parse Arg z
If is_semiprime(z) Then Say z 'is semiprime' fl
                   Else Say z 'is NOT semiprime' fl
Return

is_semiprime:
  Parse Arg z
  If z<1 | datatype(z,'W')=0 Then Do
    Say 'Argument ('z') must be a natural number (1, 2, 3, ...)'
    fl=''
    End
  Else
    fl=factr(z)
  Return words(fl)=2

/*----------------------------------FACTR subroutine-----------------*/
factr: procedure; parse arg x 1 z,list /*sets X&Z to arg1, LIST=''.  */
if x==1  then return ''             /*handle the special case of X=1.*/
j=2;     call .factr                /*factor for the only even prime.*/
j=3;     call .factr                /*factor for the 1st  odd  prime.*/
j=5;     call .factr                /*factor for the 2nd  odd  prime.*/
j=7;     call .factr                /*factor for the 3rd  odd  prime.*/
j=11;    call .factr                /*factor for the 4th  odd  prime.*/
j=13;    call .factr                /*factor for the 5th  odd  prime.*/
j=17;    call .factr                /*factor for the 6th  odd  prime.*/
                                    /* [?]   could be optimized more.*/
                                    /* [?]   J in loop starts at 17+2*/
     do y=0  by 2;     j=j+2+y//4   /*insure J isn't divisible by 3. */
     if right(j,1)==5  then iterate /*fast check for divisible by 5. */
     if j*j>z          then leave   /*are we higher than the v of Z ?*/
     if j>Z            then leave   /*are we higher than value of Z ?*/
     call .factr                    /*invoke .FACTR for some factors.*/
     end   /*y*/                    /* [?]  only tests up to the v X.*/
                                    /* [?]  LIST has a leading blank.*/
if z==1  then return list           /*if residual=unity, don't append*/
              return list z         /*return list,  append residual. */
/*-------------------------------.FACTR internal subroutine----------*/
.factr:  do  while z//j==0          /*keep dividing until we can't.  */
         list=list j                /*add number to the list  (J).   */
         z=z%j                      /*% (percent)  is integer divide.*/
         end   /*while z··· */      /*  //   ?---remainder integer ÷.*/
return                              /*finished, now return to invoker*/


procedure main()
    write("Creating: ",fName := !open("mktemp","rp"))
    write(f := open(fName,"w"),"Hello, world")
    close(f)
end


import java.io.File;
import java.io.IOException;

public class CreateTempFile {
    public static void main(String[] args)  {
        try {
            //create a temp file
            File temp = File.createTempFile("temp-file-name", ".tmp");
            System.out.println("Temp file : " + temp.getAbsolutePath());
        }
        catch(IOException e) {
            e.printStackTrace();
    	}
    }
}


msg = "Rosetta Code, Secure temporary file, implemented with Julia."

(fname, tio) = mktemp()
println(fname, " created as a temporary file.")
println(tio, msg)
close(tio)
println("\"", msg, "\" written to ", fname)


// version 1.1.2

import java.io.File

fun main(args: Array<String>) {
    try {
        val tf = File.createTempFile("temp", ".tmp")
        println(tf.absolutePath)
        tf.delete()
    }
    catch (ex: Exception) {
        println(ex.message)
    }
}


fp = io.tmpfile()

-- do some file operations

fp:close()


Module Checkit {
      \\ we get a tempname$ choosed  from Windows
      a$=tempname$
      Try ok  {
            \\ we can use wide to export in utf-16le
            \\ without wide we export as Ansi (set Local to desired language)
            Rem Locale 1033 ' when no use of wide
            Open a$ for wide output exclusive as #f
                  wait 10
                  \\ Notepad can't open, because we open it for exclusive use
                  Win "Notepad", a$
                  Print  #f, "something"
                  Print "Press a key";Key$
            Close #f
      }
      If error or not ok then Print Error$
      Win "Notepad", a$
}
Checkit


prime = 1679
decomp(prime)

func decomp nr
x = ""
sum = 0
for i = 1 to nr
    if isPrime(i) and nr % i = 0
       sum = sum + 1
       x = x + string(i) + " * " ok
    if i = nr and sum = 2
       x2 = substr(x,1,(len(x)-2))
       see string(nr) + " = " + x2 + "is semiprime" + nl
    but i = nr and sum != 2 see string(nr) + " is not semiprime" + nl ok
next

func isPrime n
     if n < 2 return false ok
     if n < 4 return true ok
     if n % 2 = 0 and n != 2 return false ok
     for d = 3 to sqrt(n) step 2
         if n % d = 0 return false ok
     next
     return true


extern crate primal;

fn isqrt(n: usize) -> usize {
    (n as f64).sqrt() as usize
}

fn is_semiprime(mut n: usize) -> bool {
    let root = isqrt(n) + 1;
    let primes1 = primal::Sieve::new(root);
    let mut count = 0;

    for i in primes1.primes_from(2).take_while(|&x| x < root) {
        while n % i == 0 {
            n /= i;
            count += 1;
        }
        if n == 1 {
            break;
        }
    }

    if n != 1 {
        count += 1;
    }
    count == 2
}

#[test]
fn test1() {
    assert_eq!((2..10).filter(|&n| is_semiprime(n)).count(), 3);
}

#[test]
fn test2() {
    assert_eq!((2..100).filter(|&n| is_semiprime(n)).count(), 34);
}

#[test]
fn test3() {
    assert_eq!((2..1_000).filter(|&n| is_semiprime(n)).count(), 299);
}

#[test]
fn test4() {
    assert_eq!((2..10_000).filter(|&n| is_semiprime(n)).count(), 2_625);
}

#[test]
fn test5() {
    assert_eq!((2..100_000).filter(|&n| is_semiprime(n)).count(), 23_378);
}

#[test]
fn test6() {
    assert_eq!((2..1_000_000).filter(|&n| is_semiprime(n)).count(), 210_035);
}


object Semiprime extends App {

  def isSP(n: Int): Boolean = {
    var nf: Int = 0
    var l = n
    for (i <- 2 to l/2) {
      while (l % i == 0) {
        if (nf == 2) return false
        nf +=1
        l /= i
      }
    }
    nf == 2
  }

  (2 to 100) filter {isSP(_) == true} foreach {i => print("%d ".format(i))}
  println
  1675 to 1681 foreach {i => println(i+" -> "+isSP(i))}

}


import Nanoquery.IO

def guaranteedTempFile()
	// create a file object to generate temp file names
	$namegen = new(File)

	// generate a temp filename
	$tempname = $namegen.tempFileName()

	// file names are generated with uuids so they shouldn't repeat
	// in the case that they do, generate new ones until the generated
	// filename is unique
	$tempfile = new(File, $tempname)
	while ($tempfile.exists())
		$tempname = $namegen.tempFileName()
		$tempfile = new(File, $tempname)
	end

	// create the file and lock it from writing
	$tempfile.create()
	lock $tempfile.fullPath()

	// return the file reference
	return $tempfile
end


/* NetRexx */
options replace format comments java crossref symbols binary

runSample(arg)
return

-- . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
method makeTempFile(prefix = String, suffix = String null, startDir = String null) -
  public static signals IOException returns File
  if startDir \= null then fStartDir = File(startDir)
  else                     fStartDir = null
  ff = File.createTempFile(prefix, suffix, fStartDir)
  ff.deleteOnExit() -- make sure the file is deleted at termination
  return ff

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method runSample(arg) private static
  do
    tempFiles = [ -
      makeTempFile('rexx'), -
      makeTempFile('rexx', '.rex'), -
      makeTempFile('rexx', null, './tmp') -
    ]
    loop fFile over tempFiles
      fName = fFile.getCanonicalPath()
      say 'Temporary file:' fName
      end fFile
  catch ex = IOException
    ex.printStackTrace()
  end
  return