F next_step(=x)
   V result = 0
   L x > 0
      result += (x % 10) ^ 2
      x I/= 10
   R result

F check(number)
   V candidate = 0
   L(n) number
      candidate = candidate * 10 + n

   L candidate != 89 & candidate != 1
      candidate = next_step(candidate)

   I candidate == 89
      V digits_count = [0] * 10
      L(d) number
         digits_count[d]++

      V result = factorial(number.len)
      L(c) digits_count
         result I/= factorial(c)
      R result

   R 0

V limit = 100000000
V cache_size = Int(ceil(log10(limit)))
assert(10 ^ cache_size == limit)

V number = [0] * cache_size
V result = 0
V i = cache_size - 1

L
   I i == 0 & number[i] == 9
      L.break
   I i == cache_size - 1 & number[i] < 9
      number[i]++
      result += check(number)
   E I number[i] == 9
      i--
   E
      number[i]++
      L(j) i + 1 .< cache_size
         number[j] = number[i]
      i = cache_size - 1
      result += check(number)

print(result)


import "/fmt" for Fmt

var jaro = Fn.new { |s1, s2|
    var le1 = s1.count
    var le2 = s2.count
    if (le1 == 0 && le2 == 0) return 1
    if (le1 == 0 || le2 == 0) return 0
    var dist = (le2 > le1) ? le2 : le1
    dist = (dist/2).floor - 1
    var matches1 = List.filled(le1, false)
    var matches2 = List.filled(le2, false)
    var matches = 0
    var transpos = 0
    for (i in 0...s1.count) {
        var start = i - dist
        if (start < 0) start = 0
        var end = i + dist + 1
        if (end > le2) end = le2
        var k = start
        while (k < end) {
            if (!(matches2[k] || s1[i] != s2[k])) {
                matches1[i] = true
                matches2[k] = true
                matches = matches + 1
                break
            }
            k = k + 1
        }
    }
    if (matches == 0) return 0
    var k = 0
    for (i in 0...s1.count) {
        if (matches1[i]) {
            while(!matches2[k]) k = k + 1
            if (s1[i] != s2[k]) transpos = transpos + 1
            k = k + 1
        }
     }
     transpos = transpos / 2
     return (matches/le1 + matches/le2 + (matches - transpos)/matches) / 3
}

System.print(Fmt.f(0, jaro.call("MARTHA", "MARHTA")))
System.print(Fmt.f(0, jaro.call("DIXON", "DICKSONX")))
System.print(Fmt.f(0, jaro.call("JELLYFISH", "SMELLYFISH")))


with Ada.Text_IO;

procedure Digits_Squaring is

   function Is_89 (Number : in Positive) return Boolean
   is
      Squares : constant array (0 .. 9)  of Natural :=
        (0, 1, 4, 9, 16, 25, 36, 49, 64, 81);

      Sum : Natural := Number;
      Acc : Natural;
   begin
      loop
         Acc := Sum;
         Sum := 0;
         while Acc > 0 loop
            Sum := Sum + Squares (Acc mod 10);
            Acc := Acc / 10;
         end loop;

         if Sum = 89 then  return True;  end if;
         if Sum =  1 then  return False; end if;
      end loop;
   end Is_89;

   use Ada.Text_IO;
   Count : Natural := 0;
begin
   for A in 1 .. 99_999_999 loop
      if Is_89 (A) then
         Count := Count + 1;
      end if;

      if A = 999_999 then
         Put_Line ("In range 1 ..    999_999: " & Count'Image);
      end if;

   end loop;
   Put_Line ("In range 1 .. 99_999_999: " & Count'Image);
end Digits_Squaring;


# count the how many numbers up to 100 000 000 have squared digit sums of 89            #

# compute a table of the sum of the squared digits of the numbers 00 to 99              #
[ 0 : 99 ]INT    digit pair square sum;
FOR d1 FROM 0 TO 9 DO
    FOR d2 FROM 0 TO 9 DO
        digit pair square sum[ ( d1 * 10 ) + d2 ] := ( d1 * d1 ) + ( d2 * d2 )
    OD
OD;

# returns the sum of the squared digits of n                                            #
PROC squared digit sum = ( INT n )INT:
     BEGIN
         INT   result := 0;
         INT   rest   := n;
         WHILE rest /= 0 DO
             INT    digit pair = rest MOD 100;
             result PLUSAB digit pair square sum[ digit pair ];
             rest   OVERAB 100
         OD;
         result
     END # squared digit sum # ;

# for values up to 100 000 000, the largest squred digit sum will be that of 99 999 999 #
# i.e. 81 * 8 = 648, we will cache the values of the squared digit sums                 #
INT   cache max = 81 * 8;
[ 1 : cache max ]INT cache;
FOR i TO cache max DO cache[ i ] := 0 OD;

INT count 89 := 0;

# fill in the cache                                                                     #
FOR value FROM 2 TO cache max DO cache[ value ] := squared digit sum( value ) OD;
# we "know" that 89 and 1 are the terminal values                                       #
cache[  1 ] :=  1;
cache[ 89 ] := 89;
FOR value FROM 2 TO cache max DO
    INT sum := cache[ value ];
    WHILE sum /= 1 AND sum /= 89 DO
        sum := cache[ sum ]
    OD;
    cache[ value ] := sum
OD;

FOR value FROM 1 TO 100 000 000 DO
    IF cache[ squared digit sum( value ) ] = 89 THEN count 89 +:= 1 FI
OD;

print( ( "Number of values whose squared digit sum is 89: ", whole( count 89, -10 ), newline ) )


   //-->String of matched characters, ordered
fcn _jaro(str1,str2, matchDistance){
   cs:=Sink(String);
   foreach i,c in ([0..].zip(str1)){
      str2.find(c,(0).max(i - matchDistance),i + matchDistance) :
      if(Void!=_) cs.write(c);
   }
   cs.close()
}

fcn jaro(str1,str2){
   s1Len,s2Len,matchDistance := str1.len(), str2.len(), s1Len.max(s2Len)/2 - 1;
   cs12,cs21 := _jaro(str1,str2, matchDistance), _jaro(str2,str1, matchDistance);

   matches:=cs12.len().toFloat();
   if(not matches) return(0.0);
   transpositions:=cs12.walker().zipWith('!=,cs21).filter().sum(0)/2;

   ( matches/s1Len + matches/s2Len +
      ((matches - transpositions)/matches) ) / 3.0
}


10 LET a$="MARTHA": LET b$="MARHTA": PRINT a$;", ";b$;": ";: GO SUB 1000: PRINT jaro
20 LET a$="DIXON": LET b$="DICKSONX": PRINT a$;", ";b$;": ";: GO SUB 1000: PRINT jaro
30 LET a$="JELLYFISH": LET b$="SMELLYFISH": PRINT a$;", ";b$;": ";: GO SUB 1000: PRINT jaro
900 STOP
1000 REM Jaro subroutine
1010 LET s1=LEN a$: LET s2=LEN b$: LET j=1: LET m=0: LET t=0
1030 IF s1>s2 THEN LET z$=a$: LET a$=b$: LET b$=z$: LET z=s1: LET s1=s2: LET s2=z
1035 LET maxdist=INT (s2/2)
1040 FOR i=1 TO s1
1050 IF a$(i)=b$(j) THEN LET m=m+1: LET b$(j)=" ": GO TO 2000
1080 FOR k=FN x(1,i-maxdist) TO FN n(s2,i+maxdist)
1090 IF a$(i)=b$(k) THEN LET t=t+1: LET m=m+1: LET b$(k)=" ": IF k>j THEN LET j=k
1100 NEXT k
2000 IF j<s2 THEN LET j=j+1:
2010 NEXT i
2020 IF m=0 THEN LET jaro=0: RETURN
2030 LET t=INT (t/2)
2040 LET jaro=(m/s1+m/s2+((m-t)/m))/3
2050 RETURN
5000 REM Functions
5010 DEF FN x(a,b)=(a AND a>b)+(b AND a<b)+(a AND a=b): REM max function
5020 DEF FN n(a,b)=(a AND a<b)+(b AND a>b)+(a AND a=b): REM min function


gen: function [n][
    result: n
    while [not? in? result [1 89]][
        s: new 0
        loop digits result 'd ->
            's + d*d
        result: s
    ]
    return result
]

chainsEndingWith89: function [ndigits][
    [prevCount,currCount]: #[]
    loop 0..9 'i -> prevCount\[i*i]: 1

    res: new 0

    loop 2..ndigits 'x [
        currCount: #[]
        loop prevCount [val,cnt][
            v: to :integer val
            loop 0..9 'newDigit [
                mm: v + newDigit*newDigit
                if not? key? currCount mm -> currCount\[mm]: 0
                currCount\[mm]: currCount\[mm] + cnt
            ]
        ]
        prevCount: currCount
    ]
    loop currCount [val,cnt][
        v: to :integer val
        if and? [v <> 0] [89=gen v] ->
            'res + cnt
    ]
    return res
]

print [
    "Number chains for integers <100000000 that end with an 89 value:"
    chainsEndingWith89 8
]


# Usage: GAWK -f ITERATED_DIGITS_SQUARING.AWK
BEGIN {
    # Setup buffer for results up to 9*9*8
    for (i = 1; i <= 648; i++) {
        k = i
        do {
            k = squaredigitsum(k)
        } while ((k != 1) && (k != 89))
        if (k == 1) # This will give us 90 entries
            buffer[i] = ""
    }
    # Check sequence for every number
    pow10 = 1
    for (i = 1; i <= 100000000; i++) {
        count += (squaredigitsum(i) in buffer) ? 0 : 1
        if (i == pow10) {
            printf("1->10^%d: %d\n", length(i) - 1, count)
            pow10 *= 10
        }
    }
}
function squaredigitsum(n,    r) {
    while (n) {
        r += (n % 10) ^ 2
        n = int(n / 10)
    }
    return r
}


   +´1↓1≠ ⊏˜⍟(⌈2⋆⁼≠) ⥊+⌜´6⥊<×˜↕10
856929


#include <stdio.h>

typedef unsigned long long ull;

int is89(int x)
{
	while (1) {
		int s = 0;
		do s += (x%10)*(x%10); while ((x /= 10));

		if (s == 89) return 1;
		if (s == 1) return 0;
		x = s;
	}
}

int main(void)
{
	// array bounds is sort of random here, it's big enough for 64bit unsigned.
	ull sums[32*81 + 1] = {1, 0};

	for (int n = 1; ; n++) {
		for (int i = n*81; i; i--) {
			for (int j = 1; j < 10; j++) {
				int s = j*j;
				if (s > i) break;
				sums[i] += sums[i-s];
			}
		}

		ull count89 = 0;
		for (int i = 1; i < n*81 + 1; i++) {
			if (!is89(i)) continue;

			if (sums[i] > ~0ULL - count89) {
				printf("counter overflow for 10^%d\n", n);
				return 0;
			}
			count89 += sums[i];
		}

		printf("1->10^%d: %llu\n", n, count89);
	}

	return 0;
}


using System;
public static class IteratedDigitsSquaring
{
    public static void Main() {
        Console.WriteLine(Count89s(1_000_000));
        Console.WriteLine(Count89s(100_000_000));
    }

    public static int Count89s(int limit) {
        if (limit < 1) return 0;
        int[] end = new int[Math.Min(limit, 9 * 9 * 9 + 2)];
        int result = 0;

        for (int i = 1; i < end.Length; i++) {
            for (end[i] = i; end[i] != 1 && end[i] != 89; end[i] = SquareDigitSum(end[i])) { }
            if (end[i] == 89) result++;
        }
        for (int i = end.Length; i < limit; i++) {
            if (end[SquareDigitSum(i)] == 89) result++;
        }
        return result;

        int SquareDigitSum(int n) {
            int sum = 0;
            while (n > 0) {
                int digit = n % 10;
                sum += digit * digit;
                n /= 10;
            }
            return sum;
        }
    }

}


#include <iostream>

// returns sum of squares of digits of n
unsigned int sum_square_digits(unsigned int n) {
        int i,num=n,sum=0;
        // process digits one at a time until there are none left
        while (num > 0) {
                // peal off the last digit from the number
                int digit=num % 10;
                num=(num - digit)/10;
                // add it's square to the sum
                sum+=digit*digit;
        }
        return sum;
}
int main(void) {
        unsigned int i=0,result=0, count=0;
        for (i=1; i<=100000000; i++) {
                // if not 1 or 89, start the iteration
                if ((i != 1) || (i != 89)) {
                        result = sum_square_digits(i);
                }
                // otherwise we're done already
                else {
                        result = i;
                }
                // while we haven't reached 1 or 89, keep iterating
                while ((result != 1) && (result != 89)) {
                        result = sum_square_digits(result);
                }
                if (result == 89) {
                        count++;
                }
        }
        std::cout << count << std::endl;
        return 0;
}


shared void run() {

	function digitsSquaredSum(variable Integer n) {
		variable value total = 0;
		while(n > 0) {
			total += (n % 10) ^ 2;
			n /= 10;
		}
		return total;
	}

	function lastSum(variable Integer n) {
		while(true) {
			n = digitsSquaredSum(n);
			if(n == 89 || n == 1) {
				return n;
			}
		}
	}

	variable value eightyNines = 0;
	for(i in 1..100M - 1) {
		if(lastSum(i) == 89) {
			eightyNines++;
		}
	}
	print(eightyNines);
}


(ns async-example.core
  (:require [clojure.math.numeric-tower :as math])
  (:use [criterium.core])
  (:gen-class))
(defn sum-sqr [digits]
  " Square sum of list of digits "
  (let [digits-sqr (fn [n]
                     (apply + (map #(* % %) digits)))]
    (digits-sqr digits)))

(defn get-digits [n]
  " Converts a digit to a list of digits (e.g. 545 -> ((5) (4) (5)) (used for squaring digits) "
  (map #(Integer/valueOf (str %)) (String/valueOf n)))

(defn -isNot89 [x]
  " Returns nil on 89 "
  (cond
    (= x 0) 0
    (= x 89) nil
    (= x 1) 0
    (< x 10) (recur (* x x))
    :else (recur (sum-sqr (get-digits x)))))

;; Cached version of isNot89 (i.e. remembers prevents inputs, and returns result by looking it up when input repeated)
(def isNot89 (memoize -isNot89))

(defn direct-method [ndigits]
  " Simple approach of looping through all the numbers from 0 to 10^ndigits - 1 "
  (->>
    (math/expt 10 ndigits)
    (range 0)									; 0 to 10^ndigits
    (filter #(isNot89 (sum-sqr (get-digits %))))	; filters out 89
    (count)										; count non-89
    (- (math/expt 10 ndigits))))				; count 89 (10^ndigits - (count 89))

(time (println (direct-method 8)))


(defun square (number)
  (expt number 2))

(defun list-digits (number)
  "Return the `number' as a list of its digits."
  (loop
    :for (rest digit) := (multiple-value-list (truncate number 10))
                      :then (multiple-value-list (truncate rest 10))
    :collect digit
    :until (zerop rest)))

(defun next (number)
  (loop
    :for digit :in (list-digits number)
    :sum (square digit)))

(defun chain-end (number)
  "Return the ending number after summing the squaring of the digits of
`number'.  Either 1 or 89."
  (loop
    :for next := (next number) :then (next next)
    :until (or (eql next 1)
               (eql next 89))
    :finally (return next)))

(time
 (loop
   :with count := 0
   :for candidate :from 1 :upto 100000000
   :do (when (eql 89 (chain-end candidate))
         (incf count))
   :finally (return count)))


import std.stdio, std.algorithm, std.range, std.functional;

uint step(uint x) pure nothrow @safe @nogc {
    uint total = 0;
    while (x) {
        total += (x % 10) ^^ 2;
        x /= 10;
    }
    return total;
}

uint iterate(in uint x) nothrow @safe {
    return (x == 89 || x == 1) ? x : x.step.memoize!iterate;
}

void main() {
    iota(1, 100_000_000).filter!(x => x.iterate == 89).count.writeln;
}


PROGRAM ITERATION

BEGIN
   PRINT(CHR$(12);) ! CLS
   INPUT(N)
   LOOP
      N$=MID$(STR$(N),2)
      S=0
      FOR I=1 TO LEN(N$) DO
         A=VAL(MID$(N$,I,1))
         S=S+A*A
      END FOR
      IF S=89 OR S=1 THEN PRINT(S;)  EXIT END IF
      PRINT(S;)
      N=S
   END LOOP
   PRINT
END PROGRAM


USING: kernel math math.ranges math.text.utils memoize
prettyprint sequences tools.time ;
IN: rosetta-code.iterated-digits-squaring

: sum-digit-sq ( n -- m ) 1 digit-groups [ sq ] map-sum ;

MEMO: 1or89 ( n -- m )
    [ dup [ 1 = ] [ 89 = ] bi or ] [ sum-digit-sq ] until ;

[
    0 1
    [
        dup sum-digit-sq 1or89 89 = [ [ 1 + ] dip ] when
        1 + dup 100,000,000 <
    ] loop
    drop .
] time


Tested for VFX Forth and GForth in Linux
\ To explain the algorithm: Each iteration is performed in set-count-sumsq below.
\ sum square of digits for 1 digit numbers are
\   Base   1  2  3  4  5  6  7  8  9
\   Sumsq: 1  4  9 16 25 36 49 54 81
\ Adding 10 to the base adds 1 to the sumsq,
\ Adding 20 to the base adds 4
\         ||
\ Adding 90 adds 81
\ Similarly for n00, n000 etc..

\ Worked example for base 3 ( to keep the lists short ).
\ The base 10 version performs 1.1 .. 1.9  with shifts of 1, 4, 9 .. 81 cells
\
\    Ix      0   1   2   3   4   5   6   7   8
\    0     [ 1 ]
\    1.1       [ 1 ]                               Previous result shifted 1 cell ( 1**2 )
\    1.2                   [ 1 ]                   Previous result shifted 4 cells ( 2** 2 )
\    ------------------------------
\    Sum   [ 1,  1,  0,  0,  1  ]
\    2.1       [ 1,  1,  0,  0,  1  ]              Previous result shifted 1 cell ( 1**2 )
\    2.2                   [ 1,  1,  0,  0,  1 ]   Previous result shifted 4 cells ( 2** 2 )
\    --------------------------------------------
\    Sum   [ 1,  2,  1,  0,  2,  2,  0,  0,  1 ]   Number of integers with ix as first iteration sum of digits sq

CELL 8 * 301 * 1000 /   CONSTANT max-digits   \  301 1000 /  is log10( 2 )
\ 19 for a 64 bit Forth and 9 for a 32 bit one.

\ **********************************
\ ****  Create a counted array  ****
\ **********************************

: counted-array  \ create: #elements -- ;  does> -- a ;
  CREATE
    HERE SWAP 1+ CELLS DUP ALLOT ERASE
  DOES> ;

\ ***********************************
\ **** Array manipulation words. ****
\ ***********************************

: arr-copy  \ a-src a-dest -- ;  \ Copy array array at a-src to array at a-dest
  OVER @ 1+ CELLS CMOVE ;

: arr-count  \ a -- a' ct ;
\ Fetch the count of cells in the array and shift addr to point to element 0.
  DUP CELL+ SWAP @ ;

: th-element  \ a ix -- a' ;  \ Leave address of the ix th element of array at a on the stack
  1+ CELLS + ;

: arr-empty   \ a -- ;  \ Sets all array elements to zero and zero length
  dup @ 1+ CELLS ERASE ;

: arr+   \ a-src a-dest count -- ;
  \ Add each cell from a-src to the cells from a-dest for count elements
  \ Storing the result in a-dest
  CELLS 0 DO
    OVER I + @ OVER I + +!   \ I is a byte count offset into either array
  CELL +LOOP
  2DROP ;  \ DROP the two base addresses

: arr.   \ a -- ;   \ Print the array. Used to debug.
  ." [ "  arr-count CELLS BOUNDS ?DO   i @ .   CELL +LOOP ." ]"   ;

\ ***********************************
\ ****  Sum digit squared words  ****
\ ***********************************

: sum-digit-sq   \ n -- n' ;
  0 SWAP
  BEGIN   DUP   WHILE
    10 /MOD  >R DUP * + R>
  REPEAT DROP ;

: 89or1<>    \ n -- f ;  \ True if n not equal to 89 or 1.
  DUP 89 <> AND 1 > ;

: iterated-89=   \ n -- f ;   \ True if n iterates to 89, false once it iterates to 1 ( or 0 ).
  BEGIN   DUP 89or1<>   WHILE
    sum-digit-sq
  REPEAT 89 = ;

\ *****************************************************
\ **** Create `count-sumsq` and `sumsq-old` arrays ****
\ *****************************************************

max-digits 81 * 1+    counted-array count-sumsq
max-digits 1- 81 * 1+ counted-array sumsq-old

: init-count-sumsq  \ -- ; \ Initialise the count-sumsq to [ 1 ]
  count-sumsq arr-empty             \ Ensure all zero
  1 count-sumsq !                   \ Set the length of the count-sumsq to 1 cell.
  1 count-sumsq  0 th-element ! ;   \ Store 1 in the first element.

: set-count-sumsq  \ #digits -- ;    \ The main work.  Only called with valid #digits
  init-count-sumsq
  0 ?DO
    count-sumsq sumsq-old arr-copy   \ copy count-sumsq to sumsq-old
    81 count-sumsq +!              \ Extend count-sumsq by 81 (9*9) cells
    10 1 DO
      sumsq-old arr-count                    ( a-sumsq-old' len )
      count-sumsq I DUP * th-element SWAP arr+
    LOOP
  LOOP ;

: count-89s   \ #digits -- n ;
  DUP max-digits U> IF
    ." Number of digits must be between 0 and " max-digits .
    DROP 0
  ELSE
    set-count-sumsq
    0 count-sumsq @ 0 DO
      count-sumsq I th-element @      ( cum ith-count )
      I iterated-89=              \ True if the index delivers 89.
      AND +     \ True is -1 ( all bits set ) AND with the count and add to the cum.
    LOOP
  THEN ;

: test    \ #digits :
  CR max-digits min 1+ 1 ?DO
    I 5 .r 2 SPACES I count-89s . CR
  LOOP ;


' FB 1.05.0 Win64

' similar to C Language (first approach)
' timing for i3 @ 2.13 GHz

Function endsWith89(n As Integer) As Boolean
  Dim As Integer digit, sum = 0
  Do
    While n > 0
      digit = n Mod 10
      sum += digit * digit
      n \= 10
    Wend
    If sum = 89 Then Return True
    If sum = 1 Then Return False
    n = sum
    sum  = 0
  Loop
End Function

Dim As Double start = timer
Dim sums(0 To 8 * 81) As UInteger
sums(0) = 1
sums(1) = 0
Dim s As Integer
For n As Integer = 1 To 8
  For i As Integer = n * 81 To 1 Step -1
    For j As Integer = 1 To 9
      s = j * j
      If s > i Then Exit For
      sums(i) += sums(i - s)
    Next j
  Next i

  If n = 8 Then
    Dim As UInteger count89 = 0
    For i As Integer = 1 To n * 81
      If Not endsWith89(i) Then Continue For
      count89 += sums(i)
    Next i
    Print "There are";count89; " numbers from 1 to 100 million ending with 89"
  End If
Next
Print "Elapsed milliseconds ="; Int((timer - start) * 1000 + 0.5)
Print
Print "Press any key to quit"
Sleep


total = 0
d = new dict
var sum

for n = 1 to 100 million - 1
{
   sum = n
   do
   {
      if sum < 1000 and [email protected] != undef
      {
         sum = [email protected]
         break
      }

      c = sum

      sum = 0
      for digit = integerDigits[c]
         sum = sum + digit^2
   } while (sum != 89) and (sum != 1)

   if (n < 1000)
      [email protected] = sum

   if (sum == 89)
      total = total + 1
}

println[total]


package main

import (
	"fmt"
)

func main() {
	var d, n, o, u, u89 int64

	for n = 1; n < 100000000; n++ {
		o = n
		for {
			u = 0
			for {
				d = o%10
				o = (o - d) / 10
				u += d*d
				if o == 0 {
					break
				}
			}
			if u == 89 || u == 1 {
				if u == 89 { u89++ }
				break
			}
			o = u
		}
	}
	fmt.Println(u89)
}


import Data.List (unfoldr)
import Data.Tuple (swap)

step :: Int -> Int
step = sum . map (^ 2) . unfoldr f where
    f 0 = Nothing
    f n = Just . swap $ n `divMod` 10

iter :: Int -> Int
iter = head . filter (`elem` [1, 89]) . iterate step

main = do
    print $ length $ filter ((== 89) . iter) [1 .. 99999999]


import java.util.stream.IntStream;

public class IteratedDigitsSquaring {

    public static void main(String[] args) {
        long r = IntStream.range(1, 100_000_000)
                .parallel()
                .filter(n -> calc(n) == 89)
                .count();
        System.out.println(r);
    }

    private static int calc(int n) {
        while (n != 89 && n != 1) {
            int total = 0;
            while (n > 0) {
                total += Math.pow(n % 10, 2);
                n /= 10;
            }
            n = total;
        }
        return n;
    }
}


def factorial: reduce range(2;.+1) as $i (1; . * $i);

# Pick n items (with replacement) from the input array,
# but only consider distinct combinations:
def pick(n):
  def pick(n; m):  # pick n, from m onwards
    if n == 0 then []
    elif m == length then empty
    elif n == 1 then (.[m:][] | [.])
    else ([.[m]] + pick(n-1; m)), pick(n; m+1)
    end;
  pick(n;0) ;

# Given any array, produce an array of [item, count] pairs for each run.
def runs:
  reduce .[] as $item
    ( [];
      if . == [] then [ [ $item, 1] ]
      else  .[length-1] as $last
            | if $last[0] == $item then (.[0:length-1] + [ [$item, $last[1] + 1] ] )
              else . + [[$item, 1]]
              end
      end ) ;


function iterate(m::Integer)
    while m != 1 && m != 89
        s = 0
        while m > 0 # compute sum of squares of digits
            m, d = divrem(m, 10)
            s += d ^ 2
        end
        m = s
    end
    return m
end
itercount(k::Integer) = count(x -> iterate(x) == 89, 1:k)


// version 1.0.6

fun endsWith89(n: Int): Boolean {
    var digit: Int
    var sum = 0
    var nn = n
    while (true) {
        while (nn > 0) {
            digit = nn % 10
            sum += digit * digit
            nn /= 10
        }
        if (sum == 89) return true
        if (sum == 1) return false
        nn = sum
        sum  = 0
    }
}

fun main(args: Array<String>) {
    val sums = IntArray(8 * 81 + 1)
    sums[0] = 1
    sums[1] = 0
    var s: Int
    for (n in 1 .. 8)
        for (i in n * 81 downTo 1)
            for (j in 1 .. 9) {
                s = j * j
                if (s > i) break
                sums[i] += sums[i - s]
            }
    var count89 = 0
    for (i in 1 .. 8 * 81)
        if (endsWith89(i)) count89 += sums[i]
    println("There are $count89 numbers from 1 to 100 million ending with 89")
}


squares = {}

for i = 0, 9 do
    for j = 0, 9 do
        squares[i * 10 + j] = i * i + j * j
    end
end

for i = 1, 99 do
    for j = 0, 99 do
        squares[i * 100 + j] = squares[i] + squares[j]
    end
end

function sum_squares(n)
    if n < 9999.5 then
        return squares[n]
    else
        local m = math.floor(n / 10000)
        return squares[n - 10000 * m] + sum_squares(m)
    end
end

memory = {}

function calc_1_or_89(n)
    local m = {}
    n = memory[n] or n
    while n ~= 1 and n ~= 89 do
        n = memory[n] or sum_squares(n)
        table.insert(m, n)
    end
    for _, i in pairs(m) do
        memory[i] = n
    end
    return n
end

counter = 0

for i = 1, 100000000 do
    if calc_1_or_89(i) == 89 then
        counter = counter + 1
    end
end

print(counter)


sumDigitsSquared[n_Integer] := Total[IntegerDigits[n]^2]
stopValues = Join[{1}, NestList[sumDigitsSquared, 89, 7]];
iterate[n_Integer] :=
 NestWhile[sumDigitsSquared, n, Intersection[stopValues, {#}] == {} &]

numberOfDigits = 8;
maxSum = numberOfDigits 9^2;
loopVariables =
  [email protected]["i" <> ToString[n], {n, numberOfDigits}];
iteratesToOne = Cases[[email protected], _?(iterate[#] == 1 &)];
allIterators =
  Flatten[{[email protected]#, 9}] & /@ Partition[loopVariables, 2, 1];
maxCombinations = numberOfDigits!;

ssd =
  SparseArray[Table[n^2 -> numberOfDigits, {n, 9}], {maxSum}];

Do[
  variables = loopVariables[[;; digitCount]];
  iterators = allIterators[[;; digitCount - 1]];

  Do[ssd +=
    SparseArray[
     Total[variables^2] ->
      maxCombinations/
       Times @@ (Tally[PadRight[variables, numberOfDigits]][[All,
            2]]!), {maxSum}], {i, 9}, Evaluate[Sequence @@ iterators]],

  {digitCount, 2, numberOfDigits}];

onesCount =
 Total[Cases[
    ArrayRules[ssd] /.
     HoldPattern[{a_} -> b_] :> {a,
       b}, {_?(MemberQ[iteratesToOne, #] &), _}][[All, 2]]];

(10^numberOfDigits - 1) - onesCount


import tables

iterator digits(n: int): int =
  ## Yield the digits starting from the unit.
  var n = n
  while true:
    yield n mod 10
    n = n div 10
    if n == 0:
      break

func gen(n: int): int =
  ## Compute the chain.
  result = n
  while result notin [1, 89]:
    var s = 0
    for d in digits(result):
      inc s, d * d
    result = s

func chainsEndingWith89(ndigits: Natural): Natural =
  ## Compute the number of chains ending with 89.

  # Initialize the count table with values for one digit numbers.
  var prevCount, currcount: CountTable[int]
  for i in 0..9: prevcount[i * i] = 1

  # Add next digits.
  for _ in 2..ndigits:
    # Create the next generation count array.
    currcount.clear()
    for val, count in prevcount:
      for newdigit in 0..9:
        # As 0 is included, "currcount" includes "prevcount".
        currcount.inc(newdigit * newdigit + val, count)
    prevcount = currcount

  for val, count in currcount:
    if val != 0 and gen(val) == 89:
      inc result, count

echo "For  8 digits: ", chainsEndingWith89(8)
echo "For 50 digits: ", chainsEndingWith89(15)


MODULE DigitsSquaring;
IMPORT
  Out;

VAR
  i,hits89: LONGINT;

  PROCEDURE Squaring(n: LONGINT): LONGINT;
  VAR
    d, sum: LONGINT;
  BEGIN
    LOOP
      sum := 0;
      WHILE n > 0 DO
        d := n MOD 10;
        INC(sum,d * d);
        n := n DIV 10
      END;
      IF (sum = 1) OR (sum = 89) THEN EXIT END;
      n := sum;
    END;

    RETURN sum
  END Squaring;

BEGIN
  hits89 := 0;
  FOR i := 1 TO 100000000 DO
    IF Squaring(i) = 89 THEN INC(hits89) END
  END;
  Out.LongInt(hits89,0);Out.Ln
END DigitsSquaring.


class Abbreviations {
  function : Main(args : String[]) ~ Nil {
    Count89s(1000000)->PrintLine();
    Count89s(100000000)->PrintLine();
  }

  function : Count89s(limit : Int) ~ Int {
    if(limit < 1) {
      return 0;
    };

    result := 0;
    ends := Int->New[Int->Min(limit, 9 * 9 * 9 + 2)];
    for(i := 1; i < ends->Size(); i++;) {
      ends[i] := i;
      while(ends[i] <> 1 & ends[i] <> 89) {
        ends[i] := SquareDigitSum(ends[i]);
      };

      if(ends[i] = 89) {
        result++;
      };
    };

    for(i := ends->Size(); i < limit; i++;) {
      if(ends[SquareDigitSum(i)] = 89) {
        result++;
      };
    };

    return result;
  }

  function : SquareDigitSum(n : Int) ~ Int {
    sum := 0;
    while(n > 0) {
      digit := n % 10;
      sum += digit * digit;
      n /= 10;
    };

    return sum;
  }
}


: sq_digits(n)
   while (n 1 <> n 89 <> and ) [
      0 while(n) [ n 10 /mod ->n dup * + ]
      ->n
      ] n ;

: iterDigits  | i | 0 100000000 loop: i [ i sq_digits 89 &= + ] . ;


1E8 -> runtime 0..4 ms // not really measureable
1E12-> runtime 0.22 secs
1E14 -> runtime 2,7 secs
1E16 -> runtime 31,0 secs
1E18 -> runtime  354 secs // 2GByte


use warnings;
use strict;

my @sq = map { $_ ** 2 } 0 .. 9;
my %cache;
my $cnt = 0;

sub Euler92 {
    my $n = 0 + join( '', sort split( '', shift ) );
    $cache{$n} //= ($n == 1 || $n == 89) ? $n :
    Euler92( sum( @sq[ split '', $n ] ) )
}

sub sum {
   my $sum;
   $sum += shift while @_;
   $sum;
}

for (1 .. 100_000_000) {
   ++$cnt if Euler92( $_ ) == 89;
}

print $cnt;


with javascript_semantics
constant MAXINT = power(2,iff(machine_bits()=32?53:64))

procedure main(integer limit)
    sequence sums = repeat(0,limit*81+1)
    sums[1] = 1
    for n=1 to limit do
        for i=n*81 to 1 by -1 do
            for j=1 to 9 do
                integer s = j*j, i1= i+1, i1ms = i1-s
                if s>i then exit end if
                sums[i1] += sums[i1ms]
            end for
        end for
        atom count89 = 0
        for i=1 to n*81 do
            integer r, digit, w = i, i1 = i+1
            while w!=1 do
                r = 0
                while w!=0 do
                    digit = mod(w,10)
                    r += digit*digit
                    w = floor(w/10)
                end while
                if r=89 then
                    count89 += sums[i1]
                    if count89>MAXINT then
                        printf(1,"counter overflow for 10^%d\n",n)
                        return
                    end if
                    exit
                end if
                w = r
            end while
        end for
        printf(1,"There are %d numbers from 1 to 10^%d ending with 89\n",{count89,n})
    end for
end procedure

atom t0 = time()
main(20)
?time()-t0


(de *Idx1or89 (89 . 89) ((1 . 1)))

(de 1or89 (N)
   (let L (mapcar format (chop N))
      (if (lup *Idx1or89 (setq N (sum * L L)))
         (cdr @)
         (prog1
            (1or89 N)
            (idx '*Idx1or89 (cons N @) T) ) ) ) )


test: procedure options (main, reorder); /* 6 August 2015 */

   declare (m, n) fixed decimal (10);
   declare (i, j, p, s, tally initial (0) ) fixed binary (31);
   declare d fixed binary (7);
   declare (start_time, finish_time, elapsed_time) float (15);

   start_time = secs();

   do m = 1 to 1000000;
      n = m;
      do until ((n = 1) | (n = 89));
         p = n; s = 0;
         do while (p > 0);
            d = mod(p, 10);
            p = p/10;
            s = s + d*d;
         end;
         n = s;
      end;
      if n = 89 then tally = tally + 1;
   end;

   finish_time = secs();
   put skip edit (Tally, ' numbers iterated to 89') (f(10), A);
   elapsed_time = finish_time - start_time;
   put skip edit ('Elapsed time=', elapsed_time, ' secs') (A, F(10,3));

end test;


OpenConsole()
Procedure is89(x)
  Repeat
    s=0
    While x : s+ x%10*x%10 : x/10 : Wend
    If s=89 : ProcedureReturn 1 : EndIf
    If s=1  : ProcedureReturn 0 : EndIf
    x=s
  ForEver
EndProcedure

Procedure main()
  Dim sums(32*81+1) : sums(0)=1 : sums(1)=0

  For n=1 To n+1
    For i=n*81 To 1 Step -1
      For j=1 To 9
        s=j*j : If s>i : Break : EndIf
        sums(i)+sums(i-s)
      Next
    Next
    count89=0
    For i=1 To n*81+1
      If Not is89(i) : Continue : EndIf
      If sums(i)>9223372036854775807-count89
        PrintN("counter overflow for 10^"+Str(n))
        ProcedureReturn 0
      EndIf
      count89+sums(i)
    Next
    PrintN("1->10^"+LSet(Str(n),2,Chr(32))+": "+Str(count89))
  Next
EndProcedure

start=ElapsedMilliseconds()
main()
Print("elapsed milliseconds= "+Str(ElapsedMilliseconds()-start))
Input()


from math import ceil, log10, factorial

def next_step(x):
    result = 0
    while x > 0:
        result += (x % 10) ** 2
        x /= 10
    return result

def check(number):
    candidate = 0
    for n in number:
        candidate = candidate * 10 + n

    while candidate != 89 and candidate != 1:
        candidate = next_step(candidate)

    if candidate == 89:
        digits_count = [0] * 10
        for d in number:
            digits_count[d] += 1

        result = factorial(len(number))
        for c in digits_count:
            result /= factorial(c)
        return result

    return 0

def main():
    limit = 100000000
    cache_size = int(ceil(log10(limit)))
    assert 10 ** cache_size == limit

    number = [0] * cache_size
    result = 0
    i = cache_size - 1

    while True:
        if i == 0 and number[i] == 9:
            break
        if i == cache_size - 1 and number[i] < 9:
            number[i] += 1
            result += check(number)
        elif number[i] == 9:
            i -= 1
        else:
            number[i] += 1
            for j in xrange(i + 1, cache_size):
                number[j] = number[i]
            i = cache_size - 1
            result += check(number)

    print result

main()


REM Version 1: Brute force

T = TIMER
n1 = 0
FOR i = 1 TO 10000000
    j = i
    DO
        k = 0
        DO
            k = INT(k + (j MOD 10) ^ 2)
            j = INT(j / 10)
        LOOP WHILE j <> 0
        j = k
    LOOP UNTIL j = 89 OR j = 1
    IF j > 1 THEN n1 = n1 + 1
NEXT i
PRINT USING "Version 1: ####### in ##.### seconds."; n1; (TIMER - T)
END


[ abs 0 swap
  [ base share /mod
    dup *
    rot + swap
    dup 0 = until ]
  drop ]            is digitsquaresum ( n --> n )

[ dup 1 != while
  dup 89 != while
  digitsquaresum
  again ]           is chainends      ( n --> n )

0 1000000 times
  [ i^ 1+ chainends
    89 = + ]
echo


#lang racket
;; Tim-brown 2014-09-11

;; The basic definition.
;; It is possible to memoise this or use fixnum (native) arithmetic, but frankly iterating over a
;; hundred million, billion, trillion numbers will be slow. No matter how you do it.
(define (digit^2-sum n)
  (let loop ((n n) (s 0))
    (if (= 0 n) s (let-values ([(q r) (quotient/remainder n 10)]) (loop q (+ s (sqr r)))))))

(define (iterated-digit^2-sum n)
  (match (digit^2-sum n) [0 0] [1 1] [89 89] [(app iterated-digit^2-sum rv) rv]))

;; Note that: ids(345) = ids(354) = ids(435) = ids(453) = ids(534) = ids(543) = 50 --> 89
;; One calculation does for 6 candidates.
;; The plan:
;;  - get all the ordered combinations of digits including 0's which can be used both as digits and
;;    "padding" digits in the most significant digits. (n.b. all-zeros is not in the range to be
;;    tested and should be dropped)
;;  - find the digit sets that have an IDS of 89
;;  - find out how many combinations there are of these digits

;; output: a list of n-digits long lists containing all of the digit combinations.
;;         a smart bunny would figure out the sums of the digits as they're generated but I'll plod
;;         along step-by-step. a truly smart bunny would also count the combinations. that said, I
;;         don't think I do much unnecessary computation here.
(define (all-digit-lists n-digits)
  (define (inner remain acc least-digit)
    (cond
      [(zero? remain) (list (list))]
      [(= least-digit 10) null]
      [else
       (for*/list
           ((ld+ (in-range least-digit 10))
            (rgt (in-list (inner (sub1 remain) empty ld+))))
         (append acc (cons ld+ rgt)))]))
  (inner n-digits '() 0))

;; We calculate IDS differently since we're presented with a list of digits rather than a number
(define (digit-list-IDS c)
  (define (digit-combo-IDS c)
    (apply + (map sqr c)))
  (iterated-digit^2-sum (digit-combo-IDS c)))

;; ! (factiorial) -- everyone's favourite combinatorial function! (that's just an exclamation mark)
;; there's one in (require math/number-theory) for any heavy lifting, but we're not or I could import
;; it from math/number-theory -- but this is about all I need. A lookup table is going to be faster
;; than a more general function.
(define (! n)
  (case n [(0 1) 1] [(2) 2] [(3) 6] [(4) 24] [(5) 120] [(6) 720] [(7) 5040] [(8) 40320] [(9) 362880]
    [else (* n (! (sub1 n)))] ; I expect this clause'll never be called
    ))

;; We need to count the permutations -- digits are in order so we can use the tail (cdr) function for
;; determining my various k's. See: https://en.wikipedia.org/wiki/Combination
(define (count-digit-list-permutations c #:length (l (length c)) #:length! (l! (! l)))
  (let loop ((c c) (i 0) (prev -1 #;"never a digit") (p l!))
    (match c
      [(list) (/ p (! i))]
      [(cons (== prev) d) (loop d (+ i 1) prev p)]
      [(cons a d) (loop d 1 a (/ p (! i)))])))

;; Wrap it all up in a neat function
(define (count-89s-in-100... n)
  (define n-digits (order-of-magnitude n))
  (define combos (drop (all-digit-lists n-digits) 1)) ; don't want first one which is "all-zeros"
  (for/sum ((c (in-list combos)) #:when (= 89 (digit-list-IDS c)))
    (count-digit-list-permutations c #:length n-digits)))

(displayln "Testing permutations:")
(time (printf "1000000:\t~a~%"        (count-89s-in-100...       1000000)))
(time (printf "100000000:\t~a~%"      (count-89s-in-100...     100000000)))
(time (printf "1000000000:\t~a~%"     (count-89s-in-100...    1000000000)))
(time (printf "1000000000000:\t~a~%"  (count-89s-in-100... 1000000000000)))
(newline)
;; Do these last, since the 10^8 takes longer than my ADHD can cope with
(displayln "Testing one number at a time (somewhat slower):")
(time (printf "1000000:\t~a~%"   (for/sum ((n (in-range 1   1000000))
                                           #:when (= 89 (iterated-digit^2-sum n))) 1)))
(time (printf "100000000:\t~a~%" (for/sum ((n (in-range 1 100000000))
                                           #:when (= 89 (iterated-digit^2-sum n))) 1)))

{module+ test
  (require tests/eli-tester)
  [test
   (iterated-digit^2-sum 15) => 89
   (iterated-digit^2-sum 7) => 1
   (digit-combo-perms '()) => 1
   (digit-combo-perms '(1 2 3)) => 6
   (digit-combo-perms '(1 1 3)) => 3
   (for/sum ((n (in-range 1 1000000)) #:when (= 89 (iterated-digit^2-sum n))) 1) => 856929
   (all-digit-lists 1) => '((0) (1) (2) (3) (4) (5) (6) (7) (8) (9))
   (length (all-digit-lists 2)) => 55
   (length (all-digit-lists 3)) => 220
   (count-89s-in-100... 1000000) => 856929]
  }


/*REXX program performs the squaring of iterated digits  (until the sum equals 1 or 89).*/
parse arg n .                                    /*obtain optional arguments from the CL*/
if n=='' | n==","  then n=10 * 1000000           /*Not specified?  Then use the default.*/
!.=0;   do m=1  for 9;  !.m=m**2;  end  /*m*/    /*build a short─cut for the squares.   */
a.=.;                                #.=!.       /*intermediate counts of some numbers. */
     do j=1  for n;                  x=j         /* [↓] process the numbers in the range*/
       do q=1  until s==89 | s==1;   s=0         /*add sum of the squared decimal digits*/
             do  until x==''                     /*process each of the dec. digits in X.*/
             parse var x _ +1 x;     s=s + !._   /*get a digit;  sum the fast square,   */
             end   /*until x ··· */              /* [↑]  S≡is sum of the squared digits.*/
       z.q=s                                     /*assign sum to a temporary auxiliary. */
       if a.s\==.  then do;  s=a.s;  leave;  end /*Found a previous sum?  Then use that.*/
       x=s                                       /*substitute the sum for the "new"  X. */
       end   /*q*/                               /* [↑]  keep looping 'til   S= 1 or 89.*/
                   do f=1  for q;  _=a.f;  a._=s /*use the auxiliary arrays (for lookup)*/
                   end   /*f*/
     #.s=#.s + 1                                 /*bump the counter for the 1's or 89's.*/
     end   /*j*/

  do k=1  by 88  for 2;   @k=right('"'k'"', 5)   /*display two results; define a literal*/
  say 'count of'   @k   " chains for all natural numbers up to "     n     ' is:'      #.k
  end   /*k*/                                    /*stick a fork in it,  we're all done. */


nr = 1000
num = 0
for n = 1 to nr
   sum = 0
   for m = 1 to len(string(n))
       sum += pow(number(substr(string(n),m,1)),2)
       if sum = 89 num += 1 see "" + n + " " + sum + nl ok
   next
next
see "Total under 1000 is : " + num + nl


# Count how many number chains for Natural Numbers < 10**d end with a value of 1.
def iterated_square_digit(d)
  f = Array.new(d+1){|n| (1..n).inject(1, :*)}      #Some small factorials
  g = -> (n) { res = n.digits.sum{|d| d*d}
               res==89 ? 0 : res }

  #An array: table[n]==0 means that n translates to 89 and 1 means that n translates to 1
  table = Array.new(d*81+1){|n| n.zero? ? 1 : (i=g.call(n))==89 ? 0 : i}
  table.collect!{|n| n = table[n] while n>1; n}
  z = 0                                             #Running count of numbers translating to 1
  [*0..9].repeated_combination(d) do |rc|           #Iterate over unique digit combinations
    next if table[rc.inject(0){|g,n| g+n*n}].zero?  #Count only ones
    nn = [0] * 10                                   #Determine how many numbers this digit combination corresponds to
    rc.each{|n| nn[n] += 1}
    z += nn.inject(f[d]){|gn,n| gn / f[n]}          #Add to the count of numbers terminating in 1
  end
  puts "\nd=(#{d}) in the range 1 to #{10**d-1}",
       "#{z} numbers produce 1 and #{10**d-1-z} numbers produce 89"
end

[8, 11, 14, 17].each do |d|
  t0 = Time.now
  iterated_square_digit(d)
  puts "  #{Time.now - t0} sec"
end


fn digit_square_sum(mut num: usize) -> usize {
    let mut sum = 0;
    while num != 0 {
        sum += (num % 10).pow(2);
        num /= 10;
    }
    sum
}

fn last_in_chain(num: usize) -> usize {
    match num {
        1 | 89 => num,
        _ => last_in_chain(digit_square_sum(num)),
    }
}

fn main() {
    let count = (1..100_000_000).filter(|&n| last_in_chain(n) == 89).count();
    println!("{}", count);
}


import scala.annotation.tailrec

object Euler92 extends App {
  override val executionStart = compat.Platform.currentTime

  @tailrec
  private def calcRec(i: Int): Int = {

    @tailrec
    def iter0(n: Int, total: Int): Int =
      if (n > 0) {
        val rest = n % 10
        iter0(n / 10, total + rest * rest)
      }
      else total

    if (i == 89 || i == 1) i else calcRec(iter0(i, 0))
  }

  private def calcConv(i: Int) = {
    var n: Int = i
    while (n != 89 && n != 1) {
      var total = 0
      while (n > 0) {
        val x = n % 10
        total += (x * x)
        n /= 10
      }
      n = total
    }
    n
  }

  println((1 until 100000000).par.count(calcConv(_) == 89))
  println(s"Runtime conventional loop.[total ${compat.Platform.currentTime - executionStart} ms]")

  val executionStart0 = compat.Platform.currentTime
  println((1 until 100000000).par.count(calcRec(_) == 89))
  println(s"Runtime recursive loop.   [total ${compat.Platform.currentTime - executionStart0} ms]")

}


func digit_square_sum_iter(n) is cached {

    if ((n == 1) || (n == 89)) {
        return n
    }

    __FUNC__(n.digits.sum { .sqr })
}

say (1..1e6 -> count_by { digit_square_sum_iter(_) == 89 })


import BigInt

func is89(_ n: Int) -> Bool {
  var n = n

  while true {
    var s = 0

    repeat {
      s += (n%10) * (n%10)
      n /= 10
    } while n > 0

    if s == 89 {
      return true
    } else if s == 1 {
      return false
    }

    n = s
  }
}

func iterSquare(upToPower pow: Int) {
  var sums = [BigInt](repeating: 0, count: pow * 81 + 1)
  sums[0] = 1

  for n in 1...pow {
    var i = n * 81

    while i > 0 {
      for j in 1..<10 {
        let s = j * j
        guard s <= i else { break }
        sums[i] += sums[i-s]
      }

      i -= 1
    }

    var count89 = BigInt(0)

    for x in 1..<n*81 + 1 {
      guard is89(x) else { continue }

      count89 += sums[x]
    }

    print("1->10^\(n): \(count89)")
  }
}

iterSquare(upToPower: 8)


proc ids n {
    while {$n != 1 && $n != 89} {
	set n [tcl::mathop::+ {*}[lmap x [split $n ""] {expr {$x**2}}]]
    }
    return $n
}
for {set i 1} {$i <= 100000000} {incr i} {
    incr count [expr {[ids $i] == 89}]
}
puts $count


start_time = Now
cnt = 0
For i = 1 To 100000000
	n = i
	sum = 0
	Do Until n = 1 Or n = 89
		For j = 1 To Len(n)
			sum = sum + (CLng(Mid(n,j,1))^2)
		Next
		n = sum
		sum = 0
	Loop
	If n = 89 Then
		cnt = cnt + 1
	End If
Next
end_time = Now

WScript.Echo "Elapse Time: " & DateDiff("s",start_time,end_time) &_
			vbCrLf & "Count: " & cnt


var endsWith89 = Fn.new { |n|
    var digit = 0
    var sum = 0
    while (true) {
        while (n > 0) {
            digit = n % 10
            sum = sum + digit*digit
            n = (n/10).floor
        }
        if (sum == 89) return true
        if (sum == 1) return false
        n = sum
        sum = 0
    }
}

var start = System.clock
var sums = List.filled(8*81 + 1, 0)
sums[0] = 1
sums[1] = 0
var s = 0
for (n in 1..8) {
    for (i in n*81..1) {
        for (j in 1..9) {
            s = j * j
            if (s > i) break
            sums[i] = sums[i] + sums[i-s]
        }
    }
    if (n == 8) {
        var count89 = 0
        for (i in 1..n*81) {
            if (endsWith89.call(i)) count89 = count89 + sums[i]
        }
        System.print("There are %(count89) numbers from 1 to 100 million ending with 89.")
    }
}
System.print("Took %(((System.clock - start)*1000).round) milliseconds.")


section .data
    count dd 0

section .text
global _main
_main:
    mov ecx, 1
    looping:
        mov eax, ecx ;pass parameter in eax
        push ecx
        call doMath
        pop ecx
        add [count], eax ;doMath returns 0 or 1 in eax
        inc ecx
        cmp ecx, 100000001
        jl looping
    mov eax, count ;returns memory address of count
    ret

addSquaredDigits:
    push ebx
    mov ebx, 0
    mov esi, 10
    looping2:
        xor edx, edx ;clear edx for division
        div esi ;div by 10 to get last digit in edx
        mov ecx, eax ;save parameter
        mov eax, edx ; get last digit
        mul eax ;square last digit
        add ebx, eax ;add the square to the result
        jecxz aSDend ;if the parameter is 0 we have all digits
        mov eax, ecx ;restore parameter before looping
        jmp looping2
    aSDend:
        mov eax, ebx ;move result to return register
        pop ebx
        ret

doMath:
    looping3:
        call addSquaredDigits ;do until eax is 89 or 1
        cmp eax, 89
        je ret1
        cmp eax, 1
        je ret0
        jmp looping3
    ret1: ;if eax == 89 we return 1 -> inc count
        mov eax, 1
        ret
    ret0: ;if eax == 1 we return 0 -> don't inc count
        mov eax, 0
        ret


fcn check(number){  // a list of digits: 13 is L(0,0,0,0,0,0,1,3)
   candidate:=number.reduce(fcn(sum,n){ sum*10 + n },0);  // digits to int

   while(candidate != 89 and candidate != 1)  // repeatedly sum squares of digits
      { candidate = candidate.split().reduce(fcn(sum,c){ sum + c*c },0); }

   if(candidate == 89){ // count permutations of these digits, they all sum to 89
      digitsCount:=List(0,0,0,0,0,0,0,0,0,0);
      foreach d in (number){ digitsCount[d] += 1; }
      return(digitsCount.reduce(fcn(r,c){ r/factorial(c) },cacheBang)); // cacheBang==number.len()!
   }
   0 // this number doesn't sum to 89 (ie sums to 1)
}
fcn factorial(n) { (1).reduce(n,fcn(N,n){ N*n },1) }

limit:=0d100_000_000;  cacheSize:=limit.toFloat().log10().ceil().toInt();
number:=(0).pump(cacheSize,List().write,0); // list of zeros
result:=0; i:=cacheSize - 1;
var cacheBang=factorial(cacheSize);  //== number.len()!

while(True){  // create numbers s.t. no set of digits is repeated
   if(i == 0 and number[i] == 9) break;
   if(i == cacheSize - 1 and number[i] < 9){ number[i] += 1; result += check(number); }
   else if(number[i] == 9) i -= 1;
   else{
      number[i] += 1;
      foreach j in ([i + 1 .. cacheSize - 1]){ number[j] = number[i]; }
      i = cacheSize - 1;
      result += check(number);
   }
}
println(result);


10 LET n=0
20 FOR i=1 TO 1000
30 LET j=i
40 LET k=0
50 LET k=INT (k+FN m(j,10)^2)
60 LET j=INT (j/10)
70 IF j<>0 THEN GO TO 50
80 LET j=k
90 IF j=89 OR j=1 THEN GO TO 100
95 GO TO 40
100 IF j>1 THEN LET n=n+1
110 NEXT i
120 PRINT "Version 1: ";n
200 DEF FN m(a,b)=a-INT (a/b)*b: REM modulo


F nextfrom(&w, =name)
   L
      V nxt = w[name][0]
      w[name] = w[name][1..] + w[name][0.<1]
      I nxt[0] C ‘0’..‘9’
         R nxt
      name = nxt

L(group) |‘A: 1 2 3
           A: 1 B 2; B: 3 4
           A: 1 D D; D: 6 7 8
           A: 1 B C; B: 3 4; C: 5 B’.split("\n")
   print("Intersecting Number Wheel group:\n  "group)
   [String = [String]] wheel
   V first = ‘’
   L(w) group.split(‘;’)
      V s = w.trim(‘ ’).split(‘ ’)
      V name = s[0]
      wheel[name[0 .< (len)-1]] = s[1..]
      first = I first == ‘’ {name[0 .< (len)-1]} E first
   V gen = (0.<20).map(i -> nextfrom(&@wheel, @first)).join(‘ ’)
   print("  Generates:\n    "gen" ...\n")


BEGIN
    # a number wheel element                                                  #
    MODE NWELEMENT = UNION( CHAR # wheel name #, INT # wheel value # );
    # a number wheel                                                          #
    MODE NW = STRUCT( CHAR name, REF INT position, FLEX[ 1 : 0 ]NWELEMENT values );
    # get the next value from a number wheel in an array of number wheels     #
    # note: invalid wheel names will cause subscript range errors             #
    OP   NEXT = ( []NW wheels )INT:
         BEGIN
            INT  result;
            BOOL found := FALSE;
            INT  w     := LWB wheels; # start with the first wheel            #
            WHILE NOT found DO
                IF position OF wheels[ w ] > UPB values OF wheels[ w ] THEN
                    # passed the end of the wheel, go back to the start       #
                    position OF wheels[ w ] := LWB values OF wheels[ w ]
                FI;
                NWELEMENT e = ( values OF wheels[ w ] )[ position OF wheels[ w ] ];
                position OF wheels[ w ] +:= 1;
                CASE e
                  IN ( INT  n ): BEGIN result := n; found := TRUE END
                   , ( CHAR c ): BEGIN
                                     w := LWB wheels;
                                     WHILE name OF wheels[ w ] /= c DO w +:= 1 OD
                                 END
                ESAC
            OD;
            result
         END # NEXT # ;
    # prints the first n values from an array of wheels                       #
    PROC show = ( INT n, []NW wheels )VOID:
         BEGIN
            print( ( "First ", whole( n, 0 ), " values from the Intersecting Number Wheels:" ) );
            FOR i FROM LWB wheels TO UPB wheels DO
                print( ( newline, "    ", name OF wheels[ i ], ":" ) );
                FOR v FROM LWB values OF wheels[ i ] TO UPB values OF wheels[ i ] DO
                    CASE ( values OF wheels[ i ] )[ v ]
                      IN ( INT  n ): print( ( " ", whole( n, 0 ) ) )
                       , ( CHAR c ): print( ( " ", c ) )
                    ESAC
                OD
            OD;
            print( ( newline, "        " ) );
            FOR i TO n DO print( ( " ", whole( NEXT wheels, 0 ) ) ) OD;
            print( ( newline, newline ) )
         END # show # ;
    # show some wheels in action                                              #
    show( 20, ( NW( "A", LOC INT := 1, (  1,   2,   3  ) ) ) );
    show( 20, ( NW( "A", LOC INT := 1, (  1,  "B",  2  ) )
              , NW( "B", LOC INT := 1, (  3,   4       ) ) ) );
    show( 20, ( NW( "A", LOC INT := 1, (  1,  "D", "D" ) )
              , NW( "D", LOC INT := 1, (  6,   7,   8  ) ) ) );
    show( 20, ( NW( "A", LOC INT := 1, (  1,  "B", "C" ) )
              , NW( "B", LOC INT := 1, (  3,   4       ) )
              , NW( "C", LOC INT := 1, (  5,  "B"      ) ) ) )
END


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

struct Wheel {
    char *seq;
    int len;
    int pos;
};

struct Wheel *create(char *seq) {
    struct Wheel *w = malloc(sizeof(struct Wheel));
    if (w == NULL) {
        return NULL;
    }

    w->seq = seq;
    w->len = strlen(seq);
    w->pos = 0;

    return w;
}

char cycle(struct Wheel *w) {
    char c = w->seq[w->pos];
    w->pos = (w->pos + 1) % w->len;
    return c;
}

struct Map {
    struct Wheel *v;
    struct Map *next;
    char k;
};

struct Map *insert(char k, struct Wheel *v, struct Map *head) {
    struct Map *m = malloc(sizeof(struct Map));
    if (m == NULL) {
        return NULL;
    }

    m->k = k;
    m->v = v;
    m->next = head;

    return m;
}

struct Wheel *find(char k, struct Map *m) {
    struct Map *ptr = m;

    while (ptr != NULL) {
        if (ptr->k == k) {
            return ptr->v;
        }
        ptr = ptr->next;
    }

    return NULL;
}

void printOne(char k, struct Map *m) {
    struct Wheel *w = find(k, m);
    char c;

    if (w == NULL) {
        printf("Missing the wheel for: %c\n", k);
        exit(1);
    }

    c = cycle(w);
    if ('0' <= c && c <= '9') {
        printf(" %c", c);
    } else {
        printOne(c, m);
    }
}

void exec(char start, struct Map *m) {
    struct Wheel *w;
    int i;

    if (m == NULL) {
        printf("Unable to proceed.");
        return;
    }

    for (i = 0; i < 20; i++) {
        printOne(start, m);
    }
    printf("\n");
}

void group1() {
    struct Wheel *a = create("123");

    struct Map *m = insert('A', a, NULL);

    exec('A', m);
}

void group2() {
    struct Wheel *a = create("1B2");
    struct Wheel *b = create("34");

    struct Map *m = insert('A', a, NULL);
    m = insert('B', b, m);

    exec('A', m);
}

void group3() {
    struct Wheel *a = create("1DD");
    struct Wheel *d = create("678");

    struct Map *m = insert('A', a, NULL);
    m = insert('D', d, m);

    exec('A', m);
}

void group4() {
    struct Wheel *a = create("1BC");
    struct Wheel *b = create("34");
    struct Wheel *c = create("5B");

    struct Map *m = insert('A', a, NULL);
    m = insert('B', b, m);
    m = insert('C', c, m);

    exec('A', m);
}

int main() {
    group1();
    group2();
    group3();
    group4();

    return 0;
}


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

public static class IntersectingNumberWheels
{
    public static void Main() {
        TurnWheels(('A', "123")).Take(20).Print();
        TurnWheels(('A', "1B2"), ('B', "34")).Take(20).Print();
        TurnWheels(('A', "1DD"), ('D', "678")).Take(20).Print();
        TurnWheels(('A', "1BC"), ('B', "34"), ('C', "5B")).Take(20).Print();
    }

    static IEnumerable<char> TurnWheels(params (char name, string values)[] wheels) {
        var data = wheels.ToDictionary(wheel => wheel.name, wheel => wheel.values.Loop().GetEnumerator());
        var primary = data[wheels[0].name];
        while (true) {
            yield return Turn(primary);
        }

        char Turn(IEnumerator<char> sequence) {
            sequence.MoveNext();
            char c = sequence.Current;
            return char.IsDigit(c) ? c : Turn(data[c]);
        }
    }

    static IEnumerable<T> Loop<T>(this IEnumerable<T> seq) {
        while (true) {
            foreach (T element in seq) yield return element;
        }
    }

    static void Print(this IEnumerable<char> sequence) => Console.WriteLine(string.Join(" ", sequence));
}


#include <initializer_list>
#include <iostream>
#include <map>
#include <vector>

struct Wheel {
private:
    std::vector<char> values;
    size_t index;

public:
    Wheel() : index(0) {
        // empty
    }

    Wheel(std::initializer_list<char> data) : values(data), index(0) {
        //values.assign(data);
        if (values.size() < 1) {
            throw new std::runtime_error("Not enough elements");
        }
    }

    char front() {
        return values[index];
    }

    void popFront() {
        index = (index + 1) % values.size();
    }
};

struct NamedWheel {
private:
    std::map<char, Wheel> wheels;

public:
    void put(char c, Wheel w) {
        wheels[c] = w;
    }

    char front(char c) {
        char v = wheels[c].front();
        while ('A' <= v && v <= 'Z') {
            v = wheels[v].front();
        }
        return v;
    }

    void popFront(char c) {
        auto v = wheels[c].front();
        wheels[c].popFront();

        while ('A' <= v && v <= 'Z') {
            auto d = wheels[v].front();
            wheels[v].popFront();
            v = d;
        }
    }
};

void group1() {
    Wheel w({ '1', '2', '3' });
    for (size_t i = 0; i < 20; i++) {
        std::cout << ' ' << w.front();
        w.popFront();
    }
    std::cout << '\n';
}

void group2() {
    Wheel a({ '1', 'B', '2' });
    Wheel b({ '3', '4' });

    NamedWheel n;
    n.put('A', a);
    n.put('B', b);

    for (size_t i = 0; i < 20; i++) {
        std::cout << ' ' << n.front('A');
        n.popFront('A');
    }
    std::cout << '\n';
}

void group3() {
    Wheel a({ '1', 'D', 'D' });
    Wheel d({ '6', '7', '8' });

    NamedWheel n;
    n.put('A', a);
    n.put('D', d);

    for (size_t i = 0; i < 20; i++) {
        std::cout << ' ' << n.front('A');
        n.popFront('A');
    }
    std::cout << '\n';
}

void group4() {
    Wheel a({ '1', 'B', 'C' });
    Wheel b({ '3', '4' });
    Wheel c({ '5', 'B' });

    NamedWheel n;
    n.put('A', a);
    n.put('B', b);
    n.put('C', c);

    for (size_t i = 0; i < 20; i++) {
        std::cout << ' ' << n.front('A');
        n.popFront('A');
    }
    std::cout << '\n';
}

int main() {
    group1();
    group2();
    group3();
    group4();

    return 0;
}


import std.exception;
import std.range;
import std.stdio;

struct Wheel {
    private string[] values;
    private uint index;

    invariant {
        enforce(index < values.length, "index out of range");
    }

    this(string[] value...) in {
        enforce(value.length > 0, "Cannot create a wheel with no elements");
    } body {
        values = value;
    }

    enum empty = false;

    auto front() {
        return values[index];
    }

    void popFront() {
        index = (index + 1) % values.length;
    }
}

struct NamedWheel {
    private Wheel[char] wheels;
    char m;

    this(char c, Wheel w) {
        add(c, w);
        m = c;
    }

    void add(char c, Wheel w) {
        wheels[c] = w;
    }

    enum empty = false;

    auto front() {
        auto v = wheels[m].front;
        char c = v[0];
        while ('A' <= c && c <= 'Z') {
            v = wheels[c].front;
            c = v[0];
        }
        return v;
    }

    void popFront() {
        auto v = wheels[m].front;
        wheels[m].popFront;

        char c = v[0];
        while ('A' <= c && c <= 'Z') {
            auto d = wheels[c].front;
            wheels[c].popFront;
            c = d[0];
        }
    }
}

void group1() {
    auto a = Wheel("1", "2", "3");
    a.take(20).writeln;
}

void group2() {
    auto a = Wheel("1", "B", "2");
    auto b = Wheel("3", "4");

    auto n = NamedWheel('A', a);
    n.add('B', b);

    n.take(20).writeln;
}

void group3() {
    auto a = Wheel("1", "D", "D");
    auto d = Wheel("6", "7", "8");

    auto n = NamedWheel('A', a);
    n.add('D', d);

    n.take(20).writeln;
}

void group4() {
    auto a = Wheel("1", "B", "C");
    auto b = Wheel("3", "4");
    auto c = Wheel("5", "B");

    auto n = NamedWheel('A', a);
    n.add('B', b);
    n.add('C', c);

    n.take(20).writeln;
}

void main() {
    group1();
    group2();
    group3();
    group4();
}


with Ada.Integer_Text_IO, Ada.Text_IO;
 procedure Introspection is
    use Ada.Integer_Text_IO, Ada.Text_IO;
 begin
    Put ("Integer range: ");
    Put (Integer'First);
    Put (" .. ");
    Put (Integer'Last);
    New_Line;

    Put ("Float digits: ");
    Put (Float'Digits);
    New_Line;
 end Introspection;


// Wheels within wheels. Nigel Galloway: September 30th., 2019.
let N(n)=fun()->n
let wheel(n:(unit->int)[])=let mutable g= -1 in (fun()->g<-(g+1)%n.Length; n.[g]())
let A1=wheel[|N(1);N(2);N(3)|]
for n in 0..20 do printf "%d " (A1())
printfn ""
let B2=wheel[|N(3);N(4)|]
let A2=wheel[|N(1);B2;N(2)|]
for n in 0..20 do printf "%d " (A2())
printfn ""
let D3=wheel[|N(6);N(7);N(8)|]
let A3=wheel[|N(1);D3;D3|]
for n in 0..20 do printf "%d " (A3())
printfn ""
let B4=wheel[|N(3);N(4)|]
let C4=wheel[|N(5);B4|]
let A4=wheel[|N(1);B4;C4|]
for n in 0..20 do printf "%d " (A4())
printfn ""


package main

import (
    "fmt"
    "sort"
    "strconv"
)

type wheel struct {
    next   int
    values []string
}

type wheelMap = map[string]wheel

func generate(wheels wheelMap, start string, maxCount int) {
    count := 0
    w := wheels[start]
    for {
        s := w.values[w.next]
        v, err := strconv.Atoi(s)
        w.next = (w.next + 1) % len(w.values)
        wheels[start] = w
        if err == nil {
            fmt.Printf("%d ", v)
            count++
            if count == maxCount {
                fmt.Println("...\n")
                return
            }
        } else {
            for {
                w2 := wheels[s]
                ss := s
                s = w2.values[w2.next]
                w2.next = (w2.next + 1) % len(w2.values)
                wheels[ss] = w2
                v, err = strconv.Atoi(s)
                if err == nil {
                    fmt.Printf("%d ", v)
                    count++
                    if count == maxCount {
                        fmt.Println("...\n")
                        return
                    }
                    break
                }
            }
        }
    }
}

func printWheels(wheels wheelMap) {
    var names []string
    for name := range wheels {
        names = append(names, name)
    }
    sort.Strings(names)
    fmt.Println("Intersecting Number Wheel group:")
    for _, name := range names {
        fmt.Printf("  %s: %v\n", name, wheels[name].values)
    }
    fmt.Print("  Generates:\n    ")
}

func main() {
    wheelMaps := []wheelMap{
        {
            "A": {0, []string{"1", "2", "3"}},
        },
        {
            "A": {0, []string{"1", "B", "2"}},
            "B": {0, []string{"3", "4"}},
        },
        {
            "A": {0, []string{"1", "D", "D"}},
            "D": {0, []string{"6", "7", "8"}},
        },
        {
            "A": {0, []string{"1", "B", "C"}},
            "B": {0, []string{"3", "4"}},
            "C": {0, []string{"5", "B"}},
        },
    }
    for _, wheels := range wheelMaps {
        printWheels(wheels)
        generate(wheels, "A", 20)
    }
}


import math

if (version < 144) {
    throw "Version of aikido is too old"
}

var bloop = -1.4

// Math package doesn't have 'abs'.  We'll use 'fabs' instead.
if ("fabs" in Math) {
    if ("bloop" in main) {
        println ("fabs(bloop) is " + eval ("Math.fabs(bloop)"))
    }
}

var x = 104
var y = 598
var z = "hello"
var a = 1234

function count_ints {
    // there are builtin integer variables that we don't want to count.  There are
    // 3 of them
    var intcount = 0
    // map of builtin variables we want to ignore
    var ignore = {"version":true, "int":true, "integer":true}
    var sum = 0

    // the 'split' function can be used to split a block into a vector of the names
    // of the variables within it
    foreach v split (main, 0) {
        var varname = v
        try {
            var value = eval (varname)
            if (typeof(value) == "integer") {
                if (varname in ignore) {
                    continue
                }
                intcount++
                sum += value
            }
        } catch (e) {
            // ignore exception
        }
    }
    println ("There are " + intcount + " integer variables in the global scope")
    println ("Their sum is " + sum)
}

count_ints()


BEGIN
    print (("Integer range: ", -max int, " .. ", max int, new line));
    print (("Integer digits: ", int width, new line));
    print (("Float range: ", -max real, " .. ", max real, new line));
    print (("Float digits: ", real width, new line))
END


if not? sys\version > 0.9.0 -> panic "version too old!"

bloop: 3 - 5

if? set? 'bloop -> "variable 'bloop' is set"
else            -> "variable 'bloop' is not set"

if set? 'abs -> print ["the absolute value of bloop is:" abs bloop]

print [
    "The sum of all globally defined integers is:"
    sum map select keys symbols 'sym -> integer? var sym
                                'sym -> var sym
]


import Data.Char (isDigit)
import Data.List (mapAccumL)
import qualified Data.Map.Strict as M
import Data.Maybe (fromMaybe)

---------------- INTERSECTING NUMBER WHEELS --------------

clockWorkTick ::
  M.Map Char String ->
  (M.Map Char String, Char)
clockWorkTick = flip click 'A'
  where
    click wheels name
      | isDigit name = (wheels, name)
      | otherwise =
        ( click
            . flip
              (M.insert name . leftRotate)
              wheels
            <*> head
        )
          $ fromMaybe ['?'] $ M.lookup name wheels

leftRotate :: [a] -> [a]
leftRotate = take . length <*> (tail . cycle)

--------------------------- TEST -------------------------
main :: IO ()
main = do
  let wheelSets =
        [ [('A', "123")],
          [('A', "1B2"), ('B', "34")],
          [('A', "1DD"), ('D', "678")],
          [('A', "1BC"), ('B', "34"), ('C', "5B")]
        ]
  putStrLn "State of each wheel-set after 20 clicks:\n"
  mapM_ print $
    fmap
      ( flip
          (mapAccumL (const . clockWorkTick))
          (replicate 20 undefined)
          . M.fromList
      )
      wheelSets
  putStrLn "\nInitial state of the wheel-sets:\n"
  mapM_ print wheelSets


wheelgroup=:{{
  yield_wheelgroup_=: {{
    i=. wheels i.<;y
    j=. i{inds
    k=. ".;y
    l=. j{k
    inds=: ((#k)|1+j) i} inds
    if. l e. wheels
    do.yield l
    else.{.".;l
    end.
  }}
  gen_wheelgroup_=: {{
    yield wheel
  }}
  grp=. cocreate ''
  coinsert__grp 'wheelgroup'
  specs__grp=: cut each boxopen m
  wheel__grp=: ;{.wheels__grp=: {.every specs__grp
  init__grp=: {{('inds';wheels)=:(0#~#specs);}.each specs}}
  init__grp''
  ('gen_',(;grp),'_')~
}}


if (A_AhkVersion < "1.0.48.03")
{
  MsgBox % "you are using" . A_AhkVersion . "`nplease upgrade to" . "1.0.48.03"
  ExitApp
}
bloop = -3
if bloop
  if IsFunc("abs")
    MsgBox % abs(bloop)
return


# syntax: GAWK -f INTROSPECTION.AWK
BEGIN {
    if (PROCINFO["version"] < "4.1.0") {
      print("version is too old")
      exit(1)
    }
    bloop = -1
    if (PROCINFO["identifiers"]["abs"] == "user" && bloop != "") {
      printf("bloop = %s\n",bloop)
      printf("abs(bloop) = %s\n",abs(bloop))
    }
    exit(0)
}
function abs(x) { if (x >= 0) { return x } else { return -x } }


      IF VAL(FNversion) < 5.94 THEN PRINT "Version is too old" : END

      ON ERROR LOCAL PRINT "Variable 'bloop' doesn't exist" : END
      test = bloop
      RESTORE ERROR

      ON ERROR LOCAL PRINT "Function 'FNabs()' is not defined" : END
      test = ^FNabs()
      RESTORE ERROR

      PRINT FNabs(bloop)
      END

      DEF FNversion
      LOCAL F%, V$
      F% = OPENOUT(@tmp$+"version.txt")
      OSCLI "OUTPUT "+STR$F%
      *HELP
      *OUTPUT 0
      PTR #F% = 0
      INPUT #F%,V$
      CLOSE #F%
      = RIGHT$(V$,5)


package intersectingNumberWheels;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.IntStream;

public class WheelController {
	private static final String IS_NUMBER = "[0-9]";
	private static final int TWENTY = 20;
	private static Map<String, WheelModel> wheelMap;

	public static void advance(String wheel) {
		WheelModel w = wheelMap.get(wheel);
		if (w.list.get(w.position).matches(IS_NUMBER)) {
			w.printThePosition();
			w.advanceThePosition();
		} else {
			String wheelName = w.list.get(w.position);
			advance(wheelName);
			w.advanceThePosition();
		}
	}

	public static void run() {
		System.out.println(wheelMap);
		IntStream.rangeClosed(1, TWENTY).forEach(i -> advance("A"));
		System.out.println();
		wheelMap.clear();
	}

	public static void main(String[] args) {
		wheelMap = new HashMap<>();
		wheelMap.put("A", new WheelModel("A", "1", "2", "3"));
		run();
		wheelMap.put("A", new WheelModel("A", "1", "B", "2"));
		wheelMap.put("B", new WheelModel("B", "3", "4"));
		run();
		wheelMap.put("A", new WheelModel("A", "1", "D", "D"));
		wheelMap.put("D", new WheelModel("D", "6", "7", "8"));
		run();
		wheelMap.put("A", new WheelModel("A", "1", "B", "C"));
		wheelMap.put("B", new WheelModel("B", "3", "4"));
		wheelMap.put("C", new WheelModel("C", "5", "B"));
		run();
	}

}

class WheelModel {
	String name;
	List<String> list;
	int position;
	int endPosition;
	private static final int INITIAL = 0;

	public WheelModel(String name, String... values) {
		super();

		this.name = name.toUpperCase();
		this.list = new ArrayList<>();
		for (String value : values) {
			list.add(value);
		}
		this.position = INITIAL;
		this.endPosition = this.list.size() - 1;
	}

	@Override
	public String toString() {
		return list.toString();
	}

	public void advanceThePosition() {
		if (this.position == this.endPosition) {
			this.position = INITIAL;// new beginning
		} else {
			this.position++;// advance position
		}
	}

	public void printThePosition() {
		System.out.print(" " + this.list.get(position));
	}
}


#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
 #pragma error("C compiler must adhere to at least C99 for the following code.")
 #else
 /* rest of file */
 #endif


using System;
using System.Reflection;

namespace Rosetta_Introspection
{
	static public class Program
	{
		static public int bloop = -10;
		static public int bloop2 = -20;

		public static void Main()
		{
			var asm = Assembly.GetExecutingAssembly();
			var version = int.Parse(asm.ImageRuntimeVersion.Split('.')[0].Substring(1));
			if (version < 4)
			{
				Console.WriteLine("Get with the program!  I'm outta here!");
				return;
			}

			FieldInfo bloopField = null;

			foreach (var type in asm.GetExportedTypes())
			{
				foreach (var field in type.GetFields())
				{
					if (field.Name != "bloop")
					{
						continue;
					}
					bloopField = field;
					if (bloopField.FieldType != typeof(int))
					{
						throw new InvalidProgramException("bloop should be an integer");
					}
					break;
				}
				if (bloopField != null)
				{
					break;
				}
			}

			if (bloopField == null)
			{
				throw new InvalidProgramException("No bloop exported value");
			}
			foreach (var refAsm in AppDomain.CurrentDomain.GetAssemblies())
			{
				foreach (var type in refAsm.GetExportedTypes())
				{
					if (type.Name == "Math")
					{
						var absMethod = type.GetMethod("Abs", new Type[] { typeof(int) });
						if (absMethod != null)
						{
							Console.WriteLine("bloop's abs value = {0}", absMethod.Invoke(null, new object[] { bloopField.GetValue(null) }));
						}
					}
				}
			}

			int intCount = 0;
			int total = 0;

			foreach (var type in asm.GetExportedTypes())
			{
				foreach (var field in type.GetFields())
				{
					if (field.FieldType == typeof(int))
					{
						intCount++;
						total += (int)field.GetValue(null);
					}
				}
			}
			Console.WriteLine("{0} exported ints which total to {1}", intCount, total);
			Console.ReadKey();
		}
	}
}


(() => {
    'use strict';

    // main :: IO ()
    const main = () => {

        // clockWorkTick :: Dict -> (Dict, Char)
        const clockWorkTick = wheelMap => {
            // The new configuration of the wheels, tupled with
            // a digit found by recursive descent from a single
            // click of the first wheel.
            const click = wheels => wheelName => {
                const
                    wheel = wheels[wheelName] || ['?'],
                    v = wheel[0];
                return bool(click)(Tuple)(isDigit(v) || '?' === v)(
                    insertDict(wheelName)(
                        leftRotate(wheel)
                    )(wheels)
                )(v);
            };
            return click(wheelMap)('A');
        };

        // leftRotate ::[a] -> [a]
        const leftRotate = xs =>
            // The head of the list appended
            // to the tail of of the list.
            0 < xs.length ? (
                xs.slice(1).concat(xs[0])
            ) : [];

        // TEST -------------------------------------------
        // State of each wheel-set after 20 clicks,
        // paired with the resulting series of characters.

        const tuple = uncurry(Tuple);
        const wheelLists = [
            [tuple('A', '123')],
            [tuple('A', '1B2'), tuple('B', '34')],
            [tuple('A', '1DD'), tuple('D', '678')],
            [tuple('A', '1BC'), tuple('B', '34'), tuple('C', '5B')]
        ];

        console.log([
            'Series and state of each wheel-set after 20 clicks:\n',
            unlines(
                map(tuples => showWheels(
                    mapAccumL(
                        compose(constant, clockWorkTick)
                    )(dictFromList(tuples))(replicate(20)(''))
                ))(wheelLists)
            ),
            '\nInitial state of each wheel-set:\n',
            map(map(compose(
                JSON.stringify,
                dictFromList,
                x => [Array.from(x)]
            )))(wheelLists).join('\n')
        ].join('\n'));
    };

    // DISPLAY FORMATTING ---------------------------------

    // showWheels :: (Dict, [Char]) -> String
    const showWheels = tpl =>
        JSON.stringify(
            Array.from(secondArrow(concat)(tpl))
        );

    // GENERIC FUNCTIONS ----------------------------------

    // Tuple (,) :: a -> b -> (a, b)
    const Tuple = a => b => ({
        type: 'Tuple',
        '0': a,
        '1': b,
        length: 2
    });

    // bool :: a -> a -> Bool -> a
    const bool = f => t => p =>
        p ? t : f;

    // compose (<<<) :: (b -> c) -> (a -> b) -> a -> c
    const compose = (...fs) =>
        x => fs.reduceRight((a, f) => f(a), x);

    // concat :: [[a]] -> [a]
    // concat :: [String] -> String
    const concat = xs =>
        0 < xs.length ? (() => {
            const unit = 'string' !== typeof xs[0] ? (
                []
            ) : '';
            return unit.concat.apply(unit, xs);
        })() : [];

    // constant :: a -> b -> a
    const constant = k => _ => k;

    // dictFromList :: [(k, v)] -> Dict
    const dictFromList = kvs =>
        Object.fromEntries(kvs);

    // secondArrow :: (a -> b) -> ((c, a) -> (c, b))
    const secondArrow = f => xy =>
        // A function over a simple value lifted
        // to a function over a tuple.
        // f (a, b) -> (a, f(b))
        Tuple(xy[0])(
            f(xy[1])
        );

    // insertDict :: String -> a -> Dict -> Dict
    const insertDict = k => v => dct =>
        Object.assign({}, dct, {
            [k]: v
        });

    // isDigit :: Char -> Bool
    const isDigit = c => {
        const n = c.codePointAt(0);
        return 48 <= n && 57 >= n;
    };

    // map :: (a -> b) -> [a] -> [b]
    const map = f => xs =>
        (Array.isArray(xs) ? (
            xs
        ) : xs.split('')).map(f);

    // Map-accumulation is a combination of map and a catamorphism;
    // it applies a function to each element of a list, passing an
    // accumulating parameter from left to right, and returning a final
    // value of this accumulator together with the new list.

    // mapAccumL :: (acc -> x -> (acc, y)) -> acc -> [x] -> (acc, [y])
    const mapAccumL = f => acc => xs =>
        xs.reduce((a, x) => {
            const pair = f(a[0])(x);
            return Tuple(pair[0])(a[1].concat(pair[1]));
        }, Tuple(acc)([]));

    // replicate :: Int -> a -> [a]
    const replicate = n => x =>
        Array.from({
            length: n
        }, () => x);

    // uncurry :: (a -> b -> c) -> ((a, b) -> c)
    const uncurry = f =>
        (x, y) => f(x)(y);

    // unlines :: [String] -> String
    const unlines = xs => xs.join('\n');

    // MAIN ---
    return main();
})();


#if !defined(__cplusplus) || __cplusplus < 201103L
    #pragma error("The following code requires at least C++11.")
#else
    // ...
#endif


; check Java version
(let [version (Double/parseDouble (re-find #"\d*\.\d*" (System/getProperty "java.version")))]
  (if (>= version 1.5)
    (println "Version ok")
    (throw (Error. "Bad version"))))

; check Clojure version
(let [version (Double/parseDouble (re-find #"\d*\.\d*" (clojure-version)))]
  (if (>= version 1.0)
    (println "Version ok")
    (throw (Error. "Bad version"))))


(let* ((ver (lisp-implementation-version))
       (major (parse-integer ver :start 0 :end (position #\. ver))))
  #+lispworks (assert (>= 5 major) () "Requires Lispworks version 5 or above")
  #+clisp (assert (>= 2 major) () "Requires CLISP 2.n")
  )


const d1 = Dict("A" => [["1", "2", "3"], 1])
const d2 = Dict("A" => [["1", "B", "2"], 1], "B" => [["3", "4"], 1])
const d3 = Dict("A" => [["1", "D", "D"], 1], "D" => [["6", "7", "8"], 1])
const d4 = Dict("A" => [["1", "B", "C"], 1], "B" => [["3", "4"], 1],
    "C" => [["5", "B"], 1])

function getvalue!(wheelname, allwheels)
    wheel = allwheels[wheelname]
    s = wheel[1][wheel[2]]
    wheel[2] = mod1(wheel[2] + 1, length(wheel[1]))
    return haskey(allwheels, s) ? getvalue!(s, allwheels) : s
end

function testwheels(wheels, numterms = 20, firstwheel = "A")
    println("\nNumber Wheels:")
    for k in sort(collect(keys(wheels)))
        print("$k: [")
        for s in wheels[k][1]
            print(s, " ")
        end
        println("\b]")
    end
    print("Output: ")
    for _ in 1:numterms
        print(getvalue!(firstwheel, wheels), " ")
    end
    println("...")
end

foreach(testwheels, [d1, d2, d3, d4])


import java.util.Collections
import java.util.stream.IntStream

object WheelController {
    private val IS_NUMBER = "[0-9]".toRegex()
    private const val TWENTY = 20
    private var wheelMap = mutableMapOf<String, WheelModel>()

    private fun advance(wheel: String) {
        val w = wheelMap[wheel]
        if (w!!.list[w.position].matches(IS_NUMBER)) {
            w.printThePosition()
        } else {
            val wheelName = w.list[w.position]
            advance(wheelName)
        }
        w.advanceThePosition()
    }

    private fun run() {
        println(wheelMap)
        IntStream.rangeClosed(1, TWENTY)
            .forEach { advance("A") }
        println()
        wheelMap.clear()
    }

    @JvmStatic
    fun main(args: Array<String>) {
        wheelMap["A"] = WheelModel("1", "2", "3")
        run()
        wheelMap["A"] = WheelModel("1", "B", "2")
        wheelMap["B"] = WheelModel("3", "4")
        run()
        wheelMap["A"] = WheelModel("1", "D", "D")
        wheelMap["D"] = WheelModel("6", "7", "8")
        run()
        wheelMap["A"] = WheelModel("1", "B", "C")
        wheelMap["B"] = WheelModel("3", "4")
        wheelMap["C"] = WheelModel("5", "B")
        run()
    }
}

internal class WheelModel(vararg values: String?) {
    var list = mutableListOf<String>()
    var position: Int
    private var endPosition: Int

    override fun toString(): String {
        return list.toString()
    }

    fun advanceThePosition() {
        if (position == endPosition) {
            position = INITIAL // new beginning
        } else {
            position++ // advance position
        }
    }

    fun printThePosition() {
        print(" ${list[position]}")
    }

    companion object {
        private const val INITIAL = 0
    }

    init {
        Collections.addAll<String>(list, *values)
        position = INITIAL
        endPosition = list.size - 1
    }
}


// Some module-level variables (D doesn't have a global scope).
immutable x = 3, y = 100, z = 3_000;
short w = 1; // Not an int, must be ignored.
immutable s = "some string"; // Not an int, must be ignored.

void main() {
    import std.compiler, std.math, std.traits;

    // Compile-time constants of the compiler version:
    static assert(version_major > 1 && version_minor > 50,
                  "I can't cope with this compiler version.");

    immutable bloop = 10;

    // To check if something compiles:
    static if (__traits(compiles, bloop.abs)) {
        pragma(msg, "The expression is compilable.");
        auto x = bloop.abs;
    } else {
        pragma(msg, "The expression can't be compiled.");
    }

    import std.stdio;
    immutable s = 10_000; // Not at module scope, must be ignored.

    int tot = 0;
    /*static*/ foreach (name; __traits(allMembers, mixin(__MODULE__)))
        static if (name != "object" &&
                   is(int == Unqual!(typeof(mixin("." ~ name)))))
            tot += mixin("." ~ name);
    writeln("Total of the module-level ints (could overflow): ", tot);
}


def version := interp.getProps()["e.version"]


$ acl2
Welcome to Clozure Common Lisp Version 1.7-r14925M  (DarwinX8664)!

 ACL2 Version 4.3 built September 8, 2011  09:08:23.
 Copyright (C) 2011  University of Texas at Austin
 ACL2 comes with ABSOLUTELY NO WARRANTY.  This is free software and you
 are welcome to redistribute it under certain conditions.  For details,
 see the GNU General Public License.

 Initialized with (INITIALIZE-ACL2 'INCLUDE-BOOK *ACL2-PASS-2-FILES*).
 See the documentation topic note-4-3 for recent changes.
 Note: We have modified the prompt in some underlying Lisps to further
 distinguish it from the ACL2 prompt.

ACL2 Version 4.3.  Level 1.  Cbd "/Users/username/".
Distributed books directory "/Users/username/Code/acl2/books/".
Type :help for help.
Type (good-bye) to quit completely out of ACL2.

ACL2 !>(defun f (s1 s2 sep)
(concatenate 'string s1 sep sep s2))

Since F is non-recursive, its admission is trivial.  We observe that
the type of F is described by the theorem (STRINGP (F S1 S2 SEP)).
We used the :type-prescription rule STRING-APPEND-LST.

Summary
Form:  ( DEFUN F ...)
Rules: ((:TYPE-PRESCRIPTION STRING-APPEND-LST))
Time:  0.01 seconds (prove: 0.00, print: 0.00, other: 0.00)
 F
ACL2 !>(f "Rosetta" "Code" ":")
"Rosetta::Code"
ACL2 !>(good-bye)


➜  $ arturo

Arturo
(c) 2019-2021 Yanis Zafirópulos

# v/0.9.6.5 b/1097 @ 2021-02-09T16:40:43+01:00
# arch: amd64/macosx

# Type info 'symbol for info about a specific symbol or built-in function
# Type help to get a list of all available functions with a short description
# For multi-line input, just add a blank space at the end of a line

# Launching interactive console - rock on! 🤘

$> f: function [x y sep]-> x ++ (repeat sep 2) ++ y

$> f "Rosetta" "Code" ":"
=> Rosetta::Code

$>


10 DEF FN f$(a$, b$, s$) = a$+s$+s$+b$
PRINT FN f$("Rosetta", "Code", ":")


>set r=Rosetta

>set c=Code

>set s=:

>echo %r%%s%%s%%c%
Rosetta::Code

>


>r$ = "Rosetta"
>c$ = "Code"
>s$ = ":"
>PRINT r$+s$+s$+c$
Rosetta::Code
>


with(ArrayTools):

module Wheel()
 option object;
 local spokes := Array([1,2,3]);
 local currentSpoke := 1;

 export currentValue::static := proc(self::Wheel)
  local valueOut;
  if type(self:-spokes[self:-currentSpoke], integer) then
   valueOut := self:-spokes[self:-currentSpoke]:
  else
   valueOut := currentValue(self:-spokes[self:-currentSpoke]):
  end if:
  rotate(self):
  return valueOut;
 end proc:

 export rotate::static := proc(self::Wheel)
  if self:-currentSpoke = ArrayNumElems(self:-spokes) then self:-currentSpoke := 1:
  else self:-currentSpoke += 1: end if:
 end proc:

 export ModuleApply::static := proc()
  Object(Wheel, _passed);
 end proc:

 export ModuleCopy::static := proc(new::Wheel, proto::Wheel, spo::Array, curr::integer, $)
  new:-spokes := spo:
  new:-currentSpoke := curr:
 end proc:
end module:

A := Wheel(Array([1,2,3]), 1):

seq(currentValue(A), 1..20);

A := Wheel(Array([1,B,2]), 1):
B := Wheel(Array([3,4]), 1):

seq(currentValue(A), 1..20);

A := Wheel(Array([1,d,d]), 1):
d := Wheel(Array([6,7,8]), 1):

seq(currentValue(A), 1..20);

A := Wheel(Array([1,b,C]), 1):
b := Wheel(Array([3,4]), 1):
C := Wheel(Array([5,b]), 1):

seq(currentValue(A), 1..20);


import strutils, tables

type

  ElemKind = enum eValue, eWheel

  Elem = object
    case kind: ElemKind
    of eValue:
      value: Natural
    of eWheel:
      name: char

  Wheel = ref object
    elems: seq[Elem]
    index: Natural

  Wheels = Table[char, Wheel]

  WheelDescription = tuple[name: char; elems: string]

func initWheels(wheels: openArray[WheelDescription]): Wheels =
  ## Initialize a table of wheels from an array of wheel descriptions.

  for (name, elems) in wheels:
    let wheel = new(Wheel)
    for e in elems.splitWhitespace():
      if e[0].isUpperAscii():
        wheel.elems.add Elem(kind: eWheel, name: e[0])
      else:
        wheel.elems.add Elem(kind: eValue, value: e.parseInt())
    result[name] = wheel

func next(wheels: Wheels; name: char): Natural =
  ## Return the next element from a wheel.

  let wheel = wheels[name]
  let elem = wheel.elems[wheel.index]
  wheel.index = (wheel.index + 1) mod wheel.elems.len
  result = case elem.kind
           of eValue: elem.value
           of eWheel: wheels.next(elem.name)

when isMainModule:

  proc generate(wheelList: openArray[WheelDescription]; count: Positive) =
    ## Create the wheels from their description, then display
    ## the first "count" values generated by wheel 'A'.

    let wheels = wheelList.initWheels()
    for (name, elems) in wheelList:
      echo name, ": ", elems
    echo "generates:"
    for _ in 1..count:
      stdout.write ' ', wheels.next('A')
    echo '\n'

  {'A': "1 2 3"}.generate(20)
  {'A': "1 B 2", 'B': "3 4"}.generate(20)
  {'A': "1 D D", 'D': "6 7 8"}.generate(20)
  {'A': "1 B C", 'B': "3 4", 'C': "5 B"}.generate(20)


(version)
→ EchoLisp - 2.50.3
  📗 local-db: db.version: 3

(when (< (version) 2.6)
  (writeln "Please reload EchoLisp : CTRL-F5, CMD-R or other...")
  (exit))

(if (and (bound? 'bloop) (bound? 'abs) (procedure? abs))
    (abs bloop) 'NOT-HERE)
    → NOT-HERE

(define bloop -777)
   → bloop
(if (and (bound? 'bloop) (bound? 'abs) (procedure? abs)) (abs bloop) 'NOT-HERE)
   → 777

(for/sum ((kv (environment-bindings user-initial-environment )))
    #:when (integer? (second kv))
    (writeln kv)
    (second kv))

    ("bloop" -777)
    ("gee" 555)
    ("buzz" 333)
    → 111 ;; sum


-module( introspection ).

-export( [task/0] ).

task() ->
    exit_if_too_old( erlang:system_info(otp_release) ),
    Bloop = lists:keyfind( bloop, 1, ?MODULE:module_info(functions) ),
    Abs = lists:keyfind( abs, 1, erlang:module_info(exports) ),
    io:fwrite( "abs( bloop ) => ~p~n", [call_abs_with_bloop(Abs, Bloop)] ),
    io:fwrite( "Number of modules: ~p~n", [erlang:length(code:all_loaded())] ).

bloop() -> -1.

call_abs_with_bloop( {abs, 1}, {bloop, 0} ) -> erlang:abs( bloop() );
call_abs_with_bloop( _Missing, _Not_here ) -> abs_and_bloop_missing.

exit_if_too_old( Release ) when Release	< "R13A" -> erlang:exit( too_old_release );
exit_if_too_old( _Release ) -> ok.


   Join ← {a 𝕊 b‿c: b∾a∾a∾c}
(function block)
   ":" Join "Rosetta"‿"Code"
"Rosetta::Code"


D:\projects\Bracmat>bracmat
Bracmat version 5, build 105 (1 December 2011)
Copyright (C) 2002 Bart Jongejan
Bracmat comes with ABSOLUTELY NO WARRANTY; for details type `!w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `!c' for details.

{?} get$help { tutorial }
{?} )        { stop }
{?} (f=a b c.
{1}   !arg:(?a,?b,?c)
{1}   & str$(!a !c !b)
{1}   )
{!} f
    S   0,00 sec  (2156.2173.0)
{?} f$(Rosetta,Code,":")
{!} Rosetta:Code
    S   0,00 sec  (2156.2173.0)
{?}


$ brat
# Interactive Brat
brat:1> f = { a, b, s | a + s + s + b }
#=> function: 0xb737ac08
brat:2> f "Rosetta" "Code" ":"
#=> Rosetta::Code
brat:3> quit
Exiting


C:\Burlesque>Burlesque.exe --shell
blsq ) {+]?+}hd"Rosetta""Code"':!a
"Rosetta:Code"
blsq )


**********************************************************************
** Visual Studio 2017 Developer Command Prompt v15.9.14
** Copyright (c) 2017 Microsoft Corporation
**********************************************************************

C:\Program Files (x86)\Microsoft Visual Studio\2017\Community>csi /?
Microsoft (R) Visual C# Interactive Compiler version 2.10.0.0
Copyright (C) Microsoft Corporation. All rights reserved.

Usage: csi [option] ... [script-file.csx] [script-argument] ...

Executes script-file.csx if specified, otherwise launches an interactive REPL (Read Eval Print Loop).

Options:
  /help                          Display this usage message (alternative form: /?)
  /version                       Display the version and exit
  /i                             Drop to REPL after executing the specified script.
  /r:<file>                      Reference metadata from the specified assembly file (alternative form: /reference)
  /r:<file list>                 Reference metadata from the specified assembly files (alternative form: /reference)
  /lib:<path list>               List of directories where to look for libraries specified by #r directive.
                                 (alternative forms: /libPath /libPaths)
  /u:<namespace>                 Define global namespace using (alternative forms: /using, /usings, /import, /imports)
  @<file>                        Read response file for more options
  --                             Indicates that the remaining arguments should not be treated as options.


with javascript_semantics
function terms(sequence wheels, integer n)
    sequence res = repeat(' ',n),
             pos = repeat(2,length(wheels)),
             wvs = vslice(wheels,1)
    integer wheel = 1, rdx = 1
    while rdx<=n do
        integer p = pos[wheel],
                c = wheels[wheel][p]
        p = iff(p=length(wheels[wheel])?2:p+1)
        pos[wheel] = p
        if c>'9' then
            wheel = find(c,wvs)
        else
            res[rdx] = c
            rdx += 1
            wheel = 1
        end if
    end while
    return res
end function

constant wheels = {{"A123"},
                   {"A1B2","B34"},
                   {"A1DD","D678"},
                   {"A1BC","B34","C5B"}}

for i=1 to length(wheels) do
    ?terms(wheels[i],20)
end for


from itertools import islice

class INW():
    """
    Intersecting Number Wheels
    represented as a dict mapping
    name to tuple of values.
    """

    def __init__(self, **wheels):
        self._wheels = wheels
        self.isect = {name: self._wstate(name, wheel)
                      for name, wheel in wheels.items()}

    def _wstate(self, name, wheel):
        "Wheel state holder"
        assert all(val in self._wheels for val in wheel if type(val) == str), \
               f"ERROR: Interconnected wheel not found in {name}: {wheel}"
        pos = 0
        ln = len(wheel)
        while True:
            nxt, pos = wheel[pos % ln], pos + 1
            yield next(self.isect[nxt]) if type(nxt) == str else nxt

    def __iter__(self):
        base_wheel_name = next(self.isect.__iter__())
        yield from self.isect[base_wheel_name]

    def __repr__(self):
        return f"{self.__class__.__name__}({self._wheels})"

    def __str__(self):
        txt = "Intersecting Number Wheel group:"
        for name, wheel in self._wheels.items():
            txt += f"\n  {name+':':4}" + ' '.join(str(v) for v in wheel)
        return txt

def first(iter, n):
    "Pretty print first few terms"
    return ' '.join(f"{nxt}" for nxt in islice(iter, n))

if __name__ == '__main__':
    for group in[
      {'A': (1, 2, 3)},
      {'A': (1, 'B', 2),
       'B': (3, 4)},
      {'A': (1, 'D', 'D'),
       'D': (6, 7, 8)},
      {'A': (1, 'B', 'C'),
       'B': (3, 4),
       'C': (5, 'B')}, # 135143145...
     ]:
        w = INW(**group)
        print(f"{w}\n  Generates:\n    {first(w, 20)} ...\n")


: if-older ( n true false -- )
    [ build > ] 2dip if ; inline

: when-older ( n true -- )
    [ ] if-older ; inline
: unless-older ( n false -- )
    [ [ ] ] dip if-older ; inline

900 [ "Your version of Factor is too old." print 1 exit ] when-older


s" MAX-U" environment? [IF]
   0xffffffff <> [IF] .( Requires 32 bits! ) bye [THEN]
[THEN]

[defined] bloop [if]
[defined] abs [if]
  bloop @ abs
[then] [then]


' FB 1.05.0 Win64

#If __FB_VERSION__ < "1.06.0"
  #Error "Compiler version is too old - needs to be 1.06.0 or later"
#EndIf

Dim bloop As Integer = -15
#IfDef bloop
  #IfDef Abs
    Print "Abs(bloop) = "; Abs(bloop)
  #Else
    Print "Abs is not available"
  #EndIf
#Else
  Print "bloop does not exist"
#EndIf
Sleep


# Apply a function to a value, given variable names for both function and value
CheckEval := function(fun, val)
	local f, x;
	if IsBoundGlobal(fun) and IsBoundGlobal(val) then
		f := ValueGlobal(fun);
		x := ValueGlobal(val);
		return f(x);
	fi;
end;

bloop := -1;
CheckEval("AbsInt", "bloop");
# 1

# Sum of integer variables
GlobalIntegers := function()
	local s, x, name;
	s := 0;
	for name in SortedList(NamesGVars()) do
		if IsBoundGlobal(name) then
			x := ValueGlobal(name);
			if IsInt(x) then
				Print(name, " ", x, "\n");
				s := s + x;
			fi;
		fi;
	od;
	return s;
end;


Clojure 1.1.0
user=> (defn f [s1 s2 sep] (str s1 sep sep s2))
#'user/f
user=> (f "Rosetta" "Code" ":")
"Rosetta::Code"
user=>


$ coffee -n
coffee> f = (a, b, c) -> a + c + c + b
[Function]
coffee> f "Rosetta", "Code", ":"
"Rosetta::Code"


$ rlwrap sbcl
This is SBCL 1.0.25, an implementation of ANSI Common Lisp.
More information about SBCL is available at <http://www.sbcl.org/>.
...
* (defun f (string-1 string-2 separator)
    (concatenate 'string string-1 separator separator string-2))

F
* (f "Rosetta" "Code" ":")

"Rosetta::Code"
*


$ vu
<1:1> f str1 str2 sep:
<1:2>     join sep [ str2 "" str1 ]
<1:3>
<2:1> . f "Rosetta" "Code" ":"
"Rosetta::Code"


$ rune   # from an OS shell. On Windows there is also a desktop shortcut.


  [ ]this[ ]done[
    dup take behead
    dup dip
      [ nested join
        swap put ]
    do ]                      is wheel    ( --> n )

  [ ]'[
    ]'[ nested
    ' [ wheel ]
    swap join
    swap replace ]            is newwheel ( -->   )

  forward is A  forward is B  forward is C
  forward is D  ( and so on, as required )

  [ wheel [ 1 2 3 ] ]   resolves A        ( --> n )

  [ wheel [ 3 4 ] ]     resolves B        ( --> n )

  [ wheel [ 5 B ] ]     resolves C        ( --> n )

  [ wheel [ 6 7 8 ] ]   resolves D        ( --> n )

  20 times [ A echo sp ] cr

  newwheel A [ 1 B 2 ]
  20 times [ A echo sp ] cr

  newwheel A [ 1 D D ]
  20 times [ A echo sp ] cr

  newwheel A [ 1 B C ]
  newwheel B [ 3 4 ]        ( As B has been used already )
                            ( it's state may be [ 4 3 ]. )
                            ( So we reset it to [ 3 4 ]. )

  20 times [ A echo sp ] cr


#| advance rotates a named wheel $n by consuming an item from an infinite sequence. It is called
#| from within a gather block and so can use take in order to construct an infinite, lazy sequence
#| of result values
sub advance($g, $n) {
	given $g{$n}.pull-one {
		when /\d/ { take $_ }
		default   { samewith $g, $_ } # samewith re-calls this function with new parameters
	}
}

#| Input groups are a hash containing each wheel name as the key, and a list of values constructed
#| using <> to split on whitespace. They are transformed using xx * to repeat the list infinitely.
#| We then retrieve the underlying iterator in order for wheel position to be persistent. Each group
#| is then aggregated into a lazy output sequence using an infinite loop inside a gather block.
[
	{A => <1 2 3>},
	{A => <1 B 2>, B => <3 4>},
	{A => <1 D D>, D => <6 7 8>},
	{A => <1 B C>, B => <3 4>, C => <5 B>},
]
	#| %() converts a list of pairs produced by map into a hash. $^k and $^v are implicit variables.
	#| They are processed in alphabetical order and make the block arity 2, called with two vars.
	#| .kv gets the list of wheel names and wheel values from the input entry
	==> map({ %(.kv.map: { $^k => (|$^v xx *).iterator }) })
	#| gather constructs a lazy sequence, in which we infinitely loop advancing wheel A
	==> map({ gather { loop { advance $_, 'A' }} })
	#| state variables are only initialised once, and are kept between invocations.
	==> map({ state $i = 1; say "Group {$i++}, First 20 values: $_[^20]" })