import math

proc `^`[T](base, exp: T): T =
  var (base, exp) = (base, exp)
  result = 1

  while exp != 0:
    if (exp and 1) != 0:
      result *= base
    exp = exp shr 1
    base *= base

proc gcd[T](u, v: T): T =
  if v != 0:
    gcd(v, u mod v)
  else:
    u.abs

proc lcm[T](a, b: T): T =
  a div gcd(a, b) * b

type Rational* = tuple[num, den: int64]

proc fromInt*(x: SomeInteger): Rational =
  result.num = x
  result.den = 1

proc frac*(x: var Rational) =
  let common = gcd(x.num, x.den)
  x.num = x.num div common
  x.den = x.den div common

proc `+` *(x, y: Rational): Rational =
  let common = lcm(x.den, y.den)
  result.num = common div x.den * x.num + common div y.den * y.num
  result.den = common
  result.frac

proc `+=` *(x: var Rational, y: Rational) =
  let common = lcm(x.den, y.den)
  x.num = common div x.den * x.num + common div y.den * y.num
  x.den = common
  x.frac

proc `-` *(x: Rational): Rational =
  result.num = -x.num
  result.den = x.den

proc `-` *(x, y: Rational): Rational =
  x + -y

proc `-=` *(x: var Rational, y: Rational) =
  x += -y

proc `*` *(x, y: Rational): Rational =
  result.num = x.num * y.num
  result.den = x.den * y.den
  result.frac

proc `*=` *(x: var Rational, y: Rational) =
  x.num *= y.num
  x.den *= y.den
  x.frac

proc reciprocal*(x: Rational): Rational =
  result.num = x.den
  result.den = x.num

proc `div`*(x, y: Rational): Rational =
  x * y.reciprocal

proc toFloat*(x: Rational): float =
  x.num.float / x.den.float

proc toInt*(x: Rational): int64 =
  x.num div x.den

proc cmp*(x, y: Rational): int =
  cmp x.toFloat, y.toFloat

proc `<` *(x, y: Rational): bool =
  x.toFloat < y.toFloat

proc `<=` *(x, y: Rational): bool =
  x.toFloat <= y.toFloat

proc abs*(x: Rational): Rational =
  result.num = abs x.num
  result.den = abs x.den

for candidate in 2'i64 .. <((2'i64)^19):
  var sum: Rational = (1'i64, candidate)
  for factor in 2'i64 .. pow(candidate.float, 0.5).int64:
    if candidate mod factor == 0:
      sum += (1'i64, factor) + (1'i64, candidate div factor)
  if sum.den == 1:
    echo "Sum of recipr. factors of ",candidate," = ",sum.num," exactly ",
      if sum.num == 1: "perfect!" else: ""


#import <Foundation/Foundation.h>

@interface RCRationalNumber : NSObject
{
 @private
  int numerator;
  int denominator;
  BOOL autoSimplify;
  BOOL withSign;
}
+(instancetype)valueWithNumerator:(int)num andDenominator: (int)den;
+(instancetype)valueWithDouble: (double)fnum;
+(instancetype)valueWithInteger: (int)inum;
+(instancetype)valueWithRational: (RCRationalNumber *)rnum;
-(instancetype)initWithNumerator: (int)num andDenominator: (int)den;
-(instancetype)initWithDouble: (double)fnum precision: (int)prec;
-(instancetype)initWithInteger: (int)inum;
-(instancetype)initWithRational: (RCRationalNumber *)rnum;
-(NSComparisonResult)compare: (RCRationalNumber *)rnum;
-(id)simplify: (BOOL)act;
-(void)setAutoSimplify: (BOOL)v;
-(void)setWithSign: (BOOL)v;
-(BOOL)autoSimplify;
-(BOOL)withSign;
-(NSString *)description;
// ops
-(id)multiply: (RCRationalNumber *)rnum;
-(id)divide: (RCRationalNumber *)rnum;
-(id)add: (RCRationalNumber *)rnum;
-(id)sub: (RCRationalNumber *)rnum;
-(id)abs;
-(id)neg;
-(id)mod: (RCRationalNumber *)rnum;
-(int)sign;
-(BOOL)isNegative;
-(id)reciprocal;
// getter
-(int)numerator;
-(int)denominator;
//setter
-(void)setNumerator: (int)num;
-(void)setDenominator: (int)num;
// defraction
-(double)number;
-(int)integer;
@end


extern crate num;
use num::bigint::BigUint;
use num::FromPrimitive;
use num::pow::pow;

fn main() {
    let big = BigUint::from_u8(5).unwrap();
    let answer_as_string = format!("{}", pow(big,pow(4,pow(3,2))));

      // The rest is output formatting.
    let first_twenty: String = answer_as_string.chars().take(20).collect();
    let last_twenty_reversed: Vec<char> = answer_as_string.chars().rev().take(20).collect();
    let last_twenty: String = last_twenty_reversed.into_iter().rev().collect();
    println!("Number of digits: {}", answer_as_string.len());
    println!("First and last digits: {:?}..{:?}", first_twenty, last_twenty);
}


class MAIN is
  main is
    r:INTI;
    p1 ::= "62060698786608744707";
    p2 ::= "92256259918212890625";

    -- computing 5^(4^(3^2)), it could be written
    -- also e.g. (5.inti)^((4.inti)^((3.inti)^(2.inti)))
    r  := (3.pow(2)).inti;
    r  := (4.inti).pow(r);
    r  := (5.inti).pow(r);

    sr ::= r.str; -- string rappr. of the number
    if sr.head(p1.size) = p1
       and sr.tail(p2.size) = p2 then
         #OUT + "result is ok..\n";
    else
         #OUT + "oops\n";
    end;
    #OUT + "# of digits: " + sr.size + "\n";
  end;
end;


#load "nums.cma";;
open Num;;

for candidate = 2 to 1 lsl 19 do
  let sum = ref (num_of_int 1 // num_of_int candidate) in
  for factor = 2 to truncate (sqrt (float candidate)) do
    if candidate mod factor = 0 then
      sum := !sum +/ num_of_int 1 // num_of_int factor
                  +/ num_of_int 1 // num_of_int (candidate / factor)
  done;
  if is_integer_num !sum then
    Printf.printf "Sum of recipr. factors of %d = %d exactly %s\n%!"
        candidate (int_of_num !sum) (if int_of_num !sum = 1 then "perfect!" else "")
done;;


(define x 3/7)
(define y 9/11)
(define z -2/5)

; demonstrate builtin functions:

(print "(abs " z ") = " (abs z))
(print "- " z " = " (- z))
(print x " + " y " = " (+ x y))
(print x " - " y " = " (- x y))
(print x " * " y " = " (* x y))
(print x " / " y " = " (/ x y))
(print x " < " y " = " (< x y))
(print x " > " y " = " (> x y))

; introduce new functions:

(define (+:= x) (+ x 1))
(define (-:= x) (- x 1))

(print "+:= " z " = " (+:= z))
(print "-:= " z " = " (-:= z))

; finally, find all perfect numbers less than 2^15:

(lfor-each (lambda (candidate)
      (let ((sum (lfold (lambda (sum factor)
                     (if (= 0 (modulo candidate factor))
                        (+ sum (/ 1 factor) (/ factor candidate))
                        sum))
                  (/ 1 candidate)
                  (liota 2 1 (+ (isqrt candidate) 1)))))
         (if (= 1 (denominator sum))
            (print candidate (if (eq? sum 1) ", perfect" "")))))
   (liota 2 1 (expt 2 15)))


(define x (expt 5 (expt 4 (expt 3 2))))
(define y (number->string x))
(define l (string-length y))
(display (string-append "5**4**3**2 = " (substring y 0 20) "..." (substring y (- l 20) l) " and has " (number->string l) " digits"))
(newline)


$ include "seed7_05.s7i";
  include "bigint.s7i";

const proc: main is func
  local
    var bigInteger: fiveToThePowerOf262144 is 5_ ** 4 ** 3 ** 2;
    var string: numberAsString is str(fiveToThePowerOf262144);
  begin
    writeln("5**4**3**2 = " <& numberAsString[..20] <&
            "..." <& numberAsString[length(numberAsString) - 19 ..]);
    writeln("decimal digits: " <& length(numberAsString));
  end func;


constant FIRST20 "62060698786608744707"
constant LAST20  "92256259918212890625"

function main()
  integer i
  string s, s2

  i = .ipower(5, .ipower(4, .ipower(3, 2)))
  s2 = .tostr(i, 10)
  if .lstr(s2, 20) == FIRST20 and .rstr(s2, 20) == LAST20
    s = "Success! The integer matches both the first 20 and the last 20 digits. There are " + .tostr(.len(s2), 10) + " digits in the result.{d}{a}"
  else
    s = ""
    if .lstr(s2, 20) != FIRST20
      s = "Failure! The first 20 digits are: " + .lstr(s2, 20) + " but they should be: " + FIRST20 + "{d}{a}"
    end if
    if .rstr(s2, 20) != LAST20
      s = s + "Failure! The first 20 digits are: " + .lstr(s2, 20) + " but they should be: " + LAST20 + "{d}{a}"
    end if
  end if
end function s


loop candidate = 6 to 2**19
    sum = .fraction~new(1, candidate)
    max2 = rxcalcsqrt(candidate)~trunc

    loop factor = 2 to max2
        if candidate // factor == 0 then do
           sum += .fraction~new(1, factor)
           sum += .fraction~new(1, candidate / factor)
        end
    end
    if sum == 1 then say candidate "is a perfect number"
end

::class fraction inherit orderable
::method init
  expose numerator denominator
  use strict arg numerator, denominator = 1

  if denominator == 0 then raise syntax 98.900 array("Fraction denominator cannot be zero")

  -- if the denominator is negative, make the numerator carry the sign
  if denominator < 0 then do
      numerator = -numerator
      denominator = - denominator
  end

  -- find the greatest common denominator and reduce to
  -- the simplest form
  gcd = self~gcd(numerator~abs, denominator~abs)

  numerator /= gcd
  denominator /= gcd

-- fraction instances are immutable, so these are
-- read only attributes
::attribute numerator GET
::attribute denominator GET

-- calculate the greatest common denominator of a numerator/denominator pair
::method gcd private
  use arg x, y

  loop while y \= 0
      -- check if they divide evenly
      temp = x // y
      x = y
      y = temp
  end
  return x

-- calculate the least common multiple of a numerator/denominator pair
::method lcm private
  use arg x, y
  return x / self~gcd(x, y) * y

::method abs
  expose numerator denominator
  -- the denominator is always forced to be positive
  return self~class~new(numerator~abs, denominator)

::method reciprocal
  expose numerator denominator
  return self~class~new(denominator, numerator)

-- convert a fraction to regular Rexx number
::method toNumber
  expose numerator denominator

  if numerator == 0 then return 0
  return numerator/denominator

::method negative
  expose numerator denominator
  return self~class~new(-numerator, denominator)

::method add
  expose numerator denominator
  use strict arg other
  -- convert to a fraction if a regular number
  if \other~isa(.fraction) then other = self~class~new(other, 1)

  multiple = self~lcm(denominator, other~denominator)
  newa = numerator * multiple / denominator
  newb = other~numerator * multiple / other~denominator
  return self~class~new(newa + newb, multiple)

::method subtract
  use strict arg other
  return self + (-other)

::method times
  expose numerator denominator
  use strict arg other
  -- convert to a fraction if a regular number
  if \other~isa(.fraction) then other = self~class~new(other, 1)
  return self~class~new(numerator * other~numerator, denominator * other~denominator)

::method divide
  use strict arg other
  -- convert to a fraction if a regular number
  if \other~isa(.fraction) then other = self~class~new(other, 1)
  -- and multiply by the reciprocal
  return self * other~reciprocal

-- compareTo method used by the orderable interface to implement
-- the operator methods
::method compareTo
  expose numerator denominator
  -- convert to a fraction if a regular number
  if \other~isa(.fraction) then other = self~class~new(other, 1)

  return (numerator * other~denominator - denominator * other~numerator)~sign

-- we still override "==" and "\==" because we want to bypass the
-- checks for not being an instance of the class
::method "=="
  expose numerator denominator
  use strict arg other

  -- convert to a fraction if a regular number
  if \other~isa(.fraction) then other = self~class~new(other, 1)
  -- Note:  these are numeric comparisons, so we're using the "="
  -- method so those are handled correctly
  return numerator = other~numerator & denominator = other~denominator

::method "\=="
  use strict arg other
  return \self~"\=="(other)

-- some operator overrides -- these only work if the left-hand-side of the
-- subexpression is a quaternion
::method "*"
  forward message("TIMES")

::method "/"
  forward message("DIVIDE")

::method "-"
  -- need to check if this is a prefix minus or a subtract
  if arg() == 0 then
      forward message("NEGATIVE")
  else
      forward message("SUBTRACT")

::method "+"
  -- need to check if this is a prefix plus or an addition
  if arg() == 0 then
      return self  -- we can return this copy since it is imutable
  else
      forward message("ADD")

::method string
  expose numerator denominator
  if denominator == 1 then return numerator
  return numerator"/"denominator

-- override hashcode for collection class hash uses
::method hashCode
  expose numerator denominator
  return numerator~hashcode~bitxor(numerator~hashcode)

::requires rxmath library


|num|
num := (5 raisedTo: (4 raisedTo: (3 raisedTo: 2))) asString.
Transcript
   show: (num first: 20), '...', (num last: 20); cr;
   show: 'digits: ', num size asString.


let
  val answer = IntInf.pow (5, IntInf.toInt (IntInf.pow (4, IntInf.toInt (IntInf.pow (3, 2)))))
  val s = IntInf.toString answer
  val len = size s
in
  print ("has " ^ Int.toString len ^ " digits: " ^
         substring (s, 0, 20) ^ " ... " ^
         substring (s, len-20, 20) ^ "\n")
end;


use bigrat;

foreach my $candidate (2 .. 2**19) {
    my $sum = 1 / $candidate;
    foreach my $factor (2 .. sqrt($candidate)+1) {
        if ($candidate % $factor == 0) {
            $sum += 1 / $factor + 1 / ($candidate / $factor);
        }
    }
    if ($sum->denominator() == 1) {
        print "Sum of recipr. factors of $candidate = $sum exactly ", ($sum == 1 ? "perfect!" : ""), "\n";
    }
}


import "unbounded_int"
decl unbounded_int x
x.set ((x.valueof 5).pow ((x.valueof 4).pow ((x.valueof 3).pow 2)))

decl string first last xstr
set xstr (string x)

# get the first twenty digits
decl int i
for (set i 0) (< i 20) (inc i)
	set first (+ first xstr<i>)
end for

# get the last twenty digits
for (set i (- (size xstr) 20)) (< i (size xstr)) (inc i)
	set last (+ last xstr<i>)
end for

out "the first and last digits of 5^(4^(3^2)) are " first "..." console
out last " (the result was " (size xstr) " digits long)" endl endl console

if (and (and (= first "62060698786608744707") (= last "92256259918212890625")) (= (size xstr) 183231))
	out "(pass)" endl console
else
	out "FAIL" endl console
end if


#import std
#import nat
#import bcd

#show+

main = <[email protected] take/$20; ^|T/~& '...'[email protected],'length: '[email protected]+ %nP+ [email protected]>@h %vP power=> <5_,4_,3_,2_>


Imports System.Console
Imports BI = System.Numerics.BigInteger

Module Module1

    Dim Implems() As String = {"Built-In", "Recursive", "Iterative"},
        powers() As Integer = {5, 4, 3, 2}

    Function intPowR(val As BI, exp As BI) As BI
        If exp = 0 Then Return 1
        Dim ne As BI, vs As BI = val * val
        If exp.IsEven Then ne = exp >> 1 : Return If (ne > 1, intPowR(vs, ne), vs)
        ne = (exp - 1) >> 1 : Return If (ne > 1, intPowR(vs, ne), vs) * val
    End Function

    Function intPowI(val As BI, exp As BI) As BI
        intPowI = 1 : While (exp > 0) : If Not exp.IsEven Then intPowI *= val
            val *= val : exp >>= 1 : End While
    End Function

    Sub DoOne(title As String, p() As Integer)
        Dim st As DateTime = DateTime.Now, res As BI, resStr As String
        Select Case (Array.IndexOf(Implems, title))
            Case 0 : res = BI.Pow(p(0), CInt(BI.Pow(p(1), CInt(BI.Pow(p(2), p(3))))))
            Case 1 : res = intPowR(p(0), intPowR(p(1), intPowR(p(2), p(3))))
            Case Else : res = intPowI(p(0), intPowI(p(1), intPowI(p(2), p(3))))
        End Select : resStr = res.ToString()
        Dim et As TimeSpan = DateTime.Now - st
        Debug.Assert(resStr.Length = 183231)
        Debug.Assert(resStr.StartsWith("62060698786608744707"))
        Debug.Assert(resStr.EndsWith("92256259918212890625"))
        WriteLine("n = {0}", String.Join("^", powers))
        WriteLine("n = {0}...{1}", resStr.Substring(0, 20),  resStr.Substring(resStr.Length - 20, 20))
        WriteLine("n digits = {0}", resStr.Length)
        WriteLine("{0} elasped: {1} milliseconds." & vblf, title, et.TotalMilliseconds)
    End Sub

    Sub Main()
        For Each itm As String in Implems : DoOne(itm, powers) : Next
        If Debugger.IsAttached Then Console.ReadKey()
    End Sub

End Module


with javascript_semantics
without warning  -- (several unused routines in this code)

constant NUM = 1, DEN = 2

type frac(object r)
    return sequence(r) and length(r)=2 and integer(r[NUM]) and integer(r[DEN])
end type

function normalise(object n, atom d=0)
    if sequence(n) then
        {n,d} = n
    end if
    if d<0 then
        n = -n
        d = -d
    end if
    atom g = gcd(n,d)
    return {n/g,d/g}
end function

function frac_new(integer n, d=1)
    return normalise(n,d)
end function

function frac_abs(frac r)
    return {abs(r[NUM]),r[DEN]}
end function

function frac_inv(frac r)
    return reverse(r)
end function

function frac_add(frac a, b)
    integer {an,ad} = a,
            {bn,bd} = b
    return normalise(an*bd+bn*ad, ad*bd)
end function

function frac_sub(frac a, b)
    integer {an,ad} = a,
            {bn,bd} = b
    return normalise(an*bd-bn*ad, ad*bd)
end function

function frac_mul(frac a, b)
integer {an,ad} = a,
        {bn,bd} = b
    return normalise(an*bn, ad*bd)
end function

function frac_div(frac a, b)
integer {an,ad} = a,
        {bn,bd} = b
    return normalise(an*bd, ad*bn)
end function

function frac_eq(frac a, b)
    return a==b
end function

function frac_ne(frac a, b)
    return a!=b
end function

function frac_lt(frac a, b)
    return frac_sub(a,b)[NUM]<0
end function

function frac_gt(frac a, b)
    return frac_sub(a,b)[NUM]>0
end function

function frac_le(frac a, b)
    return frac_sub(a,b)[NUM]<=0
end function

function frac_ge(frac a, b)
    return frac_sub(a,b)[NUM]>=0
end function

function is_perfect(integer num)
    frac total = frac_new(0)
    sequence f = factors(num,1)
    for i=1 to length(f) do
        total = frac_add(total,frac_new(1,f[i]))
    end for
    return frac_eq(total,frac_new(2))
end function

procedure get_perfect_numbers()
    atom t0 = time()
    integer lim = power(2,iff(platform()=JS?13:19))
    for i=2 to lim do
        if is_perfect(i) then
            printf(1,"perfect: %d\n",i)
        end if
    end for
    printf(1,"elapsed: %3.2f seconds\n",time()-t0)

    integer pn5 = power(2,12)*(power(2,13)-1) -- 5th perfect number
    if is_perfect(pn5) then
        printf(1,"perfect: %d\n",pn5)
    end if
end procedure

get_perfect_numbers()


import math.big
import math

fn main() {

    mut x := u32(math.pow(3,2))
    x = u32(math.pow(4,x))
	mut y := big.integer_from_int(5)
	y = y.pow(x)
	str := y.str()
	println("5^(4^(3^2)) has $str.len digits: ${str[..20]} ... ${str[str.len-20..]}")
}


import "/fmt" for Fmt
import "/big" for BigInt

var p = BigInt.three.pow(BigInt.two)
p = BigInt.four.pow(p)
p = BigInt.five.pow(p)
var s = p.toString
Fmt.print("5 ^ 4 ^ 3 ^ 2 has $,d digits.\n", s.count)
System.print("The first twenty are    : %(s[0..19])")
System.print("and the last twenty are : %(s[-20..-1])")


const std = @import("std");
const bigint = std.math.big.int.Managed;

pub fn main() !void {
    var gpa = std.heap.GeneralPurposeAllocator(.{}){};
    const allocator = &gpa.allocator;
    defer _ = gpa.deinit();

    var a = try bigint.initSet(allocator, 5);
    try a.pow(a.toConst(), try std.math.powi(u32, 4, try std.math.powi(u32, 3, 2)));
    defer a.deinit();

    var as = try a.toString(allocator, 10, false);
    defer allocator.free(as);

    std.debug.print("{s}...{s}\n", .{ as[0..20], as[as.len - 20 ..] });
    std.debug.print("{} digits\n", .{as.len});
}


(load "@lib/frac.l")

(for (N 2  (> (** 2 19) N)  (inc N))
   (let (Sum (frac 1 N)  Lim (sqrt N))
      (for (F 2  (>= Lim F) (inc F))
         (when (=0 (% N F))
            (setq Sum
               (f+ Sum
                  (f+ (frac 1 F) (frac 1 (/ N F))) ) ) ) )
      (when (= 1 (cdr Sum))
         (prinl
            "Perfect " N
            ", sum is " (car Sum)
            (and (= 1 (car Sum)) ": perfect") ) ) ) )


*process source attributes xref or(!);
 arat: Proc Options(main);
 /*--------------------------------------------------------------------
 * Rational Arithmetic
 * (Mis)use the Complex data type to represent fractions
 * real(x) is used as numerator
 * imag(x) is used as denominator
 * Output:
 * a=-3/7 b=9/2
 * a*b=-27/14
 * a+b=57/14
 * a-b=-69/14
 * a/b=-2/21
 * -3/7<9/2
 * 9/2>-3/7
 * -3/7=-3/7
 * 26.01.2015 handle 0/0
 *-------------------------------------------------------------------*/
 Dcl (abs,imag,mod,real,sign,trim) Builtin;
 Dcl sysprint Print;
 Dcl (candidate,max2,factor) Dec Fixed(15);
 Dcl sum complex Dec Fixed(15);
 Dcl one complex Dec Fixed(15);

 one=mk_fr(1,1);
 Put Edit('First solve the task at hand')(Skip,a);
 Do candidate = 2 to 10000;
   sum = mk_fr(1, candidate);
   max2 = sqrt(candidate);
   Do factor = 2 to max2;
     If mod(candidate,factor)=0 Then Do;
       sum=fr_add(sum,mk_fr(1,factor));
       sum=fr_add(sum,mk_fr(1,candidate/factor));
       End;
     End;
   If fr_cmp(sum,one)='=' Then Do;
     Put Edit(candidate,' is a perfect number')(Skip,f(7),a);
     Do factor = 2 to candidate-1;
       If mod(candidate,factor)=0 Then
         Put Edit(factor)(f(5));
       End;
     End;
   End;

 Put Edit('','Then try a few things')(Skip,a);
 Dcl a Complex Dec Fixed(15);
 Dcl b Complex Dec Fixed(15);
 Dcl p Complex Dec Fixed(15);
 Dcl s Complex Dec Fixed(15);
 Dcl d Complex Dec Fixed(15);
 Dcl q Complex Dec Fixed(15);
 Dcl zero Complex Dec Fixed(15);
 zero=mk_fr(0,1); Put Edit('zero=',fr_rep(zero))(Skip,2(a));
 a=mk_fr(0,0);    Put Edit('a=',fr_rep(a))(Skip,2(a));
 /*--------------------------------------------------------------------
 a=mk_fr(-3333,0); Put Edit('a=',fr_rep(a))(Skip,2(a));
 =>  Request mk_fr(-3333,0)
     Denominator must not be 0
     IBM0280I  ONCODE=0009  The ERROR condition was raised
               by a SIGNAL statement.
        At offset +00000276 in procedure with entry FT
 *-------------------------------------------------------------------*/
 a=mk_fr(0,3333); Put Edit('a=',fr_rep(a))(Skip,2(a));
 Put Edit('-3,7')(Skip,a);
 a=mk_fr(-3,7);
 b=mk_fr(9,2);
 p=fr_mult(a,b);
 s=fr_add(a,b);
 d=fr_sub(a,b);
 q=fr_div(a,b);
 r=fr_div(b,a);
 Put Edit('a=',fr_rep(a))(Skip,2(a));
 Put Edit('b=',fr_rep(b))(Skip,2(a));
 Put Edit('a*b=',fr_rep(p))(Skip,2(a));
 Put Edit('a+b=',fr_rep(s))(Skip,2(a));
 Put Edit('a-b=',fr_rep(d))(Skip,2(a));
 Put Edit('a/b=',fr_rep(q))(Skip,2(a));
 Put Edit('b/a=',fr_rep(r))(Skip,2(a));
 Put Edit(fr_rep(a),fr_cmp(a,b),fr_rep(b))(Skip,3(a));
 Put Edit(fr_rep(b),fr_cmp(b,a),fr_rep(a))(Skip,3(a));
 Put Edit(fr_rep(a),fr_cmp(a,a),fr_rep(a))(Skip,3(a));

 mk_fr: Proc(n,d) Recursive Returns(Dec Fixed(15) Complex);
 /*--------------------------------------------------------------------
 * make a Complex number
 * normalize and cancel
 *-------------------------------------------------------------------*/
 Dcl (n,d) Dec Fixed(15);
 Dcl (na,da) Dec Fixed(15);
 Dcl res Dec Fixed(15) Complex;
 Dcl x   Dec Fixed(15);
 na=abs(n);
 da=abs(d);
 Select;
   When(n=0) Do;
     real(res)=0;
     imag(res)=1;
     End;
   When(d=0) Do;
     Put Edit('Request mk_fr('!!n_rep(n)!!','!!n_rep(d)!!')')
             (Skip,a);
     Put Edit('Denominator must not be 0')(Skip,a);
     Signal error;
     End;
   Otherwise Do;
     x=gcd(na,da);
     real(res)=sign(n)*sign(d)*na/x;
     imag(res)=da/x;
     End;
   End;
 Return(res);
 End;

 fr_add: Proc(a,b) Returns(Dec Fixed(15) Complex);
 /*--------------------------------------------------------------------
 * add 'fractions' a and b
 *-------------------------------------------------------------------*/
 Dcl (a,b,res)     Dec Fixed(15) Complex;
 Dcl (an,ad,bn,bd) Dec Fixed(15);
 Dcl (rd,rn)       Dec Fixed(15);
 Dcl x             Dec Fixed(15);
 an=real(a);
 ad=imag(a);
 bn=real(b);
 bd=imag(b);
 rd=ad*bd;
 rn=an*bd+bn*ad;
 x=gcd(rd,rn);
 real(res)=rn/x;
 imag(res)=rd/x;
 Return(res);
 End;

 fr_sub: Proc(a,b) Returns(Dec Fixed(15) Complex);
 /*--------------------------------------------------------------------
 * subtract 'fraction' b from a
 *-------------------------------------------------------------------*/
 Dcl (a,b) Dec Fixed(15) Complex;
 Dcl b2    Dec Fixed(15) Complex;
 real(b2)=-real(b);
 imag(b2)=imag(b);
 Return(fr_add(a,b2));
 End;

 fr_mult: Proc(a,b) Returns(Dec Fixed(15) Complex);
 /*--------------------------------------------------------------------
 * multiply 'fractions' a and b
 *-------------------------------------------------------------------*/
 Dcl (a,b,res) Dec Fixed(15) Complex;
 real(res)=real(a)*real(b);
 imag(res)=imag(a)*imag(b);
 Return(res);
 End;

 fr_div: Proc(a,b) Returns(Dec Fixed(15) Complex);
 /*--------------------------------------------------------------------
 * divide 'fraction' a by b
 *-------------------------------------------------------------------*/
 Dcl (a,b) Dec Fixed(15) Complex;
 Dcl b2    Dec Fixed(15) Complex;
 real(b2)=imag(b);
 imag(b2)=real(b);
 If real(a)=0 & real(b)=0 Then
   Return(mk_fr(1,1));
 Return(fr_mult(a,b2));
 End;

 fr_cmp: Proc(a,b) Returns(char(1));
 /*--------------------------------------------------------------------
 * compare 'fractions' a and b
 *-------------------------------------------------------------------*/
 Dcl (a,b)         Dec Fixed(15) Complex;
 Dcl (an,ad,bn,bd) Dec Fixed(15);
 Dcl (a2,b2)       Dec Fixed(15);
 Dcl (rd)          Dec Fixed(15);
 Dcl res           Char(1);
 an=real(a);
 ad=imag(a);
 If ad=0 Then Do;
   Put Edit('ad=',ad,'candidate=',candidate)(Skip,a,f(10));
   Signal Error;
   End;
 bn=real(b);
 bd=imag(b);
 rd=ad*bd;
 a2=abs(an*bd)*sign(an)*sign(ad);
 b2=abs(bn*ad)*sign(bn)*sign(bd);
 Select;
   When(a2<b2) res='<';
   When(a2>b2) res='>';
   Otherwise Do;
     res='=';
     End;
   End;
 Return(res);
 End;

 fr_rep: Proc(f) Returns(char(15) Var);
 /*--------------------------------------------------------------------
 * Return the representation of 'fraction' f
 *-------------------------------------------------------------------*/
 Dcl f     Dec Fixed(15) Complex;
 Dcl res   Char(15) Var;
 Dcl (n,d) Pic'(14)Z9';
 Dcl x     Dec Fixed(15);
 Dcl s     Dec Fixed(15);
 n=abs(real(f));
 d=abs(imag(f));
 x=gcd(n,d);
 s=sign(real(f))*sign(imag(f));
 res=trim(n/x)!!'/'!!trim(d/x);
 If s<0 Then
   res='-'!!res;
 Return(res);
 End;

 n_rep: Proc(x) Returns(char(15) Var);
 /*--------------------------------------------------------------------
 * Return the representation of x
 *-------------------------------------------------------------------*/
 Dcl x     Dec Fixed(15);
 Dcl res   Char(15) Var;
 Put String(res) List(x);
 res=trim(res);
 Return(res);
 End;

 gcd: Proc(a,b) Returns(Dec Fixed(15)) Recursive;
 /*--------------------------------------------------------------------
 * Compute the greatest common divisor
 *-------------------------------------------------------------------*/
 Dcl (a,b) Dec Fixed(15) Nonassignable;
 If b=0 then Return (abs(a));
 Return(gcd(abs(b),mod(abs(a),abs(b))));
 End gcd;

 lcm: Proc(a,b) Returns(Dec Fixed(15));
 /*--------------------------------------------------------------------
 * Compute the least common multiple
 *-------------------------------------------------------------------*/
 Dcl (a,b) Dec Fixed(15) Nonassignable;
 if a=0 ! b=0 then Return (0);
 Return(abs(a*b)/gcd(a,b));
 End lcm;

 End;


divisor(N, Div) :-
    Max is floor(sqrt(N)),
    between(1, Max, D),
    divmod(N, D, _, 0),
    (Div = D; Div is N div D, Div =\= D).

divisors(N, Divs) :-
    setof(M, divisor(N, M), Divs).

recip(A, B) :- B is 1 rdiv A.

sumrecip(N, A) :-
    divisors(N, [1 | Ds]),
    maplist(recip, Ds, As),
    sum_list(As, A).

perfect(X) :- sumrecip(X, 1).

main :-
    Limit is 1 << 19,
    forall(
        (between(1, Limit, N), perfect(N)),
	(format("~w~n", [N]))),
    halt.

?- main.


from fractions import Fraction

for candidate in range(2, 2**19):
  sum = Fraction(1, candidate)
  for factor in range(2, int(candidate**0.5)+1):
    if candidate % factor == 0:
      sum += Fraction(1, factor) + Fraction(1, candidate // factor)
  if sum.denominator == 1:
    print("Sum of recipr. factors of %d = %d exactly %s" %
           (candidate, int(sum), "perfect!" if sum == 1 else ""))


  [ $ "bigrat.qky" loadfile ] now!

  [ -2 n->v rot
    factors witheach
      [ n->v 1/v v+ ]
    v0= ]             is perfect ( n -> b )

  19 bit times [ i^ perfect if [ i^ echo cr ] ]


(2..2**19).hyper.map: -> $candidate {
    my $sum = 1 / $candidate;
    for 2 .. ceiling(sqrt($candidate)) -> $factor {
        if $candidate %% $factor {
            $sum += 1 / $factor + 1 / ($candidate / $factor);
        }
    }
    if $sum.nude[1] == 1 {
        say "Sum of reciprocal factors of $candidate = $sum exactly", ($sum == 1 ?? ", perfect!" !! ".");
    }
}


/*REXX program implements a reasonably complete  rational arithmetic  (using fractions).*/
L=length(2**19 - 1)                              /*saves time by checking even numbers. */
     do j=2  by 2  to 2**19 - 1;       s=0       /*ignore unity (which can't be perfect)*/
     mostDivs=eDivs(j);                @=        /*obtain divisors>1; zero sum; null @. */
       do k=1  for  words(mostDivs)              /*unity isn't return from  eDivs  here.*/
       r='1/'word(mostDivs, k);        @[email protected] r;         s=$fun(r, , s)
       end   /*k*/
     if s\==1  then iterate                      /*Is sum not equal to unity?   Skip it.*/
     say 'perfect number:'       right(j, L)       "   fractions:"            @
     end   /*j*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
$div: procedure;  parse arg x;   x=space(x,0);   f= 'fractional division'
      parse var x n '/' d;       d=p(d 1)
      if d=0               then call err  'division by zero:'            x
      if \datatype(n,'N')  then call err  'a non─numeric numerator:'     x
      if \datatype(d,'N')  then call err  'a non─numeric denominator:'   x
      return n/d
/*──────────────────────────────────────────────────────────────────────────────────────*/
$fun: procedure;  parse arg z.1,,z.2 1 zz.2;    arg ,op;  op=p(op '+')
F= 'fractionalFunction';        do j=1  for 2;  z.j=translate(z.j, '/', "_");   end  /*j*/
if abbrev('ADD'      , op)                               then op= "+"
if abbrev('DIVIDE'   , op)                               then op= "/"
if abbrev('INTDIVIDE', op, 4)                            then op= "÷"
if abbrev('MODULUS'  , op, 3) | abbrev('MODULO', op, 3)  then op= "//"
if abbrev('MULTIPLY' , op)                               then op= "*"
if abbrev('POWER'    , op)                               then op= "^"
if abbrev('SUBTRACT' , op)                               then op= "-"
if z.1==''                                               then z.1= (op\=="+" & op\=='-')
if z.2==''                                               then z.2= (op\=="+" & op\=='-')
z_=z.2
                                                 /* [↑]  verification of both fractions.*/
  do j=1  for 2
  if pos('/', z.j)==0    then z.j=z.j"/1";         parse var  z.j  n.j  '/'  d.j
  if \datatype(n.j,'N')  then call err  'a non─numeric numerator:'     n.j
  if \datatype(d.j,'N')  then call err  'a non─numeric denominator:'   d.j
  if d.j=0               then call err  'a denominator of zero:'       d.j
                                               n.j=n.j/1;          d.j=d.j/1
             do  while \datatype(n.j,'W');     n.j=(n.j*10)/1;     d.j=(d.j*10)/1
             end  /*while*/                      /* [↑]   {xxx/1}  normalizes a number. */
  g=gcd(n.j, d.j);    if g=0  then iterate;  n.j=n.j/g;          d.j=d.j/g
  end    /*j*/

 select
 when op=='+' | op=='-' then do;  l=lcm(d.1,d.2);    do j=1  for 2;  n.j=l*n.j/d.j;  d.j=l
                                                     end   /*j*/
                                  if op=='-'  then n.2= -n.2;        t=n.1 + n.2;    u=l
                             end
 when op=='**' | op=='↑'  |,
      op=='^'  then do;  if \datatype(z_,'W')  then call err 'a non─integer power:'  z_
                    t=1;  u=1;     do j=1  for abs(z_);  t=t*n.1;  u=u*d.1
                                   end   /*j*/
                    if z_<0  then parse value   t  u   with   u  t      /*swap  U and T */
                    end
 when op=='/'  then do;      if n.2=0   then call err  'a zero divisor:'   zz.2
                             t=n.1*d.2;    u=n.2*d.1
                    end
 when op=='÷'  then do;      if n.2=0   then call err  'a zero divisor:'   zz.2
                             t=trunc($div(n.1 '/' d.1));    u=1
                    end                           /* [↑]  this is integer division.     */
 when op=='//' then do;      if n.2=0   then call err  'a zero divisor:'   zz.2
                    _=trunc($div(n.1 '/' d.1));     t=_ - trunc(_) * d.1;            u=1
                    end                          /* [↑]  modulus division.              */
 when op=='ABS'  then do;   t=abs(n.1);       u=abs(d.1);        end
 when op=='*'    then do;   t=n.1 * n.2;      u=d.1 * d.2;       end
 when op=='EQ' | op=='='                then return $div(n.1 '/' d.1)  = fDiv(n.2 '/' d.2)
 when op=='NE' | op=='\=' | op=='╪' | ,
                            op=='¬='    then return $div(n.1 '/' d.1) \= fDiv(n.2 '/' d.2)
 when op=='GT' | op=='>'                then return $div(n.1 '/' d.1) >  fDiv(n.2 '/' d.2)
 when op=='LT' | op=='<'                then return $div(n.1 '/' d.1) <  fDiv(n.2 '/' d.2)
 when op=='GE' | op=='≥'  | op=='>='    then return $div(n.1 '/' d.1) >= fDiv(n.2 '/' d.2)
 when op=='LE' | op=='≤'  | op=='<='    then return $div(n.1 '/' d.1) <= fDiv(n.2 '/' d.2)
 otherwise       call err  'an illegal function:'   op
 end   /*select*/

if t==0  then return 0;            g=gcd(t, u);             t=t/g;                   u=u/g
if u==1  then return t
              return t'/'u
/*──────────────────────────────────────────────────────────────────────────────────────*/
eDivs: procedure; parse arg x 1 b,a
         do j=2  while j*j<x;       if x//j\==0  then iterate;   a=a j;   b=x%j b;     end
       if j*j==x  then return a j b;                                            return a b
/*───────────────────────────────────────────────────────────────────────────────────────────────────*/
err:   say;   say '***error*** '    f     " detected"   arg(1);    say;         exit 13
gcd:   procedure; parse arg x,y; if x=0  then return y;  do until _==0; _=x//y; x=y; y=_; end; return x
lcm:   procedure; parse arg x,y; if y=0  then return 0; x=x*y/gcd(x, y);        return x
p:     return word( arg(1), 1)


for candidate in 2 .. 2**19
  sum = Rational(1, candidate)
  for factor in 2 .. Integer.sqrt(candidate)
    if candidate % factor == 0
      sum += Rational(1, factor) + Rational(1, candidate / factor)
    end
  end
  if sum.denominator == 1
    puts "Sum of recipr. factors of %d = %d exactly %s" %
           [candidate, sum.to_i, sum == 1 ? "perfect!" : ""]
  end
end


use std::cmp::Ordering;
use std::ops::{Add, AddAssign, Sub, SubAssign, Mul, MulAssign, Div, DivAssign, Neg};

fn gcd(a: i64, b: i64) -> i64 {
    match b {
        0 => a,
        _ => gcd(b, a % b),
    }
}

fn lcm(a: i64, b: i64) -> i64 {
    a / gcd(a, b) * b
}

#[derive(Clone, Copy, Debug, Eq, PartialEq, Hash, Ord)]
pub struct Rational {
    numerator: i64,
    denominator: i64,
}

impl Rational {
    fn new(numerator: i64, denominator: i64) -> Self {
        let divisor = gcd(numerator, denominator);
        Rational {
            numerator: numerator / divisor,
            denominator: denominator / divisor,
        }
    }
}

impl Add for Rational {
    type Output = Self;

    fn add(self, other: Self) -> Self {
        let multiplier = lcm(self.denominator, other.denominator);
        Rational::new(self.numerator * multiplier / self.denominator +
                      other.numerator * multiplier / other.denominator,
                      multiplier)
    }
}

impl AddAssign for Rational {
    fn add_assign(&mut self, other: Self) {
        *self = *self + other;
    }
}

impl Sub for Rational {
    type Output = Self;

    fn sub(self, other: Self) -> Self {
        self + -other
    }
}

impl SubAssign for Rational {
    fn sub_assign(&mut self, other: Self) {
        *self = *self - other;
    }
}

impl Mul for Rational {
    type Output = Self;

    fn mul(self, other: Self) -> Self {
        Rational::new(self.numerator * other.numerator,
                      self.denominator * other.denominator)
    }
}

impl MulAssign for Rational {
    fn mul_assign(&mut self, other: Self) {
        *self = *self * other;
    }
}

impl Div for Rational {
    type Output = Self;

    fn div(self, other: Self) -> Self {
        self *
        Rational {
            numerator: other.denominator,
            denominator: other.numerator,
        }
    }
}

impl DivAssign for Rational {
    fn div_assign(&mut self, other: Self) {
        *self = *self / other;
    }
}

impl Neg for Rational {
    type Output = Self;

    fn neg(self) -> Self {
        Rational {
            numerator: -self.numerator,
            denominator: self.denominator,
        }
    }
}

impl PartialOrd for Rational {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        (self.numerator * other.denominator).partial_cmp(&(self.denominator * other.numerator))
    }
}

impl<T: Into<i64>> From<T> for Rational {
    fn from(value: T) -> Self {
        Rational::new(value.into(), 1)
    }
}

fn main() {
    let max = 1 << 19;
    for candidate in 2..max {
        let mut sum = Rational::new(1, candidate);
        for factor in 2..(candidate as f64).sqrt().ceil() as i64 {
            if candidate % factor == 0 {
                sum += Rational::new(1, factor);
                sum += Rational::new(1, candidate / factor);
            }
        }

        if sum == 1.into() {
            println!("{} is perfect", candidate);
        }
    }
}


class Rational(n: Long, d:Long) extends Ordered[Rational]
{
   require(d!=0)
   private val g:Long = gcd(n, d)
   val numerator:Long = n/g
   val denominator:Long = d/g

   def this(n:Long)=this(n,1)

   def +(that:Rational):Rational=new Rational(
      numerator*that.denominator + that.numerator*denominator,
      denominator*that.denominator)

   def -(that:Rational):Rational=new Rational(
      numerator*that.denominator - that.numerator*denominator,
      denominator*that.denominator)

   def *(that:Rational):Rational=
      new Rational(numerator*that.numerator, denominator*that.denominator)

   def /(that:Rational):Rational=
      new Rational(numerator*that.denominator, that.numerator*denominator)

   def unary_~ :Rational=new Rational(denominator, numerator)

   def unary_- :Rational=new Rational(-numerator, denominator)

   def abs :Rational=new Rational(Math.abs(numerator), Math.abs(denominator))

   override def compare(that:Rational):Int=
      (this.numerator*that.denominator-that.numerator*this.denominator).toInt

   override def toString()=numerator+"/"+denominator

   private def gcd(x:Long, y:Long):Long=
      if(y==0) x else gcd(y, x%y)
}

object Rational
{
   def apply(n: Long, d:Long)=new Rational(n,d)
   def apply(n:Long)=new Rational(n)
   implicit def longToRational(i:Long)=new Rational(i)
}


; simply prints all the perfect numbers
(do ((candidate 2 (+ candidate 1))) ((>= candidate (expt 2 19)))
  (let ((sum (/ 1 candidate)))
    (do ((factor 2 (+ factor 1))) ((>= factor (sqrt candidate)))
      (if (= 0 (modulo candidate factor))
          (set! sum (+ sum (/ 1 factor) (/ factor candidate)))))
    (if (= 1 (denominator sum))
        (begin (display candidate) (newline)))))


$ include "seed7_05.s7i";
  include "rational.s7i";

const func boolean: isPerfect (in integer: candidate) is func
  result
    var boolean: isPerfect is FALSE;
  local
    var integer: divisor is 0;
    var rational: sum is rational.value;
  begin
    sum := 1 / candidate;
    for divisor range 2 to sqrt(candidate) do
      if candidate mod divisor = 0 then
        sum +:= 1 / divisor + 1 / (candidate div divisor);
      end if;
    end for;
    isPerfect := sum = rat(1);
  end func;

const proc: main is func
  local
    var integer: candidate is 0;
  begin
    for candidate range 2 to 2 ** 19 - 1 do
      if isPerfect(candidate) then
        writeln(candidate <& " is perfect");
      end if;
    end for;
  end func;


for n in (1 .. 2**19) {
    var frac = 0

    n.divisors.each {|d|
        frac += 1/d
    }

    if (frac.is_int) {
        say "Sum of reciprocal divisors of #{n} = #{frac} exactly #{
            frac == 2 ? '- perfect!' : ''
        }"
    }
}


54 / 7.
20 reciprocal.
(5 / 6) reciprocal.
(5 / 6) as: Float.


import Foundation

extension BinaryInteger {
  @inlinable
  public func gcd(with other: Self) -> Self {
    var gcd = self
    var b = other

    while b != 0 {
      (gcd, b) = (b, gcd % b)
    }

    return gcd
  }

  @inlinable
  public func lcm(with other: Self) -> Self {
    let g = gcd(with: other)

    return self / g * other
  }
}

public struct Frac<NumType: BinaryInteger & SignedNumeric>: Equatable {
  @usableFromInline
  var _num: NumType

  @usableFromInline
  var _dom: NumType

  @usableFromInline
  init(_num: NumType, _dom: NumType) {
    self._num = _num
    self._dom = _dom
  }

  @inlinable
  public init(numerator: NumType, denominator: NumType) {
    let divisor = numerator.gcd(with: denominator)

    self._num = numerator / divisor
    self._dom = denominator / divisor
  }

  @inlinable
  public static func + (lhs: Frac, rhs: Frac) -> Frac {
    let multiplier = lhs._dom.lcm(with: rhs.denominator)

    return Frac(
      numerator: lhs._num * multiplier / lhs._dom + rhs._num * multiplier / rhs._dom,
      denominator: multiplier
    )
  }

  @inlinable
  public static func += (lhs: inout Frac, rhs: Frac) {
    lhs = lhs + rhs
  }

  @inlinable
  public static func - (lhs: Frac, rhs: Frac) -> Frac {
    return lhs + -rhs
  }

  @inlinable
  public static func -= (lhs: inout Frac, rhs: Frac) {
    lhs = lhs + -rhs
  }

  @inlinable
  public static func * (lhs: Frac, rhs: Frac) -> Frac {
    return Frac(numerator: lhs._num * rhs._num, denominator: lhs._dom * rhs._dom)
  }

  @inlinable
  public static func *= (lhs: inout Frac, rhs: Frac) {
    lhs = lhs * rhs
  }

  @inlinable
  public static func / (lhs: Frac, rhs: Frac) -> Frac {
    return lhs * Frac(_num: rhs._dom, _dom: rhs._num)
  }

  @inlinable
  public static func /= (lhs: inout Frac, rhs: Frac) {
    lhs = lhs / rhs
  }

  @inlinable
  prefix static func - (rhs: Frac) -> Frac {
    return Frac(_num: -rhs._num, _dom: rhs._dom)
  }
}

extension Frac {
  @inlinable
  public var numerator: NumType {
    get { _num }
    set {
      let divisor = newValue.gcd(with: denominator)

      _num = newValue / divisor
      _dom = denominator / divisor
    }
  }

  @inlinable
  public var denominator: NumType {
    get { _dom }
    set {
      let divisor = newValue.gcd(with: numerator)

      _num = numerator / divisor
      _dom = newValue / divisor
    }
  }
}

extension Frac: CustomStringConvertible {
  public var description: String {
    let neg = numerator < 0 || denominator < 0

    return "Frac(\(neg ? "-" : "")\(abs(numerator)) / \(abs(denominator)))"
  }
}

extension Frac: Comparable {
  @inlinable
  public static func <(lhs: Frac, rhs: Frac) -> Bool {
    return lhs._num * rhs._dom < lhs._dom * rhs._num
  }
}

extension Frac: ExpressibleByIntegerLiteral {
  public init(integerLiteral value: Int) {
    self._num = NumType(value)
    self._dom = 1
  }
}

for candidate in 2..<1<<19 {
  var sum = Frac(numerator: 1, denominator: candidate)

  let m = Int(ceil(Double(candidate).squareRoot()))

  for factor in 2..<m where candidate % factor == 0 {
    sum += Frac(numerator: 1, denominator: factor)
    sum += Frac(numerator: 1, denominator: candidate / factor)
  }

  if sum == 1 {
    print("\(candidate) is perfect")
  }
}


namespace eval rat {}

proc rat::new {args} {
    if {[llength $args] == 0} {
        set args {0}
    }
    lassign [split {*}$args] n d
    if {$d == 0} {
        error "divide by zero"
    }
    if {$d < 0} {
        set n [expr {-1 * $n}]
        set d [expr {abs($d)}]
    }
    return [normalize $n $d]
}

proc rat::split {args} {
    if {[llength $args] == 1} {
        lassign [::split $args /] n d
        if {$d eq ""} {
            set d 1
        }
    } else {
        lassign $args n d
    }
    return [list $n $d]
}

proc rat::join {rat} {
    lassign $rat n d
    if {$n == 0} {
        return 0
    } elseif {$d == 1} {
        return $n
    } else {
        return $n/$d
    }
}

proc rat::normalize {n d} {
    set gcd [gcd $n $d]
    return [join [list [expr {$n/$gcd}] [expr {$d/$gcd}]]]
}

proc rat::gcd {a b} {
    while {$b != 0} {
        lassign [list $b [expr {$a % $b}]] a b
    }
    return $a
}

proc rat::abs {rat} {
    lassign [split $rat] n d
    return [join [list [expr {abs($n)}] $d]]
}

proc rat::inv {rat} {
    lassign [split $rat] n d
    return [normalize $d $n]
}

proc rat::+ {args} {
    set n 0
    set d 1
    foreach arg $args {
        lassign [split $arg] an ad
        set n [expr {$n*$ad + $an*$d}]
        set d [expr {$d * $ad}]
    }
    return [normalize $n $d]
}

proc rat::- {args} {
    lassign [split [lindex $args 0]] n d
    if {[llength $args] == 1} {
        return [join [list [expr {-1 * $n}] $d]]
    }
    foreach arg [lrange $args 1 end] {
        lassign [split $arg] an ad
        set n [expr {$n*$ad - $an*$d}]
        set d [expr {$d * $ad}]
    }
    return [normalize $n $d]
}

proc rat::* {args} {
    set n 1
    set d 1
    foreach arg $args {
        lassign [split $arg] an ad
        set n [expr {$n * $an}]
        set d [expr {$d * $ad}]
    }
    return [normalize $n $d]
}

proc rat::/ {a b} {
    set r [* $a [inv $b]]
    if {[string match */0 $r]} {
        error "divide by zero"
    }
    return $r
}

proc rat::== {a b} {
    return [expr {[- $a $b] == 0}]
}

proc rat::!= {a b} {
    return [expr { ! [== $a $b]}]
}

proc rat::< {a b} {
    lassign [split [- $a $b]] n d
    return [expr {$n < 0}]
}

proc rat::> {a b} {
    lassign [split [- $a $b]] n d
    return [expr {$n > 0}]
}

proc rat::<= {a b} {
    return [expr { ! [> $a $b]}]
}

proc rat::>= {a b} {
    return [expr { ! [< $a $b]}]
}

################################################
proc is_perfect {num} {
    set sum [rat::new 0]
    foreach factor [all_factors $num] {
        set sum [rat::+ $sum [rat::new 1/$factor]]
    }
    # note, all_factors includes 1, so sum should be 2
    return [rat::== $sum 2]
}

proc get_perfect_numbers {} {
    set t [clock seconds]
    set limit [expr 2**19]
    for {set num 2} {$num < $limit} {incr num} {
        if {[is_perfect $num]} {
            puts "perfect: $num"
        }
    }
    puts "elapsed: [expr {[clock seconds] - $t}] seconds"

    set num [expr {2**12 * (2**13 - 1)}] ;# 5th perfect number
    if {[is_perfect $num]} {
        puts "perfect: $num"
    }
}

source primes.tcl
get_perfect_numbers


import "/math" for Int
import "/rat" for Rat

System.print("The following numbers (less than 2^19) are perfect:")
for (i in 2...(1<<19)) {
    var sum = Rat.new(1, i)
    for (j in Int.properDivisors(i)[1..-1]) sum = sum + Rat.new(1, j)
    if (sum == Rat.one) System.print("  %(i)")
}


class Rational{  // Weenie Rational class, can handle BigInts
   fcn init(_a,_b){ var a=_a, b=_b; normalize(); }
   fcn toString{
      if(b==1) a.toString()
      else     "%d//%d".fmt(a,b)
   }
   var [proxy] isZero=fcn{ a==0 };
   fcn normalize{  // divide a and b by gcd
      g:= a.gcd(b);
      a/=g; b/=g;
      if(b<0){ a=-a; b=-b; } // denominator > 0
      self
   }
   fcn abs       { a=a.abs(); self }
   fcn __opNegate{ a=-a;      self }			    // -Rat
   fcn __opAdd(n){
      if(Rational.isChildOf(n)) self(a*n.b + b*n.a, b*n.b); // Rat + Rat
      else self(b*n + a, b);				    // Rat + Int
   }
   fcn __opSub(n){ self(a*n.b - b*n.a, b*n.b) }		    // Rat - Rat
   fcn __opMul(n){
      if(Rational.isChildOf(n)) self(a*n.a, b*n.b);	    // Rat * Rat
      else self(a*n, b);				    // Rat * Int
   }
   fcn __opDiv(n){ self(a*n.b,b*n.a) }			    // Rat / Rat
   fcn __opEQ(r){				       // Rat==Rat, Rat==n
      if(Rational.isChildOf(r)) a==r.a and b=r.b;
      else			b==1   and a==r;
   }
}


with Ada.Text_IO; use Ada.Text_IO;
with Ada.Numerics.Generic_Elementary_Functions;

procedure Main is
   type Real is digits 18;
   package Real_Funcs is new Ada.Numerics.Generic_Elementary_Functions(Real);
   use Real_Funcs;
   package Real_IO is new Ada.Text_IO.Float_IO(Real);
   use Real_IO;

   function Approx_Equal (Left : Real; Right : Real) return Boolean is

      -- Calculate an epsilon value based upon the magnitude of the
      -- maximum value of the two parameters
      eps : Real := Real'Max(Left, Right) * 1.0e-9;
   begin
      if left > Right then
         return Left - Right < eps;
      else
         return Right - Left < eps;
      end if;
   end Approx_Equal;

   Type Index is (Left, Right);
   type Pairs_List is array (Index) of Real;
   type Pairs_Table is array(1..8) of Pairs_List;
   Table : Pairs_Table;

begin
   Table := ((100000000000000.01,   100000000000000.011),
             (100.01,   100.011),
             (10000000000000.001 / 10000.0,   1000000000.0000001000),
             (0.001,   0.0010000001),
             (0.000000000000000000000101,   0.0),
             (sqrt(2.0) * sqrt(2.0),    2.0),
             (-sqrt(2.0) * sqrt(2.0),   -2.0),
             (3.14159265358979323846,   3.14159265358979324));

   for Pair of Table loop
      Put(Item => Pair(Left), Exp => 0, Aft => 16, Fore => 6);
      Put("  ");
      Put(Item => Pair(Right), Exp => 0, Aft => 16, Fore => 6);
      Put_Line("  " & Boolean'Image(Approx_Equal(Pair(Left), Pair(Right))));
   end loop;

end Main;


BEGIN # test REAL values for approximate equality #
    # returns TRUE if value is approximately equal to other, FALSE otherwide #
    PROC approx equals = ( REAL value, REAL other, REAL epsilon )BOOL: ABS ( value - other ) < epsilon;
    # shows the result of testing a for approximate equality with b #
    PROC test = ( REAL a, b )VOID:
         BEGIN
            REAL epsilon = 1e-18;
            print( ( a, ", ", b, " => ", IF approx equals( a, b, epsilon ) THEN "true" ELSE "false" FI, newline ) )
         END # test # ;
    # task test cases #
    test( 100000000000000.01, 100000000000000.011 );
    test( 100.01, 100.011 );
    test( 10000000000000.001 / 10000.0, 1000000000.0000001000);
    test( 0.001, 0.0010000001 );
    test( 0.000000000000000000000101, 0.0 );
    test(   sqrt( 2 ) * sqrt( 2 ),  2.0 );
    test( - sqrt( 2 ) * sqrt( 2 ), -2.0 );
    test( 3.14159265358979323846, 3.14159265358979324 )
END


(defun approx-equal (float1 float2 &optional (threshold 0.000001))
  "Determine whether float1 and float2 are equal; THRESHOLD is the
maximum allowable difference between normalized significands of floats
with the same exponent. The significands are scaled appropriately
before comparison for floats with different exponents."
  (multiple-value-bind (sig1 exp1 sign1) (decode-float float1)
    (multiple-value-bind (sig2 exp2 sign2) (decode-float float2)
      (let ((cmp1 (float-sign sign1 (scale-float sig1 (floor (- exp1 exp2) 2))))
            (cmp2 (float-sign sign2 (scale-float sig2 (floor (- exp2 exp1) 2)))))
        (< (abs (- cmp1 cmp2)) threshold)))))


program Approximate_Equality;

{$APPTYPE CONSOLE}

uses
  System.SysUtils,
  System.Math;

const
  EPSILON: Double = 1E-18;

procedure Test(a, b: Double; Expected: Boolean);
var
  result: Boolean;
const
  STATUS: array[Boolean] of string = ('FAIL', 'OK');
begin
  result := SameValue(a, b, EPSILON);
  Write(a, ' ', b, ' => ', result, ' '^I);
  writeln(Expected, ^I, STATUS[Expected = result]);
end;

begin
  Test(100000000000000.01, 100000000000000.011, True);
  Test(100.01, 100.011, False);
  Test(double(10000000000000.001) / double(10000.0), double(1000000000.0000001000),
    False);
  Test(0.001, 0.0010000001, False);
  Test(0.000000000000000000000101, 0.0, True);
  Test(double(Sqrt(2)) * double(Sqrt(2)), 2.0, False);
  Test(-double(Sqrt(2)) * double(Sqrt(2)), -2.0, false);
  Test(3.14159265358979323846, 3.14159265358979324, True);
  Readln;
end.


: test-f~   ( f1 f2 -- )
  1e-18                  \ epsilon
  f~                     \ AproximateEqual
  if ." True" else ." False" then
;


program main
  implicit none

  integer                       :: i
  double precision, allocatable :: vals(:)

  vals = [ 100000000000000.01d0,          100000000000000.011d0,   &
    &      100.01d0,                      100.011d0,               &
    &      10000000000000.001d0/10000d0,  1000000000.0000001000d0, &
    &      0.001d0,                       0.0010000001d0,          &
    &      0.000000000000000000000101d0,  0d0,                     &
    &      sqrt(2d0)*sqrt(2d0),           2d0,                     &
    &     -sqrt(2d0)*sqrt(2d0),          -2d0,                     &
    &      3.14159265358979323846d0,      3.14159265358979324d0    ]

  do i = 1, size(vals)/2
    print '(ES30.18, A, ES30.18, A, L)', vals(2*i-1), ' == ', vals(2*i), ' ? ', eq_approx(vals(2*i-1), vals(2*i))
  end do

contains

  logical function eq_approx(a, b, reltol, abstol)
    !! is a approximately equal b?

    double precision, intent(in)           :: a, b
      !! values to compare
    double precision, intent(in), optional :: reltol, abstol
      !! relative and absolute error thresholds.
      !! defaults: epsilon, smallest non-denormal number

    double precision :: rt, at

    rt = epsilon(1d0)
    at = tiny(1d0)
    if (present(reltol)) rt = reltol
    if (present(abstol)) at = abstol

    eq_approx = abs(a - b) .le. max(rt * max(abs(a), abs(b)), at)
    return
  end function

end program


class Approximate {
    private static boolean approxEquals(double value, double other, double epsilon) {
        return Math.abs(value - other) < epsilon
    }

    private static void test(double a, double b) {
        double epsilon = 1e-18
        System.out.printf("%f, %f => %s\n", a, b, approxEquals(a, b, epsilon))
    }

    static void main(String[] args) {
        test(100000000000000.01, 100000000000000.011)
        test(100.01, 100.011)
        test(10000000000000.001 / 10000.0, 1000000000.0000001000)
        test(0.001, 0.0010000001)
        test(0.000000000000000000000101, 0.0)
        test(Math.sqrt(2.0) * Math.sqrt(2.0), 2.0)
        test(-Math.sqrt(2.0) * Math.sqrt(2.0), -2.0)
        test(3.14159265358979323846, 3.14159265358979324)
    }
}


class (Num a, Ord a, Eq a) => AlmostEq a where
  eps :: a

infix 4 ~=
(~=) :: AlmostEq a => a -> a -> Bool
a ~= b = or [ a == b
            , abs (a - b) < eps * abs(a + b)
            , abs (a - b) < eps ]

instance AlmostEq Int where eps = 0
instance AlmostEq Integer where eps = 0
instance AlmostEq Double where eps = 1e-14
instance AlmostEq Float where eps = 1e-5


public class Approximate {
    private static boolean approxEquals(double value, double other, double epsilon) {
        return Math.abs(value - other) < epsilon;
    }

    private static void test(double a, double b) {
        double epsilon = 1e-18;
        System.out.printf("%f, %f => %s\n", a, b, approxEquals(a, b, epsilon));
    }

    public static void main(String[] args) {
        test(100000000000000.01, 100000000000000.011);
        test(100.01, 100.011);
        test(10000000000000.001 / 10000.0, 1000000000.0000001000);
        test(0.001, 0.0010000001);
        test(0.000000000000000000000101, 0.0);
        test(Math.sqrt(2.0) * Math.sqrt(2.0), 2.0);
        test(-Math.sqrt(2.0) * Math.sqrt(2.0), -2.0);
        test(3.14159265358979323846, 3.14159265358979324);
    }
}


from math import sqrt
import strformat
import strutils

const Tolerance = 1e-10

proc `~=`(a, b: float): bool =
  ## Check if "a" and "b" are close.
  ## We use a relative tolerance to compare the values.
  result = abs(a - b) < max(abs(a), abs(b)) * Tolerance

proc compare(a, b: string) =
  ## Compare "a" and "b" transmitted as strings.
  ## Values are computed using "parseFloat".
  let r = a.parseFloat() ~= b.parseFloat()
  echo fmt"{a} ~= {b} is {r}"

proc compare(a: string; avalue: float; b: string) =
  ## Compare "a" and "b" transmitted as strings.
  ## The value of "a" is transmitted and not computed.
  let r = avalue ~= b.parseFloat()
  echo fmt"{a} ~= {b} is {r}"

compare("100000000000000.01", "100000000000000.011")
compare("100.01", "100.011")
compare("10000000000000.001 / 10000.0", 10000000000000.001 / 10000.0, "1000000000.0000001000")
compare("0.001", "0.0010000001")
compare("0.000000000000000000000101", "0.0")
compare("sqrt(2) * sqrt(2)", sqrt(2.0) * sqrt(2.0), "2.0")
compare("-sqrt(2) * sqrt(2)", -sqrt(2.0) * sqrt(2.0), "-2.0")
compare("3.14159265358979323846", "3.14159265358979324")


program approximateEqual(output);

{
	\brief determines whether two `real` values are approximately equal
	\param x a reference value
	\param y the value to compare with \param x
	\return true if \param x is equal or approximately equal to \param y
}
function equal(protected x, y: real): Boolean;
	function approximate: Boolean;
		function d(protected x: real): integer;
		begin
			d := trunc(ln(abs(x) + minReal) / ln(2)) + 1
		end;
	begin
		approximate := abs(x - y) <= epsReal * (maxReal / (d(x) + d(y)))
	end;
begin
	equal := (x = y) or_else (x * y >= 0.0) and_then approximate
end;

{ --- auxilliary routines ---------------------------------------------- }
procedure test(protected x, y: real);
const
	{ ANSI escape code for color coding }
	CSI = chr(8#33) + '[';
	totalMinimumWidth = 40;
	postRadixDigits = 24;
begin
	write(x:totalMinimumWidth:postRadixDigits, '':1, CSI, '1;3');

	if equal(x, y) then
	begin
		if x = y then
		begin
			write('2m≅')
		end
		else
		begin
			write('5m≆')
		end
	end
	else
	begin
		write('1m≇')
	end;

	writeLn(CSI, 'm', '':1, y:totalMinimumWidth:postRadixDigits)
end;

{ === MAIN ============================================================= }
var
	n: integer;
	x: real;
begin
	{ Variables were used to thwart compile-time evaluation done }
	{ by /some/ compilers potentially confounding the results. }
	n := 2;
	x := 100000000000000.01;

	test(x, 100000000000000.011);
	test(100.01, 100.011);
	test(x / 10000.0, 1000000000.0000001000);
	test(0.001, 0.0010000001);
	test(0.000000000000000000000101, 0.0);
	x := sqrt(n);
	test(sqr(x), 2.0);
	test((-x) * x, -2.0);
	test(3.14159265358979323846, 3.14159265358979324)
end.


math.isclose -> bool
    a: double
    b: double
    *
    rel_tol: double = 1e-09
        maximum difference for being considered "close", relative to the
        magnitude of the input values
    abs_tol: double = 0.0
        maximum difference for being considered "close", regardless of the
        magnitude of the input values
Determine whether two floating point numbers are close in value.
Return True if a is close in value to b, and False otherwise.
For the values to be considered close, the difference between them
must be smaller than at least one of the tolerances.
-inf, inf and NaN behave similarly to the IEEE 754 Standard.  That
is, NaN is not close to anything, even itself.  inf and -inf are
only close to themselves.


/*REXX program mimics an  "approximately equal to"  for comparing floating point numbers*/
numeric digits 15                                /*what other FP hardware normally uses.*/
@.=                                              /*assign default for the   @   array.  */
parse arg @.1                                    /*obtain optional argument from the CL.*/
if @.1=''  |  @.1==","  then do;   @.1= 100000000000000.01           100000000000000.011
                                   @.2= 100.01                       100.011
                                   @.3= 10000000000000.001 / 10000   1000000000.0000001000
                                   @.4= 0.001                        0.0010000001
                                   @.5= 0.00000000000000000000101    0.0
                                   @.6=  sqrt(2) * sqrt(2)           2.0
                                   @.7= -sqrt(2) * sqrt(2)           '-2.0'
                                   @.8= 3.14159265358979323846       3.14159265358979324
          /* added ───► */         @.9= 100000000000000003.0         100000000000000004.0
                             end
     do j=1  while @.j\==''                      /*process CL argument or the array #s. */
     say
     say center(' processing pair ' j" ",71,'═') /*display a title for the pair of #s.  */
     parse value  @.j  with  a  b                /*extract two values from a pair of #s.*/
     say 'A='   a                                /*display the value of  A  to the term.*/
     say 'B='   b                                /*   "     "    "    "  B   "  "    "  */
     say right('A approximately equal to B?', 65)   word("false true", 1 + approxEQ(a,b) )
     end   /*j*/                                 /* [↑]  right─justify text & true/false*/
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
approxEQ: procedure; parse arg x,y;   return x=y /*floating point compare with 15 digits*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
sqrt: procedure; parse arg x;  if x=0  then return 0;  d=digits();  numeric digits;  h=d+6
      numeric form; m.=9; parse value format(x,2,1,,0) 'E0' with g "E" _ .; g=g *.5'e'_ %2
        do j=0  while h>9;      m.j=h;               h=h%2+1;       end  /*j*/
        do k=j+5  to 0  by -1;  numeric digits m.k;  g=(g+x/g)*.5;  end  /*k*/; return g/1


require "bigdecimal"

testvalues = [[100000000000000.01,           100000000000000.011],
              [100.01,                       100.011],
              [10000000000000.001 / 10000.0, 1000000000.0000001000],
              [0.001,                        0.0010000001],
              [0.000000000000000000000101,   0.0],
              [(2**0.5) * (2**0.5),            2.0],
              [-(2**0.5) * (2**0.5),          -2.0],
              [BigDecimal("3.14159265358979323846"),       3.14159265358979324],
              [Float::NAN, Float::NAN,],
              [Float::INFINITY, Float::INFINITY],
               ]

class  Numeric
  def close_to?(num, tol = Float::EPSILON)
    return true  if self == num
    return false if (self.to_f.nan? or num.to_f.nan?)        # NaN is not even close to itself
    return false if [self, num].count( Float::INFINITY) == 1 # Infinity is only close to itself
    return false if [self, num].count(-Float::INFINITY) == 1
    (self-num).abs <= tol * ([self.abs, num.abs].max)
  end
end

testvalues.each do |a,b|
  puts "#{a} #{a.close_to?(b) ? '≈' : '≉'} #{b}"
end


object Approximate extends App {
  val (ok, notOk, ε) = ("👌", "❌", 1e-18d)

  private def approxEquals(value: Double, other: Double, epsilon: Double) =
    scala.math.abs(value - other) < epsilon

  private def test(a: BigDecimal, b: BigDecimal, expected: Boolean): Unit = {
    val result = approxEquals(a.toDouble, b.toDouble, ε)
    println(f"$a%40.24f ≅ $b%40.24f => $result%5s ${if (expected == result) ok else notOk}")
  }

  test(BigDecimal("100000000000000.010"), BigDecimal("100000000000000.011"), true)
  test(BigDecimal("100.01"), BigDecimal("100.011"), false)
  test(BigDecimal(10000000000000.001 / 10000.0), BigDecimal("1000000000.0000001000"), false)
  test(BigDecimal("0.001"), BigDecimal("0.0010000001"), false)
  test(BigDecimal("0.000000000000000000000101"), BigDecimal(0), true)
  test(BigDecimal(math.sqrt(2) * math.sqrt(2d)), BigDecimal(2.0), false)
  test(BigDecimal(-Math.sqrt(2) * Math.sqrt(2)), BigDecimal(-2.0), false)
  test(BigDecimal("3.14159265358979323846"), BigDecimal("3.14159265358979324"), true)
}


import Foundation

extension FloatingPoint {
  @inlinable
  public func isAlmostEqual(
    to other: Self,
    tolerance: Self = Self.ulpOfOne.squareRoot()
  ) -> Bool {
    // tolerances outside of [.ulpOfOne,1) yield well-defined but useless results,
    // so this is enforced by an assert rathern than a precondition.
    assert(tolerance >= .ulpOfOne && tolerance < 1, "tolerance should be in [.ulpOfOne, 1).")

    // The simple computation below does not necessarily give sensible
    // results if one of self or other is infinite; we need to rescale
    // the computation in that case.
    guard self.isFinite && other.isFinite else {
      return rescaledAlmostEqual(to: other, tolerance: tolerance)
    }

    // This should eventually be rewritten to use a scaling facility to be
    // defined on FloatingPoint suitable for hypot and scaled sums, but the
    // following is good enough to be useful for now.
    let scale = max(abs(self), abs(other), .leastNormalMagnitude)
    return abs(self - other) < scale*tolerance
  }

  @usableFromInline
  internal func rescaledAlmostEqual(to other: Self, tolerance: Self) -> Bool {
    // NaN is considered to be not approximately equal to anything, not even
    // itself.
    if self.isNaN || other.isNaN { return false }
    if self.isInfinite {
      if other.isInfinite { return self == other }

      // Self is infinite and other is finite. Replace self with the binade
      // of the greatestFiniteMagnitude, and reduce the exponent of other by
      // one to compensate.
      let scaledSelf = Self(sign: self.sign,
        exponent: Self.greatestFiniteMagnitude.exponent,
        significand: 1)
      let scaledOther = Self(sign: .plus,
        exponent: -1,
        significand: other)

      // Now both values are finite, so re-run the naive comparison.
      return scaledSelf.isAlmostEqual(to: scaledOther, tolerance: tolerance)
    }

    // If self is finite and other is infinite, flip order and use scaling
    // defined above, since this relation is symmetric.
    return other.rescaledAlmostEqual(to: self, tolerance: tolerance)
  }
}

let testCases = [
  (100000000000000.01, 100000000000000.011),
  (100.01, 100.011),
  (10000000000000.001 / 10000.0, 1000000000.0000001000),
  (0.001, 0.0010000001),
  (0.000000000000000000000101, 0.0),
  (sqrt(2) * sqrt(2), 2.0),
  (-sqrt(2) * sqrt(2), -2.0),
  (3.14159265358979323846, 3.14159265358979324)
]

for testCase in testCases {
  print("\(testCase.0), \(testCase.1) => \(testCase.0.isAlmostEqual(to: testCase.1))")
}


catch {namespace delete test_almost_equal_decimal} ;# Start with a clean namespace

namespace eval test_almost_equal_decimal {
    package require Tcl 8.5 ;# required by tcllib
    package require math::decimal ;# from tcllib
    namespace import ::math::decimal::* ;# for: setVariable, fromstr, and compare

    array set yesno {0 Yes -1 No 1 No} ;# For nice output

    # More info here: http://speleotrove.com/decimal/dax3274.html
    # This puts the library into "simplified" mode. Which
    # rounds the "decimal digits" in the coefficient to the
    # number of digits that "precision" is set to.
    setVariable extended 0
    setVariable precision 9

    set data {
        {100000000000000.01 100000000000000.011}
        {100.01 100.011}
        {[expr {10000000000000.001 / 10000.0}] 1000000000.0000001000}
        {0.001 0.0010000001}
        {0.000000000000000000000101 0.0}
        {[expr { sqrt(2) * sqrt(2)}] 2.0}
        {[expr {-sqrt(2) * sqrt(2)}] -2.0}
        {3.14159265358979323846 3.14159265358979324}
    }
    set data [subst $data] ;# resolves expressions in the list

    foreach {a b} [join $data] {
        set a_d [fromstr $a]
        set b_d [fromstr $b]

        puts [format "Is %26s ≈ %21s ? %4s." $a $b $yesno([compare $a_d $b_d])]
    }
}


Imports System.Runtime.CompilerServices

Module Module1

    <Extension()>
    Function ApproxEquals(ByVal value As Double, other As Double, epsilon As Double)
        Return Math.Abs(value - other) < epsilon
    End Function

    Sub Test(a As Double, b As Double)
        Dim epsilon = 1.0E-18
        Console.WriteLine($"{a}, {b} => {a.ApproxEquals(b, epsilon)}")
    End Sub

    Sub Main()
        Test(100000000000000.02, 100000000000000.02)
        Test(100.01, 100.011)
        Test(10000000000000.002 / 10000.0, 1000000000.0000001)
        Test(0.001, 0.0010000001)
        Test(1.01E-22, 0.0)
        Test(Math.Sqrt(2) * Math.Sqrt(2), 2.0)
        Test(-Math.Sqrt(2) * Math.Sqrt(2), -2.0)
        Test(3.1415926535897931, 3.1415926535897931)
    End Sub

End Module


with Ada.Text_IO;

procedure Apply_Filter is

   generic
      type Num is digits <>;
      type Num_Array is array (Natural range <>) of Num;
      A : Num_Array;
      B : Num_Array;
   package Direct_Form_II_Transposed is
      pragma Assert (A'First = 0 and B'First = 0);
      pragma Assert (A'Last = B'Last);
      pragma Assert (A (0) = 1.000);

      function Filter (X : in Num) return Num;
   end Direct_Form_II_Transposed;

   package body Direct_Form_II_Transposed
   is
      W : Num_Array (A'Range) := (others => 0.0);

      function Filter (X : in Num) return Num is
         Y : constant Num := X * B (0) + W (0);
      begin
         --  Calculate delay line for next sample
         for I in 1 .. W'Last loop
            W (I - 1) := X * B (I) - Y * A (I) + W (I);
         end loop;
         return Y;
      end Filter;

   end Direct_Form_II_Transposed;

   type Coeff_Array is array (Natural range <>) of Float;

   package Butterworth is
      new Direct_Form_II_Transposed (Float, Coeff_Array,
                                     A => (1.000000000000, -2.77555756e-16,
                                           3.33333333e-01, -1.85037171e-17),
                                     B => (0.16666667, 0.50000000,
                                           0.50000000, 0.16666667));

   subtype Signal_Array is Coeff_Array;

   X_Signal : constant Signal_Array :=
     (-0.917843918645, 0.141984778794, 1.20536903482, 0.190286794412, -0.662370894973,
      -1.00700480494, -0.404707073677, 0.800482325044, 0.743500089861, 1.01090520172,
      0.741527555207,  0.277841675195, 0.400833448236, -0.2085993586, -0.172842103641,
      -0.134316096293, 0.0259303398477, 0.490105989562, 0.549391221511, 0.9047198589);

   package Float_IO is
      new Ada.Text_IO.Float_IO (Float);
   Y : Float;
begin
   for Sample of X_Signal loop
      Y := Butterworth.Filter (Sample);
      Float_IO.Put (Y, Exp => 0, Aft => 6);
      Ada.Text_IO.New_Line;
   end loop;
end Apply_Filter;


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

#define MAX_LEN 1000

typedef struct{
	float* values;
	int size;
}vector;

vector extractVector(char* str){
	vector coeff;
	int i=0,count = 1;
	char* token;

	while(str[i]!=00){
		if(str[i++]==' ')
			count++;
	}

	coeff.values = (float*)malloc(count*sizeof(float));
	coeff.size = count;

	token = strtok(str," ");

	i = 0;

	while(token!=NULL){
		coeff.values[i++] = atof(token);
		token = strtok(NULL," ");
	}

	return coeff;
}

vector processSignalFile(char* fileName){
	int i,j;
	float sum;
	char str[MAX_LEN];
	vector coeff1,coeff2,signal,filteredSignal;

	FILE* fp = fopen(fileName,"r");

	fgets(str,MAX_LEN,fp);
	coeff1 = extractVector(str);

	fgets(str,MAX_LEN,fp);
	coeff2 = extractVector(str);

	fgets(str,MAX_LEN,fp);
	signal = extractVector(str);

        fclose(fp);

	filteredSignal.values = (float*)calloc(signal.size,sizeof(float));
	filteredSignal.size = signal.size;

	for(i=0;i<signal.size;i++){
		sum = 0;

		for(j=0;j<coeff2.size;j++){
			if(i-j>=0)
				sum += coeff2.values[j]*signal.values[i-j];
		}

		for(j=0;j<coeff1.size;j++){
			if(i-j>=0)
				sum -= coeff1.values[j]*filteredSignal.values[i-j];
		}

		sum /= coeff1.values[0];
		filteredSignal.values[i] = sum;
	}

	return filteredSignal;
}

void printVector(vector v, char* outputFile){
	int i;

	if(outputFile==NULL){
		printf("[");
		for(i=0;i<v.size;i++)
			printf("%.12f, ",v.values[i]);
		printf("\b\b]");
	}

	else{
		FILE* fp = fopen(outputFile,"w");
		for(i=0;i<v.size-1;i++)
			fprintf(fp,"%.12f, ",v.values[i]);
		fprintf(fp,"%.12f",v.values[i]);
		fclose(fp);
	}

}

int main(int argC,char* argV[])
{
	char *str;
	if(argC<2||argC>3)
		printf("Usage : %s <name of signal data file and optional output file.>",argV[0]);
	else{
		if(argC!=2){
			str = (char*)malloc((strlen(argV[2]) + strlen(str) + 1)*sizeof(char));
			strcpy(str,"written to ");
		}
		printf("Filtered signal %s",(argC==2)?"is:\n":strcat(str,argV[2]));
		printVector(processSignalFile(argV[1]),argV[2]);
	}
	return 0;
}


import Data.List (tails)

-- lazy convolution of a list by given kernel
conv :: Num a => [a] -> [a] -> [a]
conv ker = map (dot (reverse ker)) . tails  . pad
  where
    pad v = replicate (length ker - 1) 0 ++ v
    dot v = sum . zipWith (*) v

-- The lazy digital filter
dFilter :: [Double] -> [Double] -> [Double] -> [Double]
dFilter (a0:a) b s = tail res
  where
    res = (/ a0) <$> 0 : zipWith (-) (conv b s) (conv a res)


use std::cmp::Ordering;

struct IIRFilter<'f>(&'f [f32], &'f [f32]);

impl<'f> IIRFilter<'f> {
    pub fn with_coefficients(a: &'f [f32], b: &'f [f32]) -> IIRFilter<'f> {
        IIRFilter(a, b)
    }

    // Performs the calculation as an iterator chain.
    pub fn apply<I: Iterator<Item = &'f f32> + 'f>(
        &self,
        samples: I,
    ) -> impl Iterator<Item = f32> + 'f {
        // Name some things for readability
        let a_coeff = self.0;
        let b_coeff = self.1;

        let mut prev_results = Vec::<f32>::new();
        let mut prev_samples = Vec::<f32>::new();

        // The actual calculation, done one number at a time
        samples.enumerate() // (i, sample[i])
            .map(move |(i, sample)| { // for each sample, apply this function
                prev_samples.push(*sample);
                prev_results.push(0f32); // the initial version of the previous result

                let sum_b: f32 = b_coeff.iter() // for each coefficient in b
                    .enumerate() // (j, b_coeff[j])
                    .map(|(j, c)| { // calculate the weight of the coefficient
                        if i >= j {
                            (*c) * prev_samples[i-j]
                        } else {
                            0f32
                        }
                    })
                    .sum(); // add them all together

                let sum_a: f32 = a_coeff.iter() // for each coefficient in a
                    .enumerate() // (j, a_coeff[j])
                    .map(|(j, c)| { // calculate the weight of the coefficient
                        if i >= j {
                            (*c) * prev_results[i-j]
                        } else {
                            0f32
                        }
                    })
                    .sum(); // add them all together

                // perform the final calculation
                let result = (sum_b - sum_a) / a_coeff[0];

                // update the previous result for the next iteration
                prev_results[i] = result;

                // return the current result in this iteration
                result
            }
        )
    }
}

fn main() {
    let a: &[f32] = &[1.00000000, -2.77555756e-16, 3.33333333e-01, -1.85037171e-17];
    let b: &[f32] = &[0.16666667, 0.5, 0.5, 0.16666667];

    let samples: Vec<f32> = vec![
        -0.917843918645,
        0.141984778794,
        1.20536903482,
        0.190286794412,
        -0.662370894973,
        -1.00700480494,
        -0.404707073677,
        0.800482325044,
        0.743500089861,
        1.01090520172,
        0.741527555207,
        0.277841675195,
        0.400833448236,
        -0.2085993586,
        -0.172842103641,
        -0.134316096293,
        0.0259303398477,
        0.490105989562,
        0.549391221511,
        0.9047198589,
    ];

    for (i, result) in IIRFilter::with_coefficients(a, b)
        .apply(samples.iter())
        .enumerate()
    {
        print!("{:.8}", result);
        if (i + 1) % 5 != 0 {
            print!(", ");
        } else {
            println!();
        }
    }
    println!();
}


fcn direct_form_II_transposed_filter(b,a,signal){
   out:=List.createLong(signal.len(),0.0);  // vector of zeros
   foreach i in (signal.len()){
      tmp:=0.0;
      foreach j in (b.len()){ if(i-j >=0) tmp += b[j]*signal[i-j] }
      foreach j in (a.len()){ if(i-j >=0) tmp -= a[j]*out[i-j]    }
      out[i] = tmp/a[0];
   }
   out
}


V max_divisors = 0
V c = 0
V n = 1
L
   V divisors = 1
   L(i) 1 .. n I/ 2
      I n % i == 0
         divisors++

   I divisors > max_divisors
      max_divisors = divisors
      print(n, end' ‘ ’)
      c++
      I c == 20
         L.break

   n++


puts:	equ	9	; MS-DOS print string syscall
amount:	equ	20 	; Amount of antiprimes to find
	cpu	8086
	org	100h
	xor	si,si	; SI = current number
	xor	cx,cx	; CH = max # of factors, CL = # of antiprimes
cand:	inc	si
 	mov	di,si	; DI = maximum factor to test
	shr	di,1
	mov	bp,1	; BP = current candidate
	xor	bl,bl	; BL = factor count
.test:	mov	ax,si	; Test current candidate
	xor	dx,dx
	div	bp
	test	dx,dx	; Evenly divisible?
	jnz	.next
	inc	bx	; Then increment factors
.next:	inc	bp	; Next possible factor
	cmp	bp,si	; Are we there yet?
	jbe	.test	; If not, try next factor
	cmp	bl,ch	; Is it an antiprime?
	jbe	cand	; If not, next candidate
	inc	cx	; If so, increment the amount of antiprimes seen
	mov	ch,bl	; Update maximum amount of factors
	mov	bx,nbuf	; Convert current number to ASCII
	mov	ax,si
	mov	di,10
digit:	xor	dx,dx	; Extract a digit
	div	di
	add	dl,'0'	; Add ASCII 0
	dec	bx
	mov 	[bx],dl	; Store it
	test	ax,ax	; Any more digits?
	jnz	digit	; If so, get next digit
	mov	dx,bx
	mov	ah,puts
	int	21h	; Print using MS-DOS
	cmp 	cl,amount	; Do we need any more antiprimes?
	jb	cand	; If so, find the next one
	ret		; Otherwise, back to DOS
	db	'.....'	; Placeholder for decimal output
nbuf:	db	' $'


/* ARM assembly AARCH64 Raspberry PI 3B */
/*  program antiprime64.s   */

/************************************/
/* Constantes                       */
/************************************/
.include "../includeConstantesARM64.inc"

.equ NMAXI,      20
.equ MAXLINE,     5
/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResult:        .asciz " @ "
szCarriageReturn:   .asciz "\n"
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:                  .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                             // entry of program
    ldr x3,qNMaxi                 // load limit
    mov x5,#0                     // maxi
    mov x6,#0                     // result counter
    mov x7,#0                     // display counter
    mov x4,#1                     // number begin
1:
    mov x0,x4                     // number
    bl decFactor                  // compute number factors
    cmp x0,x5                     // maxi ?
    cinc x4,x4,le                 // no -> increment indice
    //addle x4,x4,#1                // no -> increment indice
    ble 1b                        // and loop
    mov x5,x0
    mov x0,x4
    bl displayResult
    add x7,x7,#1                  // increment display counter
    cmp x7,#MAXLINE               // line maxi ?
    blt 2f
    mov x7,#0
    ldr x0,qAdrszCarriageReturn
    bl affichageMess              // display message
2:
    add x6,x6,#1                  // increment result counter
    add x4,x4,#1                  // increment number
    cmp x6,x3                     // end ?
    blt 1b

100:                              // standard end of the program
    mov x0, #0                    // return code
    mov x8,EXIT
    svc #0                        // perform the system call
qAdrszCarriageReturn:        .quad szCarriageReturn
qNMaxi:                       .quad NMAXI
/***************************************************/
/*   display message number                        */
/***************************************************/
/* x0 contains number 1           */
/* x1 contains number 2               */
displayResult:
    stp x1,lr,[sp,-16]!        // save  registers
    ldr x1,qAdrsZoneConv
    bl conversion10            // call décimal conversion
    ldr x0,qAdrsMessResult
    ldr x1,qAdrsZoneConv       // insert conversion in message
    bl strInsertAtCharInc

    bl affichageMess           // display message
    ldp x1,lr,[sp],16          // restaur  registers
    ret
qAdrsMessResult:     .quad sMessResult
qAdrsZoneConv:       .quad sZoneConv
/***************************************************/
/*   compute factors sum                        */
/***************************************************/
/* x0 contains the number            */
decFactor:
    stp x1,lr,[sp,-16]!       // save  registers
    stp x2,x3,[sp,-16]!       // save  registers
    stp x4,x5,[sp,-16]!       // save  registers
    mov x5,#0                 // init number factors
    mov x4,x0                 // save number
    mov x1,#1                 // start factor -> divisor
1:
    mov x0,x4                 // dividende
    udiv x2,x0,x1
    msub x3,x2,x1,x0
    cmp x1,x2                 // divisor > quotient ?
    bgt 3f
    cmp x3,#0                 // remainder = 0 ?
    bne 2f
    add x5,x5,#1              // increment counter factors
    cmp x1,x2                 // divisor = quotient ?
    beq 3f                    // yes -> end
    add x5,x5,#1              // no -> increment counter factors
2:
    add x1,x1,#1              // increment factor
    b 1b                      // and loop
3:
    mov x0,x5                 // return counter
    ldp x4,x5,[sp],16 // restaur  registers
    ldp x2,x3,[sp],16 // restaur  registers
    ldp x1,lr,[sp],16  // restaur  registers
    ret
/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../includeARM64.inc"


BYTE FUNC CountDivisors(INT a)
  INT i
  BYTE prod,count

  prod=1 count=0
  WHILE a MOD 2=0
  DO
    count==+1
    a==/2
  OD
  prod==*(1+count)

  i=3
  WHILE i*i<=a
  DO
    count=0
    WHILE a MOD i=0
    DO
      count==+1
      a==/i
    OD
    prod==*(1+count)
    i==+2
  OD

  IF a>2 THEN
    prod==*2
  FI
RETURN (prod)

PROC Main()
  BYTE toFind=[20],found=[0],count,max=[0]
  INT i=[1]

  PrintF("The first %B Anti-primes are:%E",toFind)
  WHILE found<toFind
  DO
    count=CountDivisors(i)
    IF count>max THEN
      max=count
      found==+1
      PrintI(i)
      IF found<toFind THEN
        Print(", ")
      FI
    FI
    i==+1
  OD
RETURN


with Ada.Text_IO; use Ada.Text_IO;

procedure Antiprimes is

   function Count_Divisors (N : Integer) return Integer is
      Count : Integer := 1;
   begin
      for i in 1 .. N / 2 loop
         if N mod i = 0 then
            Count := Count + 1;
         end if;
      end loop;
      return Count;
   end Count_Divisors;

   Results      : array (1 .. 20) of Integer;
   Candidate    : Integer := 1;
   Divisors     : Integer;
   Max_Divisors : Integer := 0;

begin
   for i in Results'Range loop
      loop
         Divisors := Count_Divisors (Candidate);
         if Max_Divisors < Divisors then
            Results (i)  := Candidate;
            Max_Divisors := Divisors;
            exit;
         end if;
         Candidate := Candidate + 1;
      end loop;
   end loop;
   Put_Line ("The first 20 anti-primes are:");
   for I in Results'Range loop
      Put (Integer'Image (Results (I)));
   end loop;
   New_Line;
end Antiprimes;


BEGIN # find some anti-primes: numbers with more divisors than the     #
      # previous numbers                                               #
    INT max number   := 10 000;
    INT max divisors := 0;
    # construct a table of the divisor counts                          #
    [ 1 : max number ]INT ndc; FOR i FROM 1 TO UPB ndc DO ndc[ i ] := 1 OD;
    FOR i FROM 2 TO UPB ndc DO
        FOR j FROM i BY i TO UPB ndc DO ndc[ j ] +:= 1 OD
    OD;
    # show the numbers with more divisors than their predecessors      #
    INT a count := 0;
    FOR i TO UPB ndc WHILE a count < 20 DO
        INT divisor count = ndc[ i ];
        IF divisor count > max divisors THEN
            print( ( " ", whole( i, 0 ) ) );
            max divisors := divisor count;
            a count     +:= 1
        FI
    OD;
    print( ( newline ) )
END


begin
    % find some anti-primes - numbers with more factors than the numbers    %
    % smaller than them                                                     %
    % calculates the number of divisors of v                                %
    integer procedure divisor_count( integer value v ) ; begin
        integer total, n, p;
        total := 1; n := v;
        while not odd( n ) do begin
            total := total + 1;
            n     := n div 2
        end while_not_odd_n ;
        p := 3;
        while ( p * p ) <= n do begin
            integer count;
            count := 1;
            while n rem p = 0 do begin
                count := count + 1;
                n     := n div p
            end while_n_rem_p_eq_0 ;
            p     := p + 2;
            total := total * count
        end while_p_x_p_le_n ;
        if n > 1 then total := total * 2;
        total
    end divisor_count ;
    begin
        integer maxAntiPrime, antiPrimeCount, maxDivisors, n;
        maxAntiPrime := 20;
        n := maxDivisors := antiPrimeCount := 0;
        while antiPrimeCount < maxAntiPrime do begin
            integer divisors;
            n := n + 1;
            divisors := divisor_count( n );
            if divisors > maxDivisors then begin
                writeon( i_w := 1, s_w := 0, " ", n );
                maxDivisors    := divisors;
                antiPrimeCount := antiPrimeCount + 1
            end if_have_an_anti_prime
        end while_antiPrimeCoiunt_lt_maxAntiPrime
    end
end.


on factorCount(n)
    set counter to 0
    set sqrt to n ^ 0.5
    set limit to sqrt div 1
    if (limit = sqrt) then
        set counter to counter + 1
        set limit to limit - 1
    end if
    repeat with i from limit to 1 by -1
        if (n mod i is 0) then set counter to counter + 2
    end repeat

    return counter
end factorCount

on antiprimes(howMany)
    set output to {}
    set mostFactorsSoFar to 0
    set n to 0
    repeat until ((count output) = howMany)
        set n to n + 1
        tell (factorCount(n))
            if (it > mostFactorsSoFar) then
                set end of output to n
                set mostFactorsSoFar to it
            end if
        end tell
    end repeat

    return output
end antiprimes

antiprimes(20)


f←{⍸≠⌈\(⍴∘∪⊢∨⍳)¨⍳⍵}


/* ARM assembly Raspberry PI or android with termux */
/*  program antiprime.s   */

 /* REMARK 1 : this program use routines in a include file
   see task Include a file language arm assembly
   for the routine affichageMess conversion10
   see at end of this program the instruction include */
/* for constantes see task include a file in arm assembly */
/************************************/
/* Constantes                       */
/************************************/
.include "../constantes.inc"

.equ NMAXI,      20
.equ MAXLINE,     5
/*********************************/
/* Initialized data              */
/*********************************/
.data
sMessResult:        .asciz " @ "
szCarriageReturn:   .asciz "\n"
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:                  .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:                             @ entry of program
    ldr r3,iNMaxi                 @ load limit
    mov r5,#0                     @ maxi
    mov r6,#0                     @ result counter
    mov r7,#0                     @ display counter
    mov r4,#1                     @ number begin
1:
    mov r0,r4                     @ number
    bl decFactor                  @ compute number factors
    cmp r0,r5                     @ maxi ?
    addle r4,r4,#1                @ no -> increment indice
    ble 1b                        @ and loop
    mov r5,r0
    mov r0,r4
    bl displayResult
    add r7,r7,#1                  @ increment display counter
    cmp r7,#MAXLINE               @ line maxi ?
    blt 2f
    mov r7,#0
    ldr r0,iAdrszCarriageReturn
    bl affichageMess              @ display message
2:
    add r6,r6,#1                  @ increment result counter
    add r4,r4,#1                  @ increment number
    cmp r6,r3                     @ end ?
    blt 1b

100:                              @ standard end of the program
    mov r0, #0                    @ return code
    mov r7, #EXIT                 @ request to exit program
    svc #0                        @ perform the system call
iAdrszCarriageReturn:        .int szCarriageReturn
iNMaxi:                       .int NMAXI
/***************************************************/
/*   display message number                        */
/***************************************************/
/* r0 contains number 1           */
/* r1 contains number 2               */
displayResult:
    push {r1,lr}               @ save registers
    ldr r1,iAdrsZoneConv
    bl conversion10            @ call décimal conversion
    ldr r0,iAdrsMessResult
    ldr r1,iAdrsZoneConv       @ insert conversion in message
    bl strInsertAtCharInc

    bl affichageMess           @ display message
    pop {r1,pc}                @ restaur des registres
iAdrsMessResult:     .int sMessResult
iAdrsZoneConv:       .int sZoneConv
/***************************************************/
/*   compute factors sum                        */
/***************************************************/
/* r0 contains the number            */
decFactor:
    push {r1-r5,lr}           @ save registers
    mov r5,#0                 @ init number factors
    mov r4,r0                 @ save number
    mov r1,#1                 @ start factor -> divisor
1:
    mov r0,r4                 @ dividende
    bl division
    cmp r1,r2                 @ divisor > quotient ?
    bgt 3f
    cmp r3,#0                 @ remainder = 0 ?
    bne 2f
    add r5,r5,#1              @ increment counter factors
    cmp r1,r2                 @ divisor = quotient ?
    beq 3f                    @ yes -> end
    add r5,r5,#1              @ no -> increment counter factors
2:
    add r1,r1,#1              @ increment factor
    b 1b                      @ and loop
3:
    mov r0,r5                 @ return counter
    pop {r1-r5,pc}            @ restaur registers

/***************************************************/
/*      ROUTINES INCLUDE                           */
/***************************************************/
.include "../affichage.inc"


found: 0
i: 1
maxDiv: 0

while [found<20][
    fac: size factors i
    if fac > maxDiv [
        print i
        maxDiv: fac
        found: found + 1
    ]
    i: i + 1
]


# syntax: GAWK -f ANTI-PRIMES.AWK
BEGIN {
    print("The first 20 anti-primes are:")
    while (count < 20) {
      d = count_divisors(++n)
      if (d > max_divisors) {
        printf("%d ",n)
        max_divisors = d
        count++
      }
    }
    printf("\n")
    exit(0)
}
function count_divisors(n,  count,i) {
    if (n < 2) {
      return(1)
    }
    count = 2
    for (i=2; i<=n/2; i++) {
      if (n % i == 0) {
        count++
      }
    }
    return(count)
}


10 DEFINT A-Z
20 N=1
30 IF S>=20 THEN END ELSE F=1
40 IF N<2 GOTO 70 ELSE FOR I=1 TO N\2
50 IF N MOD I=0 THEN F=F+1
60 NEXT
70 IF F<=M GOTO 110
80 PRINT N,
90 M=F
100 S=S+1
110 N=N+1
120 GOTO 30


Dim Results(20)
Candidate = 1
max_divisors = 0

Print "Los primeros 20 anti-primos son:"
For j = 0 To 19
	Do
		divisors = count_divisors(Candidate)
		If max_divisors < divisors Then
			Results[j] = Candidate
			max_divisors = divisors
			Exit Do
		End If
		Candidate += 1
	Until false
	Print Results[j];" ";
Next j

Function count_divisors(n)
	cont = 1
	For i = 1 To n/2
		If (n % i) = 0 Then cont += 1
	Next i
	count_divisors = cont
End Function


get "libhdr"
manifest $( LIMIT = 20 $)

let nfactors(n) =
    n < 2 -> 1, valof
$(  let c = 2
    for i=2 to n/2
        if n rem i = 0 then c := c + 1
    resultis c
$)

let start() be
$(  let max = 0 and seen = 0 and n = 1
    while seen < LIMIT
    $(  let f = nfactors(n)
        if f > max
        $(  writef("%N ",n)
            max := f
            seen := seen + 1
        $)
        n := n + 1
    $)
    wrch('*N')
$)


#include <stdio.h>

int countDivisors(int n) {
    int i, count;
    if (n < 2) return 1;
    count = 2; // 1 and n
    for (i = 2; i <= n/2; ++i) {
        if (n%i == 0) ++count;
    }
    return count;
}

int main() {
    int n, d, maxDiv = 0, count = 0;
    printf("The first 20 anti-primes are:\n");
    for (n = 1; count < 20; ++n) {
        d = countDivisors(n);
        if (d > maxDiv) {
            printf("%d ", n);
            maxDiv = d;
            count++;
        }
    }
    printf("\n");
    return 0;
}


using System;
using System.Linq;
using System.Collections.Generic;

public static class Program
{
    public static void Main() =>
        Console.WriteLine(string.Join(" ", FindAntiPrimes().Take(20)));

    static IEnumerable<int> FindAntiPrimes() {
        int max = 0;
        for (int i = 1; ; i++) {
            int divisors = CountDivisors(i);
            if (divisors > max) {
                max = divisors;
                yield return i;
            }
        }

        int CountDivisors(int n) => Enumerable.Range(1, n / 2).Count(i => n % i == 0) + 1;
    }
}


#include <iostream>

int countDivisors(int n) {
    if (n < 2) return 1;
    int count = 2; // 1 and n
    for (int i = 2; i <= n/2; ++i) {
        if (n%i == 0) ++count;
    }
    return count;
}

int main() {
    int maxDiv = 0, count = 0;
    std::cout << "The first 20 anti-primes are:" << std::endl;
    for (int n = 1; count < 20; ++n) {
        int d = countDivisors(n);
        if (d > maxDiv) {
            std::cout << n << " ";
            maxDiv = d;
            count++;
        }
    }
    std::cout << std::endl;
    return 0;
}


% Count factors
factors = proc (n: int) returns (int)
    if n<2 then return(1) end
    count: int := 2
    for i: int in int$from_to(2, n/2) do
        if n//i = 0 then count := count + 1 end
    end
    return(count)
end factors

% Generate antiprimes
antiprimes = iter () yields (int)
    max: int := 0
    n: int := 1
    while true do
        f: int := factors(n)
        if f > max then
            yield(n)
            max := f
        end
        n := n + 1
    end
end antiprimes

% Show the first 20 antiprimes
start_up = proc ()
    max = 20
    po: stream := stream$primary_output()
    count: int := 0

    for i: int in antiprimes() do
        stream$puts(po, int$unparse(i) || " ")
        count := count + 1
        if count = max then break end
    end
end start_up


      ******************************************************************
      * COBOL solution to Anti-primes challange
      * The program was run on OpenCobolIDE
      ******************************************************************
       IDENTIFICATION DIVISION.
       PROGRAM-ID. ANGLE-PRIMES.

       ENVIRONMENT DIVISION.
       DATA DIVISION.
       WORKING-STORAGE SECTION.
       77  ANTI-PRIMES-CTR              PIC 9(3) VALUE 0.
       77  FACTORS-CTR                  PIC 9(3) VALUE 0.
       77  WS-INTEGER                   PIC 9(5) VALUE 1.
       77  WS-MAX                       PIC 9(5) VALUE 0.
       77  WS-I                         PIc 9(5) VALUE 0.
       77  WS-LIMIT                     PIC 9(5) VALUE 1.
       77  WS-REMAINDER                 PIC 9(5).

       01  OUT-HDR         PIC X(23)    VALUE 'SEQ ANTI-PRIME FACTORS'.
       01  OUT-LINE.
           05 OUT-SEQ      PIC 9(3).
           05 FILLER       PIC X(3)     VALUE SPACES.
           05 OUT-ANTI     PIC ZZZZ9.
           05 FILLER       PIC X(4)     VALUE SPACES.
           05 OUT-FACTORS  PIC ZZZZ9.

       PROCEDURE DIVISION.
       000-MAIN.
           DISPLAY OUT-HDR.
           PERFORM 100-GET-ANTI-PRIMES
               VARYING WS-INTEGER FROM 1 By 1
               UNTIL ANTI-PRIMES-CTR >= 20.
           STOP RUN.

       100-GET-ANTI-PRIMES.
           SET FACTORS-CTR TO 0.
           COMPUTE WS-LIMIT = 1 + WS-INTEGER ** .5.
           PERFORM 200-COUNT-FACTORS
               VARYING WS-I FROM 1 BY 1
               UNTIL WS-I >= WS-LIMIT.
           IF FACTORS-CTR > WS-MAX
               ADD 1 TO ANTI-PRIMES-CTR
               COMPUTE WS-MAX = FACTORS-CTR
               MOVE ANTI-PRIMES-CTR TO OUT-SEQ
               MOVE WS-INTEGER TO OUT-ANTI
               MOVE FACTORS-CTR TO OUT-FACTORS
               DISPLAY OUT-LINE
           END-IF.

       200-COUNT-FACTORS.
           COMPUTE WS-REMAINDER =
               FUNCTION MOD(WS-INTEGER WS-I).
           IF WS-REMAINDER = ZERO
               ADD 1 TO FACTORS-CTR
               IF WS-INTEGER NOT = WS-I ** 2
                   ADD 1 TO FACTORS-CTR
               END-IF
           END-IF.

      ******************************************************************
      *    OUTPUT:
      ******************************************************************
      *     SEQ ANTI-PRIME FACTORS
      *     001       1        1
      *     002       2        2
      *     003       4        3
      *     004       6        4
      *     005      12        6
      *     006      24        8
      *     007      36        9
      *     008      48       10
      *     009      60       12
      *     010     120       16
      *     011     180       18
      *     012     240       20
      *     013     360       24
      *     014     720       30
      *     015     840       32
      *     016    1260       36
      *     017    1680       40
      *     018    2520       48
      *     019    5040       60
      *     020    7560       64
      ******************************************************************


(defun factors (n &aux (lows '()) (highs '()))
    (do ((limit (1+ (isqrt n))) (factor 1 (1+ factor)))
        ((= factor limit)
            (when (= n (* limit limit))
                (push limit highs))
            (remove-duplicates (nreconc lows highs)))
        (multiple-value-bind (quotient remainder) (floor n factor)
            (when (zerop remainder)
                (push factor lows)
                (push quotient highs)))))

(defun anti-prime ()
    (format t "The first 20 anti-primes are :~%")
    (do ((dmax 0) (c 0) (i 0 (1+ i)))
        ((= c 20))
        (setf facts (list-length (factors i)))
        (when (< dmax facts)
            (format t "~d " i)
            (setq dmax facts)
            (incf c))))


include "cowgol.coh";
const AMOUNT := 20;

sub countFactors(n: uint16): (count: uint16) is
    var i: uint16 := 1;
    count := 1;
    while i <= n/2 loop
        if n%i == 0 then
            count := count + 1;
        end if;
        i := i + 1;
    end loop;
end sub;

var max: uint16 := 0;
var seen: uint8 := 0;
var n: uint16 := 1;
var f: uint16 := 0;

while seen < AMOUNT loop;
    f := countFactors(n);
    if f > max then
        print_i16(n);
        print_char(' ');
        max := f;
        seen := seen + 1;
    end if;
    n := n + 1;
end loop;
print_nl();


def count_divisors(n : Int64) : Int64
  return 1_i64 if n < 2
  count = 2_i64

  i = 2
  while i <= n // 2
    count += 1 if n % i == 0
    i += 1
  end

  count
end

max_div = 0_i64
count = 0_i64

print "The first 20 anti-primes are: "

n = 1_i64
while count < 20
  d = count_divisors n

  if d > max_div
    print "#{n} "
    max_div = d
    count += 1
  end

  n += 1
end

puts ""