      ┌──────────────────────────────────────────────────────────────────────────┐
      │  One common method that ensures enough accuracy in REXX is specifying    │
      │  more precision  (via  NUMERIC DIGITS  nnn)  than is needed,  and then   │
      │  displaying the number of digits that are desired,  or  the number(s)    │
      │  could be re-normalized using the  FORMAT  BIF.                          │
      │                                                                          │
      │  The technique used (below) is to set the   numeric digits   ten higher  │
      │  than the desired digits,  as specified by the   SHOWDIGS  variable.     │
      └──────────────────────────────────────────────────────────────────────────┘


radians = Math::PI / 4
degrees = 45.0

def deg2rad(d)
  d * Math::PI / 180
end

def rad2deg(r)
  r * 180 / Math::PI
end

#sine
puts "#{Math.sin(radians)} #{Math.sin(deg2rad(degrees))}"
#cosine
puts "#{Math.cos(radians)} #{Math.cos(deg2rad(degrees))}"
#tangent
puts "#{Math.tan(radians)} #{Math.tan(deg2rad(degrees))}"
#arcsine
arcsin = Math.asin(Math.sin(radians))
puts "#{arcsin} #{rad2deg(arcsin)}"
#arccosine
arccos = Math.acos(Math.cos(radians))
puts "#{arccos} #{rad2deg(arccos)}"
#arctangent
arctan = Math.atan(Math.tan(radians))
puts "#{arctan} #{rad2deg(arctan)}"


' Find these three ratios:  Sine, Cosine, Tangent.  (These ratios have NO units.)

deg = 45.0
' Run BASIC works in radians; so, first convert deg to rad as shown in next line.
rad = deg * (atn(1)/45)
print "Ratios for a "; deg; " degree angle, (or "; rad; " radian angle.)"
print "Sine:        "; SIN(rad)
print "Cosine:      "; COS(rad)
print "Tangent:     "; TAN(rad)

print "Inverse Functions - - (Using above ratios)"
' Now, use those ratios to work backwards to show their original angle in radians.
' Also, use this:  rad / (atn(1)/45) = deg   (To change radians to degrees.)
print "Arcsine:     "; ASN(SIN(rad)); " radians, (or "; ASN(SIN(rad))/(atn(1)/45); " degrees)"
print "Arccosine:   "; ACS(COS(rad)); " radians, (or "; ACS(COS(rad))/(atn(1)/45); " degrees)"
print "Arctangent:  "; ATN(TAN(rad)); " radians, (or "; ATN(TAN(rad))/(atn(1)/45); " degrees)"

' This code also works in Liberty BASIC.
' The above (atn(1)/45) = approx .01745329252


// 20210221 Rust programming solution

use std::f64::consts::PI;

fn main() {
   let angle_radians: f64 = PI/4.0;
   let angle_degrees: f64 = 45.0;

   println!("{} {}", angle_radians.sin(), angle_degrees.to_radians().sin());
   println!("{} {}", angle_radians.cos(), angle_degrees.to_radians().cos());
   println!("{} {}", angle_radians.tan(), angle_degrees.to_radians().tan());

   let asin = angle_radians.sin().asin();
   println!("{} {}", asin, asin.to_degrees());
   let acos = angle_radians.cos().acos();
   println!("{} {}", acos, acos.to_degrees());
   let atan = angle_radians.tan().atan();
   println!("{} {}", atan, atan.to_degrees());
}


data _null_;
pi = 4*atan(1);
deg = 30;
rad = pi/6;
k = pi/180;
x = 0.2;

a = sin(rad);
b = sin(deg*k);
put a b;

a = cos(rad);
b = cos(deg*k);
put a b;

a = tan(rad);
b = tan(deg*k);
put a b;

a=arsin(x);
b=arsin(x)/k;
put a b;

a=arcos(x);
b=arcos(x)/k;
put a b;

a=atan(x);
b=atan(x)/k;
put a b;
run;


import scala.math._

object Gonio extends App {
  //Pi / 4 rad is 45 degrees. All answers should be the same.
  val radians = Pi / 4
  val degrees = 45.0

  println(s"${sin(radians)} ${sin(toRadians(degrees))}")
  //cosine
  println(s"${cos(radians)} ${cos(toRadians(degrees))}")
  //tangent
  println(s"${tan(radians)} ${tan(toRadians(degrees))}")
  //arcsine
  val bgsin = asin(sin(radians))
  println(s"$bgsin ${toDegrees(bgsin)}")
  val bgcos = acos(cos(radians))
  println(s"$bgcos ${toDegrees(bgcos)}")
  //arctangent
  val bgtan = atan(tan(radians))
  println(s"$bgtan ${toDegrees(bgtan)}")
  val bgtan2 = atan2(1, 1)
  println(s"$bgtan ${toDegrees(bgtan)}")
}


(define pi (* 4 (atan 1)))

(define radians (/ pi 4))
(define degrees 45)

(display (sin radians))
(display " ")
(display (sin (* degrees (/ pi 180))))
(newline)

(display (cos radians))
(display " ")
(display (cos (* degrees (/ pi 180))))
(newline)

(display (tan radians))
(display " ")
(display (tan (* degrees (/ pi 180))))
(newline)

(define arcsin (asin (sin radians)))
(display arcsin)
(display " ")
(display (* arcsin (/ 180 pi)))
(newline)

(define arccos (acos (cos radians)))
(display arccos)
(display " ")
(display (* arccos (/ 180 pi)))
(newline)

(define arctan (atan (tan radians)))
(display arctan)
(display " ")
(display (* arctan (/ 180 pi)))
(newline)


$ include "seed7_05.s7i";
  include "float.s7i";
  include "math.s7i";

const proc: main is func
  local
    const float: radians is PI / 4.0;
    const float: degrees is 45.0;
  begin
    writeln("            radians  degrees");
    writeln("sine:       " <& sin(radians) digits 5 <& sin(degrees * PI / 180.0) digits 5 lpad 9);
    writeln("cosine:     " <& cos(radians) digits 5 <& cos(degrees * PI / 180.0) digits 5 lpad 9);
    writeln("tangent:    " <& tan(radians) digits 5 <& tan(degrees * PI / 180.0) digits 5 lpad 9);
    writeln("arcsine:    " <& asin(0.70710677) digits 5 <& asin(0.70710677) * 180.0 / PI digits 5 lpad 9);
    writeln("arccosine:  " <& acos(0.70710677) digits 5 <& acos(0.70710677) * 180.0 / PI digits 5 lpad 9);
    writeln("arctangent: " <& atan(1.0) digits 5 <& atan(1.0) * 180.0 / PI digits 5 lpad 9);
  end func;


var angle_deg = 45;
var angle_rad = Num.pi/4;

for arr in [
    [sin(angle_rad), sin(deg2rad(angle_deg))],
    [cos(angle_rad), cos(deg2rad(angle_deg))],
    [tan(angle_rad), tan(deg2rad(angle_deg))],
    [cot(angle_rad), cot(deg2rad(angle_deg))],
] {
    say arr.join(" ");
}

for n in [
    asin(sin(angle_rad)),
    acos(cos(angle_rad)),
    atan(tan(angle_rad)),
    acot(cot(angle_rad)),
] {
    say [n, rad2deg(n)].join(' ');
}


--Conversion
VALUES degrees(3.1415926);
VALUES radians(180);
-- This is equal to Pi.

--PI/4 45
VALUES sin(radians(180)/4);
VALUES sin(radians(45));
VALUES cos(radians(180)/4);
VALUES cos(radians(45));
VALUES tan(radians(180)/4);
VALUES tan(radians(45));
VALUES cot(radians(180)/4);
VALUES cot(radians(45));
VALUES asin(sin(radians(180)/4));
VALUES asin(sin(radians(45)));
VALUES atan(tan(radians(180)/4));
VALUES atan(tan(radians(45)));

--PI/3 60
VALUES sin(radians(180)/3);
VALUES sin(radians(60));
VALUES cos(radians(180)/3);
VALUES cos(radians(60));
VALUES tan(radians(180)/3);
VALUES tan(radians(60));
VALUES cot(radians(180)/3);
VALUES cot(radians(60));
VALUES asin(sin(radians(180)/3));
VALUES asin(sin(radians(60)));
VALUES atan(tan(radians(180)/3));
VALUES atan(tan(radians(60)));


scalar deg=_pi/180

display cos(30*deg)
display sin(30*deg)
display tan(30*deg)

display cos(_pi/6)
display sin(_pi/6)
display tan(_pi/6)

display acos(0.5)
display asin(0.5)
display atan(0.5)


package require Tcl 8.5

proc PI {} {expr {4*atan(1)}}
proc deg2rad d {expr {$d/180*[PI]}}
proc rad2deg r {expr {$r*180/[PI]}}

namespace path ::tcl::mathfunc

proc trig degrees {
    set radians [deg2rad $degrees]
    puts [sin $radians]
    puts [cos $radians]
    puts [tan $radians]
    set arcsin [asin [sin $radians]]; puts "$arcsin [rad2deg $arcsin]"
    set arccos [acos [cos $radians]]; puts "$arccos [rad2deg $arccos]"
    set arctan [atan [tan $radians]]; puts "$arctan [rad2deg $arctan]"
}
trig 60.0


Public Sub trig()
    Pi = WorksheetFunction.Pi()
    Debug.Print Sin(Pi / 2)
    Debug.Print Sin(90 * Pi / 180)
    Debug.Print Cos(0)
    Debug.Print Cos(0 * Pi / 180)
    Debug.Print Tan(Pi / 4)
    Debug.Print Tan(45 * Pi / 180)
    Debug.Print WorksheetFunction.Asin(1) * 2
    Debug.Print WorksheetFunction.Asin(1) * 180 / Pi
    Debug.Print WorksheetFunction.Acos(0) * 2
    Debug.Print WorksheetFunction.Acos(0) * 180 / Pi
    Debug.Print Atn(1) * 4
    Debug.Print Atn(1) * 180 / Pi
End Sub


Module Module1

    Sub Main()
        Console.WriteLine("=== radians ===")
        Console.WriteLine("  sin (pi/3) = {0}", Math.Sin(Math.PI / 3))
        Console.WriteLine("  cos (pi/3) = {0}", Math.Cos(Math.PI / 3))
        Console.WriteLine("  tan (pi/3) = {0}", Math.Tan(Math.PI / 3))
        Console.WriteLine("arcsin (1/2) = {0}", Math.Asin(0.5))
        Console.WriteLine("arccos (1/2) = {0}", Math.Acos(0.5))
        Console.WriteLine("arctan (1/2) = {0}", Math.Atan(0.5))
        Console.WriteLine()
        Console.WriteLine("=== degrees ===")
        Console.WriteLine("    sin (60) = {0}", Math.Sin(60 * Math.PI / 180))
        Console.WriteLine("    cos (60) = {0}", Math.Cos(60 * Math.PI / 180))
        Console.WriteLine("    tan (60) = {0}", Math.Tan(60 * Math.PI / 180))
        Console.WriteLine("arcsin (1/2) = {0}", Math.Asin(0.5) * 180 / Math.PI)
        Console.WriteLine("arccos (1/2) = {0}", Math.Acos(0.5) * 180 / Math.PI)
        Console.WriteLine("arctan (1/2) = {0}", Math.Atan(0.5) * 180 / Math.PI)
    End Sub

End Module


import "/fmt" for Fmt

var d = 30
var r = d * Num.pi / 180
var s = 0.5
var c = 3.sqrt / 2
var t = 1 / 3.sqrt

Fmt.print("sin($9.6f deg) = $f",  d, (d*Num.pi/180).sin)
Fmt.print("sin($9.6f rad) = $f",  r, r.sin)
Fmt.print("cos($9.6f deg) = $f",  d, (d*Num.pi/180).cos)
Fmt.print("cos($9.6f rad) = $f",  r, r.cos)
Fmt.print("tan($9.6f deg) = $f",  d, (d*Num.pi/180).tan)
Fmt.print("tan($9.6f rad) = $f",  r, r.tan)
Fmt.print("asin($f) = $9.6f deg", s, s.asin*180/Num.pi)
Fmt.print("asin($f) = $9.6f rad", s, s.asin)
Fmt.print("acos($f) = $9.6f deg", c, c.acos*180/Num.pi)
Fmt.print("acos($f) = $9.6f rad", c, c.acos)
Fmt.print("atan($f) = $9.6f deg", t, t.atan*180/Num.pi)
Fmt.print("atan($f) = $9.6f rad", t, t.atan)


include c:\cxpl\codes;  \intrinsic 'code' declarations
def     Pi = 3.14159265358979323846;

func real ATan(Y);      \Arc tangent
real Y;
return ATan2(Y, 1.0);

func real Deg(X);       \Convert radians to degrees
real X;
return 57.2957795130823 * X;

func real Rad(X);       \Convert degrees to radians
real X;
return X / 57.2957795130823;

real A, B, C;
[A:= Sin(Pi/6.0);
RlOut(0, A);  ChOut(0, 9\tab\);  RlOut(0, Sin(Rad(30.0)));  CrLf(0);
B:= Cos(Pi/6.0);
RlOut(0, B);  ChOut(0, 9\tab\);  RlOut(0, Cos(Rad(30.0)));  CrLf(0);
C:= Tan(Pi/4.0);
RlOut(0, C);  ChOut(0, 9\tab\);  RlOut(0, Tan(Rad(45.0)));  CrLf(0);

RlOut(0, ASin(A));  ChOut(0, 9\tab\);  RlOut(0, Deg(ASin(A)));  CrLf(0);
RlOut(0, ACos(B));  ChOut(0, 9\tab\);  RlOut(0, Deg(ACos(B)));  CrLf(0);
RlOut(0, ATan(C));  ChOut(0, 9\tab\);  RlOut(0, Deg(ATan(C)));  CrLf(0);
]


10 DEF FN d(a)=a*PI/180:REM convert degrees to radians; all ZX Spectrum trig calculations are done in radians
20 DEF FN i(r)=180*r/PI:REM convert radians to degrees for inverse functions
30 LET d=45
40 LET r=PI/4
50 PRINT SIN r,SIN FN d(d)
60 PRINT COS r,COS FN d(d)
70 PRINT TAN r,TAN FN d(d)
80 PRINT
90 LET d=.5
110 PRINT ASN d,FN i(ASN d)
120 PRINT ACS d,FN i(ACS d)
130 PRINT ATN d,FN i(ATN d)


on run
    1 + 2

    ap({square, squareRoot}, {result})

    --> {9, 1.732050807569}
end run

-- square :: Num a => a -> a
on square(x)
    x * x
end square

-- squareRoot :: Num a, Float b => a -> b
on squareRoot(x)
    x ^ 0.5
end squareRoot

-- GENERIC FUNCTIONS ----------------------------------------------------------

-- A list of functions applied to a list of arguments
-- (<*> | ap) :: [(a -> b)] -> [a] -> [b]
on ap(fs, xs)
    set lst to {}
    repeat with f in fs
        tell mReturn(contents of f)
            repeat with x in xs
                set end of lst to |λ|(contents of x)
            end repeat
        end tell
    end repeat
    return lst
end ap

-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: Handler -> Script
on mReturn(f)
    if class of f is script then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn


function Sum (x, y)
    Sum = x + y  # using name of function
end function

function SumR (x, y)
    return x + y  # using Return keyword which always returns immediately
end function

print Sum (1, 2)
print SumR(2, 3)


' FB 1.05.0 Win64

' Three different ways of returning a value from a function

Function Sum (x As Integer, y As Integer) As Integer
  Sum = x + y  '' using name of function
End Function

Function Sum2 (x As Integer, y As Integer) As Integer
  Function = x + y  '' using Function keyword
End Function

Function Sum3 (x As Integer, y As Integer) As Integer
  Return x + y  '' using Return keyword which always returns immediately
End Function

Print Sum (1, 2)
Print Sum2(2, 3)
Print Sum3(3, 4)
Sleep


package main

import (
    "math"
    "os"
    "strconv"
    "text/template"
)

func sqr(x string) string {
    f, err := strconv.ParseFloat(x, 64)
    if err != nil {
        return "NA"
    }
    return strconv.FormatFloat(f*f, 'f', -1, 64)
}

func sqrt(x string) string {
    f, err := strconv.ParseFloat(x, 64)
    if err != nil {
        return "NA"
    }
    return strconv.FormatFloat(math.Sqrt(f), 'f', -1, 64)
}

func main() {
    f := template.FuncMap{"sqr": sqr, "sqrt": sqrt}
    t := template.Must(template.New("").Funcs(f).Parse(`. = {{.}}
square: {{sqr .}}
square root: {{sqrt .}}
`))
    t.Execute(os.Stdout, "3")
}


   example=: *:, %:  NB. *: is square, %: is square root
   example 3
9 1.73205


julia> 3
3
julia> ans * ans, ans - 1
(9, 2)


// version 1.1.2

fun main(args: Array<String>) {
    3.let {
        println(it)
        println(it * it)
        println(Math.sqrt(it.toDouble()))
    }
}


with javascript_semantics
object _
_ = 3
?_
?_*_


PicoLisp sets the value of the variable (symbol) '@' to the result of
conditional and controlling expressions in flow- and logic-functions (cond, if,
and, when, while, etc.).

Within a function or method '@' behaves like a local variable, i.e. its value is
automatically saved upon function entry and restored at exit.

For example, to read the current input channel until EOF, and print the square
of every item which is a number:


65..67 | ForEach-Object {$_ * 2}     # Multiply the numbers by 2
65..67 | ForEach-Object {[char]$_ }  # ASCII values of the numbers


#lang racket

(module topic1 racket
  ;; define $ as a "parameter", but make it look like a plain identifier
  (provide $ (rename-out [$if if] [$#%app #%app]))
  (define current-value (make-parameter #f))
  (define-syntax $
    (syntax-id-rules (set!)
      [(_ x ...) ((current-value) x ...)]
      [(set! _ val) (current-value val)]
      [_ (current-value)]))
  ;; make an `if' form that binds it to the condition result
  (define-syntax-rule ($if C T E)
    (parameterize ([current-value C])
      (if $ T E)))
  ;; function application with []s uses the topic variable for the first arg
  (define-syntax ($#%app stx)
    (syntax-case stx ()
      [(_ f x y ...) (equal? #\[ (syntax-property stx 'paren-shape))
       #'(parameterize ([current-value x]) (f y ...))]
      [(_ f x ...) #'(f x ...)])))

(module topic2 racket
  ;; better variant: define `$' as a syntax parameter, which is adjusted to an
  ;; actual local binding; make it work in `if', and have a function definition
  ;; form that binds it to the actual arguments
  (provide $ (rename-out [$if if]) defun)
  (require racket/stxparam)
  (define-syntax-parameter $ (λ(stx) (raise-syntax-error '$ "not in scope")))
  (define-syntax-rule ($if C T E)
    (let ([c C]) (syntax-parameterize ([$ (make-rename-transformer #'c)])
                   (if c T E))))
  (define-syntax-rule (defun name body ...)
    (define (name arg)
      (syntax-parameterize ([$ (make-rename-transformer #'arg)])
        body ...)))
  )

(module sample1 racket
  (require (submod ".." topic1))
  (if (memq 2 '(1 2 3)) (cadr $) 'missing)
  ;; => 3
  (define (foo) (list (sqrt $) (* $ $)))
  [foo 9]
  ;; => '(3 81)
  )
(require 'sample1)

(module sample2 racket
  (require (submod ".." topic2))
  (if (memq 2 '(1 2 3)) (cadr $) 'missing)
  ;; => 3
  (defun foo (list (sqrt $) (* $ $)))
  (foo 9)
  ;; => '(3 81)
  )
(require 'sample2)


/*REXX program shows something close to a  "topic variable" (for functions/subroutines).*/
parse arg N                                      /*obtain a variable from the cmd line. */
call  squareIt N                                 /*invoke a function to square da number*/
say   result       '  ◄───'                      /*display returned value from the func.*/
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
squareIt:  return  arg(1) ** 2                   /*return the square of passed argument.*/


see "sum1 = " + sum1(1,2) + nl
see "sum2 = " + sum2(2,3) + nl

func sum1 (x, y)
     sum = x + y
     return sum

func sum2 (x, y)
     return x + y


while DATA.gets     # assigns to $_ (local scope)
  print             # If no arguments are given, prints $_
end
__END__
This is line one
This is line two
This is line three


object TopicVar extends App {
  class SuperString(val org: String){
    def it(): Unit = println(org)
  }

  new SuperString("FvdB"){it()}
  new SuperString("FvdB"){println(org)}

  Seq(1).foreach {println}
  Seq(2).foreach {println(_)}
  Seq(4).foreach { it => println(it)}
  Seq(8).foreach { it => println(it + it)}
}


- 3.0;
val it = 3.0 : real
- it * it;
val it = 9.0 : real
- Math.sqrt it;
val it = 3.0 : real
-


multiply 3 4    # We assume this user defined function has been previously defined
echo $?    # This will output 12, but $? will now be zero indicating a successful echo


var T // global scope

var doSomethingWithT = Fn.new { [T * T, T.sqrt] }

T = 3
System.print(doSomethingWithT.call())


a,_,c:=List(1,2,3,4,5,6) //-->a=1, c=3, here _ is used as "ignore"
3.0 : _.sqrt() : println(_) //-->"1.73205", _ (and :) is used to "explode" a computation
                            // as syntactic sugar
1.0 + 2 : _.sqrt() : _.pow(4)  // no variables used, the compiler "implodes" the computation
    // --> 9


F f(n)
   R sum((1..n).filter(k -> gcd(@n, k) == 1).map(k -> 1))

F is_prime(n)
   R f(n) == n - 1

L(n) 1..25
   print(‘ f(#.) == #.’.format(n, f(n))‘’(I is_prime(n) {‘, is prime’} E ‘’))
V count = 0
L(n) 1..10'000
   count += is_prime(n)
   I n C (100, 1000, 10'000)
      print(‘Primes up to #.: #.’.format(n, count))


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

/************************************/
/* Constantes                       */
/************************************/
.include "../includeConstantesARM64.inc"
.equ MAXI,      25

/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessNumber:       .asciz " number @ totient @  @ \n"
szCarriageReturn:   .asciz "\n"
szMessPrime:        .asciz " is prime."
szMessSpace:        .asciz " "
szMessCounterPrime: .asciz "Number of primes to @ : @ \n"
szMessOverflow:     .asciz "Overflow function isPrime.\n"
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:           .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:
    mov x4,#1                   // start number
1:
    mov x0,x4
    bl totient                  // compute totient
    mov x5,x0
    mov x0,x4
    bl isPrime                  // control if number is prime
    mov x6,x0
    mov x0,x4                   // display result
    ldr x1,qAdrsZoneConv
    bl conversion10             // call décimal conversion
    ldr x0,qAdrszMessNumber
    ldr x1,qAdrsZoneConv        // insert conversion in message
    bl strInsertAtCharInc
    mov x7,x0
    mov x0,x5
    ldr x1,qAdrsZoneConv
    bl conversion10             // call décimal conversion
    mov x0,x7
    ldr x1,qAdrsZoneConv        // insert conversion in message
    bl strInsertAtCharInc
    mov x7,x0
    cmp x6,#1
    ldr x1,qAdrszMessPrime
    ldr x8,qAdrszMessSpace
    csel x1,x1,x8,eq
    mov x0,x7
    bl strInsertAtCharInc
    bl affichageMess             // display message

    add x4,x4,#1                 // increment number
    cmp x4,#MAXI                 // maxi ?
    ble 1b                       // and loop

    mov x4,#2                    // first number
    mov x5,#0                    // prime counter
    ldr x6,iCst1000              // load constantes
    ldr x7,iCst10000
    ldr x8,iCst100000
2:
    mov x0,x4
    bl isPrime
    cmp x0,#0
    beq 3f
    add x5,x5,#1
3:
    add x4,x4,#1
    cmp x4,#100
    bne 4f
    mov x0,#100
    mov x1,x5
    bl displayCounter
    b 7f
4:
    cmp x4,x6        // 1000
    bne 5f
    mov x0,x6
    mov x1,x5
    bl displayCounter
    b 7f
5:
    cmp x4,x7        // 10000
    bne 6f
    mov x0,x7
    mov x1,x5
    bl displayCounter
    b 7f
6:
    cmp x4,x8        // 100000
    bne 7f
    mov x0,x8
    mov x1,x5
    bl displayCounter
7:
    cmp x4,x8
    ble 2b                      // and loop

100:                            // standard end of the program
    mov x0, #0                  // return code
    mov x8,EXIT
    svc #0                      // perform the system call
qAdrszCarriageReturn:    .quad szCarriageReturn
qAdrsZoneConv:           .quad sZoneConv
qAdrszMessNumber:        .quad szMessNumber
qAdrszMessCounterPrime:  .quad szMessCounterPrime
qAdrszMessPrime:         .quad szMessPrime
qAdrszMessSpace:         .quad szMessSpace
iCst1000:                .quad 1000
iCst10000:               .quad 10000
iCst100000:              .quad 100000
/******************************************************************/
/*    display counter                                             */
/******************************************************************/
/* x0 contains limit  */
/* x1 contains counter */
displayCounter:
    stp x1,lr,[sp,-16]!          // save  registers
    stp x2,x3,[sp,-16]!          // save  registers
    mov x2,x1
    ldr x1,qAdrsZoneConv
    bl conversion10             // call décimal conversion
    ldr x0,qAdrszMessCounterPrime
    ldr x1,qAdrsZoneConv        // insert conversion in message
    bl strInsertAtCharInc
    mov x3,x0
    mov x0,x2
    ldr x1,qAdrsZoneConv
    bl conversion10             // call décimal conversion
    mov x0,x3
    ldr x1,qAdrsZoneConv        // insert conversion in message
    bl strInsertAtCharInc
    bl affichageMess
100:
    ldp x2,x3,[sp],16        // restaur  registers
    ldp x1,lr,[sp],16            // restaur  registers
    ret
/******************************************************************/
/*     compute totient of number                                  */
/******************************************************************/
/* x0 contains number  */
totient:
    stp x1,lr,[sp,-16]!       // save  registers
    stp x2,x3,[sp,-16]!       // save  registers
    stp x4,x5,[sp,-16]!       // save  registers
    mov x4,x0                 // totient
    mov x5,x0                 // save number
    mov x1,#0                 // for first divisor
1:                            // begin loop
    mul x3,x1,x1              // compute square
    cmp x3,x5                 // compare number
    bgt 4f                    // end
    add x1,x1,#2              // next divisor
    udiv x2,x5,x1
    msub x3,x1,x2,x5          // compute remainder
    cmp x3,#0                 // remainder null ?
    bne 3f
2:                            // begin loop 2
    udiv x2,x5,x1
    msub x3,x1,x2,x5          // compute remainder
    cmp x3,#0
    csel x5,x2,x5,eq          // new value = quotient
    beq 2b

    udiv x2,x4,x1             // divide totient
    sub x4,x4,x2              // compute new totient
3:
    cmp x1,#2                 // first divisor ?
    mov x0,1
    csel x1,x0,x1,eq          // divisor = 1
    b 1b                      // and loop
4:
    cmp x5,#1                 // final value > 1
    ble 5f
    mov x0,x4                 // totient
    mov x1,x5                 // divide by value
    udiv x2,x4,x5             // totient divide by value
    sub x4,x4,x2              // compute new totient
5:

    mov x0,x4
100:
    ldp x4,x5,[sp],16         // restaur  registers
    ldp x2,x3,[sp],16         // restaur  registers
    ldp x1,lr,[sp],16         // restaur  registers
    ret
/***************************************************/
/*   Verification si un nombre est premier         */
/***************************************************/
/* x0 contient le nombre à verifier */
/* x0 retourne 1 si premier  0 sinon */
isPrime:
    stp x1,lr,[sp,-16]!        // save  registres
    stp x2,x3,[sp,-16]!        // save  registres
    mov x2,x0
    sub x1,x0,#1
    cmp x2,0
    beq 99f                    // retourne zéro
    cmp x2,2                   // pour 1 et 2 retourne 1
    ble 2f
    mov x0,#2
    bl moduloPur64
    bcs 100f                   // erreur overflow
    cmp x0,#1
    bne 99f                    // Pas premier
    cmp x2,3
    beq 2f
    mov x0,#3
    bl moduloPur64
    blt 100f                   // erreur overflow
    cmp x0,#1
    bne 99f

    cmp x2,5
    beq 2f
    mov x0,#5
    bl moduloPur64
    bcs 100f                   // erreur overflow
    cmp x0,#1
    bne 99f                    // Pas premier

    cmp x2,7
    beq 2f
    mov x0,#7
    bl moduloPur64
    bcs 100f                   // erreur overflow
    cmp x0,#1
    bne 99f                    // Pas premier

    cmp x2,11
    beq 2f
    mov x0,#11
    bl moduloPur64
    bcs 100f                   // erreur overflow
    cmp x0,#1
    bne 99f                    // Pas premier

    cmp x2,13
    beq 2f
    mov x0,#13
    bl moduloPur64
    bcs 100f                   // erreur overflow
    cmp x0,#1
    bne 99f                    // Pas premier

    cmp x2,17
    beq 2f
    mov x0,#17
    bl moduloPur64
    bcs 100f                   // erreur overflow
    cmp x0,#1
    bne 99f                    // Pas premier
2:
    cmn x0,0                   // carry à zero pas d'erreur
    mov x0,1                   // premier
    b 100f
99:
    cmn x0,0                   // carry à zero pas d'erreur
    mov x0,#0                  // Pas premier
100:
    ldp x2,x3,[sp],16          // restaur des  2 registres
    ldp x1,lr,[sp],16          // restaur des  2 registres
    ret                        // retour adresse lr x30

/**************************************************************/
/********************************************************/
/*   Calcul modulo de b puissance e modulo m  */
/*    Exemple 4 puissance 13 modulo 497 = 445         */
/********************************************************/
/* x0  nombre  */
/* x1 exposant */
/* x2 modulo   */
moduloPur64:
    stp x1,lr,[sp,-16]!        // save  registres
    stp x3,x4,[sp,-16]!        // save  registres
    stp x5,x6,[sp,-16]!        // save  registres
    stp x7,x8,[sp,-16]!        // save  registres
    stp x9,x10,[sp,-16]!        // save  registres
    cbz x0,100f
    cbz x1,100f
    mov x8,x0
    mov x7,x1
    mov x6,1                   // resultat
    udiv x4,x8,x2
    msub x9,x4,x2,x8           // contient le reste
1:
    tst x7,1
    beq 2f
    mul x4,x9,x6
    umulh x5,x9,x6
    //cbnz x5,99f
    mov x6,x4
    mov x0,x6
    mov x1,x5
    bl divisionReg128U
    cbnz x1,99f                // overflow
    mov x6,x3
2:
    mul x8,x9,x9
    umulh x5,x9,x9
    mov x0,x8
    mov x1,x5
    bl divisionReg128U
    cbnz x1,99f                // overflow
    mov x9,x3
    lsr x7,x7,1
    cbnz x7,1b
    mov x0,x6                  // result
    cmn x0,0                   // carry à zero pas d'erreur
    b 100f
99:
    ldr x0,qAdrszMessOverflow
    bl  affichageMess
    cmp x0,0                   // carry à un car erreur
    mov x0,-1                  // code erreur

100:
    ldp x9,x10,[sp],16          // restaur des  2 registres
    ldp x7,x8,[sp],16          // restaur des  2 registres
    ldp x5,x6,[sp],16          // restaur des  2 registres
    ldp x3,x4,[sp],16          // restaur des  2 registres
    ldp x1,lr,[sp],16          // restaur des  2 registres
    ret                        // retour adresse lr x30
qAdrszMessOverflow:         .quad  szMessOverflow
/***************************************************/
/*   division d un nombre de 128 bits par un nombre de 64 bits */
/***************************************************/
/* x0 contient partie basse dividende */
/* x1 contient partie haute dividente */
/* x2 contient le diviseur */
/* x0 retourne partie basse quotient */
/* x1 retourne partie haute quotient */
/* x3 retourne le reste */
divisionReg128U:
    stp x6,lr,[sp,-16]!        // save  registres
    stp x4,x5,[sp,-16]!        // save  registres
    mov x5,#0                  // raz du reste R
    mov x3,#128                // compteur de boucle
    mov x4,#0                  // dernier bit
1:
    lsl x5,x5,#1               // on decale le reste de 1
    tst x1,1<<63               // test du bit le plus à gauche
    lsl x1,x1,#1               // on decale la partie haute du quotient de 1
    beq 2f
    orr  x5,x5,#1              // et on le pousse dans le reste R
2:
    tst x0,1<<63
    lsl x0,x0,#1               // puis on decale la partie basse
    beq 3f
    orr x1,x1,#1               // et on pousse le bit de gauche dans la partie haute
3:
    orr x0,x0,x4               // position du dernier bit du quotient
    mov x4,#0                  // raz du bit
    cmp x5,x2
    blt 4f
    sub x5,x5,x2                // on enleve le diviseur du reste
    mov x4,#1                   // dernier bit à 1
4:
                               // et boucle
    subs x3,x3,#1
    bgt 1b
    lsl x1,x1,#1               // on decale le quotient de 1
    tst x0,1<<63
    lsl x0,x0,#1              // puis on decale la partie basse
    beq 5f
    orr x1,x1,#1
5:
    orr x0,x0,x4                  // position du dernier bit du quotient
    mov x3,x5
100:
    ldp x4,x5,[sp],16          // restaur des  2 registres
    ldp x6,lr,[sp],16          // restaur des  2 registres
    ret                        // retour adresse lr x30

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


with Ada.Text_IO;
with Ada.Integer_Text_IO;

procedure Totient is

   function Totient (N : in Integer) return Integer is
      Tot : Integer := N;
      I   : Integer;
      N2  : Integer := N;
   begin
      I := 2;
      while I * I <= N2 loop
         if N2 mod I = 0 then
            while N2 mod I = 0 loop
               N2 := N2 / I;
            end loop;
            Tot := Tot - Tot / I;
         end if;

         if I = 2 then
            I := 1;
         end if;
         I := I + 2;
      end loop;

      if N2 > 1 then
         Tot := Tot - Tot / N2;
      end if;

      return Tot;
   end Totient;

   Count : Integer := 0;
   Tot   : Integer;
   Placeholder : String := "  n  Phi  Is_Prime";
   Image_N     : String renames Placeholder ( 1 ..  3);
   Image_Phi   : String renames Placeholder ( 6 ..  8);
   Image_Prime : String renames Placeholder (11 .. 17);
   use Ada.Text_IO;
   use Ada.Integer_Text_IO;
begin

   Put_Line (Placeholder);

   for N in 1 .. 25 loop
      Tot := Totient (N);

      if N - 1 = Tot then
         Count := Count + 1;
      end if;
      Put (Image_N, N);
      Put (Image_Phi, Tot);
      Image_Prime := (if N - 1 = Tot then "    True" else "   False");
      Put_Line (Placeholder);
   end loop;
   New_Line;

   Put_Line ("Number of primes up to " & Integer'(25)'Image &" =" & Count'Image);

   for N in 26 .. 100_000 loop
      Tot := Totient (N);

      if Tot = N - 1 then
         Count := Count + 1;
      end if;

      if N = 100 or N = 1_000 or N mod 10_000 = 0 then
         Put_Line ("Number of primes up to " & N'Image & " =" & Count'Image);
      end if;
   end loop;

end Totient;


BEGIN
    # returns the number of integers k where 1 <= k <= n that are mutually prime to n #
    PROC totient = ( INT n )INT:
        IF   n < 3 THEN 1
        ELIF n = 3 THEN 2
        ELSE
            INT result := n;
            INT v      := n;
            INT i      := 2;
            WHILE i * i <= v DO
                IF v MOD i = 0 THEN
                    WHILE v MOD i = 0 DO v OVERAB i OD;
                    result -:= result OVER i
                FI;
                IF i = 2 THEN
                   i := 1
                FI;
                i +:= 2
            OD;
            IF v > 1 THEN result -:= result OVER v FI;
            result
         FI # totient # ;
    # show the totient function values for the first 25 integers #
    print( ( " n  phi(n) remarks", newline ) );
    FOR n TO 25 DO
        INT tn = totient( n );
        print( ( whole( n, -2 ), ": ", whole( tn, -5 ), IF tn = n - 1 AND tn /= 0 THEN "  n is prime" ELSE "" FI, newline ) )
    OD;
    # use the totient function to count primes #
    INT n100 := 0, n1000 := 0, n10000 := 0, n100000 := 0;
    FOR n TO 100 000 DO
        IF totient( n ) = n - 1 THEN
            IF n <=     100 THEN    n100 +:= 1 FI;
            IF n <=   1 000 THEN   n1000 +:= 1 FI;
            IF n <=  10 000 THEN  n10000 +:= 1 FI;
            IF n <= 100 000 THEN n100000 +:= 1 FI
        FI
    OD;
    print( ( "There are ", whole(    n100, -6 ), " primes below      100", newline ) );
    print( ( "There are ", whole(   n1000, -6 ), " primes below    1 000", newline ) );
    print( ( "There are ", whole(  n10000, -6 ), " primes below   10 000", newline ) );
    print( ( "There are ", whole( n100000, -6 ), " primes below  100 000", newline ) )
END


BEGIN

%  RETURN P MOD Q  %
INTEGER FUNCTION MOD (P, Q);
INTEGER P, Q;
BEGIN
	MOD := P - Q * (P / Q);
END;

%  RETURN GREATEST COMMON DIVISOR OF X AND Y  %
INTEGER FUNCTION GCD (X, Y);
INTEGER X, Y;
BEGIN
	INTEGER R;
	IF X < Y THEN
	BEGIN
		INTEGER TEMP;
		TEMP := X;
		X := Y;
		Y := TEMP;
	END;
	WHILE (R := MOD(X, Y)) <> 0 DO
	BEGIN
		X := Y;
		Y := R;
	END;
	GCD := Y;
END;

% RETURN PHI (ALSO CALLED TOTIENT) OF N %
INTEGER FUNCTION PHI(N);
INTEGER N;
BEGIN
	INTEGER I, COUNT;
        COUNT := 1;
        FOR I := 2 STEP 1 UNTIL N DO
	BEGIN
		IF GCD(N,I) = 1 THEN COUNT := COUNT + 1;
 	END;
	PHI := COUNT;
END;

COMMENT - EXERCISE THE FUNCTION;
INTEGER N, TOTIENT, COUNT;
WRITE("    N   PHI(N)  PRIME?");
FOR N := 1 STEP 1 UNTIL 25 DO
BEGIN
        WRITE(N, (TOTIENT := PHI(N)));
        WRITEON(IF TOTIENT = (N-1) THEN "   YES" ELSE "   NO");
END;

COMMENT - AND USE IT TO COUNT PRIMES;
WRITE("");
COUNT := 0;
FOR N := 1 STEP 1 UNTIL 1000 DO
BEGIN
   	IF PHI(N) = (N-1) THEN COUNT := COUNT + 1;
   	IF N = 100 THEN
		WRITE("PRIMES UP TO 100 =", COUNT)
        ELSE IF N = 1000 THEN
		WRITE("PRIMES UP TO 1000 =", COUNT);
END;

END


task←{
    totient ← 1+.=⍳∨⊢
    prime   ← totient=-∘1

    ⎕←'Index' 'Totient' 'Prime',(⊢⍪totient¨,[÷2]prime¨)⍳25
    {⎕←'There are' (+/prime¨⍳⍵) 'primes below' ⍵}¨100 1000 10000
}


/* ARM assembly Raspberry PI or android with termux */
/*  program totient.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 MAXI,      25

/*********************************/
/* Initialized data              */
/*********************************/
.data
szMessNumber:       .asciz " number @ totient @  @ \n"
szCarriageReturn:   .asciz "\n"
szMessPrime:        .asciz " is prime."
szMessSpace:        .asciz " "
szMessCounterPrime: .asciz "Number of primes to @ : @ \n"
/*********************************/
/* UnInitialized data            */
/*********************************/
.bss
sZoneConv:           .skip 24
/*********************************/
/*  code section                 */
/*********************************/
.text
.global main
main:
    mov r4,#1                   @ start number
1:
    mov r0,r4
    bl totient                  @ compute totient
    mov r5,r0
    mov r0,r4
    bl isPrime                  @ control if number is prime
    mov r6,r0
    mov r0,r4                   @ display result
    ldr r1,iAdrsZoneConv
    bl conversion10             @ call décimal conversion
    ldr r0,iAdrszMessNumber
    ldr r1,iAdrsZoneConv        @ insert conversion in message
    bl strInsertAtCharInc
    mov r7,r0
    mov r0,r5
    ldr r1,iAdrsZoneConv
    bl conversion10             @ call décimal conversion
    mov r0,r7
    ldr r1,iAdrsZoneConv        @ insert conversion in message
    bl strInsertAtCharInc
    mov r7,r0
    cmp r6,#1
    ldreq r1,iAdrszMessPrime
    ldrne r1,iAdrszMessSpace
    mov r0,r7
    bl strInsertAtCharInc
    bl affichageMess             @ display message

    add r4,r4,#1                 @ increment number
    cmp r4,#MAXI                 @ maxi ?
    ble 1b                       @ and loop

    mov r4,#2                    @ first number
    mov r5,#0                    @ prime counter
    ldr r6,iCst1000              @ load constantes
    ldr r7,iCst10000
    ldr r8,iCst100000
2:
    mov r0,r4
    bl isPrime
    cmp r0,#0
    beq 3f
    add r5,r5,#1
3:
    add r4,r4,#1
    cmp r4,#100
    bne 4f
    mov r0,#100
    mov r1,r5
    bl displayCounter
    b 7f
4:
    cmp r4,r6        @ 1000
    bne 5f
    mov r0,r6
    mov r1,r5
    bl displayCounter
    b 7f
5:
    cmp r4,r7        @ 10000
    bne 6f
    mov r0,r7
    mov r1,r5
    bl displayCounter
    b 7f
6:
    cmp r4,r8        @ 100000
    bne 7f
    mov r0,r8
    mov r1,r5
    bl displayCounter
7:
    cmp r4,r8
    ble 2b                      @ and loop

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
iAdrsZoneConv:           .int sZoneConv
iAdrszMessNumber:        .int szMessNumber
iAdrszMessCounterPrime:  .int szMessCounterPrime
iAdrszMessPrime:         .int szMessPrime
iAdrszMessSpace:         .int szMessSpace
iCst1000:                .int 1000
iCst10000:               .int 10000
iCst100000:              .int 100000
/******************************************************************/
/*    display counter                                             */
/******************************************************************/
/* r0 contains limit  */
/* r1 contains counter */
displayCounter:
    push {r1-r3,lr}           @ save  registers
    mov r2,r1
    ldr r1,iAdrsZoneConv
    bl conversion10             @ call décimal conversion
    ldr r0,iAdrszMessCounterPrime
    ldr r1,iAdrsZoneConv        @ insert conversion in message
    bl strInsertAtCharInc
    mov r3,r0
    mov r0,r2
    ldr r1,iAdrsZoneConv
    bl conversion10             @ call décimal conversion
    mov r0,r3
    ldr r1,iAdrsZoneConv        @ insert conversion in message
    bl strInsertAtCharInc
    bl affichageMess
100:
    pop {r1-r3,pc}             @ restaur registers
/******************************************************************/
/*     compute totient of number                                  */
/******************************************************************/
/* r0 contains number  */
totient:
    push {r1-r5,lr}           @ save  registers
    mov r4,r0                 @ totient
    mov r5,r0                 @ save number
    mov r1,#0                 @ for first divisor
1:                            @ begin loop
    mul r3,r1,r1              @ compute square
    cmp r3,r5                 @ compare number
    bgt 4f                    @ end
    add r1,r1,#2              @ next divisor
    mov r0,r5
    bl division
    cmp r3,#0                 @ remainder null ?
    bne 3f
2:                            @ begin loop 2
    mov r0,r5
    bl division
    cmp r3,#0
    moveq r5,r2               @ new value = quotient
    beq 2b

    mov r0,r4                 @ totient
    bl division
    sub r4,r4,r2              @ compute new totient
3:
    cmp r1,#2                 @ first divisor ?
    moveq r1,#1               @ divisor = 1
    b 1b                      @ and loop
4:
    cmp r5,#1                 @ final value > 1
    ble 5f
    mov r0,r4                 @ totient
    mov r1,r5                 @ divide by value
    bl division
    sub r4,r4,r2              @ compute new totient
5:

    mov r0,r4
100:
    pop {r1-r5,pc}             @ restaur registers

/***************************************************/
/*   check if a number is prime              */
/***************************************************/
/* r0 contains the number            */
/* r0 return 1 if prime  0 else */
@2147483647
@4294967297
@131071
isPrime:
    push {r1-r6,lr}    @ save registers
    cmp r0,#0
    beq 90f
    cmp r0,#17
    bhi 1f
    cmp r0,#3
    bls 80f            @ for 1,2,3 return prime
    cmp r0,#5
    beq 80f            @ for 5 return prime
    cmp r0,#7
    beq 80f            @ for 7 return prime
    cmp r0,#11
    beq 80f            @ for 11 return prime
    cmp r0,#13
    beq 80f            @ for 13 return prime
    cmp r0,#17
    beq 80f            @ for 17 return prime
1:
    tst r0,#1          @ even ?
    beq 90f            @ yes -> not prime
    mov r2,r0          @ save number
    sub r1,r0,#1       @ exposant n - 1
    mov r0,#3          @ base
    bl moduloPuR32     @ compute base power n - 1 modulo n
    cmp r0,#1
    bne 90f            @ if <> 1  -> not prime

    mov r0,#5
    bl moduloPuR32
    cmp r0,#1
    bne 90f

    mov r0,#7
    bl moduloPuR32
    cmp r0,#1
    bne 90f

    mov r0,#11
    bl moduloPuR32
    cmp r0,#1
    bne 90f

    mov r0,#13
    bl moduloPuR32
    cmp r0,#1
    bne 90f

    mov r0,#17
    bl moduloPuR32
    cmp r0,#1
    bne 90f
80:
    mov r0,#1        @ is prime
    b 100f
90:
    mov r0,#0        @ no prime
100:                 @ fin standard de la fonction
    pop {r1-r6,lr}   @ restaur des registres
    bx lr            @ retour de la fonction en utilisant lr
/********************************************************/
/*   Calcul modulo de b puissance e modulo m  */
/*    Exemple 4 puissance 13 modulo 497 = 445         */
/*                                             */
/********************************************************/
/* r0  nombre  */
/* r1 exposant */
/* r2 modulo   */
/* r0 return result  */
moduloPuR32:
    push {r1-r7,lr}    @ save registers
    cmp r0,#0          @ verif <> zero
    beq 100f
    cmp r2,#0          @ verif <> zero
    beq 100f           @ TODO: vérifier les cas erreur
1:
    mov r4,r2          @ save modulo
    mov r5,r1          @ save exposant
    mov r6,r0          @ save base
    mov r3,#1          @ start result

    mov r1,#0          @ division de r0,r1 par r2
    bl division32R
    mov r6,r2          @ base <- remainder
2:
    tst r5,#1          @  exposant even or odd
    beq 3f
    umull r0,r1,r6,r3
    mov r2,r4
    bl division32R
    mov r3,r2          @ result <- remainder
3:
    umull r0,r1,r6,r6
    mov r2,r4
    bl division32R
    mov r6,r2          @ base <- remainder

    lsr r5,#1          @ left shift 1 bit
    cmp r5,#0          @ end ?
    bne 2b
    mov r0,r3
100:                   @ fin standard de la fonction
    pop {r1-r7,lr}     @ restaur des registres
    bx lr              @ retour de la fonction en utilisant lr

/***************************************************/
/*   division number 64 bits in 2 registers by number 32 bits */
/***************************************************/
/* r0 contains lower part dividende   */
/* r1 contains upper part dividende   */
/* r2 contains divisor   */
/* r0 return lower part quotient    */
/* r1 return upper part quotient    */
/* r2 return remainder               */
division32R:
    push {r3-r9,lr}    @ save registers
    mov r6,#0          @ init upper upper part remainder  !!
    mov r7,r1          @ init upper part remainder with upper part dividende
    mov r8,r0          @ init lower part remainder with lower part dividende
    mov r9,#0          @ upper part quotient
    mov r4,#0          @ lower part quotient
    mov r5,#32         @ bits number
1:                     @ begin loop
    lsl r6,#1          @ shift upper upper part remainder
    lsls r7,#1         @ shift upper  part remainder
    orrcs r6,#1
    lsls r8,#1         @ shift lower  part remainder
    orrcs r7,#1
    lsls r4,#1         @ shift lower part quotient
    lsl r9,#1          @ shift upper part quotient
    orrcs r9,#1
                       @ divisor sustract  upper  part remainder
    subs r7,r2
    sbcs  r6,#0        @ and substract carry
    bmi 2f             @ négative ?

                       @ positive or equal
    orr r4,#1          @ 1 -> right bit quotient
    b 3f
2:                     @ negative
    orr r4,#0          @ 0 -> right bit quotient
    adds r7,r2         @ and restaur remainder
    adc  r6,#0
3:
    subs r5,#1         @ decrement bit size
    bgt 1b             @ end ?
    mov r0,r4          @ lower part quotient
    mov r1,r9          @ upper part quotient
    mov r2,r7          @ remainder
100:                   @ function end
    pop {r3-r9,lr}     @ restaur registers
    bx lr

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


# syntax: GAWK -f TOTIENT_FUNCTION.AWK
BEGIN {
    print(" N Phi isPrime")
    for (n=1; n<=1000000; n++) {
      tot = totient(n)
      if (n-1 == tot) {
        count++
      }
      if (n <= 25) {
        printf("%2d %3d %s\n",n,tot,(n-1==tot)?"true":"false")
        if (n == 25) {
          printf("\n  Limit PrimeCount\n")
          printf("%7d %10d\n",n,count)
        }
      }
      else if (n ~ /^100+$/) {
        printf("%7d %10d\n",n,count)
      }
    }
    exit(0)
}
function totient(n,  i,tot) {
    tot = n
    for (i=2; i*i<=n; i+=2) {
      if (n % i == 0) {
        while (n % i == 0) {
          n /= i
        }
        tot -= tot / i
      }
      if (i == 2) {
        i = 1
      }
    }
    if (n > 1) {
      tot -= tot / n
    }
    return(tot)
}


GCD ← {𝕨(|𝕊⍟(>⟜0)⊣)𝕩}
Totient ← +´1=⊢GCD¨1+↕


/*Abhishek Ghosh, 7th December 2018*/

#include<stdio.h>

int totient(int n){
	int tot = n,i;

	for(i=2;i*i<=n;i+=2){
		if(n%i==0){
			while(n%i==0)
				n/=i;
			tot-=tot/i;
		}

		if(i==2)
			i=1;
	}

	if(n>1)
		tot-=tot/n;

	return tot;
}

int main()
{
	int count = 0,n,tot;

	printf(" n    %c   prime",237);
        printf("\n---------------\n");

	for(n=1;n<=25;n++){
		tot = totient(n);

		if(n-1 == tot)
			count++;

		printf("%2d   %2d   %s\n", n, tot, n-1 == tot?"True":"False");
	}

	printf("\nNumber of primes up to %6d =%4d\n", 25,count);

	for(n = 26; n <= 100000; n++){
        tot = totient(n);
        if(tot == n-1)
			count++;

        if(n == 100 || n == 1000 || n%10000 == 0){
            printf("\nNumber of primes up to %6d = %4d\n", n, count);
        }
    }

	return 0;
}


using static System.Console;
using static System.Linq.Enumerable;

public class Program
{
    static void Main()
    {
        for (int i = 1; i <= 25; i++) {
            int t = Totient(i);
            WriteLine(i + "\t" + t + (t == i - 1 ? "\tprime" : ""));
        }
        WriteLine();
        for (int i = 100; i <= 100_000; i *= 10) {
            WriteLine($"{Range(1, i).Count(x => Totient(x) + 1 == x):n0} primes below {i:n0}");
        }
    }

    static int Totient(int n) {
        if (n < 3) return 1;
        if (n == 3) return 2;

        int totient = n;

        if ((n & 1) == 0) {
            totient >>= 1;
            while (((n >>= 1) & 1) == 0) ;
        }

        for (int i = 3; i * i <= n; i += 2) {
            if (n % i == 0) {
                totient -= totient / i;
                while ((n /= i) % i == 0) ;
            }
        }
        if (n > 1) totient -= totient / n;
        return totient;
    }
}


#include <cassert>
#include <iomanip>
#include <iostream>
#include <vector>

class totient_calculator {
public:
    explicit totient_calculator(int max) : totient_(max + 1) {
        for (int i = 1; i <= max; ++i)
            totient_[i] = i;
        for (int i = 2; i <= max; ++i) {
            if (totient_[i] < i)
                continue;
            for (int j = i; j <= max; j += i)
                totient_[j] -= totient_[j] / i;
        }
    }
    int totient(int n) const {
        assert (n >= 1 && n < totient_.size());
        return totient_[n];
    }
    bool is_prime(int n) const {
        return totient(n) == n - 1;
    }
private:
    std::vector<int> totient_;
};

int count_primes(const totient_calculator& tc, int min, int max) {
    int count = 0;
    for (int i = min; i <= max; ++i) {
        if (tc.is_prime(i))
            ++count;
    }
    return count;
}

int main() {
    const int max = 10000000;
    totient_calculator tc(max);
    std::cout << " n  totient  prime?\n";
    for (int i = 1; i <= 25; ++i) {
        std::cout << std::setw(2) << i
            << std::setw(9) << tc.totient(i)
            << std::setw(8) << (tc.is_prime(i) ? "yes" : "no") << '\n';
    }
    for (int n = 100; n <= max; n *= 10) {
        std::cout << "Count of primes up to " << n << ": "
            << count_primes(tc, 1, n) << '\n';
    }
    return 0;
}


import std.stdio;

int totient(int n) {
    int tot = n;

    for (int i = 2; i * i <= n; i += 2) {
        if (n % i == 0) {
            while (n % i == 0) {
                n /= i;
            }
            tot -= tot / i;
        }
        if (i==2) {
            i = 1;
        }
    }

    if (n > 1) {
        tot -= tot / n;
    }
    return tot;
}

void main() {
    writeln(" n    φ   prime");
    writeln("---------------");

    int count = 0;
    for (int n = 1; n <= 25; n++) {
        int tot = totient(n);

        if (n - 1 == tot) {
            count++;
        }

        writefln("%2d   %2d   %s", n,tot, n - 1 == tot);
    }
    writeln;

    writefln("Number of primes up to %6d = %4d", 25, count);
    for (int n = 26; n <= 100_000; n++) {
        int tot = totient(n);

        if (n - 1 == tot) {
            count++;
        }

        if (n == 100 || n == 1_000 || n % 10_000 == 0) {
            writefln("Number of primes up to %6d = %4d", n, count);
        }
    }
}


func totient(n) {
    var tot = n
    var i = 2
    while i * i <= n {
        if n % i == 0 {
            while n % i == 0 {
                n /= i
            }
            tot -= tot / i
        }
        if i == 2 {
            i = 1
        }
        i += 2
    }
    if n > 1 {
        tot -= tot / n
    }
    return tot
}

print("n\tphi\tprime")
var count = 0
for n in 1..25 {
    var tot = totient(n)
    var isPrime = n - 1 == tot
    if isPrime {
        count += 1
    }
    print("\(n)\t\(tot)\t\(isPrime)")
}
print("\nNumber of primes up to 25 \t= \(count)")
for n in 26..100000 {
    var tot = totient(n)
    if tot == n - 1 {
        count += 1
    }
    if n == 100 || n == 1000 || n % 10000 == 0 {
        print("Number of primes up to \(n) \t= \(count)")
    }
}


USING: combinators formatting io kernel math math.primes.factors
math.ranges sequences ;
IN: rosetta-code.totient-function

: Φ ( n -- m )
    {
        { [ dup 1 < ] [ drop 0 ] }
        { [ dup 1 = ] [ drop 1 ] }
        [
            dup unique-factors
            [ 1 [ 1 - * ] reduce ] [ product ] bi / *
        ]
    } cond ;

: show-info ( n -- )
    [ Φ ] [ swap 2dup - 1 = ] bi ", prime" "" ?
    "Φ(%2d) = %2d%s\n" printf ;

: totient-demo ( -- )
    25 [1,b] [ show-info ] each nl 0 100,000 [1,b] [
        [ dup Φ - 1 = [ 1 + ] when ]
        [ dup { 100 1,000 10,000 100,000 } member? ] bi
        [ dupd "%4d primes <= %d\n" printf ] [ drop ] if
    ] each drop ;

MAIN: totient-demo


#define esPar(n) (((n) And 1) = 0)
#define esImpar(n)  (esPar(n) = 0)

Function Totient(n As Integer) As Integer
    'delta son números no divisibles por 2,3,5
    Dim delta(7) As Integer = {6,4,2,4,2,4,6,2}
    Dim As Integer i, quot, idx, result
    ' div mod por constante es rápido.
    'i = 2
    result = n
    If (2*2 <= n) Then
        If Not(esImpar(n)) Then
            ' eliminar números con factor 2,4,8,16,...
            While Not(esImpar(n))
                n = n \ 2
            Wend
            'eliminar los múltiplos de 2
            result -= result \ 2
        End If
    End If
    'i = 3
    If (3*3 <= n) And (n Mod 3 = 0) Then
        Do
            quot = n \ 3
            If n <> quot*3 Then
                Exit Do
            Else
                n = quot
            End If
        Loop Until false
        result -= result \ 3
    End If
    'i = 5
    If (5*5 <= n) And (n Mod 5 = 0) Then
        Do
            quot = n \ 5
            If n <> quot*5 Then
                Exit Do
            Else
                n = quot
            End If
        Loop Until false
        result -= result \ 5
    End If
    i = 7
    idx = 1
    'i = 7,11,13,17,19,23,29,...,49 ..
    While i*i <= n
        quot = n \ i
        If n = quot*i Then
            Do
                If n <> quot*i Then
                    Exit Do
                Else
                    n = quot
                End If
                quot = n \ i
            Loop Until false
            result -= result \ i
        End If
        i = i + delta(idx)
        idx = (idx+1) And 7
    Wend
    If n > 1 Then result -= result \ n
    Totient = result
End Function

Sub ContandoPrimos(n As Integer)
    Dim As Integer i, cnt = 0
    For i = 1 To n
        If Totient(i) = (i-1) Then cnt += 1
    Next i
    Print Using " #######      ######"; i-1; cnt
End Sub

Function esPrimo(n As Ulongint) As String
    esPrimo = "False"
    If n = 1 then Return "False"
    If (n=2) Or (n=3) Then Return "True"
    If n Mod 2=0 Then Exit Function
    If n Mod 3=0 Then Exit Function
    Dim As Ulongint limite = Sqr(N)+1
    For i As Ulongint = 6 To limite Step 6
        If N Mod (i-1)=0 Then Exit Function
        If N Mod (i+1)=0 Then Exit Function
    Next i
    Return "True"
End Function

Sub display(n As Integer)
    Dim As Integer idx, phi
    If n = 0 Then Exit Sub
    Print "  n  phi(n)   esPrimo"
    For idx = 1 To n
        phi = Totient(idx)
        Print Using "###   ###      \   \"; idx; phi; esPrimo(idx)
    Next idx
End Sub

Dim l As Integer
display(25)

Print Chr(10) & "   Limite  Son primos"
ContandoPrimos(25)
l = 100
Do
    ContandoPrimos(l)
    l = l*10
Loop Until l > 1000000
End


: totient   \ n -- n' ;
  DUP DUP 2 ?DO     ( tot n )
    DUP I DUP * < IF   LEAVE   THEN                     \ for(i=2;i*i<=n;i+=2){
    DUP I MOD 0= IF					\     if(n%i==0){
      BEGIN   DUP I /MOD SWAP 0=   WHILE  ( tot n n/i ) \       while(n%i==0);
        NIP       ( tot n/i )                           \         n/=i;
      REPEAT
      DROP                    ( tot n  )  \ Remove the new n on exit from loop
      SWAP DUP I / - SWAP 	  ( tot' n )        	\       tot-=tot/i;
    THEN
  2 I 2 = + +LOOP    \  If I = 2 add 1 else add 2 to loop index.
  DUP 1 > IF   OVER SWAP / -   ELSE   DROP   THEN ;

: bool.  \ f -- ;
  IF   ." True "   ELSE   ." False"   THEN ;

: count-primes  \ n -- n' ;
  0 SWAP 2 ?DO   I DUP totient 1+ = -   LOOP ;

: challenge  \ -- ;
  CR ."   n   φ    prime" CR
  26 1 DO
    I 3 .r
    I totient DUP 4 .r 4 SPACES
    1+ I = bool. CR
  LOOP CR
  100001 100 DO
    ." Number of primes up to " I 6 .R ."  is " I count-primes 4 .R CR
  I 9 * +LOOP  ;


package main

import "fmt"

func gcd(n, k int) int {
    if n < k || k < 1 {
        panic("Need n >= k and k >= 1")
    }

    s := 1
    for n&1 == 0 && k&1 == 0 {
        n >>= 1
        k >>= 1
        s <<= 1
    }

    t := n
    if n&1 != 0 {
        t = -k
    }
    for t != 0 {
        for t&1 == 0 {
            t >>= 1
        }
        if t > 0 {
            n = t
        } else {
            k = -t
        }
        t = n - k
    }
    return n * s
}

func totient(n int) int {
    tot := 0
    for k := 1; k <= n; k++ {
        if gcd(n, k) == 1 {
            tot++
        }
    }
    return tot
}

func main() {
    fmt.Println(" n  phi   prime")
    fmt.Println("---------------")
    count := 0
    for n := 1; n <= 25; n++ {
        tot := totient(n)
        isPrime := n-1 == tot
        if isPrime {
            count++
        }
        fmt.Printf("%2d   %2d   %t\n", n, tot, isPrime)
    }
    fmt.Println("\nNumber of primes up to 25     =", count)
    for n := 26; n <= 100000; n++ {
        tot := totient(n)
        if tot == n-1 {
            count++
        }
        if n == 100 || n == 1000 || n%10000 == 0 {
            fmt.Printf("\nNumber of primes up to %-6d = %d\n", n, count)
        }
    }
}


{-# LANGUAGE BangPatterns #-}

import Control.Monad (when)
import Data.Bool (bool)

totient
  :: (Integral a)
  => a -> a
totient n
  | n == 0 = 1 -- by definition phi(0) = 1
  | n < 0 = totient (-n) -- phi(-n) is taken to be equal to phi(n)
  | otherwise = loop n n 2 --
  where
    loop !m !tot !i
      | i * i > m = bool tot (tot - (tot `div` m)) (1 < m)
      | m `mod` i == 0 = loop m_ tot_ i_
      | otherwise = loop m tot i_
      where
        i_
          | i == 2 = 3
          | otherwise = 2 + i
        m_ = nextM m
        tot_ = tot - (tot `div` i)
        nextM !x
          | x `mod` i == 0 = nextM $ x `div` i
          | otherwise = x

main :: IO ()
main = do
  putStrLn "n\tphi\tprime\n---------------------"
  let loop !i !count
        | i >= 10 ^ 6 = return ()
        | otherwise = do
          let i_ = succ i
              tot = totient i_
              isPrime = tot == pred i_
              count_
                | isPrime = succ count
                | otherwise = count
          when (25 >= i_) $
            putStrLn $ show i_ ++ "\t" ++ show tot ++ "\t" ++ show isPrime
          when
            (i_ `elem`
             25 :
             [ 10 ^ k
             | k <- [2 .. 6] ]) $
            putStrLn $ "Number of primes up to " ++ show i_ ++ " = " ++ show count_
          loop (i + 1) count_
  loop 0 0


public class TotientFunction {

    public static void main(String[] args) {
        computePhi();
        System.out.println("Compute and display phi for the first 25 integers.");
        System.out.printf("n  Phi  IsPrime%n");
        for ( int n = 1 ; n <= 25 ; n++ ) {
            System.out.printf("%2d  %2d  %b%n", n, phi[n], (phi[n] == n-1));
        }
        for ( int i = 2 ; i < 8 ; i++ ) {
            int max = (int) Math.pow(10, i);
            System.out.printf("The count of the primes up to %,10d = %d%n", max, countPrimes(1, max));
        }
    }

    private static int countPrimes(int min, int max) {
        int count = 0;
        for ( int i = min ; i <= max ; i++ ) {
            if ( phi[i] == i-1 ) {
                count++;
            }
        }
        return count;
    }

    private static final int max = 10000000;
    private static final int[] phi = new int[max+1];

    private static final void computePhi() {
        for ( int i = 1 ; i <= max ; i++ ) {
            phi[i] = i;
        }
        for ( int i = 2 ; i <= max ; i++ ) {
            if (phi[i] < i) continue;
            for ( int j = i ; j <= max ; j += i ) {
                phi[j] -= phi[j] / i;
            }
        }
    }

}


# jq optimizes the recursive call of _gcd in the following:
def gcd(a;b):
  def _gcd:
    if .[1] != 0 then [.[1], .[0] % .[1]] | _gcd else .[0] end;
  [a,b] | _gcd ;

def count(s): reduce s as $x (0; .+1);

def totient:
  . as $n
  | count( range(0; .) | select( gcd($n; .) == 1) );

# input: determines the maximum via range(0; .)
# and so may be `infinite`
def primes_via_totient:
  range(0; .) | select(totient == . - 1);


φ(n) = sum(1 for k in 1:n if gcd(n, k) == 1)

is_prime(n) = φ(n) == n - 1

function runphitests()
    for n in 1:25
        println(" φ($n) == $(φ(n))", is_prime(n) ? ", is prime" : "")
    end
    count = 0
    for n in 1:100_000
        count += is_prime(n)
        if n in [100, 1000, 10_000, 100_000]
            println("Primes up to $n: $count")
        end
    end
end

runphitests()


// Version 1.3.21

fun totient(n: Int): Int {
    var tot = n
    var nn = n
    var i = 2
    while (i * i <= nn) {
        if (nn % i == 0) {
            while (nn % i == 0) nn /= i
            tot -= tot / i
        }
        if (i == 2) i = 1
        i += 2
    }
    if (nn > 1) tot -= tot / nn
    return tot
}

fun main() {
    println(" n  phi   prime")
    println("---------------")
    var count = 0
    for (n in 1..25) {
        val tot = totient(n)
        val isPrime  = n - 1 == tot
        if (isPrime) count++
        System.out.printf("%2d   %2d   %b\n", n, tot, isPrime)
    }
    println("\nNumber of primes up to 25     = $count")
    for (n in 26..100_000) {
        val tot = totient(n)
        if (tot == n-1) count++
        if (n == 100 || n == 1000 || n % 10_000 == 0) {
            System.out.printf("\nNumber of primes up to %-6d = %d\n", n, count)
        }
    }
}


-- Return the greatest common denominator of x and y
function gcd (x, y)
  return y == 0 and math.abs(x) or gcd(y, x % y)
end

-- Return the totient number for n
function totient (n)
  local count = 0
  for k = 1, n do
    if gcd(n, k) == 1 then count = count + 1 end
  end
  return count
end

-- Determine (inefficiently) whether p is prime
function isPrime (p)
  return totient(p) == p - 1
end

-- Output totient and primality for the first 25 integers
print("n", string.char(237), "prime")
print(string.rep("-", 21))
for i = 1, 25 do
  print(i, totient(i), isPrime(i))
end

-- Count the primes up to 100, 1000 and 10000
local pCount, i, limit = 0, 1
for power = 2, 4 do
  limit = 10 ^ power
  repeat
    i = i + 1
    if isPrime(i) then pCount = pCount + 1 end
  until i == limit
  print("\nThere are " .. pCount .. " primes below " .. limit)
end


Do[
 tmp = EulerPhi[i];
 If[i - 1 == tmp,
  Print["\[CurlyPhi](", i, ")=", tmp, ", is prime"]
  ,
  Print["\[CurlyPhi](", i, ")=", tmp]
  ]
 ,
 {i, 25}
 ]
Count[EulerPhi[Range[100]] - Range[100], -1]
Count[EulerPhi[Range[1000]] - Range[1000], -1]
Count[EulerPhi[Range[10000]] - Range[10000], -1]
Count[EulerPhi[Range[100000]] - Range[100000], -1]
(*Alternative much faster way of findings the number primes up to a number*)
(*PrimePi[100]*)
(*PrimePi[1000]*)
(*PrimePi[10000]*)
(*PrimePi[100000]*)


import strformat

func totient(n: int): int =
    var tot = n
    var nn = n
    var i = 2
    while i * i <= nn:
        if nn mod i == 0:
            while nn mod i == 0:
                nn = nn div i
            dec tot, tot div i
        if i == 2:
            i = 1
        inc i, 2
    if nn > 1:
        dec tot, tot div nn
    tot

echo " n    φ   prime"
echo "---------------"
var count = 0
for n in 1..25:
    let tot = totient(n)
    let isPrime = n - 1 == tot
    if isPrime:
        inc count
    echo fmt"{n:2}   {tot:2}   {isPrime}"
echo ""
echo fmt"Number of primes up to {25:>6} = {count:>4}"
for n in 26..100_000:
    let tot = totient(n)
    if tot == n - 1:
        inc count
    if n == 100 or n == 1000 or n mod 10_000 == 0:
        echo fmt"Number of primes up to {n:>6} = {count:>4}"


{$IFDEF FPC}
  {$MODE DELPHI}
{$IFEND}
function gcd_mod(u, v: NativeUint): NativeUint;inline;
//prerequisites  u > v and u,v > 0
  var
    t: NativeUInt;
  begin
    repeat
      t := u;
      u := v;
      v := t mod v;
    until v = 0;
    gcd_mod := u;
  end;

function Totient(n:NativeUint):NativeUint;
var
  i : NativeUint;
Begin
  result := 1;
  For i := 2 to n do
    inc(result,ORD(GCD_mod(n,i)=1));
end;

function CheckPrimeTotient(n:NativeUint):Boolean;inline;
begin
  result :=  (Totient(n) = (n-1));
end;

procedure OutCountPrimes(n:NativeUInt);
var
  i,cnt :  NativeUint;
begin
  cnt := 0;
  For i := 1 to n do
    inc(cnt,Ord(CheckPrimeTotient(i)));
  writeln(n:10,cnt:8);
end;

procedure display(n:NativeUint);
var
  idx,phi : NativeUint;
Begin
  if n = 0 then
    EXIT;
  writeln('number n':5,'Totient(n)':11,'isprime':8);
  For idx := 1 to n do
  Begin
    phi := Totient(idx);
    writeln(idx:4,phi:10,(phi=(idx-1)):12);
  end
end;
var
  i : NativeUint;
Begin
  display(25);

  writeln('Limit  primecount');
  i := 100;
  repeat
    OutCountPrimes(i);
    i := i*10;
  until i >100000;
end.


F hanoi(ndisks, startPeg = 1, endPeg = 3) -> N
   I ndisks
      hanoi(ndisks - 1, startPeg, 6 - startPeg - endPeg)
      print(‘Move disk #. from peg #. to peg #.’.format(ndisks, startPeg, endPeg))
      hanoi(ndisks - 1, 6 - startPeg - endPeg, endPeg)

hanoi(ndisks' 3)


function totient(integer n)
    integer tot = n, i = 2
    while i*i<=n do
        if mod(n,i)=0 then
            while true do
                n /= i
                if mod(n,i)!=0 then exit end if
            end while
            tot -= tot/i
        end if
        i += iff(i=2?1:2)
    end while
    if n>1 then
        tot -= tot/n
    end if
    return tot
end function

printf(1," n  phi   prime\n")
printf(1," --------------\n")
integer count = 0
for n=1 to 25 do
    integer tot = totient(n),
            prime = (n-1=tot)
    count += prime
    string isp = iff(prime?"true":"false")
    printf(1,"%2d   %2d   %s\n",{n,tot,isp})
end for
printf(1,"\nNumber of primes up to 25     = %d\n",count)
for n=26 to 100000 do
    count += (totient(n)=n-1)
    if find(n,{100,1000,10000,100000}) then
        printf(1,"Number of primes up to %-6d = %d\n",{n,count})
    end if
end for


*        Towers of Hanoi           08/09/2015
HANOITOW CSECT
         USING  HANOITOW,R12       r12 : base register
         LR     R12,R15            establish base register
         ST     R14,SAVE14         save r14
BEGIN    LH     R2,=H'4'           n <===
         L      R3,=C'123 '        stating position
         BAL    R14,MOVE           r1=move(m,n)
RETURN   L      R14,SAVE14         restore r14
         BR     R14                return to caller
SAVE14   DS     F                  static save r14
PG       DC     CL44'xxxxxxxxxxxx Move disc from pole X to pole Y'
NN       DC     F'0'
POLEX    DS     F                  current poles
POLEN    DS     F                  new poles
*        ....   recursive          subroutine move(n, poles)  [r2,r3]
MOVE     LR     R10,R11            save stackptr (r11) in r10 temp
         LA     R1,STACKLEN        amount of storage required
         GETMAIN RU,LV=(R1)        allocate storage for stack
         USING  STACKDS,R11        make storage addressable
         LR     R11,R1             establish stack addressability
         ST     R14,SAVE14M        save previous r14
         ST     R10,SAVE11M        save previous r11
         LR     R1,R5              restore saved argument r5
BEGINM   STM    R2,R3,STACK        push arguments to stack
         ST     R3,POLEX
         CH     R2,=H'1'           if n<>1
         BNE    RECURSE            then goto recurse
         L      R1,NN
         LA     R1,1(R1)           nn=nn+1
         ST     R1,NN
         XDECO  R1,PG              nn
         MVC    PG+33(1),POLEX+0   from
         MVC    PG+43(1),POLEX+1   to
         XPRNT  PG,44              print "move disk from to"
         B      RETURNM
RECURSE  L      R2,N               n
         BCTR   R2,0               n=n-1
         MVC    POLEN+0(1),POLES+0 from
         MVC    POLEN+1(1),POLES+2 via
         MVC    POLEN+2(1),POLES+1 to
         L      R3,POLEN           new poles
         BAL    R14,MOVE           call move(n-1,from,via,to)
         LA     R2,1               n=1
         MVC    POLEN,POLES
         L      R3,POLEN           new poles
         BAL    R14,MOVE           call move(1,from,to,via)
         L      R2,N               n
         BCTR   R2,0               n=n-1
         MVC    POLEN+0(1),POLES+2 via
         MVC    POLEN+1(1),POLES+1 to
         MVC    POLEN+2(1),POLES+0 from
         L      R3,POLEN           new poles
         BAL    R14,MOVE           call move(n-1,via,to,from)
RETURNM  LM     R2,R3,STACK        pull arguments from stack
         LR     R1,R11             current stack
         L      R14,SAVE14M        restore r14
         L      R11,SAVE11M        restore r11
         LA     R0,STACKLEN        amount of storage to free
         FREEMAIN A=(R1),LV=(R0)   free allocated storage
         BR     R14                return to caller
         LTORG
         DROP   R12                base no longer needed
STACKDS  DSECT                     dynamic area
SAVE14M  DS     F                  saved r14
SAVE11M  DS     F                  saved r11
STACK    DS     0F                 stack
N        DS     F                  r2 n
POLES    DS     F                  r3 poles
STACKLEN EQU    *-STACKDS
         YREGS
         END    HANOITOW


	org	100h
	lhld	6	; Top of CP/M usable memory
	sphl		; Put the stack there
	lxi	b,0401h	; Set up first arguments to move()
	lxi	d,0203h
	call	move	; move(4, 1, 2, 3)
	rst	0	; quit program
	;;;	Move B disks from C via D to E.
move:	dcr	b	; One fewer disk in next iteration
	jz	mvout	; If this was the last disk, print move and stop
	push	b	; Otherwise, save registers,
	push	d
	mov	a,d	; First recursive call
	mov	d,e
	mov	e,a
	call	move	; move(B-1, C, E, D)
	pop	d	; Restore registers
	pop	b
	call	mvout	; Print current move
	mov	a,c	; Second recursive call
	mov	c,d
	mov	d,a
	jmp	move	; move(B-1, D, C, E) - tail call optimization
	;;;	Print move, saving registers.
mvout:	push	b	; Save registers on stack
	push	d
	mov	a,c	; Store 'from' as ASCII digit in 'from' space
	adi	'0'
	sta	out1
	mov	a,e	; Store 'to' as ASCII digit in 'to' space
	adi	'0'
	sta	out2
	lxi	d,outstr
	mvi	c,9	; CP/M call to print the string
	call	5
	pop	d	; Restore register contents
	pop	b
	ret
	;;;	Move output with placeholder for pole numbers
outstr:	db	'Move disk from pole '
out1:	db	'* to pole '
out2:	db	'*',13,10,'$'


(gc 32)
(de gcd (A B)
   (until (=0 B)
      (let M (% A B)
         (setq A B B M) ) )
   (abs A) )
(de totient (N)
   (let C 0
      (for I N
         (and (=1 (gcd N I)) (inc 'C)) )
      (cons C (= C (dec N))) ) )
(de p? (N)
   (let C 0
      (for A N
         (and
            (cdr (totient A))
            (inc 'C) ) )
      C ) )
(let Fmt (3 7 10)
   (tab Fmt "N" "Phi" "Prime?")
   (tab Fmt "-" "---" "------")
   (for N 25
      (tab Fmt
         N
         (car (setq @ (totient N)))
         (cdr @) ) ) )
(println
   (mapcar p? (25 100 1000 10000 100000)) )


from math import gcd

def  φ(n):
    return sum(1 for k in range(1, n + 1) if gcd(n, k) == 1)

if __name__ == '__main__':
    def is_prime(n):
        return φ(n) == n - 1

    for n in range(1, 26):
        print(f" φ({n}) == {φ(n)}{', is prime' if is_prime(n)  else ''}")
    count = 0
    for n in range(1, 10_000 + 1):
        count += is_prime(n)
        if n in {100, 1000, 10_000}:
            print(f"Primes up to {n}: {count}")


  [ [ dup while
      tuck mod again ]
    drop abs ]              is gcd        ( n n --> n )

  [ 0 swap dup times
      [ i over gcd
        1 = rot + swap ]
      drop ]                is totient    (   n --> n )

  [ 0 temp put
    times
      [ i dup 1+ totient
        = temp tally ]
     temp take ]            is primecount (   n --> n )

  25 times
     [ say "The totient of "
       i^ 1+ dup echo
       say " is "
       dup totient dup echo
       say ", so it is "
       1+ != if say "not "
       say "prime." cr ]
  cr
  ' [ 100 1000 10000 100000 ]
  witheach
    [ say "There are "
      dup primecount echo
      say " primes up to " echo
      say "." cr ]


	cpu	8086
	bits	16
	org	100h
section	.text
	mov	bx,0402h	; Set up first arguments to move()
	mov	cx,0103h	; Registers chosen s.t. CX contains output
	;;;	Move BH disks from CH via BL to CL
move:	dec	bh		; One fewer disk in next iteration
	jz	.out		; If this was last disk, just print move
	push	bx		; Save the registers for a recursive call
	push	cx
	xchg	bl,cl		; Swap the 'to' and 'via' registers
	call	move		; move(BH, CH, CL, BL)
	pop	cx		; Restore the registers from the stack
	pop	bx
	call	.out		; Print the move
	xchg	ch,bl		; Swap the 'from' and 'via' registers
	jmp	move		; move(BH, BL, CH, CL)
	;;;	Print the move
.out:	mov	ax,'00'		; Add ASCII 0 to both 'from' and 'to'
	add	ax,cx		; in one 16-bit operation
	mov	[out1],ah	; Store 'from' field in output
	mov	[out2],al	; Store 'to' field in output
	mov	dx,outstr	; MS-DOS system call to print string
	mov	ah,9
	int	21h
	ret
section	.data
outstr:	db	'Move disk from pole '
out1:	db	'* to pole '
out2:	db	'*',13,10,'$'


#lang racket

(require math/number-theory)

(define (prime*? n) (= (totient n) (sub1 n)))

(for ([n (in-range 1 26)])
  (printf "φ(~a) = ~a~a~a\n"
          n
          (totient n)
          (if (prime*? n) " is prime" "")
          (if (prime? n) " (confirmed)" "")))

(for/fold ([count 0] #:result (void)) ([n (in-range 1 10001)])
   (define new-count (if (prime*? n) (add1 count) count))
   (when (member n '(100 1000 10000))
     (printf "Primes up to ~a: ~a\n" n new-count))
   new-count)


/*REXX program calculates the totient numbers for a range of numbers, and count primes. */
parse arg N .                                    /*obtain optional argument from the CL.*/
if N==''  |  N==","  then N= 25                  /*Not specified?  Then use the default.*/
tell= N>0                                        /*N positive>?  Then display them all. */
N= abs(N)                                        /*use the absolute value of N for loop.*/
w= length(N)                                     /*W:  is used in aligning the output.  */
primes= 0                                        /*the number of primes found  (so far).*/
                                                 /*if N was negative, only count primes.*/
    do j=1  for  N;              T= phi(j)       /*obtain totient number for a number.  */
    prime= word('(prime)', 1 +  (T \== j-1 ) )   /*determine if  J  is a prime number.  */
    if prime\==''  then primes= primes + 1       /*if a prime, then bump the prime count*/
    if tell  then say 'totient number for '  right(j, w)  " ──► "  right(T, w)  ' '  prime
    end   /*j*/
say
say right(primes, w)      ' primes detected for numbers up to and including '        N
exit 0                                           /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
gcd: parse arg x,y;   do until y==0;     parse value   x//y  y    with    y  x
                      end   /*until*/;                                            return x
/*──────────────────────────────────────────────────────────────────────────────────────*/
phi: procedure; parse arg z;             if z==1  then return 1
     #= 1
                      do m=2  for z-2;   if gcd(m, z)==1  then #= # + 1
                      end   /*m*/;                                                return #


5 var, disks
var sa
var sb
var sc

: save sc ! sb ! sa ! disks ! ;
: get sa @ sb @ sc @ ;
: get2 get swap ;
: hanoi
	save disks @ not if ;; then
	disks @ get
	disks @ n:1- get2 hanoi save
	cr
	" move a ring from " .  sa @ . " to " . sb @ .
	disks @ n:1- get2 rot hanoi
;

" Tower of Hanoi, with " . disks @ . " rings: " .
disks @ 1 2 3 hanoi cr bye


public function move(n:int, from:int, to:int, via:int):void
{
    if (n > 0)
    {
        move(n - 1, from, via, to);
        trace("Move disk from pole " + from + " to pole " + to);
        move(n - 1, via, to, from);
    }
}


require "prime"

def 𝜑(n)
  n.prime_division.inject(1) {|res, (pr, exp)| res *= (pr-1) * pr**(exp-1) }
end

1.upto 25 do |n|
  tot = 𝜑(n)
  puts "#{n}\t #{tot}\t #{"prime" if n-tot==1}"
end

[100, 1_000, 10_000, 100_000].each do |u|
  puts "Number of primes up to #{u}: #{(1..u).count{|n| n-𝜑(n) == 1} }"
end


use num::integer::gcd;

fn main() {
    // Compute the totient of the first 25 natural integers
    println!("N\t phi(n)\t Prime");
    for n in 1..26 {
        let phi_n = phi(n);
        println!("{}\t {}\t {:?}", n, phi_n, phi_n == n - 1);
    }

    // Compute the number of prime numbers for various steps
    [1, 100, 1000, 10000, 100000]
        .windows(2)
        .scan(0, |acc, tuple| {
            *acc += (tuple[0]..=tuple[1]).filter(is_prime).count();
            Some((tuple[1], *acc))
        })
        .for_each(|x| println!("Until {}: {} prime numbers", x.0, x.1));
}

fn is_prime(n: &usize) -> bool {
    phi(*n) == *n - 1
}

fn phi(n: usize) -> usize {
    (1..=n).filter(|&x| gcd(n, x) == 1).count()
}


$lines

rem - return p mod q
function mod(p, q = integer) = integer
end = p - q * (p / q)

rem - return greatest common divisor of x and y
function gcd(x, y = integer) = integer
   var r, temp = integer
   if x < y then
      begin
         temp = x
         x = y
         y = temp
      end
   r = mod(x, y)
   while r <> 0 do
      begin
         x = y
         y = r
         r = mod(x, y)
      end
end = y

rem - return phi (also called totient) of n
function phi(n = integer) = integer
   var i, count = integer
   count = 1
   for i = 2 to n
      if gcd(n, i) = 1 then count = count + 1
   next i
end = count

rem - exercise the function
var n, totient, count = integer
print "  n    Phi(n)   Prime?"
for n = 1 to 25
   totient = phi(n)
   print using "####  ####     ";n, totient;
   if totient + 1 = n then
      print "yes"
   else
      print "no"
next n

rem - and further test it by counting primes
print
count = 0
for n = 1 to 1000
   if phi(n) = n - 1 then count = count + 1
   if n = 100 then
      print "Primes up to 100  = ";count
   else if n = 1000 then
      print "Primes up to 1000 = ";count
next n

end


@tailrec
def gcd(a: Int, b: Int): Int = if(b == 0) a else gcd(b, a%b)
def totientLaz(num: Int): Int = LazyList.range(2, num).count(gcd(num, _) == 1) + 1


with Ada.Text_Io; use Ada.Text_Io;

procedure Towers is
   type Pegs is (Left, Center, Right);
   procedure Hanoi (Ndisks : Natural; Start_Peg : Pegs := Left; End_Peg : Pegs := Right; Via_Peg : Pegs := Center) is
   begin
      if Ndisks > 0 then
         Hanoi(Ndisks - 1, Start_Peg, Via_Peg, End_Peg);
         Put_Line("Move disk" & Natural'Image(Ndisks) & " from " & Pegs'Image(Start_Peg) & " to " & Pegs'Image(End_Peg));
         Hanoi(Ndisks - 1, Via_Peg, End_Peg, Start_Peg);
      end if;
   end Hanoi;
begin
   Hanoi(4);
end Towers;


move := proc(n::number, src::number, dst::number, via::number) is
   if n > 0 then
      move(n - 1, src, via, dst)
      print(src & ' to ' & dst)
      move(n - 1, via, dst, src)
   fi
end

move(4, 1, 2, 3)


#!/usr/local/bin/shale

primes library

init dup var {
  pl sieve type primes::()
  100000 0 pl generate primes::()
} =

go dup var {
  i var
  c0 var
  c1 var
  c2 var
  c3 var
  p var

  " N  Phi  Is prime" println
  i 1 =
  { i 25 <= } {
    i pl isprime primes::() { "True" } { "False" } if i pl phi primes::() i "%2d  %3d  %s\n" printf
    i++
  } while

  c0 0 =
  c1 0 =
  c2 0 =
  c3 0 =
  i 0 =
  { i count pl:: < } {
    p i pl get primes::() =
    p 100 < { c0++ } ifthen
    p 1000 < { c1++ } ifthen
    p 10000 < { c2 ++ } ifthen
    p 100000 < { c3 ++ } ifthen
    i++
  } while

  "" println
  "  Limit  Count" println
  c0 "    100  %5d\n" printf
  c1 "  1,000  %5d\n" printf
  c2 " 10,000  %5d\n" printf
  c3 "100,000  %5d\n" printf
} =

init()
go()


     REM PRINT THE DATA FOR N=1 TO 25
     LET N = 0
  10 LET N = N + 1
     IF N = 26 THEN GOTO 100
     GOSUB 1000
     IF T = N - 1 THEN LET P = 1
     IF T <> N - 1 THEN LET P = 0
     PRINT N," ", T," ",P
     GOTO 10
 100 REM COUNT PRIMES BELOW 10000
     LET C = 0
     LET N = 2
 110 GOSUB 1000
     IF T = N - 1 THEN LET C = C + 1
     IF N = 100 THEN PRINT "There are ", C, " primes below 100."
     IF N = 1000 THEN PRINT "There are ", C, " primes below 1000."
     IF N = 10000 THEN PRINT "There are ", C, " primes below 10000."
     LET N = N + 1
     IF N < 10001 THEN GOTO 110
     END
1000 REM TOTIENT FUNCTION OF INTEGER N
     LET M = 1
     LET T = 0
1010 IF M > N THEN RETURN
     LET A = N
     LET B = M    REM NEED TO RENAME THESE SO THEY ARE PRESERVED
     GOSUB 2000
     IF G = 1 THEN LET T = T + 1
     LET M = M + 1
     GOTO 1010
2000 REM GCD OF INTEGERS A, B
2010 IF A>B THEN GOTO 2020
     LET B = B - A
     IF A=0 THEN LET G = B
     IF A=0 THEN RETURN
2020 LET S = A
     LET A = B
     LET B = S
     GOTO 2010


Private Function totient(ByVal n As Long) As Long
    Dim tot As Long: tot = n
    Dim i As Long: i = 2
    Do While i * i <= n
        If n Mod i = 0 Then
            Do While True
                n = n \ i
                If n Mod i <> 0 Then Exit Do
            Loop
            tot = tot - tot \ i
        End If
        i = i + IIf(i = 2, 1, 2)
    Loop
    If n > 1 Then
        tot = tot - tot \ n
    End If
    totient = tot
End Function

Public Sub main()
    Debug.Print " n  phi   prime"
    Debug.Print " --------------"
    Dim count As Long
    Dim tot As Integer, n As Long
    For n = 1 To 25
        tot = totient(n)
        prime = (n - 1 = tot)
        count = count - prime
        Debug.Print Format(n, "@@"); Format(tot, "@@@@@"); Format(prime, "@@@@@@@@")
    Next n
    Debug.Print
    Debug.Print "Number of primes up to 25     = "; Format(count, "@@@@")
    For n = 26 To 100000
        count = count - (totient(n) = n - 1)
        Select Case n
            Case 100, 1000, 10000, 100000
                Debug.Print "Number of primes up to"; n; String$(6 - Len(CStr(n)), " "); "="; Format(count, "@@@@@")
            Case Else
        End Select
    Next n
End Sub


begin
  procedure movedisk(n, f, t);
  integer n, f, t;
  begin
    outstring (1, "Move disk from");
    outinteger(1, f);
    outstring (1, "to");
    outinteger(1, t);
    outstring (1, "\n");
  end;

  procedure dohanoi(n, f, t, u);
  integer n, f, t, u;
  begin
    if n < 2 then
      movedisk(1, f, t)
    else
      begin
        dohanoi(n - 1, f, u, t);
        movedisk(1, f, t);
        dohanoi(n - 1, u, t, f);
      end;
  end;

  dohanoi(4, 1, 2, 3);
  outstring(1,"Towers of Hanoi puzzle completed!")
end


PROC move = (INT n, from, to, via) VOID:
  IF n > 0 THEN
    move(n - 1, from, via, to);
    printf(($"Move disk from pole "g" to pole "gl$, from, to));
    move(n - 1, via, to, from)
  FI
;

main: (
  move(4, 1,2,3)
)


Imports System.Linq.Enumerable

Module Module1

    Sub Main()
        For i = 1 To 25
            Dim t = Totient(i)
            Console.WriteLine("{0}{1}{2}{3}", i, vbTab, t, If(t = i - 1, vbTab & "prime", ""))
        Next
        Console.WriteLine()

        Dim j = 100
        While j <= 100000
            Console.WriteLine($"{Range(1, j).Count(Function(x) Totient(x) + 1 = x):n0} primes below {j:n0}")
            j *= 10
        End While
    End Sub

    Function Totient(n As Integer) As Integer
        If n < 3 Then
            Return 1
        End If
        If n = 3 Then
            Return 2
        End If

        Dim tot = n

        If (n And 1) = 0 Then
            tot >>= 1
            Do
                n >>= 1
            Loop While (n And 1) = 0
        End If

        Dim i = 3
        While i * i <= n
            If n Mod i = 0 Then
                tot -= tot \ i
                Do
                    n \= i
                Loop While (n Mod i) = 0
            End If
            i += 2
        End While

        If n > 1 Then
            tot -= tot \ n
        End If

        Return tot
    End Function

End Module


import "/fmt" for Fmt

var totient = Fn.new { |n|
    var tot = n
    var i = 2
    while (i*i <= n) {
        if (n%i == 0) {
            while(n%i == 0) n = (n/i).floor
            tot = tot - (tot/i).floor
        }
        if (i == 2) i = 1
        i = i + 2
    }
    if (n > 1) tot = tot - (tot/n).floor
    return tot
}

System.print(" n  phi   prime")
System.print("---------------")
var count = 0
for (n in 1..25) {
    var tot = totient.call(n)
    var isPrime = (n - 1) == tot
    if (isPrime) count = count + 1
    System.print("%(Fmt.d(2, n))   %(Fmt.d(2, tot))   %(isPrime)")
}
System.print("\nNumber of primes up to 25     = %(count)")
for (n in 26..100000) {
    var tot = totient.call(n)
    if (tot == n - 1) count = count + 1
    if (n == 100 || n == 1000 || n%10000 == 0) {
        System.print("\nNumber of primes up to %(Fmt.d(-6, n)) = %(count)")
    }
}


begin
procedure move(n, src, via, dest);
integer n;
string(1) src, via, dest;
begin
    if n > 0 then
    begin
        move(n-1, src, dest, via);
        write("Move disk from pole ");
        writeon(src);
        writeon(" to pole ");
        writeon(dest);
        move(n-1, via, src, dest);
    end;
end;

move(4, "1", "2", "3");
end


begin
    procedure move ( integer value n, from, to, via ) ;
        if n > 0 then begin
            move( n - 1, from, via, to );
            write( i_w := 1, s_w := 0, "Move disk from peg: ", from, " to peg: ", to );
            move( n - 1, via, to, from )
        end move ;

    move( 4, 1, 2, 3 )
end.


func GCD(N, D);         \Return the greatest common divisor of N and D
int  N, D;              \numerator and denominator
int  R;
[if D > N then
    [R:= D;  D:= N;  N:= R];    \swap D and N
while D > 0 do
    [R:= rem(N/D);
    N:= D;
    D:= R;
    ];
return N;
];      \GCD

func Totient(N);        \Return the totient of N
int  N, Phi, M;
[Phi:= 0;
for M:= 1 to N do
    if GCD(M, N) = 1 then Phi:= Phi+1;
return Phi;
];

int N, Phi, Pwr, C, Limit;
[Text(0, "n       phi     is prime^m^j");
for N:= 1 to 25 do
    [IntOut(0, N);  ChOut(0, 9\tab\);
    Phi:= Totient(N);
    IntOut(0, Phi);  ChOut(0, 9\tab\);
    Text(0, if Phi = N-1 then "true" else "false");
    CrLf(0);
    ];
CrLf(0);
for Pwr:= 2 to 4 do
    [C:= 0;
    Limit:= fix(Pow(10.0, float(Pwr)));
    IntOut(0, Limit);  ChOut(0, 9\tab\);
    for N:= 1 to Limit do
        [Phi:= Totient(N);
        if Phi = N-1 then C:= C+1;
        ];
    IntOut(0, C);  CrLf(0);
    ];
]


fcn totient(n){ [1..n].reduce('wrap(p,k){ p + (n.gcd(k)==1) }) }
fcn isPrime(n){ totient(n)==(n - 1) }


PROC move(n, from, to, via)
  IF n > 0
    move(n-1, from, via, to)
    WriteF('Move disk from pole \d to pole \d\n', from, to)
    move(n-1, via, to, from)
  ENDIF
ENDPROC

PROC main()
  move(4, 1,2,3)
ENDPROC


#include <hopper.h>
#proto hanoi(_X_,_Y_,_Z_,_W_)
main:
   get arg number (2,discos)
   {discos}!neg? do{fail=0,mov(fail),{"I need a positive (or zero) number here, not: ",fail}println,exit(0)}
   pos? do{
      _hanoi( discos, "A", "B", "C" )
   }
exit(0)
.locals
hanoi(discos,inicio,aux,fin)
   iif( {discos}eqto(1), {inicio, "->", fin, "\n"};print,  _hanoi({discos}minus(1), inicio,fin,aux);\
                                                           {inicio, "->", fin, "\n"};print;\
                                                           _hanoi({discos}minus(1), aux, inicio, fin))
back


hanoi←{
    move←{
        n from to via←⍵
        n≤0:⍬
        l←∇(n-1) from via to
        r←∇(n-1) via to from
        l,(⊂from to),r
    }
    '⊂Move disk from pole ⊃,I1,⊂ to pole ⊃,I1'⎕FMT↑move ⍵
}


--------------------- TOWERS OF HANOI --------------------

-- hanoi :: Int -> (String, String, String) -> [(String, String)]
on hanoi(n, abc)
    script go
        on |λ|(n, {x, y, z})
            if n > 0 then
                set m to n - 1

                |λ|(m, {x, z, y}) & ¬
                    {{x, y}} & |λ|(m, {z, y, x})
            else
                {}
            end if
        end |λ|
    end script

    go's |λ|(n, abc)
end hanoi

--------------------------- TEST -------------------------
on run
    unlines(map(intercalate(" -> "), ¬
        hanoi(3, {"left", "right", "mid"})))
end run

-------------------- GENERIC FUNCTIONS -------------------

-- intercalate :: String -> [String] -> String
on intercalate(delim)
    script
        on |λ|(xs)
            set {dlm, my text item delimiters} to ¬
                {my text item delimiters, delim}
            set s to xs as text
            set my text item delimiters to dlm
            s
        end |λ|
    end script
end intercalate

-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
    if class of f is script then
        f
    else
        script
            property |λ| : f
        end script
    end if
end mReturn

-- map :: (a -> b) -> [a] -> [b]
on map(f, xs)
    tell mReturn(f)
        set lng to length of xs
        set lst to {}
        repeat with i from 1 to lng
            set end of lst to |λ|(item i of xs, i, xs)
        end repeat
        return lst
    end tell
end map

-- unlines :: [String] -> String
on unlines(xs)
    set {dlm, my text item delimiters} to ¬
        {my text item delimiters, linefeed}
    set str to xs as text
    set my text item delimiters to dlm
    str
end unlines


.text
.global	_start
_start:	mov	r0,#4		@ 4 disks,
	mov	r1,#1		@ from pole 1,
	mov	r2,#2		@ via pole 2,
	mov	r3,#3		@ to pole 3.
	bl	move
	mov	r0,#0		@ Exit to Linux afterwards
	mov	r7,#1
	swi	#0
	@@@	Move r0 disks from r1 via r2 to r3
move:	subs	r0,r0,#1	@ One fewer disk in next iteration
	beq	show		@ If last disk, just print move
	push	{r0-r3,lr}	@ Save all the registers incl. link register
	eor	r2,r2,r3	@ Swap the 'to' and 'via' registers
	eor	r3,r2,r3
	eor	r2,r2,r3
	bl	move		@ Recursive call
	pop	{r0-r3}		@ Restore all the registers except LR
	bl	show		@ Show current move
	eor	r1,r1,r3	@ Swap the 'to' and 'via' registers
	eor	r3,r1,r3
	eor	r1,r1,r3
	pop	{lr}		@ Restore link register
	b	move		@ Tail call
	@@@	Show move
show:	push	{r0-r3,lr}	@ Save all the registers
	add	r1,r1,#'0	@ Write the source pole
	ldr	lr,=spole
	strb	r1,[lr]
	add	r3,r3,#'0	@ Write the destination pole
	ldr	lr,=dpole
	strb	r3,[lr]
	mov	r0,#1		@ 1 = stdout
	ldr	r1,=moves	@ Pointer to string
	ldr	r2,=mlen	@ Length of string
	mov	r7,#4		@ 4 = Linux write syscall
	swi	#0 		@ Print the move
	pop	{r0-r3,pc}	@ Restore all the registers and return
.data
moves:	.ascii	"Move disk from pole "
spole:	.ascii	"* to pole "
dpole:	.ascii	"*\n"
mlen	=	. - moves


hanoi: function [n f dir via][
	if n>0 [
		hanoi n-1 f via dir
		print ["Move disk" n "from" f "to" dir]
		hanoi n-1 via dir f
	]
]

hanoi 3 'L 'M 'R


move(n, from, to, via)  ;n = # of disks, from = start pole, to = end pole, via = remaining pole
{
  if (n = 1)
  {
    msgbox , Move disk from pole %from% to pole %to%
  }
  else
  {
    move(n-1, from, via, to)
    move(1, from, to, via)
    move(n-1, via, to, from)
  }
}
move(64, 1, 3, 2)


Func move($n, $from, $to, $via)
	If ($n = 1) Then
		ConsoleWrite(StringFormat("Move disk from pole "&$from&" To pole "&$to&"\n"))
	Else
		move($n - 1, $from, $via, $to)
		move(1, $from, $to, $via)
		move($n - 1, $via, $to, $from)
	EndIf
EndFunc

move(4, 1,2,3)


$ awk 'func hanoi(n,f,t,v){if(n>0){hanoi(n-1,f,v,t);print(f,"->",t);hanoi(n-1,v,t,f)}}
BEGIN{hanoi(4,"left","middle","right")}'


SUB move (n AS Integer, fromPeg AS Integer, toPeg AS Integer, viaPeg AS Integer)
    IF n>0 THEN
        move n-1, fromPeg, viaPeg, toPeg
        PRINT "Move disk from "; fromPeg; " to "; toPeg
        move n-1, viaPeg, toPeg, fromPeg
    END IF
END SUB

move 4,1,2,3


call move(4,1,2,3)
print "Towers of Hanoi puzzle completed!"
end

subroutine move (n, fromPeg, toPeg, viaPeg)
    if n>0 then
        call move(n-1, fromPeg, viaPeg, toPeg)
        print "Move disk from "+fromPeg+" to "+toPeg
        call move(n-1, viaPeg, toPeg, fromPeg)
    end if
end subroutine


@echo off
setlocal enabledelayedexpansion

	%==The main thing==%
	%==First param - Number of disks==%
	%==Second param - Start pole==%
	%==Third param - End pole==%
	%==Fourth param - Helper pole==%
call :move 4 START END HELPER
echo.
pause
exit /b 0

	%==The "function"==%
:move
	setlocal
	set n=%1
	set from=%2
	set to=%3
	set via=%4

	if %n% gtr 0 (
		set /a x=!n!-1
		call :move !x! %from% %via% %to%
		echo Move top disk from pole %from% to pole %to%.
		call :move !x! %via% %to% %from%
	)
	exit /b 0


      DIM Disc$(13),Size%(3)
      FOR disc% = 1 TO 13
        Disc$(disc%) = STRING$(disc%," ")+STR$disc%+STRING$(disc%," ")
        IF disc%>=10 Disc$(disc%) = MID$(Disc$(disc%),2)
        Disc$(disc%) = CHR$17+CHR$(128+disc%-(disc%>7))+Disc$(disc%)+CHR$17+CHR$128
      NEXT disc%

      MODE 3
      OFF
      ndiscs% = 13
      FOR n% = ndiscs% TO 1 STEP -1
        PROCput(n%,1)
      NEXT
      INPUT TAB(0,0) "Press Enter to start" dummy$
      PRINT TAB(0,0) SPC(20);
      PROChanoi(ndiscs%,1,2,3)
      VDU 30
      END

      DEF PROChanoi(a%,b%,c%,d%)
      IF a%=0 ENDPROC
      PROChanoi(a%-1,b%,d%,c%)
      PROCtake(a%,b%)
      PROCput(a%,c%)
      PROChanoi(a%-1,d%,c%,b%)
      ENDPROC

      DEF PROCput(disc%,peg%)
      PRINTTAB(13+26*(peg%-1)-disc%,20-Size%(peg%))Disc$(disc%);
      Size%(peg%) = Size%(peg%)+1
      ENDPROC

      DEF PROCtake(disc%,peg%)
      Size%(peg%) = Size%(peg%)-1
      PRINTTAB(13+26*(peg%-1)-disc%,20-Size%(peg%))STRING$(2*disc%+1," ");
      ENDPROC


get "libhdr"

let start() be move(4, 1, 2, 3)
and move(n, src, via, dest) be if n > 0 do
$(  move(n-1, src, dest, via)
    writef("Move disk from pole %N to pole %N*N", src, dest);
    move(n-1, via, src, dest)
$)


Move ← {
    𝕩⊑⊸≤0 ? ⟨⟩;
    𝕊 n‿from‿to‿via:
    l ← 𝕊 ⟨n-1, from, via, to⟩
    r ← 𝕊 ⟨n-1, via, to, from⟩
    l∾(<from‿to)∾r
}
{"Move disk from pole "∾(•Fmt 𝕨)∾" to pole "∾•Fmt 𝕩}´˘>Move 4‿1‿2‿3


( ( move
  =   n from to via
    .   !arg:(?n,?from,?to,?via)
      & (   !n:>0
          & move$(!n+-1,!from,!via,!to)
          & out$("Move disk from pole " !from " to pole " !to)
          & move$(!n+-1,!via,!to,!from)
        |
        )
  )
& move$(4,1,2,3)
);


[
This implementation is recursive and uses
a stack, consisting of frames that are 8
bytes long. The layout is as follows:

Byte   Description
   0   recursion flag
       (the program stops if the flag is
        zero)
   1   the step which is currently
       executed
       4 means a call to
               move(a, c, b, n - 1)
       3 means a call to
               move(a, b, c, 1)
       2 means a call to
               move(b, a, c, n - 1)
       1 prints the source and dest pile
   2   flag to check whether the current
       step has already been done or if
       it still must be executed
   3   the step which will be executed
       in the next loop
   4   the source pile
   5   the helper pile
   6   the destination pile
   7   the number of disks to move

The first stack frame (0 0 0 0 0 0 0 0)
is used to abort the recursion.
]

>>>>>>>>

These are the parameters for the program
(1 4 1 0 'a 'b 'c 5)
+>++++>+>>
>>>>++++++++[<++++++++++++>-]<
[<<<+>+>+>-]<<<+>++>+++>+++++>
<<<<<<<<

[> while (recurse)
  [- if (step gt 0)
    >[-]+< todo = 1
    [- if (step gt 1)
      [- if (step gt 2)
        [- if (step gt 3)
          >>+++<< next = 3
          >-< todo = 0
          >>>>>>[>+>+<<-]>[<+>-]> n dup
          -
          [[-] if (sub(n 1) gt 0)
            <+>>>++++> push (1 0 0 4)

            copy and push a
            <<<<<<<<[>>>>>>>>+>+
            <<<<<<<<<-]>>>>>>>>
            >[<<<<<<<<<+>>>>>>>>>-]< >

            copy and push c
            <<<<<<<[>>>>>>>+>+
            <<<<<<<<-]>>>>>>>
            >[<<<<<<<<+>>>>>>>>-]< >

            copy and push b
            <<<<<<<<<[>>>>>>>>>+>+
            <<<<<<<<<<-]>>>>>>>>>
            >[<<<<<<<<<<+>>>>>>>>>>-]< >

            copy n and push sub(n 1)
            <<<<<<<<[>>>>>>>>+>+
            <<<<<<<<<-]>>>>>>>>
            >[<<<<<<<<<+>>>>>>>>>-]< -
            >>
          ]
          <<<<<<<<
        ]
        >[-< if ((step gt 2) and todo)
          >>++<< next = 2
          >>>>>>>
          +>>>+> push 1 0 0 1 a b c 1
          <<<<<<<<[>>>>>>>>+>+
          <<<<<<<<<-]>>>>>>>>
          >[<<<<<<<<<+>>>>>>>>>-]< > a
          <<<<<<<<[>>>>>>>>+>+
          <<<<<<<<<-]>>>>>>>>
          >[<<<<<<<<<+>>>>>>>>>-]< > b
          <<<<<<<<[>>>>>>>>+>+
          <<<<<<<<<-]>>>>>>>>
          >[<<<<<<<<<+>>>>>>>>>-]< > c
          + >>
        >]<
      ]
      >[-< if ((step gt 1) and todo)
        >>>>>>[>+>+<<-]>[<+>-]> n dup
        -
        [[-] if (n sub 1 gt 0)
          <+>>>++++> push (1 0 0 4)

          copy and push b
          <<<<<<<[>>>>>>>+
          <<<<<<<-]>>>>>>>
          >[<<<<<<<<+>>>>>>>>-]< >

          copy and push a
          <<<<<<<<<[>>>>>>>>>+
          <<<<<<<<<-]>>>>>>>>>
          >[<<<<<<<<<<+>>>>>>>>>>-]< >

          copy and push c
          <<<<<<<<[>>>>>>>>+
          <<<<<<<<-]>>>>>>>>
          >[<<<<<<<<<+>>>>>>>>>-]< >

          copy n and push sub(n 1)
          <<<<<<<<[>>>>>>>>+>+
          <<<<<<<<<-]>>>>>>>>
          >[<<<<<<<<<+>>>>>>>>>-]< -
          >>
        ]
        <<<<<<<<
      >]<
    ]
    >[-< if ((step gt 0) and todo)
      >>>>>>>
      >++++[<++++++++>-]<
      >>++++++++[<+++++++++>-]<++++
      >>++++++++[<++++++++++++>-]<+++++
      >>+++++++++[<++++++++++++>-]<+++
      <<<
      >.+++++++>.++.--.<<.
      >>-.+++++.----.<<.
      >>>.<---.+++.>+++.+.+.<.<<.
      >.>--.+++++.---.++++.
        -------.+++.<<.
      >>>++.-------.-.<<<.
      >+.>>+++++++.---.-----.<<<.
      <<<<.>>>>.
      >>----.>++++++++.<+++++.<<.
      >.>>.---.-----.<<<.
      <<.>>++++++++++++++.
      >>>[-]<[-]<[-]<[-]
      +++++++++++++.---.[-]
      <<<<<<<
    >]<
    >>[<<+>>-]<< step = next
  ]
  return with clear stack frame
  <[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<
  <<<<<<<<
  >>[<<+>>-]<< step = next
  <
]


#include <stdio.h>

void move(int n, int from, int via, int to)
{
  if (n > 1) {
    move(n - 1, from, to, via);
    printf("Move disk from pole %d to pole %d\n", from, to);
    move(n - 1, via, from, to);
  } else {
    printf("Move disk from pole %d to pole %d\n", from, to);
  }
}
int main()
{
  move(4, 1,2,3);
  return 0;
}


public  void move(int n, int from, int to, int via) {
   if (n == 1) {
     System.Console.WriteLine("Move disk from pole " + from + " to pole " + to);
   } else {
     move(n - 1, from, via, to);
     move(1, from, to, via);
     move(n - 1, via, to, from);
   }
 }


void move(int n, int from, int to, int via) {
  if (n == 1) {
    std::cout << "Move disk from pole " << from << " to pole " << to << std::endl;
  } else {
    move(n - 1, from, via, to);
    move(1, from, to, via);
    move(n - 1, via, to, from);
  }
}


(defn towers-of-hanoi [n from to via]
  (when (pos? n)
    (towers-of-hanoi (dec n) from via to)
    (printf "Move from %s to %s\n" from to)
    (recur (dec n) via to from)))


move = proc (n, from, via, to: int)
    po: stream := stream$primary_output()
    if n > 0 then
        move(n-1, from, to, via)
        stream$putl(po, "Move disk from pole "
                     || int$unparse(from)
                     || " to pole "
                     || int$unparse(to))
        move(n-1, via, from, to)
    end
end move

start_up = proc ()
    move(4, 1, 2, 3)
end start_up


       >>SOURCE FREE
IDENTIFICATION DIVISION.
PROGRAM-ID. towers-of-hanoi.

PROCEDURE DIVISION.
    CALL "move-disk" USING 4, 1, 2, 3
    .
END PROGRAM towers-of-hanoi.

IDENTIFICATION DIVISION.
PROGRAM-ID. move-disk RECURSIVE.

DATA DIVISION.
LINKAGE SECTION.
01  n                         PIC 9 USAGE COMP.
01  from-pole                 PIC 9 USAGE COMP.
01  to-pole                   PIC 9 USAGE COMP.
01  via-pole                  PIC 9 USAGE COMP.

PROCEDURE DIVISION USING n, from-pole, to-pole, via-pole.
    IF n > 0
       SUBTRACT 1 FROM n
       CALL "move-disk" USING CONTENT n, from-pole, via-pole, to-pole
       DISPLAY "Move disk from pole " from-pole " to pole " to-pole
       CALL "move-disk" USING CONTENT n, via-pole, to-pole, from-pole
    END-IF
    .
END PROGRAM move-disk.