def compress(tc:String) = {
    //initial dictionary
    val startDict = (1 to 255).map(a=>(""+a.toChar,a)).toMap
    val (fullDict, result, remain) = tc.foldLeft ((startDict, List[Int](), "")) {
      case ((dict,res,leftOver),nextChar) =>
        if (dict.contains(leftOver + nextChar)) // current substring already in dict
          (dict, res, leftOver+nextChar)
        else if (dict.size < 4096) // add to dictionary
          (dict + ((leftOver+nextChar, dict.size+1)), dict(leftOver) :: res, ""+nextChar)
        else // dictionary is full
          (dict, dict(leftOver) :: res, ""+nextChar)
    }
    if (remain.isEmpty) result.reverse else (fullDict(remain) :: result).reverse
}

def decompress(ns: List[Int]): String = {
  val startDict = (1 to 255).map(a=>(a,""+a.toChar)).toMap
  val (_, result, _) =
    ns.foldLeft[(Map[Int, String], List[String], Option[(Int, String)])]((startDict, Nil, None)) {
    case ((dict, result, conjecture), n) => {
      dict.get(n) match {
        case Some(output) => {
          val (newDict, newCode) = conjecture match {
            case Some((code, prefix)) => ((dict + (code -> (prefix + output.head))), code + 1)
            case None => (dict, dict.size + 1)
          }
          (newDict, output :: result, Some(newCode -> output))
        }
        case None => {
          // conjecture being None would be an encoding error
          val (code, prefix) = conjecture.get
          val output = prefix + prefix.head
          (dict + (code -> output), output :: result, Some(code + 1 -> output))
        }
      }
    }
  }
  result.reverse.mkString("")
}
// test
val text = "TOBEORNOTTOBEORTOBEORNOT"
val compressed = compress(text)
println(compressed)
val result = decompress(compressed)
println(result)


; Get the list reference number for a member or #f if not found
(define (member-string-ref m l)
  (define r #f)
  (let loop ((i 0))
    (if (< i (length l))
        (if (not (string=? (list-ref l i) m))
            (loop (+ i 1))
            (set! r i))))
  r)

;; Compress a string with LZW
(define (lzw-compress uncompressed)
  (define dictionary '())
  (define n 0)
  (define result '())
  (set! uncompressed (string->list uncompressed))

  ;; Setup Dictionary
  (let dict-setup ((c 0))
    (if (> 256 c)
        (begin
          (set! dictionary (append dictionary
                                   (list (string (integer->char c)))))
          (set! n (+ n 1))
          (dict-setup (+ c 1)))))

  ;; Compress the string
  (let compress ((w "") (ci 0))
    (define c (string (list-ref uncompressed ci)))
    (define wc "")
    (set! wc (string-append w c))
    (if (member-string-ref wc dictionary)
        (set! w wc)
        (begin
          (set! result (append result
                               (list (member-string-ref w dictionary))))
          (set! dictionary (append dictionary (list wc)))
          (set! n (+ n 1))
          (set! w c)))
    (if (eqv? ci (- (length uncompressed) 1))
        (set! result (append result
                             (list (member-string-ref w dictionary))))
        (compress w (+ ci 1))))
  result)

;; Decompress a LZW compressed string (input should be a list of integers)
(define (lzw-decompress compressed)
  (define dictionary '())
  (define n 0)
  (define result "")

  ;; Setup Dictionary
  (let dict-setup ((c 0))
    (if (> 256 c)
        (begin
          (set! dictionary (append dictionary
                                   (list (string (integer->char c)))))
          (set! n (+ n 1))
          (dict-setup (+ c 1)))))

  ;; Decompress the list
  (let decompress ((k (list-ref compressed 0)) (ci 0))
    (define kn #f)
    ;; Add to dictionary
    (if (> (length compressed) (+ ci 1))
        (begin
          (set! kn (list-ref compressed (+ ci 1)))
          (if (< kn (length dictionary))
              (set! dictionary
                    (append dictionary
                            (list (string-append
           (list-ref dictionary k)
           (string (string-ref (list-ref dictionary kn) 0)))))))))

    ;; Build the resulting string
    (set! result (string-append result (list-ref dictionary k)))

    (if (not (eqv? ci (- (length compressed) 1)))
        (decompress kn (+ ci 1))))
  result)

(define compressed (lzw-compress "TOBEORNOTTOBEORTOBEORNOT"))
(display compressed) (newline)
(define decompressed (lzw-decompress compressed))
(display decompressed) (newline)


program mandelbrot;

  {$IFDEF FPC}
      {$MODE DELPHI}
  {$ENDIF}

const
   ixmax = 800;
   iymax = 800;
   cxmin = -2.5;
   cxmax =  1.5;
   cymin = -2.0;
   cymax =  2.0;
   maxcolorcomponentvalue = 255;
   maxiteration = 200;
   escaperadius = 2;

type
   colortype = record
      red   : byte;
      green : byte;
      blue  : byte;
   end;

var
   ix, iy      : integer;
   cx, cy      : real;
   pixelwidth  : real = (cxmax - cxmin) / ixmax;
   pixelheight : real = (cymax - cymin) / iymax;
   filename    : string = 'new1.ppm';
   comment     : string = '# ';
   outfile     : textfile;
   color       : colortype;
   zx, zy      : real;
   zx2, zy2    : real;
   iteration   : integer;
   er2         : real = (escaperadius * escaperadius);

begin
   {$I-}
   assign(outfile, filename);
   rewrite(outfile);
   if ioresult <> 0 then
   begin
      {$IFDEF FPC}
         writeln(stderr, 'Unable to open output file: ', filename);
      {$ELSE}
         writeln('ERROR: Unable to open output file: ', filename);
      {$ENDIF}
      exit;
   end;

   writeln(outfile, 'P6');
   writeln(outfile, ' ', comment);
   writeln(outfile, ' ', ixmax);
   writeln(outfile, ' ', iymax);
   writeln(outfile, ' ', maxcolorcomponentvalue);

   for iy := 1 to iymax do
   begin
      cy := cymin + (iy - 1)*pixelheight;
      if abs(cy) < pixelheight / 2 then cy := 0.0;
      for ix := 1 to ixmax do
      begin
         cx := cxmin + (ix - 1)*pixelwidth;
         zx := 0.0;
         zy := 0.0;
         zx2 := zx*zx;
         zy2 := zy*zy;
         iteration := 0;
         while (iteration < maxiteration) and (zx2 + zy2 < er2) do
         begin
            zy := 2*zx*zy + cy;
            zx := zx2 - zy2 + cx;
            zx2 := zx*zx;
            zy2 := zy*zy;
            iteration := iteration + 1;
         end;
         if iteration = maxiteration then
         begin
            color.red   := 0;
            color.green := 0;
            color.blue  := 0;
         end
         else
         begin
            color.red   := 255;
            color.green := 255;
            color.blue  := 255;
         end;
         write(outfile, chr(color.red), chr(color.green), chr(color.blue));
      end;
   end;

   close(outfile);
end.


F rev(n)
   R BigInt(reversed(String(n)))

[BigInt = (Bool, BigInt)] cache

F lychrel(BigInt =n)
   I n C :cache
      R :cache[n]

   V r = rev(n)
   V res = (1B, n)
   [BigInt] seen
   L(i) 1000
      n += r
      r = rev(n)
      I n == r
         res = (0B, BigInt(0))
         L.break
      I n C :cache
         res = :cache[n]
         L.break
      seen [+]= n

   L(x) seen
      :cache[x] = res
   R res

[Int] seeds, related, palin

L(i) 1..9999
   V tf_s = lychrel(i)
   I !tf_s[0]
      L.continue
   I BigInt(i) == tf_s[1]
      seeds [+]= i
   E
      related [+]= i
   I BigInt(i) == rev(i)
      palin [+]= i

print(seeds.len‘ Lychrel seeds: ’seeds)
print(related.len‘ Lychrel related’)
print(palin.len‘ Lychrel palindromes: ’palin)


$ include "seed7_05.s7i";

const func string: lzwCompress (in string: uncompressed) is func
  result
    var string: compressed is "";
  local
    var char: ch is ' ';
    var hash [string] char: mydict is (hash [string] char).value;
    var string: buffer is "";
    var string: xstr is "";
  begin
    for ch range chr(0) to chr(255) do
      mydict @:= [str(ch)] ch;
    end for;
    for ch range uncompressed do
      xstr := buffer & str(ch);
      if xstr in mydict then
        buffer &:= str(ch)
      else
        compressed &:= str(mydict[buffer]);
        mydict @:= [xstr] chr(length(mydict));
        buffer := str(ch);
      end if;
    end for;
    if buffer <> "" then
      compressed &:= str(mydict[buffer]);
    end if;
  end func;

const func string: lzwDecompress (in string: compressed) is func
  result
    var string: uncompressed is "";
  local
    var char: ch is ' ';
    var hash [char] string: mydict is (hash [char] string).value;
    var string: buffer is "";
    var string: current is "";
    var string: chain is "";
  begin
    for ch range chr(0) to chr(255) do
      mydict @:= [ch] str(ch);
    end for;
    for ch range compressed do
      if buffer = "" then
        buffer := mydict[ch];
        uncompressed &:= buffer;
      elsif ch <= chr(255) then
        current := mydict[ch];
        uncompressed &:= current;
        chain := buffer & current;
        mydict @:= [chr(length(mydict))] chain;
        buffer := current;
      else
        if ch in mydict then
          chain := mydict[ch];
        else
          chain := buffer & str(buffer[1]);
        end if;
        uncompressed &:= chain;
        mydict @:= [chr(length(mydict))] buffer & str(chain[1]);
        buffer := chain;
      end if;
    end for;
  end func;

const proc: main is func
  local
    var string: compressed is "";
    var string: uncompressed is "";
  begin
    compressed := lzwCompress("TOBEORNOTTOBEORTOBEORNOT");
    writeln(literal(compressed));
    uncompressed := lzwDecompress(compressed);
    writeln(uncompressed);
  end func;


# Compress a string to a list of output symbols.
func compress(String uncompressed) -> Array {

    # Build the dictionary.
    var dict_size = 256
    var dictionary = Hash()

    for i in range(dict_size) {
        dictionary{i.chr} = i.chr
    }

    var w = ''
    var result = []
    uncompressed.each { |c|
        var wc = w+c
        if (dictionary.exists(wc)) {
            w = wc
        } else {
            result << dictionary{w}
            # Add wc to the dictionary.
            dictionary{wc} = dict_size
            dict_size++
            w = c
        }
    }

    # Output the code for w.
    if (w != '') {
        result << dictionary{w}
    }

    return result
}

# Decompress a list of output ks to a string.
func decompress(Array compressed) -> String {

    # Build the dictionary.
    var dict_size = 256
    var dictionary = Hash()

    for i in range(dict_size) {
        dictionary{i.chr} = i.chr
    }

    var w = compressed.shift
    var result = w
    compressed.each { |k|
        var entry = nil
        if (dictionary.exists(k)) {
            entry = dictionary{k}
        } elsif (k == dict_size) {
            entry = w+w.first
        } else {
            die "Bad compressed k: #{k}"
        }
        result += entry

        # Add w+entry[0] to the dictionary.
        dictionary{dict_size} = w+entry.first
        dict_size++

        w = entry
    }
    return result
}

# How to use:
var compressed = compress('TOBEORNOTTOBEORTOBEORNOT')
say compressed.join(' ')
var decompressed = decompress(compressed)
say decompressed


PR read "aArray.a68" PR

# number of additions to attempt before deciding the number is Lychrel #
INT max additions = 500;

# buffer to hold number during testing                                 #
# addition of two equal sized numbers can produce a number of at most  #
# one additional digit, so for 500 additions of numbers up to 10 000   #
# we need a bit over 500 digits...                                     #
[ 512 ]CHAR number;
FOR c TO UPB number DO number[ c ] := "0" OD;
# count of used digits in number                                       #
INT digits := 0;

# sets the number buffer to the specified positive value               #
PROC set number = ( INT value )VOID:
    BEGIN
        digits := 0;
        INT v  := ABS value;
        WHILE digits +:= 1;
              number[ digits ] := REPR ( ABS "0" + v MOD 10 );
              v OVERAB 10;
              v > 0
        DO SKIP OD
     END # set number # ;

# adds the reverse of number to itself                                 #
PROC add reverse = VOID:
     BEGIN
        [ digits + 1 ]CHAR result;
        INT carry := 0;
        INT r pos := digits;
        FOR d pos TO digits DO
            INT sum = ( ( ABS number[ d pos ] + ABS number[ r pos ] + carry )
                      - ( 2 * ABS "0" )
                      );
            IF sum < 10 THEN
                # no carry required                                    #
                result[ d pos ] := REPR( sum + ABS "0" );
                carry           := 0
            ELSE
                # need to carry                                        #
                result[ d pos ] := REPR ( ( sum - 10 ) + ABS "0" );
                carry           := 1
            FI;
            r pos -:= 1
        OD;
        IF carry /= 0 THEN
            # need another digit                                       #
            digits +:= 1;
            result[ digits ] := REPR ( ABS "0" + carry )
        FI;
        number[ : digits ] := result[ : digits ]
     END # add reverse # ;

# returns TRUE if number is a palindrome, FALSE otherwise              #
PROC is palindromic = BOOL:
     BEGIN
        BOOL result := TRUE;
        INT d pos := 1;
        INT r pos := digits;
        WHILE IF   d pos >= r pos
              THEN FALSE
              ELSE result := ( number[ d pos ] = number[ r pos ] )
              FI
        DO
            d pos +:= 1;
            r pos -:= 1
        OD;
        result
     END # is palindromic # ;

# associative array of numbers that are not palindromic after 500      #
# iterations                                                           #
REF AARRAY related := INIT HEAP AARRAY;

# adds the elements of the specified path to the related numbers       #
PROC add related numbers = ( REF AARRAY path )VOID:
     BEGIN
        REF AAELEMENT r := FIRST path;
        WHILE r ISNT nil element DO
            related // key OF r := "Y";
            r := NEXT path
        OD
     END # add related numbers # ;

# Lychrel number results                                               #
# lychrel[n] is:                                                       #
#    not lychrel      if n becomes palidromic before 500 additions     #
#    lychrel seed     if n is a seed lychrel number                    #
#    lychrel related  if n is a related lychrel number                 #
#    untested         if n hasn't been tested yet                      #
INT not lychrel      = 0;
INT lychrel seed     = 1;
INT lychrel related  = 2;
INT untested         = 3;
INT max number = 10 000;
[ max number ]INT lychrel;
FOR n TO UPB lychrel DO lychrel[ n ] := untested OD;
[ UPB lychrel ]BOOL palindromic;
FOR n TO UPB palindromic DO palindromic[ n ] := FALSE OD;
INT seed count       := 0;
INT related count    := 0;
INT palindrome count := 0;

# set the lychrel array to the values listed above                     #
FOR n TO UPB lychrel DO
    # classify this number                                             #
    set number( n );
    palindromic[ n ] := is palindromic;
    add reverse;
    REF AARRAY path  := INIT HEAP AARRAY;
    BOOL continue searching := TRUE;
    TO max additions WHILE continue searching :=
                     IF related CONTAINSKEY number[ : digits ] THEN
                         # this number is already known to be lychrel  #
                         lychrel[ n ] := lychrel related;
                         add related numbers( path );
                         related count +:= 1;
                         FALSE
                     ELIF is palindromic THEN
                         # have reached a palindrome                   #
                         lychrel[ n ] := not lychrel;
                         FALSE
                     ELSE
                         # not palindromic - try another iteration     #
                         path // number[ : digits ] := "Y";
                         add reverse;
                         TRUE
                     FI
    DO SKIP OD;
    IF continue searching THEN
        # we have a lychrel seed                                       #
        add related numbers( path );
        lychrel[ n ] := lychrel seed;
        seed count  +:= 1
    FI;
    IF palindromic[ n ] AND ( lychrel[ n ] = lychrel seed OR lychrel[ n ] = lychrel related ) THEN
        # have a palindromic related or seed lychrel number            #
        palindrome count +:= 1
    FI
OD;

# print the lychrel numbers up to max number                           #
print( ( "There are "
       , whole( seed count,    0 ), " seed Lychrel numbers and "
       , whole( related count, 0 ), " related Lychrel numbers up to "
       , whole( UPB lychrel,   0 )
       , newline
       )
     );
# shpw the seeds                                                       #
print( ( "Seed Lychrel numbers up to ", whole( UPB lychrel, 0 ), ":" ) );
FOR n TO UPB lychrel DO IF lychrel[ n ] = lychrel seed THEN print( ( " ", whole( n, 0 ) ) ) FI OD;
print( ( newline ) );
# show the Lychrel numbers that are palindromic                        #
print( ( "There are "
       , whole( palindrome count, 0 )
       , " palindromic Lychrel numbers up to "
       , whole( UPB lychrel, 0 )
       , ":"
       )
     );
FOR n TO UPB lychrel DO
    IF ( lychrel[ n ] = lychrel seed OR lychrel[ n ] = lychrel related ) AND palindromic[ n ] THEN print( ( " ", whole( n, 0 ) ) ) FI
OD;
print( ( newline ) )


class LZW {
    class func compress(_ uncompressed:String) -> [Int] {
        var dict = [String : Int]()

        for i in 0 ..< 256 {
            let s = String(Unicode.Scalar(UInt8(i)))
            dict[s] = i
        }

        var dictSize = 256
        var w = ""
        var result = [Int]()
        for c in uncompressed {
            let wc = w + String(c)
            if dict[wc] != nil {
                w = wc
            } else {
                result.append(dict[w]!)
                dict[wc] = dictSize
                dictSize += 1
                w = String(c)
            }
        }

        if w != "" {
            result.append(dict[w]!)
        }
        return result
    }

    class func decompress(_ compressed:[Int]) -> String? {
        var dict = [Int : String]()

        for i in 0 ..< 256 {
            dict[i] = String(Unicode.Scalar(UInt8(i)))
        }

        var dictSize = 256
        var w = String(Unicode.Scalar(UInt8(compressed[0])))
        var result = w
        for k in compressed[1 ..< compressed.count] {
            let entry : String
            if let x = dict[k] {
                entry = x
            } else if k == dictSize {
                entry = w + String(w[w.startIndex])
            } else {
                return nil
            }

            result += entry
            dict[dictSize] = w + String(entry[entry.startIndex])
            dictSize += 1
            w = entry
        }
        return result
    }
}

let comp = LZW.compress("TOBEORNOTTOBEORTOBEORNOT")
print(comp)

if let decomp = LZW.decompress(comp) {
    print(decomp)
}


namespace eval LZW {
    variable char2int
    variable chars
    for {set i 0} {$i < 256} {incr i} {
        set char [binary format c $i]
        set char2int($char) $i
        lappend chars $char
    }
}

proc LZW::encode {data} {
    variable char2int
    array set dict [array get char2int]

    set w ""
    set result [list]

    foreach c [split $data ""] {
        set wc $w$c
        if {[info exists dict($wc)]} {
            set w $wc
        } else {
            lappend result $dict($w)
            set dict($wc) [array size dict]
            set w $c
        }
    }
    lappend result $dict($w)
}

proc LZW::decode {cdata} {
    variable chars
    set dict $chars

    set k [lindex $cdata 0]
    set w [lindex $dict $k]
    set result $w

    foreach k [lrange $cdata 1 end] {
        set currSizeDict [llength $dict]
        if {$k < $currSizeDict} {
            set entry [lindex $dict $k]
        } elseif {$k == $currSizeDict} {
            set entry $w[string index $w 0]
        } else {
            error "invalid code ($k) in ($cdata)"
        }
        append result $entry
        lappend dict $w[string index $entry 0]
        set w $entry
    }
    return $result
}

set s TOBEORNOTTOBEORTOBEORNOT#
set e [LZW::encode $s] ;# ==> 84 79 66 69 79 82 78 79 84 256 258 260 265 259 261 263 35
set d [LZW::decode $e] ;# ==> TOBEORNOTTOBEORTOBEORNOT#

# or
if {$s eq [LZW::decode [LZW::encode $s]]} then {puts success} else {puts fail} ;# ==> success


--
-- Mandlebrot set in ascii art demo.
--
constant b=" .:,;!/>)|&IH%*#"
atom r, i, c, C, z, Z, t, k
    for y=30 to 0 by -1 do
        C = y*0.1-1.5
        puts(1,'\n')
        for x=0 to 74 do
            c = x*0.04-2
            z = 0
            Z = 0
            r = c
            i = C
            k = 0
            while k<112 do
                t = z*z-Z*Z+r
                Z = 2*z*Z+i
                z = t
                if z*z+Z*Z>10 then exit end if
                k += 1
            end while
            puts(1,b[remainder(k,16)+1])
        end for
    end for


$min_x=-2;
$max_x=1;
$min_y=-1;
$max_y=1;

$dim_x=400;
$dim_y=300;

$im = @imagecreate($dim_x, $dim_y)
  or die("Cannot Initialize new GD image stream");
header("Content-Type: image/png");
$black_color = imagecolorallocate($im, 0, 0, 0);
$white_color = imagecolorallocate($im, 255, 255, 255);

for($y=0;$y<=$dim_y;$y++) {
  for($x=0;$x<=$dim_x;$x++) {
    $c1=$min_x+($max_x-$min_x)/$dim_x*$x;
    $c2=$min_y+($max_y-$min_y)/$dim_y*$y;

    $z1=0;
    $z2=0;

    for($i=0;$i<100;$i++) {
      $new1=$z1*$z1-$z2*$z2+$c1;
      $new2=2*$z1*$z2+$c2;
      $z1=$new1;
      $z2=$new2;
      if($z1*$z1+$z2*$z2>=4) {
        break;
      }
    }
    if($i<100) {
      imagesetpixel ($im, $x, $y, $white_color);
    }
  }
}

imagepng($im);
imagedestroy($im);


on Lychrels(numberLimit, iterationLimit)
    script o
        property digits : missing value -- Digits of the current startNumber or a derived sum.
        property stigid : missing value -- Reverse thereof.
        property digitLists : missing value -- Copies of the digit lists in the current sequence.
        -- The digit lists from earlier Lychrel sequences, grouped into 1000 sublists
        -- indexed by their last three digits (+ 1) to speed up searches for them.
        property earlierDigitLists : listOfLists(1000)
        property subgroup : missing value -- Sublist picked from earlierDigitLists.
        -- Lychrel output.
        property seeds : {}
        property relateds : {}
        property palindromics : {}

        -- Subhandler: Has the current list of digits come up in the sequence for an earlier Lychrel?
        on isRelated()
            -- Unless it only has one digit, look for it in the appropriate subgroup of earlierDigitLists.
            set digitCount to (count my digits)
            if (digitCount > 1) then
                set i to (item -2 of my digits) * 10 + (end of my digits) + 1
                if (digitCount > 2) then set i to i + (item -3 of my digits) * 100
                set subgroup to item i of my earlierDigitLists
                -- It's faster to test this using a repeat than with 'is in'!
                repeat with i from 1 to (count my subgroup)
                    if (item i of my subgroup = digits) then return true
                end repeat
            end if
            return false
        end isRelated
    end script

    repeat with startNumber from 1 to numberLimit
        -- Get the number's digits and their reverse.
        set o's digits to {}
        set temp to startNumber
        repeat until (temp = 0)
            set beginning of o's digits to temp mod 10
            set temp to temp div 10
        end repeat
        set o's stigid to reverse of o's digits
        -- Note if the number itself is palindromic.
        set startNumberIsPalindrome to (o's digits = o's stigid)

        if (o's isRelated()) then
            -- It(s digits) occurred in the sequence for an earlier Lychrel, so it's a related Lychrel.
            set end of o's relateds to startNumber
        else
            -- Otherwise run its sequence.
            set o's digitLists to {}
            set digitCount to (count o's digits)

            -- Sequence loop.
            repeat iterationLimit times
                -- Add the reversed digits to those of the current number.
                set carry to 0
                repeat with i from digitCount to 1 by -1
                    set d to (item i of o's digits) + (item i of o's stigid) + carry
                    set item i of o's digits to d mod 10
                    set carry to d div 10
                end repeat
                if (carry > 0) then
                    set beginning of o's digits to carry
                    set digitCount to digitCount + 1
                end if

                -- If the sum's digits are palindromic, the start number's not a Lychrel.
                set o's stigid to reverse of o's digits
                set sumIsPalindrome to (o's digits = o's stigid)
                if (sumIsPalindrome) then exit repeat
                -- Otherwise, if the digits occurred in an earlier Lychrel sequence, the start number's a related Lychrel.
                set startNumberIsRelated to (o's isRelated())
                if (startNumberIsRelated) then
                    set sumIsPalindrome to false
                    exit repeat
                end if
                -- Otherwise keep a copy of the digits and go for the next number in the sequence.
                copy o's digits to end of o's digitLists
            end repeat

            if (not sumIsPalindrome) then
                -- No palindrome other than the start number occurred in the sequence,
                -- so the number's a Lychrel. Store it as the relevant type.
                if (startNumberIsRelated) then
                    set end of o's relateds to startNumber
                else
                    set end of o's seeds to startNumber
                end if
                if (startNumberIsPalindrome) then set end of o's palindromics to startNumber
                -- Store this sequence's digit lists based on their last three digits. There won't be any
                -- single-digit lists (they're palindromes), but there may be some with only two digits.
                repeat with thisList in o's digitLists
                    set i to (item -2 of thisList) * 10 + (end of thisList) + 1
                    set digitCount to (count thisList)
                    if (digitCount > 2) then set i to i + (item -3 of thisList) * 100
                    set end of item i of o's earlierDigitLists to thisList's contents
                end repeat
            end if
        end if
    end repeat

    return {seeds:o's seeds, relateds:o's relateds, palindromics:o's palindromics}
end Lychrels

on listOfLists(len)
    script o
        property lst : {}
    end script
    repeat len times
        set end of o's lst to {}
    end repeat
    return o's lst
end listOfLists

on join(lst, delim)
    set astid to AppleScript's text item delimiters
    set AppleScript's text item delimiters to delim
    set txt to lst as text
    set AppleScript's text item delimiters to astid
    return txt
end join

on task()
    set numberLimit to 10000
    set iterationLimit to 500
    set {seeds:seeds, relateds:relateds, palindromics:palindromics} to Lychrels(numberLimit, iterationLimit)
    set output to {"Lychrel numbers between 1 and " & numberLimit & ":", ""}
    set end of output to ((count seeds) as text) & " seed Lychrels: " & join(seeds, ", ")
    set end of output to ((count relateds) as text) & " related Lychrels"
    set end of output to ((count palindromics) as text) & " palindromic Lychrels: " & join(palindromics, ", ")
    return join(output, linefeed)
end task

task()


class LZW {
    /* Compress a string to a list of output symbols. */
    static compress(uncompressed) {
        // Build the dictionary.
        var dictSize = 256
        var dictionary = {}
        for (i in 0...dictSize) dictionary[String.fromByte(i)] = i
        var w = ""
        var result = []
        for (c in uncompressed.bytes) {
            var cs = String.fromByte(c)
            var wc = w + cs
            if (dictionary.containsKey(wc)) {
                w = wc
            } else {
                result.add(dictionary[w])
                // Add wc to the dictionary.
                dictionary[wc] = dictSize
                dictSize = dictSize + 1
                w = cs
            }
        }

        // Output the code for w
        if (w != "") result.add(dictionary[w])
        return result
    }

    /* Decompress a list of output symbols to a string. */
    static decompress(compressed) {
        // Build the dictionary.
        var dictSize = 256
        var dictionary = {}
        for (i in 0...dictSize) dictionary[i] = String.fromByte(i)
        var w = String.fromByte(compressed[0])
        var result = w
        for (k in compressed.skip(1)) {
            var entry
            if (dictionary.containsKey(k)) {
                entry = dictionary[k]
            } else if (k == dictSize) {
                entry = w + String.fromByte(w.bytes[0])
            } else {
                Fiber.abort("Bad compressed k: %(k)")
            }
            result = result + entry

            // Add w + entry[0] to the dictionary.
            dictionary[dictSize] = w + String.fromByte(entry.bytes[0])
            dictSize = dictSize + 1
            w = entry
        }
        return result
    }
}

var compressed = LZW.compress("TOBEORNOTTOBEORTOBEORNOT")
System.print(compressed)
var decompressed = LZW.decompress(compressed)
System.print(decompressed)


go =>

   Width = 90,
   Height = 50,
   Limit = 50,
   foreach(Y in 1..Height)
      P="",
      foreach (X in 1..Width)
         Z=complex(0,0),
         C=complex(2.5*X/Width-2.0,2.0*Y/Height-1.0),
         J = 0,
         while (J < Limit, c_abs(Z)<2.0)
            Z := c_add(c_mul(Z,Z),C),
            J := J + 1
         end,
         if J == Limit then
             P := P ++ "#"
         else
             P := P ++ "."
         end
      end,
      printf("%s\n", P)
  end,
  nl.

% Operations on complex numbers
complex(R,I) = [R,I].
c_add(X,Y) = complex(X[1]+Y[1],X[2]+Y[2]).
c_mul(X,Y) = complex(X[1]*Y[1]-X[2]*Y[2],X[1]*Y[2]+X[2]*Y[1]).
c_abs(X) = sqrt(X[1]*X[1]+X[2]*X[2]).


' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '
' Lychrel Numbers V1.0                              '
'                                                   '
' Developed by A. David Garza Marín in QB64 for     '
' RosettaCode. December 2, 2016.                    '
' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' ' '

OPTION _EXPLICIT  ' Change to OPTION EXPLICIT in VB-DOS or PDS 7.1. Remove in QB and QBASIC

' SUBs and FUNCTIONs
DECLARE SUB doAddLychrel (WhichNumber AS LONG)
DECLARE SUB doAddRelated (WhichNumber AS LONG)
DECLARE SUB doFindLychrelPalyndromes ()
DECLARE FUNCTION CalculateMaxRes& (WhichNumber AS LONG)
DECLARE FUNCTION IsLychrel% (WhichNumber AS LONG)
DECLARE FUNCTION Reverse$ (WhatToReverse AS STRING)
DECLARE FUNCTION Sum$ (N1 AS STRING, N2 AS STRING)

' Var
DIM sN1 AS STRING, sN2 AS STRING, sLychrel AS STRING
DIM i AS LONG, iLychrel AS INTEGER, iCount AS INTEGER, l AS INTEGER
DIM c1 AS INTEGER, l1 AS INTEGER, c2 AS INTEGER, l2 AS INTEGER
DIM lMC AS LONG, lT AS LONG
DIM lLC AS LONG, lRL AS LONG, lPN AS LONG
CONST MaxNumbers = 10000, MaxIterations = 500, False = 0, True = NOT False

' Init
REDIM lLC(1, 0) AS LONG, lRL(0) AS LONG, lPN(0) AS LONG
lMC = CalculateMaxRes&(MaxNumbers)
lT = TIMER

' ------------------ Main program -----------------------------------------
CLS
PRINT "Lychrel Numbers 1.0"
PRINT
PRINT "Calculating numbers from 1 to"; MaxNumbers;
c1 = POS(1)
l1 = CSRLIN
COLOR 7 + 16: PRINT "...": PRINT
COLOR 7
c2 = POS(1)
l2 = CSRLIN
FOR i = 1 TO MaxNumbers
  sN1 = LTRIM$(STR$(i))
  sN2 = Reverse$(sN1)
  iCount = 0
  LOCATE l2, 1: PRINT "Analyzing number"; i;
  COLOR 7 + 16: PRINT "...": COLOR 7
  DO
    iCount = iCount + 1
    sN1 = Sum$(sN1, sN2)
    sN2 = Reverse$(sN1)
  LOOP UNTIL iCount >= MaxIterations OR sN1 = sN2

  IF sN1 <> sN2 THEN
    IF IsLychrel%(i) THEN
      doAddLychrel i
    ELSE
      doAddRelated i
    END IF
    PRINT "Potential Lychrel numbers:"; UBOUND(lLC, 2); "{";
    FOR l = 1 TO UBOUND(lLC, 2)
      PRINT lLC(1, l);
    NEXT
    PRINT "}"

    IF UBOUND(lRL) > 0 THEN
      PRINT "Kin Lychrel numbers found:"; UBOUND(lRL)
    END IF
  END IF
NEXT i

' Look for palyndromes
IF UBOUND(lLC, 2) > 0 THEN
  doFindLychrelPalyndromes
END IF

' Shows the results
CLS
PRINT "Lychrel numbers 1.0 in QB64"
PRINT
PRINT "Lychrel numbers found: "; UBOUND(lLC, 2)
PRINT "Lychrel numbers: {";
FOR i = 1 TO UBOUND(lLC, 2)
  PRINT lLC(1, i);
NEXT
PRINT "}"
PRINT
PRINT "Kin numbers found: "; UBOUND(lRL)
' You can uncomment the following lines if you want to see the
'   Kin or Related numbers found.
'PRINT "Kin numbers: {";
'FOR i = 1 TO UBOUND(lRL)
'  PRINT lRL(i);
'NEXT i
'PRINT "}"
PRINT
PRINT "Palyndrome Lychrel numbers found:"; UBOUND(lPN); "{";
FOR i = 1 TO UBOUND(lPN)
  PRINT lPN(i);
NEXT i
PRINT "}"
lT = TIMER - lT
PRINT
PRINT USING "Calculation took ##:## seconds."; FIX(lT / 60), (lT MOD 60)
PRINT "End of program."
' ------------------ End of Main program --------------------------------------
END

FUNCTION CalculateMaxRes& (WhichNumber AS LONG)
  ' Var
  IF (WhichNumber MOD 10) <> 0 THEN
    CalculateMaxRes& = WhichNumber + VAL(Reverse$(LTRIM$(STR$(WhichNumber))))
  ELSE
    CalculateMaxRes& = (WhichNumber - 1) + VAL(Reverse$(LTRIM$(STR$(WhichNumber - 1))))
  END IF
END FUNCTION

SUB doAddLychrel (WhichNumber AS LONG)
  ' Var
  DIM iMaxC AS INTEGER, iMaxR AS INTEGER
  DIM lRes AS LONG, iRow AS INTEGER
  DIM sN1 AS STRING, sN2 AS STRING
  DIM lNum(1 TO 10) AS LONG
  SHARED lLC() AS LONG, lMC AS LONG

  '
  lNum(1) = WhichNumber
  iRow = 1
  iMaxR = 10
  lRes = WhichNumber
  DO
    iRow = iRow + 1
    IF iRow > iMaxR THEN
      ' Change to REDIM PRESERVE for VB-DOS, QB, QBASIC and PDS 7.1
	  REDIM _PRESERVE lNum(1 TO iMaxR + 10) AS LONG
    END IF
    sN1 = LTRIM$(STR$(lRes))
    sN2 = Reverse$(sN1)
    lRes = VAL(Sum$(sN1, sN2))
    lNum(iRow) = lRes
  LOOP UNTIL lRes > lMC

  ' Change to REDIM PRESERVE for VB-DOS, QB, QBASIC and PDS 7.1
  REDIM _PRESERVE lNum(1 TO iRow) AS LONG

  ' Now, Gathers the size of the lLC table
  iMaxC = UBOUND(lLC, 2) + 1
  IF iMaxC = 1 THEN
    ERASE lLC
    iMaxR = iRow
  ELSE
    iMaxR = UBOUND(lLC, 1)
  END IF

  IF iMaxC = 1 THEN
    REDIM lLC(1 TO iMaxR, 1 TO iMaxC) AS LONG
  ELSE
    ' Change to REDIM PRESERVE for VB-DOS, QB, QBASIC and PDS 7.1
	REDIM _PRESERVE lLC(1 TO iMaxR, 1 TO iMaxC) AS LONG
  END IF

  ' Assigns the result to the table
  FOR lRes = 1 TO iRow
    lLC(lRes, iMaxC) = lNum(lRes)
  NEXT lRes

  ERASE lNum
END SUB

SUB doAddRelated (WhichNumber AS LONG)
  ' Var
  DIM iMax AS INTEGER
  SHARED lRL() AS LONG

  iMax = UBOUND(lRL) + 1
  IF iMax = 1 THEN
    ERASE lRL
  END IF
  ' Change to REDIM PRESERVE for VB-DOS, QB, QBASIC and PDS 7.1
  REDIM _PRESERVE lRL(1 TO iMax) AS LONG
  lRL(iMax) = WhichNumber
END SUB

SUB doFindLychrelPalyndromes ()
  ' Var
  DIM iMaxC AS INTEGER, i AS INTEGER, iCount AS INTEGER
  DIM sN1 AS STRING, sN2 AS STRING
  SHARED lLC() AS LONG, lRL() AS LONG, lPN() AS LONG

  ' Verify seeds
  iMaxC = UBOUND(lLC, 2)
  FOR i = 1 TO iMaxC
    IF lLC(1, i) > 0 THEN
      sN1 = LTRIM$(STR$(lLC(1, i)))
      sN2 = Reverse$(sN1)
      IF sN1 = sN2 THEN
        iCount = iCount + 1
        GOSUB AddSpaceForItem
        lPN(iCount) = VAL(sN1)
      END IF
    END IF
  NEXT i

  ' Verify Kins
  iMaxC = UBOUND(lRL)
  FOR i = 1 TO iMaxC
    IF lRL(i) > 0 THEN
      sN1 = LTRIM$(STR$(lRL(i)))
      sN2 = Reverse$(sN1)
      IF sN1 = sN2 THEN
        iCount = iCount + 1
        GOSUB AddSpaceForItem
        lPN(iCount) = VAL(sN1)
      END IF
    END IF
  NEXT i

  ' Change to REDIM PRESERVE for VB-DOS, QB, QBASIC and PDS 7.1
  REDIM _PRESERVE lPN(1 TO iCount) AS LONG

  EXIT SUB

  AddSpaceForItem:
  IF UBOUND(lPN) < iCount THEN
    IF UBOUND(lPN) = 0 THEN
      ERASE lPN
    END IF
    ' Change to REDIM PRESERVE for VB-DOS, QB, QBASIC and PDS 7.1
	REDIM _PRESERVE lPN(1 TO iCount + 9) AS LONG
  END IF
  RETURN

END SUB

FUNCTION IsLychrel% (WhichNumber AS LONG)
  ' Var
  DIM iMaxC AS INTEGER, iMaxR AS INTEGER
  DIM iCol AS INTEGER, iRow AS INTEGER
  DIM lToCompare AS LONG
  DIM YesItIs AS INTEGER
  DIM sN1 AS STRING, sN2 AS STRING
  SHARED lLC() AS LONG, lMC AS LONG

  iMaxC = UBOUND(lLC, 2)
  iMaxR = UBOUND(lLC, 1)
  lToCompare = WhichNumber
  IF iMaxC > 0 THEN
    DO
      sN1 = LTRIM$(STR$(lToCompare))
      sN2 = Reverse$(sN1)
      lToCompare = VAL(Sum$(sN1, sN2))
      iCol = 0
      DO
        iCol = iCol + 1
        iRow = 0
        DO
          iRow = iRow + 1
        LOOP UNTIL iRow = iMaxR OR lToCompare = lLC(iRow, iCol)
      LOOP UNTIL iCol = iMaxC OR lToCompare = lLC(iRow, iCol)
    LOOP UNTIL lToCompare >= lMC OR lToCompare = lLC(iRow, iCol)
    YesItIs = (lToCompare <> lLC(iRow, iCol))
  ELSE
    YesItIs = True
  END IF

  IsLychrel = YesItIs

END FUNCTION

FUNCTION Reverse$ (WhatToReverse AS STRING)
  ' Var
  DIM sChar AS STRING
  DIM sRes AS STRING
  DIM i AS INTEGER, l AS INTEGER

  l = LEN(WhatToReverse)
  sRes = ""
  FOR i = 1 TO l
    sRes = MID$(WhatToReverse, i, 1) + sRes
  NEXT i

  Reverse$ = sRes
END FUNCTION

FUNCTION Sum$ (N1 AS STRING, N2 AS STRING)
  ' Var
  DIM iN1 AS INTEGER, iN2 AS INTEGER, iSum AS INTEGER
  DIM i AS INTEGER, l AS INTEGER, iCarry AS INTEGER, lM AS LONG
  DIM sRes AS STRING

  IF LEN(N1) > LEN(N2) THEN
    l = LEN(N1)
  ELSE
    l = LEN(N2)
  END IF
  lM = 2147483647 / 2

  ' Add trailing zeroes (uncomment in case strings have not equal number of digits)
  ' N1 = STRING$(l - LEN(N1), 48) + N1
  ' N2 = STRING$(l - LEN(N2), 48) + N2

  ' Hace la suma
  IF VAL(N1) < lM THEN
    sRes = LTRIM$(STR$(VAL(N1) + VAL(N2)))
  ELSE

    FOR i = l TO 1 STEP -1
      iN1 = VAL(MID$(N1, i, 1))
      iN2 = VAL(MID$(N2, i, 1))

      iSum = iN1 + iN2 + iCarry

      iCarry = FIX(iSum / 10)
      iSum = iSum MOD 10

      sRes = LTRIM$(STR$(iSum)) + sRes
    NEXT i
    IF iCarry > 0 THEN sRes = LTRIM$(STR$(iCarry)) + sRes
  END IF

  Sum$ = sRes

END FUNCTION


    Function compress(str as String) As String
      Dim i as integer
      Dim w as String = ""
      Dim c as String
      Dim strLen as Integer
      Dim wc as string
      Dim dic() as string
      Dim result() as string
      Dim lookup as integer
      Dim startPos as integer = 0
      Dim combined as String

      strLen = len(str)

      dic = populateDictionary

      for i = 1 to strLen
        c = str.mid(i, 1)
        wc = w + c

        startPos = getStartPos(wc)

        lookup = findArrayPos(dic, wc, startPos)
        if (lookup <> -1) then
          w = wc
        Else
          startPos = getStartPos(w)
          lookup = findArrayPos(dic, w, startPos)
          if lookup <> -1 then
            result.Append(lookup.ToText)
          end if
          dic.append(wc)
          w = c
        end if
      next i

      if (w <> "") then
        startPos = getStartPos(w)
        lookup = findArrayPos(dic, w, startPos)
        result.Append(lookup.ToText)
      end if

      return join(result, ",")
    End Function

    Function decompress(str as string) As string
      dim comStr() as string
      dim w as string
      dim result as string
      dim comStrLen as integer
      dim entry as string
      dim dic() as string
      dim i as integer

      comStr = str.Split(",")
      comStrLen = comStr.Ubound
      dic = populateDictionary

      w = chr(val(comStr(0)))
      result = w
      for i = 1 to comStrLen
        entry = dic(val(comStr(i)))
        result = result + entry
        dic.append(w + entry.mid(1,1))
        w = entry
      next i

      return result
    End Function

    Private Function findArrayPos(arr() as String, search as String, start as integer) As Integer
      dim arraySize as Integer
      dim arrayPosition as Integer = -1
      dim i as Integer

      arraySize = UBound(arr)

      for i = start to arraySize
        if (strcomp(arr(i), search, 0) = 0) then
          arrayPosition = i
          exit
        end if
      next i

      return arrayPosition
    End Function

    Private Function getStartPos(str as String) As integer
      if (len(str) = 1) then
        return 0
      else
        return 255
      end if
    End Function

    Private Function populateDictionary() As string()
      dim dic() as string
      dim i as integer

      for i = 0 to 255
        dic.append(Chr(i))
      next i

      return dic
    End Function


%!PS-Adobe-2.0
%%BoundingBox: 0 0 300 200
%%EndComments
/origstate save def
/ld {load def} bind def
/m /moveto ld /g /setgray ld
/dot { currentpoint 1 0 360 arc fill } bind def
%%EndProlog
% param
/maxiter 200 def
% complex manipulation
/complex { 2 array astore } def
/real { 0 get } def
/imag { 1 get } def
/cmul { /a exch def /b exch def
    a real b real mul
    a imag b imag mul sub
    a real b imag mul
    a imag b real mul add
    2 array astore
} def
/cadd { aload pop 3 -1 roll aload pop
    3 -1 roll add
    3 1 roll add exch 2 array astore
} def
/cconj { aload pop neg 2 array astore } def
/cabs2 { dup cconj cmul 0 get} def
% mandel
200 100 translate
-200 1 100 { /x exch def
  -100 1 100 { /y exch def
    /z0 0.0 0.0 complex def
    0 1 maxiter { /iter exch def
	x 100 div y 100 div complex
	z0 z0 cmul
	cadd dup /z0 exch def
	cabs2 4 gt {exit} if
    } for
    iter maxiter div g
    x y m dot
  } for
} for
%
showpage
origstate restore
%%EOF


#include <iostream>
#include <map>
#include <vector>
#include <gmpxx.h>

using integer = mpz_class;

integer reverse(integer n) {
    integer rev = 0;
    while (n > 0) {
        rev = rev * 10 + (n % 10);
        n /= 10;
    }
    return rev;
}

void print_vector(const std::vector<integer>& vec) {
    if (vec.empty())
        return;
    auto i = vec.begin();
    std::cout << *i++;
    for (; i != vec.end(); ++i)
        std::cout << ", " << *i;
    std::cout << '\n';
}

int main() {
    std::map<integer, std::pair<bool, integer>> cache;
    std::vector<integer> seeds, related, palindromes;
    for (integer n = 1; n <= 10000; ++n) {
        std::pair<bool, integer> p(true, n);
        std::vector<integer> seen;
        integer rev = reverse(n);
        integer sum = n;
        for (int i = 0; i < 500; ++i) {
            sum += rev;
            rev = reverse(sum);
            if (rev == sum) {
                p.first = false;
                p.second = 0;
                break;
            }
            auto iter = cache.find(sum);
            if (iter != cache.end()) {
                p = iter->second;
                break;
            }
            seen.push_back(sum);
        }
        for (integer s : seen)
            cache.emplace(s, p);
        if (!p.first)
            continue;
        if (p.second == n)
            seeds.push_back(n);
        else
            related.push_back(n);
        if (n == reverse(n))
            palindromes.push_back(n);
    }
    std::cout << "number of seeds: " << seeds.size() << '\n';
    std::cout << "seeds: ";
    print_vector(seeds);
    std::cout << "number of related: " << related.size() << '\n';
    std::cout << "palindromes: ";
    print_vector(palindromes);
    return 0;
}


fcn lzwCompress(uncompressed){ // text-->list of 12 bit ints
   dictionary:=(256).pump(Dictionary(),fcn(n){ return(n.toChar(),n) });
   w,compressed:="",List();
   foreach c in (uncompressed){
      wc:=w+c;
      if(dictionary.holds(wc)) w=wc;
      else{
   compressed.append(dictionary[w]);  // 12 bits
   dictionary[wc]=dictionary.len();
   w=c;
      }
   }
   if(w) compressed.append(dictionary[w]);
   compressed
}
fcn lzwUncompress(compressed){ // compressed data-->text
   dictionary:=(256).pump(Dictionary(),fcn(n){ return(n,n.toChar()) });
   w,decommpressed:=dictionary[compressed[0]],Data(Void,w);
   foreach k in (compressed[1,*]){
      if(dictionary.holds(k))      entry:=dictionary[k];
      else if(k==dictionary.len()) entry:=w+w[0];
      else throw(Exception.ValueError("Invalid compressed data"));
      decommpressed.append(entry);
      dictionary.add(dictionary.len(),w+entry[0]);
      w=entry;
   }
   decommpressed.text
}


$x = $y = $i = $j = $r = -16
$colors = [Enum]::GetValues([System.ConsoleColor])

while(($y++) -lt 15)
{
    for($x=0; ($x++) -lt 84; Write-Host " " -BackgroundColor ($colors[$k -band 15]) -NoNewline)
    {
        $i = $k = $r = 0

        do
        {
            $j = $r * $r - $i * $i -2 + $x / 25
            $i = 2 * $r * $i + $y / 10
            $r = $j
        }
        while (($j * $j + $i * $i) -lt 11 -band ($k++) -lt 111)
    }

    Write-Host
}


(ns lychrel.core
  (require [clojure.string :as s])
  (require [clojure.set :as set-op])
  (:gen-class))

(defn palindrome? "Returns true if given number is a palindrome (number on base 10)"
  [number]
  (let [number-str (str number)]
    (= number-str (s/reverse number-str))))

(defn delete-leading-zeros
  "Delete leading zeros so that you can read the string"
  [number-str]
  (read-string (re-find (re-pattern "[1-9]\\d*") number-str))
  )

(defn lychrel "Returns T if number is a candidate Lychrel (up to max iterations), and a second value with the sequence of sums"
  ([number] (lychrel number 500))
  ([number depth]
   (let [next-number (+' number (delete-leading-zeros (s/reverse (str number))))
         depth (- depth 1)]
     (if (palindrome? next-number) (conj [next-number] number)
                                   (if (not= depth 0) (conj (lychrel next-number depth) number) (conj [] nil))
                                   )
     )))

(defn lychrel? "Test if number is a possible lychrel number"
  [number]
  (= nil (first (lychrel number 500))))

(defn lychrel-up-to-n "Get all lychrels up to N"
  [N]
  (filter lychrel? (range 1 N)))

(defn make-kin "Removes the starting number of the list, the starting number"
  [kin]
  (rest (butlast kin)))

(defn calc-seed "The seeding" []
  (let [kin-set (atom #{})
        seed-set (atom #{})]
    (fn [n] (let [lychrel-seed (set #{(last n)})
                  kins (set (butlast n))]
              (if (= kins (clojure.set/difference kins @kin-set))
                (do (swap! kin-set clojure.set/union kins)
                    (swap! seed-set clojure.set/union lychrel-seed)
                    @kin-set))
              @seed-set
              ))))

(defn filter-seeds "Filtering the seed through the paths"
  []
  (let [calc-f (calc-seed)
        all-lychrels (for [lychrel-list (filter lychrel? (range 1 10000))]
                       (filter (fn [x] (> 1000001 x)) (rest (lychrel lychrel-list))))]
    (last (for [ll all-lychrels]
            (do (calc-f ll))))))

(defn -main
  "Here we do the three tasks:
      Get all possible Lychrel numbers up to 10000
      Count them
      Reduce all possible numbers to seed"

  [& args]
  (let [lychrels-n (filter-seeds)
        count-lychrels (count lychrels-n)
        related-n (- (count (filter lychrel? (range 1 10000))) count-lychrels)
        palindrom-n (filter palindrome? (filter lychrel? (range 1 10000)))
        count-palindromes (count palindrom-n)
        ]
    (println count-lychrels "Lychrel seeds:"  lychrels-n)
    (println related-n "Lychrel related.")
    (println count-palindromes "Lychrel palindromes found:" palindrom-n))
  )


double x, y, zr, zi, zr2, zi2, cr, ci, n;
double zmx1, zmx2, zmy1, zmy2, f, di, dj;
double fn1, fn2, fn3, re, gr, bl, xt, yt, i, j;

void setup() {
  size(500, 500);
  di = 0;
  dj = 0;
  f = 10;
  fn1 = random(20);
  fn2 = random(20);
  fn3 = random(20);
  zmx1 = int(width / 4);
  zmx2 = 2;
  zmy1 = int(height / 4);
  zmy2 = 2;
}

void draw() {
  if (i <= width) i++;
  x =  (i +  di)/ zmx1 - zmx2;
  for ( j = 0; j <= height; j++) {
    y = zmy2 - (j + dj) / zmy1;
    zr = 0;
    zi = 0;
    zr2 = 0;
    zi2 = 0;
    cr = x;
    ci = y;
    n = 1;
    while (n < 200 && (zr2 + zi2) < 4) {
      zi2 = zi * zi;
      zr2 = zr * zr;
      zi = 2 * zi * zr + ci;
      zr = zr2 - zi2 + cr;
      n++;
    }
    re = (n * fn1) % 255;
    gr = (n * fn2) % 255;
    bl = (n * fn3) % 255;
    stroke((float)re, (float)gr, (float)bl);
    point((float)i, (float)j);
  }
}

void mousePressed() {
  background(200);
  xt = mouseX;
  yt = mouseY;
  di = di + xt - float(width / 2);
  dj = dj + yt - float(height / 2);
  zmx1 = zmx1 * f;
  zmx2 = zmx2 * (1 / f);
  zmy1 = zmy1 * f;
  zmy2 = zmy2 * (1 / f);
  di = di * f;
  dj = dj * f;
  i = 0;
  j = 0;
}


(defun Lychrel (number &optional (max 500))
 "Returns T if number is a candidate Lychrel (up to max iterations), and a second value with the sequence of sums"
  (do* ((n number (+ n (parse-integer rev-str)))
        (n-str (write-to-string n) (write-to-string n))
        (rev-str (reverse n-str) (reverse n-str))
        (i 0 (1+ i))
        (list (list n) (cons n list)) )
    ((or (> i max) (and (string= n-str rev-str) (> i 0))) (values (not (string= n-str rev-str)) (nreverse list)))))

(defun Lychrel-test (n &optional (max 500))
 "Tests the first n numbers up to max number of iterations"
  (let ((seeds nil)
        (related 0)
        (palyndromes nil) )
    (dotimes (i (1+ n))
      (multiple-value-bind (Lychrel-p seq) (Lychrel i max)
        (when Lychrel-p
          (if (find seq seeds :test #'intersection :key #'cdr)
            (incf related)
            (push (cons i seq) seeds) )
          (when (= i (parse-integer (reverse (write-to-string i))))
            (push i palyndromes) ))))
    (format T "Testing numbers: 1 to ~D~%Iteration maximum: ~D~%~%Number of Lychrel seeds found: ~d => ~a~%~
    Number of related found: ~D~%Palyndrome Lychrel numbers: ~D => ~a~%"
    n max (length seeds) (nreverse (mapcar #'car seeds)) related (length palyndromes) (nreverse palyndromes)) ))


require "set"
require "big"

def add_reverse(num, max_iter=1000)
  num = num.to_big_i
  nums = [] of BigInt
  (1..max_iter).each_with_object(Set.new([num])) do |_, nums|
    num += reverse_int(num)
    nums << num
    return nums if palindrome?(num)
  end
end

def palindrome?(num)
  num == reverse_int(num)
end

def reverse_int(num)
  num.to_s.reverse.to_big_i
end

def split_roots_from_relateds(roots_and_relateds)
  roots = roots_and_relateds.dup
  i = 1
  while i < roots.size
    this = roots[i]
    if roots[0...i].any?{ |prev| this.intersects?(prev) }
      roots.delete_at(i)
    else
      i += 1
    end
  end
  root = roots.map{ |each_set| each_set.min }
  related = roots_and_relateds.map{ |each_set| each_set.min }
  related = related.reject{ |n| root.includes?(n) }
  return root, related
end

def find_lychrel(maxn, max_reversions)
  series = (1..maxn).map{ |n| add_reverse(n, max_reversions*2) }
  roots_and_relateds = series.select{ |s| s.size > max_reversions }
  split_roots_from_relateds(roots_and_relateds)
end

maxn, reversion_limit = 10000, 500
puts "Calculations using n = 1..#{maxn} and limiting each search to 2*#{reversion_limit} reverse-digits-and-adds"
lychrel, l_related = find_lychrel(maxn, reversion_limit)
puts "  Number of Lychrel numbers: #{lychrel.size}"
puts "    Lychrel numbers: #{lychrel}"
puts "  Number of Lychrel related: #{l_related.size}"
pals = (lychrel + l_related).select{|x| palindrome?(x)}.sort
puts "  Number of Lychrel palindromes: #{pals.size}"
puts "    Lychrel palindromes: #{pals}"


:- use_module(library(pce)).

mandelbrot :-
    new(D, window('Mandelbrot Set')),
    send(D, size, size(700, 650)),
    new(Img, image(@nil, width := 700, height := 650, kind := pixmap)),

    forall(between(0,699, I),
           (   forall(between(0,649, J),
              (   get_RGB(I, J, R, G, B),
                  R1 is (R * 256) mod 65536,
                  G1 is (G * 256) mod 65536,
                  B1 is (B * 256) mod 65536,
                  send(Img, pixel(I, J, colour(@default, R1, G1, B1))))))),
    new(Bmp, bitmap(Img)),
    send(D, display, Bmp, point(0,0)),
    send(D, open).

get_RGB(X, Y, R, G, B) :-
    CX is (X - 350) / 150,
    CY is (Y - 325) / 150,
    Iter = 570,
    compute_RGB(CX, CY, 0, 0, Iter, It),
    IterF is It \/ It << 15,
    R is IterF >> 16,
    Iter1 is IterF - R << 16,
    G is Iter1 >> 8,
    B  is Iter1 - G << 8.

compute_RGB(CX, CY, ZX, ZY, Iter, IterF) :-
    ZX * ZX + ZY * ZY < 4,
    Iter > 0,
    !,
    Tmp is  ZX * ZX - ZY * ZY + CX,
    ZY1 is 2 * ZX * ZY + CY,
    Iter1 is Iter - 1,
    compute_RGB(CX, CY, Tmp, ZY1, Iter1, IterF).

compute_RGB(_CX, _CY, _ZX, _ZY, Iter, Iter).


import std.stdio, std.conv, std.range, std.typecons, std.bigInt;

auto rev(in BigInt n) {
    return n.text.retro.text.BigInt;
}

alias Res = Tuple!(bool, BigInt);

Res lychrel(BigInt n) {
    static Res[BigInt] cache;
    if (n in cache)
        return cache[n];

    auto r = n.rev;
    auto res = Res(true, n);
    immutable(BigInt)[] seen;
    foreach (immutable i; 0 .. 1_000) {
        n += r;
        r = n.rev;
        if (n == r) {
            res = Res(false, BigInt(0));
            break;
        }
        if (n in cache) {
            res = cache[n];
            break;
        }
        seen ~= n;
    }

    foreach (x; seen)
        cache[x] = res;
    return res;
}

void main() {
    BigInt[] seeds, related, palin;

    foreach (immutable i; BigInt(1) .. BigInt(10_000)) { // 1_000_000
        const tf_s = i.lychrel;
        if (!tf_s[0])
            continue;
        (i == tf_s[1] ? seeds : related) ~= i;
        if (i == i.rev)
            palin ~= i;
    }

    writeln(seeds.length, " Lychrel seeds: ", seeds);
    writeln(related.length, " Lychrel related");
    writeln(palin.length, " Lychrel palindromes: ", palin);
}


# Python 3.0+ and 2.5+
try:
    from functools import reduce
except:
    pass

def mandelbrot(a):
    return reduce(lambda z, _: z * z + a, range(50), 0)

def step(start, step, iterations):
    return (start + (i * step) for i in range(iterations))

rows = (("*" if abs(mandelbrot(complex(x, y))) < 2 else " "
        for x in step(-2.0, .0315, 80))
        for y in step(1, -.05, 41))

print("\n".join("".join(row) for row in rows))


      SUBROUTINE CROAK(GASP)	!A dying message.
       CHARACTER*(*) GASP	!The message.
        WRITE (6,*) "Oh dear! ",GASP	!The gasp.
        STOP "Alas."		!The death.
      END			!Goodbye, cruel world.

      MODULE LYCHREL SEARCH	!Assistants for the pursuit of Lychrel numbers.
       INTEGER LOTSADIGITS,BASE	!Parameters.
       PARAMETER (LOTSADIGITS = 1000, BASE = 10)	!This should do.
       TYPE BIGINT	!Can't use an element zero as the count, as lots of digits are needed.
        INTEGER LDIGIT	!Count in use.
        INTEGER*1 DIGIT(LOTSADIGITS)	!Stored in increasing powers of BASE.
       END TYPE BIGINT		!No fractional parts.
       INTEGER MSTASH		!Now for my stash.
       PARAMETER (MSTASH = 66666)	!This should be enough.
       TYPE(BIGINT) STASH(MSTASH)	!The work area.
       INTEGER AVAILS(0:MSTASH)		!A list of available STASH entries.
       INTEGER PLIST(0:MSTASH)	!These strings of fingers
       INTEGER LLIST(0:MSTASH)	!Each starting with a count
       INTEGER LYCHREL(0:MSTASH)!Finger BIGINTs in the STASH
       INTEGER L0P(0:MSTASH)	!Without the body of the BIGINT being copied.
       INTEGER LONGESTNUMBER	!Keep track out of curiosity.
       DATA LONGESTNUMBER/0/	!No digits so far.
       CONTAINS		!A miscellany.
Commence with some STASH service. If problems were to arise, better error messages would be in order.
        SUBROUTINE PREPARESTASH	!Since fancy usage is involved, fancy initialisation is needed.
         INTEGER I	!A stepper.
          AVAILS(0) = MSTASH	!All are available.
          FORALL (I = 1:MSTASH) AVAILS(I) = MSTASH + 1 - I	!Will be used stack style.
          STASH.LDIGIT = -666				!This will cause trouble!
        END SUBROUTINE PREPARESTASH	!Simple enough.
        SUBROUTINE GRABSTASH(X)	!Finger an available STASH.
         INTEGER X		!The finger.
         INTEGER L		!The last.
          L = AVAILS(0)		!Pick on the last in the list.
          IF (L .LE. 0) CALL CROAK("Run out of stashes!")	!Hopefully not.
          X = AVAILS(L)		!Select some element or other.
          AVAILS(L) = 0		!Might as well unfinger.
          AVAILS(0) = L - 1	!As well as drop off the list.
        END SUBROUTINE GRABSTASH!Can't be bothered making this a function. Sudden death instead.
        SUBROUTINE FREESTASH(X)	!Unhand a STASH.
         INTEGER X		!The finger.
          IF (X.EQ.0) RETURN	!A non-finger.
          IF (X.LT.0) CALL CROAK("Unhanding a non-stash!")	!Paranoia.
          IF (X.GT.MSTASH) CALL CROAK("Not a stash!")		!I don't expect any of these.
          IF (AVAILS(0).GE.MSTASH) CALL CROAK("Over subscribed!")	!But on principle...
          AVAILS(0) = AVAILS(0) + 1	!So, append to the list of available entries.
          AVAILS(AVAILS(0)) = X		!Thus.
          X = 0				!The finger is amputated.
        END SUBROUTINE FREESTASH	!Last out, first in. Etc.

        SUBROUTINE BIGWRITE(T,N)!Reveal an annotated bignumber.
         CHARACTER*(*) T	!The text of its name.
         TYPE(BIGINT) N		!The value of its name.
          WRITE (6,1) T,N.LDIGIT,N.DIGIT(N.LDIGIT:1:-1)	!Roll!
    1     FORMAT (A,"(1:",I0,") = ",(300I1))	!This should do.
        END SUBROUTINE BIGWRITE	!Perhaps bigger than Integer*8.

        SUBROUTINE SHOWLIST(BLAH,LIST)	!One can become confused.
         INTEGER LIST(0:MSTASH)	!Explicit bounds prevents confusion.
         CHARACTER*(*) BLAH	!An identifying message.
         CHARACTER*4 ZOT	!Scratchpad.
         INTEGER I,IT		!Stepper.
c         REAL*8 V,P		!For logarithmic output.
c         INTEGER J		!Another stepper needed.
          WRITE (6,1) BLAH,LIST(0)		!A heading.
    1     FORMAT ("The count for ",A," is ",I0)	!Ah, layout.
          DO I = 1,LIST(0)		!Work through the list.
            WRITE(ZOT,"('#',I3)") I	!Prepare an annotation.
            IT = LIST(I)		!Finger the stash.
            CALL BIGWRITE(ZOT,STASH(IT))	!Show.
c            V = 0		!Convert the BIGINT to a floating-point number.
c            P = 1		!Tracking the powers of BASE, presumed ten.
c         PP:DO J = STASH(IT).LDIGIT,1,-1	!Start with the highest power.
c              V = V + STASH(IT).DIGIT(J)/P	!Deem it a units digit.
c              P = P*10				!The next digit will have a lesser power.
c              IF (P.GT.1000000) EXIT PP		!This will do.
c            END DO PP				!On to the next digit.
c            V = STASH(IT).LDIGIT - 1 + LOG10(V)	!Convert. LOG10(196) = 2.29225607135648
c            WRITE (6,*) I,V			!Reveal.
          END DO			!On to the next.
        END SUBROUTINE SHOWLIST	!Adrift in indirection.

        SUBROUTINE BIGLOAD(A,NUM)	!Shatters a proper number into its digits.
Can't overflow, because the biggest normal integer has far fewer than LOTSADIGITS digits.
         TYPE(BIGINT) A		!The bignumber.
         INTEGER NUM		!The normal integer to put in it.
         INTEGER L,N		!Assistants.
          N = NUM		!A copy that I can damage.
          A.DIGIT = 0		!Scrub, against a future carry..
          L = 0			!No digits so far.
          DO WHILE(N .GT. 0)	!Some number remaining?
            L = L + 1			!Yes. Count another digit.
            A.DIGIT(L) = MOD(N,BASE)	!Place it.
            N = N/BASE			!Reduce the number.
          END DO		!And try again.
          A.LDIGIT = MAX(1,L)	!Zero will have one digit, a zero.
        END SUBROUTINE BIGLOAD	!A small service.

Continue with routines for doing the work.
        SUBROUTINE ADVANCE(A,B)	!Advance A, giving B.
C Experiment shows that for 196, log10(v) = 0·43328*step + 2·1616, or, each advance increases by a factor of ~2·7.
         TYPE(BIGINT) A,B	!To be twiddled.
         INTEGER D		!An assistant for carrying.
         INTEGER I		!A stepper.
          B.LDIGIT = A.LDIGIT		!Same size, so far.
          FORALL(I = 1:A.LDIGIT)	!Do these in any order, even in parallel!
     1     B.DIGIT(I) = A.DIGIT(I)			!Add each digit
     2                + A.DIGIT(A.LDIGIT - I + 1)	! to its other-end partner.
          B.DIGIT(B.LDIGIT + 1) = 0	!Perhaps another digit will be needed shortly.
          DO I = 1,B.LDIGIT		!Now slow down and taste the carry.
            D = B.DIGIT(I) - BASE	!Allowable digits are 0:BASE - 1.
            IF (D.GE.0) THEN		!So, has this digit overflowed?
              B.DIGIT(I) = D			!Yes. Only addition, so no div and mod stuff.
              B.DIGIT(I + 1) = B.DIGIT(I + 1) + 1	!Carry one up, corresponding to subtracting one BASE down.
            END IF			!So much for that digit.
          END DO		!On to the next digit, of higher power.
          IF (D.GE.0) THEN	!A carry from the highest digit?
            IF (B.LDIGIT .GE. LOTSADIGITS) CALL CROAK("Overflow!")	!Oh dear.
            B.LDIGIT = B.LDIGIT + 1	!NB! Always there is room left for ONE more digit.
            LONGESTNUMBER = MAX(B.LDIGIT,LONGESTNUMBER)	!Perhaps a surprise awaits.
          END IF		!Avoids overflow testing for every carry above.
        END SUBROUTINE ADVANCE	!That was fun!

        LOGICAL FUNCTION PALINDROME(N)	!Perhaps a surprise property?
Calls a one-digit number palindromic through the execution of vacuous logic.
         TYPE(BIGINT) N	!The big number to inspect.
          PALINDROME = ALL(N.DIGIT(1:N.LDIGIT/2)	!Compare each digit in the first half...
     1                 .EQ.N.DIGIT(N.LDIGIT:N.LDIGIT/2 + 1:-1))	!To its opposite digit in the second. Whee!
        END FUNCTION PALINDROME	!If an odd number of digits, ignores the middle digit.

        INTEGER FUNCTION ORDER(A,B)	!Does B follow A?
         TYPE(BIGINT) A,B	!The two numbers.
         INTEGER I		!A stepper.
          IF (A.LDIGIT - B.LDIGIT) 1,10,2	!First, compare the lengths.
    1     ORDER = +1		!B has more digits.
         RETURN			!So, A must be smaller: in order.
    2     ORDER = -1		!A has more digits.
         RETURN			!So B must be smaller: reverse order.
Compare the digits of the two numbers, known to be of equal length.
   10     DO 11 I = A.LDIGIT,1,-1	!The last digit has the highest power.
            IF (A.DIGIT(I) - B.DIGIT(I)) 1,11,2	!Compare the digits.
   11     CONTINUE		!If they match, continue with the next digit.
          ORDER = 0		!If all match, A = B.
        END FUNCTION ORDER	!Ah, three-way tests...

        SUBROUTINE COMBSORT(XNDX)	!Sort according to STASH(XNDX)) by reordering XNDX.
Crank up a Comb sort of array STASH as indexed by XNDX.
         INTEGER XNDX(0:),T	!The index to be rearranged.
         INTEGER I,H		!Tools. H ought not be a small integer.
         LOGICAL CURSE		!Annoyance.
          H = XNDX(0) - 1	!Last - First, and not +1.
          IF (H.LE.0) GO TO 999	!Ha ha.
    1     H = MAX(1,H*10/13)	!The special feature.
          IF (H.EQ.9 .OR. H.EQ.10) H = 11	!A twiddle.
          CURSE = .FALSE.		!So far, so good.
          DO I = XNDX(0) - H,1,-1	!If H = 1, this is a BubbleSort.
            IF (ORDER(STASH(XNDX(I)),STASH(XNDX(I + H))) .LT. 0) THEN	!One compare.
              T=XNDX(I); XNDX(I)=XNDX(I+H); XNDX(I+H)=T		!One swap.
              CURSE = .TRUE.				!One curse.
            END IF				!One test.
          END DO			!One loop.
          IF (CURSE .OR. H.GT.1) GO TO 1!Work remains?
  999    RETURN			!If not, we're done.
        END SUBROUTINE COMBSORT	!Good performance, and simple.

        SUBROUTINE INSERTIONSORT(XNDX)	!Adjust XNDX according to STASH(XNDX)
Crank up an Insertion sort of array STASH as indexed by XNDX.
         INTEGER XNDX(0:),IT	!The index to be prepared, and a safe place.
         INTEGER I,L		!Fingers.
          DO L = 2,XNDX(0)	!Step along the array.
            IF (ORDER(STASH(XNDX(L - 1)),STASH(XNDX(L))) .LT. 0) THEN	!Disorder?
              I = L		!Yes. Element L belongs earlier.
              IT = XNDX(L)	!Save it so that others can be shifted up one.
    1         XNDX(I) = XNDX(I - 1)	!Shift one.
              I = I - 1		!The next candidate back.
              IF (I.GT.1 .AND. ORDER(STASH(XNDX(I - 1)),	!Do I have to go further back?
     1                               STASH(IT)).LT.0) GO TO 1	!Yes.
              XNDX(I) = IT	!Done. Place it in the space created.
            END IF		!So much for that comparison.
          END DO		!On to the next.
        END SUBROUTINE INSERTIONSORT	!Swift only if the array is nearly in order.

        INTEGER FUNCTION FOUNDIN(XNDX,X)	!Search STASH(XNDX) for X.
Crank up a binary serach. This uses EXCLUSIVE bounds.
         INTEGER XNDX(0:)	!The list of elements.
         TYPE(BIGINT) X		!The value to be sought.
         INTEGER L,P,R		!Fingers for the binary search.
          L = 0			!Establish outer bounds.
          R = XNDX(0) + 1	!One before, and one after, the first and last.
    1     P = (R - L)/2		!Probe point offset. Beware integer overflow with (L + R)/2.
          IF (P.LE.0) THEN	!Is the search span exhausted?
            FOUNDIN = -L	!Alas. X should follow position L but doesn't.
           RETURN		!Nothing more to search.
          END IF		!Otherwise, STASH(XNDX(L + 1)) <= X <= STASH(XNDX(R - 1))
          P = L + P		!Convert from offset to probe point.
          IF (ORDER(X,STASH(XNDX(P)))) 2,4,3	!Compare X to the probe point's value.
    2     L = P			!STASH(XNDX(P)) < X: advance L to P.
          GO TO 1		!Try again.
    3     R = P			!X < STASH(XNDX(P)): retract R to P.
          GO TO 1		!Try again.
Caught it! X = STASH(XNDX(P)) - the result indexes XNDX, not STASH.
    4     FOUNDIN = P		!So, X is found, here! *Not* at P, but at XNDX(P).
        END FUNCTION FOUNDIN	!Hopefully, without array copy-in, copy-out.

        SUBROUTINE INSPECT(S1,S2,ENUFF)	!Follow the Lychrel protocol.
Careful! A march is stopped on encountering a palindrome, BUT, the starting value is not itself checked.
         INTEGER S1,S2		!Start and stop values.
         INTEGER ENUFF		!An infinite trail can't be followed.
         INTEGER STEP,SEED	!Counts the advances along the long march.
         INTEGER START		!The first value of a march has special treatment.
         INTEGER MARCH(0:ENUFF)	!The waypoints of a long march.
         INTEGER DEJAVU		!Some may prove to be junctions.
         INTEGER LP,NP,LL,NL	!Counters for various odd outcomes.
          NP = 0		!No palindromic stops.
          LP = 0		!Nor any that head for one.
          NL = 0		!No neverending sequences seen.
          LL = 0		!Nor any that head for one.
          WRITE (6,10) S1,S2,ENUFF	!Announce the plan.
   10     FORMAT ("Starting values ",I0," to ",I0,"; step limit ",I0)
C   For each try, steps (but not the START) are saved in MARCH, and those steps end up in one list or another.
C Thus, there is no removal of their entries from the working STASH. If a plaindrome is found, or a step's value is
c noticed in the PLIST or LYCHREL list, the last STEP is not saved (being in that list, as a different entry in STASH)
c and its redundant value in STASH is unhanded via CALL FREESTASH(MARCH(STEP)).
c But if instead the MARCH is to be added to the LYCHREL list, the last value is included.
c   Since tries are made in increasing order, and ADVANCE always produces a bigger number, there is no point
c in saving the START value in STASH, except, some START values turn out to be notable and being saved in L0P
c or LLIST, their entry in STASH must not be rugpulled, thus the START = 0 to note this and prevent FREESTASH.
      TRY:DO SEED = S1,S2	!Here we go.
            CALL GRABSTASH(START)		!Ask for a starting space.
            CALL BIGLOAD(STASH(START),SEED)	!The starting value.
c            CALL BIGWRITE("N0",STASH(START))	!Show it.
c            IF (FOUNDIN(LYCHREL,STASH(START)) .GT. 0) THEN!	Have we been here during a long march?
c              WRITE (6,*) SEED,"Falls in!"		!Yes!
c              CYCLE TRY				!Nothing will be learnt by continuing.
c            END IF				!Otherwise, we're not discouraged.
            STEP = 1				!Even the longest journey stars with its first step.
            MARCH(0) = STEP			!And I'm remembering every step.
            CALL GRABSTASH(MARCH(STEP))		!A place for my first footfall.
            CALL ADVANCE(STASH(START),STASH(MARCH(STEP)))	!Start the stomping.
Contemplate the current step.
  100       CONTINUE	!Can't label a blank line...
c            CALL BIGWRITE("N1",STASH(MARCH(STEP)))	!Progress may be of interest.
            DEJAVU = FOUNDIN(PLIST,STASH(MARCH(STEP)))	!A value known to later become a palindrome?
            IF (DEJAVU .GT. 0) THEN			!It being amongst those stashed for that cause.
c              WRITE (6,*) SEED,STEP,"Deja vu! List#",DEJAVU
              LP = LP + 1				!Count a late starter.
              CALL FREESTASH(MARCH(STEP))		!The last step is already known.
              CALL SLURP(PLIST)				!Add the MARCH to the palindrome starters.
              GO TO 110					!And we're finished with this try.
            END IF					!So much for prospective palindromes.
            IF (PALINDROME(STASH(MARCH(STEP)))) THEN	!Attained an actual palindrome?
c              WRITE (6,*) SEED,STEP,"Palindrome!"	!Yes!
              NP = NP + 1				!Count a proper palendrome.
              CALL FREESTASH(MARCH(STEP))		!The last step is a palindrome.
              CALL SLURP(PLIST)				!So remember only those non-palindromes before it.
              GO TO 110					!This is a pretext for ending.
            END IF					!Since one could advance past a palindrome, and then find another.
            DEJAVU = FOUNDIN(LYCHREL,STASH(MARCH(STEP)))	!A value known to later pass ENUFF?
            IF (DEJAVU .GT. 0) THEN			!If so, there is no need to follow that march again.
c              WRITE (6,*) SEED,STEP,"Latecomer! List#",DEJAVU	!So this starter has been preempted.
c              CALL BIGWRITE("Latecomer!",STASH(LYCHREL(DEJAVU)))	!Or, STASH(MARCH(STEP)), they being equal.
              LLIST(0) = LLIST(0) + 1			!Count another latecomer.
              LLIST(LLIST(0)) = START			!This was its starting value's finger.
              IF (PALINDROME(STASH(START))) THEN	!Perhaps its starting value was also already a palindrome?
                L0P(0) = L0P(0) + 1				!Yes! Count another such.
                L0P(L0P(0)) = START				!Using a finger, rather than copying a BIGINT.
              END IF					!A Lychrel number whose zeroth step is palindromic.
              START = 0					!This is not to be unfingered!
              LL = LL + 1				!Anyway, this path has joined a known long march.
              CALL FREESTASH(MARCH(STEP))		!This value is already fingered in a list.
              CALL SLURP(LYCHREL)			!So, all its steps do so also, including the last.
              GO TO 110					!Even though its later start might find a palindrome within ENUFF steps.
            END IF					!So much for discoveries at each step.
            IF (STEP.LT.ENUFF) THEN	!Are we there yet?
              STEP = STEP + 1			!It seems there is no reason to stop.
              MARCH(0) = STEP			!So, the long march extends.
              CALL GRABSTASH(MARCH(STEP))	!Another step.
              CALL ADVANCE(STASH(MARCH(STEP - 1)),STASH(MARCH(STEP)))	!Lurch forwards.
              GO TO 100				!And see what happens here.
            END IF			!The end of the loop.
Chase completed, having reached STEP = ENUFF with no decision.
            WRITE (6,*) SEED,"retains Lychrel potential."	!Since a palindrome has not been reached.
            IF (PALINDROME(STASH(START))) THEN	!Perhaps it started as a palindrome?
              L0P(0) = L0P(0) + 1			!It did!
              L0P(L0P(0)) = START			!So remember it.
              START = 0					!And don't unhand this entry, a finger to it being saved.
            END IF				!Enough shades of classification.
            NL = NL + 1			!Count another at the end of a long march.
            CALL SLURP(LYCHREL)		!And save the lot, including the final value.
  110       IF (START.GT.0) CALL FREESTASH(START)	!The starting value was not held as a part of the MARCH.
          END DO TRY		!Start another.
Cast forth a summary.
          WRITE (6,*)
          WRITE (6,11) NL,ENUFF,LL,LYCHREL(0)
   11     FORMAT (I8," starters attained step ",I0," and ",
     1     I0," joined a long march. "
     2     I0," waypoints stashed.")
c          CALL SHOWLIST("starters that joined a Long March",LLIST)
          CALL SHOWLIST("Long Marchers starting as palindromes",L0P)
          WRITE (6,12) NP,LP,PLIST(0)
   12     FORMAT (I8," starters ended as a palindrome, ",
     1     I0," joined a route leading to a palindrome. ",
     2     I0," waypoints stashed.")
         CONTAINS	!An assistant.
          SUBROUTINE SLURP(LIST)	!Adds the elements in MARCH to LIST.
C   Entries in LIST are such that STASH(LIST(~)) is ordered. Because I arrange this.
C   Entries MARCH are also in increasing order as they are successive values from ADVANCE.
C   Accordingly, if only a few entries are to be added, a binary search can be used to find the
C location for insertion, and then existing entries can be shifted up to make room for the new entry.
C This is the basic task of Insertionsort, however, this shift can be conducted without invoking ORDER
C to determine its bounds, as is done by Insertionsort, and ORDER takes a lot of time to decide.
C In other words, the binary search makes only a few calls to ORDER and then the moves follow, in one go,
C whereas the Insertionsort makes as many calls to ORDER as it makes moves, and does so stepwise.
C   When many entries are to be added, they could be appended to LIST and then COMBSORT invoked.
C This is infrequent as few numbers evoke a lengthy march, so that method is adequate.
C But since both lists are in order, a merge of the two lists would be more stylish, if encoded clunkily.
C   It turns out that the incoming set may finger a value that is already in LIST,
c so equal values may appear. With the binary search method, such incomers can simply be skipped,
c but with the merge it is a bit more messy. In the event, the new value is discarded and the
c old one retained.
C   For instance, 5 -> 10 -> 11 so fingers for 5 and 10 are added to PLIST.
C Later on, 10 -> 11 and a finger for 10 is to be added to PLIST, because the starting value is not checked.
C However, a later version refrains from adding the (unchecked) starting value, and then, no worries.
           INTEGER LIST(0:MSTASH)	!Some string of numbers.
           INTEGER MIST(0:MSTASH)	!LIST(0) is the upper bound, but risks stack overflow.
           INTEGER I,S,L		!A stepper.
Check for annoying nullities.
    1       IF (MARCH(0).LE.0) RETURN	!An empty march already!
            IF (MARCH(MARCH(0)).LE.0) THEN	!Otherwise, look at the last step.
              MARCH(0) = MARCH(0) - 1		!It was boring.
              GO TO 1				!So, go back one and look afresh.
            END IF			!Having snipped off trailing nullities, what remains means effort.
Can't escape some work.
            IF (MARCH(0) .LE. 6) THEN	!If we have a few only,
              DO I = 1,MARCH(0)		!Work through them one by one,
                S = MARCH(I)			!The finger for this step of the march.
                IF (S.LE.0) CYCLE		!A stump?
                L = FOUNDIN(LIST,STASH(S))	!Using a binary search to find the proper place.
                IF (L.GT.0) THEN		!If already present,
                  CALL FREESTASH(S)		!Its entry is no longer needed.
                  CYCLE				!So skip this.
                END IF				!But if not found, a place must be made.
                L = 1 - L			!Finger where the missing element should be.
                LIST(LIST(0) + 1:L + 1:-1) = LIST(LIST(0):L:-1)	!Shift followers up to make space.
                LIST(0) = LIST(0) + 1		!Count another.
                LIST(L) = S			!Place it.
              END DO			!On to the next.
             ELSE	!But if there are many to add, merge the two lists... Both are ordered.
              MIST(0:LIST(0)) = LIST(0:LIST(0))	!Copy the source list.
              LIST(0) = 0		!It is to be reformed by the merge.
              L = 1			!Start with the first in MIST.
              DO I = 1,MARCH(0)		!And work along the long MARCH.
                S = MARCH(I)		!So, a step from the long march.
                IF (S.LE.0) CYCLE	!And if not an empty step, we have one.
   11           LIST(0) = LIST(0) + 1		!Count in another for this list.
                IF (L.LE.MIST(0)) THEN		!Still have suppliers from what had been LIST?
                  IF (ORDER(STASH(MIST(L)),STASH(S))) 14,13,12	!Yes, Which is to be selected?
   12             LIST(LIST(0)) = MIST(L)	!STASH(MIST(L)) precedes STASH(S), so take it.
                  L = L + 1			!Advance to the next MIST entry.
                  GO TO 11			!And look again.
   13             CALL FREESTASH(S)		!Equal. Discard the new entry.
                  S = MIST(L)			!And pefer the established entry.
                  L = L + 1			!Advance past the MIST(L) entry.
                END IF			!Thus, MIST entries have been rolled until a MARCH entry was due.
   14           LIST(LIST(0)) = S	!Save the finger - which may have come from MIST...
              END DO			!On to the next MARCH.
              S = MIST(0) - L + 1	!The number of MIST entries still waiting.
              IF (S .GT. 0) THEN	!Are there any?
                LIST(LIST(0) + 1:LIST(0) + S) = MIST(L:MIST(0))	!Yes. Append them.
                LIST(0) = LIST(0) + S	!And count them in.
              END IF			!So much for the merge.
            END IF			!Otherwise, a COMBSORT would do.
          END SUBROUTINE SLURP	!Can't overflow, because each LIST has room for MSTASH entries.
        END SUBROUTINE INSPECT	!That was fun.
      END MODULE LYCHREL SEARCH	!Enough of that.

      PROGRAM TEST
      USE LYCHREL SEARCH
       CALL PREPARESTASH
Clear my lists.
       LYCHREL = 0	!No Lychrel candidates.
       LLIST = 0	!No latecomers to a Lychrel candidacy sequence.
       PLIST = 0	!No numbers leading to a palindrome.
       L0P = 0		!No Lychrel/latecomers starting as a palindrome.

       CALL INSPECT(1,10000,500)	!Whee!

       WRITE (6,*) "Longest digit string =",LONGESTNUMBER
       WRITE (6,*) "Unused STASH entries =",AVAILS(0)
      END


iterate.until.escape <- function(z, c, trans, cond, max=50, response=dwell) {
  #we iterate all active points in the same array operation,
  #and keeping track of which points are still iterating.
  active <- seq_along(z)
  dwell <- z
  dwell[] <- 0
  for (i in 1:max) {
    z[active] <- trans(z[active], c[active]);
    survived <- cond(z[active])
    dwell[active[!survived]] <- i
    active <- active[survived]
    if (length(active) == 0) break
  }
  eval(substitute(response))
}

re = seq(-2, 1, len=500)
im = seq(-1.5, 1.5, len=500)
c <- outer(re, im, function(x,y) complex(real=x, imaginary=y))
x <- iterate.until.escape(array(0, dim(c)), c,
                          function(z,c)z^2+c, function(z)abs(z) <= 2,
                          max=100)
image(x)


#lang racket

(require racket/draw)

(define (iterations a z i)
  (define z′ (+ (* z z) a))
  (if (or (= i 255) (> (magnitude z′) 2))
      i
      (iterations a z′ (add1 i))))

(define (iter->color i)
  (if (= i 255)
      (make-object color% "black")
      (make-object color% (* 5 (modulo i 15)) (* 32 (modulo i 7)) (* 8 (modulo i 31)))))

(define (mandelbrot width height)
  (define target (make-bitmap width height))
  (define dc (new bitmap-dc% [bitmap target]))
  (for* ([x width] [y height])
    (define real-x (- (* 3.0 (/ x width)) 2.25))
    (define real-y (- (* 2.5 (/ y height)) 1.25))
    (send dc set-pen (iter->color (iterations (make-rectangular real-x real-y) 0 0)) 1 'solid)
    (send dc draw-point x y))
  (send target save-file "mandelbrot.png" 'png))

(mandelbrot 300 200)


' version 13-09-2015
' compile with: fbc -s console

' iteration limit
#Define max_it 500
' the highest number to be tested
#Define max_number_to_test 10000

Dim As String num, rev
Dim As String temp(), store()

Dim As Integer x, x1, palindrome
Dim As UInteger it, s, carry, sum, match, seed, related
Dim As UInteger num2test, p_count, lychrel_palindrome()

For num2test = 1 To max_number_to_test
    num = Str(num2test)
    rev = num : s = Len(num) - 1
    For x = 0 To s
        rev[s - x] = num[x]
    Next
    ' if num = rev then palindrome = -1 else palindrome = 0
    ' palindrome is set to the result of the compare of num and rev
    palindrome = (num = rev)
    it = 0
    ReDim temp(1 To max_it)
    Do
        carry = 0
        For x = s To 0 Step -1 'add the two numbers
            sum = num[x] + rev[x] + carry
            If sum > (9 + 48 + 48) Then
                num[x] = sum - 10 - 48
                carry = 1
            Else
                num[x] = sum - 48
                carry = 0
            End If
        Next
        If carry = 1 Then num = "1" + num
        it = it + 1 : temp(it) = num
        rev = num : s = Len(num) - 1
        For x = 0 To s
            rev[s - x] = num[x]
        Next
    Loop Until num = rev OrElse it = max_it
    If it = max_it Then
        match = 0
        ' if it's palindrome then save the number
        If palindrome <> 0 Then
            p_count = p_count + 1
            ReDim Preserve lychrel_palindrome(1 To p_count)
            lychrel_palindrome(p_count) = num2test
        End If
        For x = 1 To seed ' check against previous found seed(s)
            For x1 = max_it To 1 Step -1
                If store(x, 1) = temp(x1) Then
                    match = 1
                    related = related + 1
                    Exit For, For
                Else
                    If Len(store(x,1)) > Len(temp(x1)) Then
                        Exit For
                    End If
                End If
            Next
        Next
        ' no match found then it's a new seed, store it
        If match = 0 Then
            seed = seed + 1
            ReDim Preserve store(seed, 1)
            store(seed, 0) = Str(num2test)
            store(seed, 1) = temp(max_it)
        End If
    End If
Next

Print
Print "                      Testing numbers: 1 to "; Str(max_number_to_test)
Print "                    Iteration maximum: ";Str(max_it)
Print
Print "              Number of Lychrel seeds: "; seed
Print "                       Lychrel number: ";
For x = 1 To seed : Print store(x,0); " "; : Next : Print
Print "             Number of relateds found: "; related
Print " Lychrel numbers that are palindromes: "; p_count
Print "                  Lychrel palindromes: ";
For x = 1 To p_count : Print lychrel_palindrome(x); " "; : Next : Print
Print

' empty keyboard buffer
While Inkey <> "" : Wend
Print : Print "hit any key to end program"
Sleep
End


package main

import (
	"flag"
	"fmt"
	"math"
	"math/big"
	"os"
)

var maxRev = big.NewInt(math.MaxUint64 / 10) // approximate
var ten = big.NewInt(10)

// Reverse sets `result` to the value of the base ten digits of `v` in
// reverse order and returns `result`.
// Only handles positive integers.
func reverseInt(v *big.Int, result *big.Int) *big.Int {
	if v.Cmp(maxRev) <= 0 {
		// optimize small values that fit within uint64
		result.SetUint64(reverseUint64(v.Uint64()))
	} else {
		if true {
			// Reverse the string representation
			s := reverseString(v.String())
			result.SetString(s, 10)
		} else {
			// This has fewer allocations but is slower:
			// Use a copy of `v` since we mutate it.
			v := new(big.Int).Set(v)
			digit := new(big.Int)
			result.SetUint64(0)
			for v.BitLen() > 0 {
				v.QuoRem(v, ten, digit)
				result.Mul(result, ten)
				result.Add(result, digit)
			}
		}
	}
	return result
}

func reverseUint64(v uint64) uint64 {
	var r uint64
	for v > 0 {
		r *= 10
		r += v % 10
		v /= 10
	}
	return r
}

func reverseString(s string) string {
	b := make([]byte, len(s))
	for i, j := 0, len(s)-1; j >= 0; i, j = i+1, j-1 {
		b[i] = s[j]
	}
	return string(b)
}

var known = make(map[string]bool)

func Lychrel(n uint64, iter uint) (isLychrel, isSeed bool) {
	v, r := new(big.Int).SetUint64(n), new(big.Int)
	reverseInt(v, r)
	seen := make(map[string]bool)
	isLychrel = true
	isSeed = true
	for i := iter; i > 0; i-- {
		str := v.String()
		if seen[str] {
			//log.Println("found a loop with", n, "at", str)
			isLychrel = true
			break
		}
		if ans, ok := known[str]; ok {
			//log.Println("already know:", str, ans)
			isLychrel = ans
			isSeed = false
			break
		}
		seen[str] = true

		v = v.Add(v, r)
		//log.Printf("%v + %v = %v\n", str, r, v)
		reverseInt(v, r)
		if v.Cmp(r) == 0 {
			//log.Println(v, "is a palindrome,", n, "is not a Lychrel number")
			isLychrel = false
			isSeed = false
			break
		}
	}
	for k := range seen {
		known[k] = isLychrel
	}
	//if isLychrel { log.Printf("%v may be a Lychrel number\n", n) }
	return isLychrel, isSeed
}

func main() {
	max := flag.Uint64("max", 10000, "search in the range 1..`N` inclusive")
	iter := flag.Uint("iter", 500, "limit palindrome search to `N` iterations")
	flag.Parse()
	if flag.NArg() != 0 {
		flag.Usage()
		os.Exit(2)
	}

	fmt.Printf("Calculating using n = 1..%v and %v iterations:\n", *max, *iter)
	var seeds []uint64
	var related int
	var pals []uint64
	for i := uint64(1); i <= *max; i++ {
		if l, s := Lychrel(i, *iter); l {
			if s {
				seeds = append(seeds, i)
			} else {
				related++
			}
			if i == reverseUint64(i) {
				pals = append(pals, i)
			}
		}
	}

	fmt.Println("      Number of Lychrel seeds:", len(seeds))
	fmt.Println("                Lychrel seeds:", seeds)
	fmt.Println("            Number of related:", related)
	fmt.Println("Number of Lychrel palindromes:", len(pals))
	fmt.Println("          Lychrel palindromes:", pals)
}


/*REXX program  generates and displays a Mandelbrot set as an ASCII art character image.*/
@ = '>=<;:9876543210/.-,+*)(''&%$#"!'            /*the characters used in the display.  */
Xsize = 59;  minRE = -2;  maxRE = +1;     stepX = (maxRE-minRE) / Xsize
Ysize = 21;  minIM = -1;  maxIM = +1;     stepY = (maxIM-minIM) / Ysize

  do y=0  for ysize;      im=minIM + stepY*y
  $=
        do x=0  for Xsize;   re=minRE + stepX*x;    zr=re;    zi=im

            do n=0  for 30;  a=zr**2;   b=zi**2;    if a+b>4  then leave
            zi=zr*zi*2 + im;            zr=a-b+re
            end   /*n*/

        $=$ || substr(@, n+1, 1)                 /*append number (as a char) to $ string*/
        end       /*x*/
  say $                                          /*display a line of  character  output.*/
  end             /*y*/                          /*stick a fork in it,  we're all done. */


module Main where

import Data.List

procLychrel :: Integer -> [Integer]
procLychrel a = a : pl a
  where
    pl n =
        let s = n + reverseInteger n
             in if isPalindrome s
                  then [s]
                  else s : pl s

isPalindrome :: Integer -> Bool
isPalindrome n =
  let s = show n
  in (s == reverse s)

isLychrel :: Integer -> Bool
isLychrel = not . null . drop 500 . procLychrel

reverseInteger :: Integer -> Integer
reverseInteger = read . reverse . show

seedAndRelated :: (Int, [Integer], [Integer], Int)
seedAndRelated =
  let (seed, related, _) = foldl sar ([], [], []) [1 .. 10000]
      lseed = length seed
      lrelated = length related
      totalCount = lseed + lrelated
      pal = filter isPalindrome $ seed ++ related
  in (totalCount, pal, seed, lrelated)
  where
    sar (seed, related, lych) x =
      let s = procLychrel x
          sIsLychrel = not . null . drop 500 $ s
          (isIn, isOut) = partition (`elem` lych) . take 501 $ s
          newLych = lych ++ isOut
      in if sIsLychrel
           then if null isIn -- seed lychrel number
                  then (x : seed, related, newLych)
                  else (seed, x : related, newLych) -- related lychrel number
           else (seed, related, lych)

main = do
  let (totalCount, palindromicLychrel, lychrelSeeds, relatedCount) = seedAndRelated
  putStrLn $ "[1..10,000] contains " ++ show totalCount ++ " Lychrel numbers."
  putStrLn $ show palindromicLychrel ++ " are palindromic Lychrel numbers."
  putStrLn $ show lychrelSeeds ++ " are Lychrel seeds."
  putStrLn $ "There are " ++ show relatedCount ++ " related Lychrel numbers."


load "guilib.ring"

new qapp
        {
        win1 = new qwidget() {
               setwindowtitle("Mandelbrot set")
               setgeometry(100,100,500,500)
               label1 = new qlabel(win1) {
                        setgeometry(10,10,400,400)
                        settext("")
               }
               new qpushbutton(win1) {
                   setgeometry(200,400,100,30)
                   settext("draw")
                   setclickevent("draw()")
               }
               show()
         }
         exec()
         }

func draw
        p1 = new qpicture()
             color = new qcolor() {
             setrgb(0,0,255,255)
        }
        pen = new qpen() {
              setcolor(color)
              setwidth(1)
        }
        new qpainter() {
            begin(p1)
            setpen(pen)

        x1=300 y1=250
        i1=-1 i2=1 r1=-2 r2=1
        s1=(r2-r1)/x1 s2=(i2-i1)/y1
        for y=0 to y1
            i3=i1+s2*y
            for x=0 to x1
                r3=r1+s1*x z1=r3 z2=i3
                for n=0 to 30
                    a=z1*z1 b=z2*z2
                    if a+b>4 exit ok
                       z2=2*z1*z2+i3 z1=a-b+r3
                next
                if n != 31 drawpoint(x,y) ok
            next
        next

        endpaint()
        }
        label1 { setpicture(p1) show() }


require 'complex'

def mandelbrot(a)
  Array.new(50).inject(0) { |z,c| z*z + a }
end

(1.0).step(-1,-0.05) do |y|
  (-2.0).step(0.5,0.0315) do |x|
    print mandelbrot(Complex(x,y)).abs < 2 ? '*' : ' '
  end
  puts
end


import java.math.BigInteger;
import java.util.*;

public class Lychrel {

    static Map<BigInteger, Tuple> cache = new HashMap<>();

    static class Tuple {
        final Boolean flag;
        final BigInteger bi;

        Tuple(boolean f, BigInteger b) {
            flag = f;
            bi = b;
        }
    }

    static BigInteger rev(BigInteger bi) {
        String s = new StringBuilder(bi.toString()).reverse().toString();
        return new BigInteger(s);
    }

    static Tuple lychrel(BigInteger n) {
        Tuple res;
        if ((res = cache.get(n)) != null)
            return res;

        BigInteger r = rev(n);
        res = new Tuple(true, n);
        List<BigInteger> seen = new ArrayList<>();

        for (int i = 0; i < 500; i++) {
            n = n.add(r);
            r = rev(n);

            if (n.equals(r)) {
                res = new Tuple(false, BigInteger.ZERO);
                break;
            }

            if (cache.containsKey(n)) {
                res = cache.get(n);
                break;
            }

            seen.add(n);
        }

        for (BigInteger bi : seen)
            cache.put(bi, res);

        return res;
    }

    public static void main(String[] args) {

        List<BigInteger> seeds = new ArrayList<>();
        List<BigInteger> related = new ArrayList<>();
        List<BigInteger> palin = new ArrayList<>();

        for (int i = 1; i <= 10_000; i++) {
            BigInteger n = BigInteger.valueOf(i);

            Tuple t = lychrel(n);

            if (!t.flag)
                continue;

            if (n.equals(t.bi))
                seeds.add(t.bi);
            else
                related.add(t.bi);

            if (n.equals(t.bi))
                palin.add(t.bi);
        }

        System.out.printf("%d Lychrel seeds: %s%n", seeds.size(), seeds);
        System.out.printf("%d Lychrel related%n", related.size());
        System.out.printf("%d Lychrel palindromes: %s%n", palin.size(), palin);
    }
}


extern crate image;
extern crate num_complex;

use std::fs::File;
use num_complex::Complex;

fn main() {
    let max_iterations = 256u16;
    let img_side = 800u32;
    let cxmin = -2f32;
    let cxmax = 1f32;
    let cymin = -1.5f32;
    let cymax = 1.5f32;
    let scalex = (cxmax - cxmin) / img_side as f32;
    let scaley = (cymax - cymin) / img_side as f32;

    // Create a new ImgBuf
    let mut imgbuf = image::ImageBuffer::new(img_side, img_side);

    // Calculate for each pixel
    for (x, y, pixel) in imgbuf.enumerate_pixels_mut() {
        let cx = cxmin + x as f32 * scalex;
        let cy = cymin + y as f32 * scaley;

        let c = Complex::new(cx, cy);
        let mut z = Complex::new(0f32, 0f32);

        let mut i = 0;
        for t in 0..max_iterations {
            if z.norm() > 2.0 {
                break;
            }
            z = z * z + c;
            i = t;
        }

        *pixel = image::Luma([i as u8]);
    }

    // Save image
    imgbuf.save("fractal.png").unwrap();
}


$canvasWidth: 200;
$canvasHeight: 200;
$iterations: 20;
$xCorner: -2;
$yCorner: -1.5;
$zoom: 3;
$data: ()!global;
@mixin plot ($x,$y,$count){
  $index: ($y * $canvasWidth + $x) * 4;
  $r: $count * -12 + 255;
  $g: $count * -12 + 255;
  $b: $count * -12 + 255;
  $data: append($data, $x + px $y + px 0 rgb($r,$g,$b), comma)!global;
}

@for $x from 1 to $canvasWidth {
    @for $y from 1 to $canvasHeight {
      $count: 0;
      $size: 0;
      $cx: $xCorner + (($x * $zoom) / $canvasWidth);
      $cy: $yCorner + (($y * $zoom) / $canvasHeight);

      $zx: 0;
      $zy: 0;

      @while $count < $iterations and $size <= 4  {
        $count: $count + 1;
        $temp:  ($zx * $zx) - ($zy * $zy);
        $zy:  (2 * $zx * $zy) + $cy;
        $zx:  $temp + $cx;
        $size:  ($zx * $zx) + ($zy * $zy);
      }

      @include plot($x, $y, $count);
    }
}
.set {
  height: 1px;
  width: 1px;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate($canvasWidth*0.5px, $canvasWidth*0.5px);
  box-shadow: $data;
}


# This workhorse function assumes its arguments are
# non-negative integers represented as decimal strings:
def add(num1;num2):
  if (num1|length) < (num2|length) then add(num2;num1)
  else  (num1 | explode | map(.-48) | reverse) as $a1
  | (num2 | explode | map(.-48) | reverse) as $a2
  | reduce range(0; num1|length) as $ix
      ($a2;  # result
       ( $a1[$ix] + .[$ix] ) as $r
         | if $r > 9 # carrying
           then
             .[$ix + 1] = ($r / 10 | floor) +  (if $ix + 1 >= length then 0 else .[$ix + 1] end )
             | .[$ix] = $r - ( $r / 10 | floor ) * 10
           else
             .[$ix] = $r
           end )
  | reverse | map(.+48) | implode
  end ;

# Input: an array
def is_palindrome:
  . as $in
  | (length -1) as $n
  | all( range(0; length/2); $in[.] == $in[$n - .]);

# Input: a string representing a decimal number.
# Output: a stream of such strings generated in accordance with the Lychrel rule,
# subject to the limitation imposed by "limit", and ending in true if the previous item in the stream is a palindrome
def next_palindromes(limit):
   def toa: explode | map(.-48);
   def tos: map(.+48) | implode;
   def myadd(x;y): add(x|tos; y|tos) | toa;
   # input: [limit, n]
   def next:
     .[0] as $limit
     | .[1] as $n
     | if $limit <= 0 then empty
       else  myadd($n ; $n|reverse) as $sum
	| ($sum,
         if ($sum | is_palindrome) then true else [$limit - 1, $sum] | next end)
       end;
  [limit, toa] | next | if type == "boolean" then . else tos end;

# Consider integers in range(0;n) using maxiter as the maximum number
# of iterations in the search for palindromes.
# Emit a dictionary:
# { seed: _, palindromic_seed: _, related: _} + {($n): $n} for all related $n
# where .seed is an array of integers holding the potential Lychrel seeds, etc
def lychrel_dictionary(n; maxiter):
    reduce range(0; n) as $i ({};
        ($i | tostring) as $is
	| if .[$is] then .related += [$i]
	  else [$is | next_palindromes(maxiter)] as $seq
	  | . as $dict
          # | ([$i, $seq] | debug) as $debug
          | if $seq[-1] == true then .
	    else if ($is | explode | is_palindrome) then .palindromic_seed += [$i] else . end
            | if any($seq[]; $dict[.]) then .related += [$i]
              else .seed += [$i]
              end
            | reduce $seq[] as $n (.; if .[$n] then . else .[$n] = $n end)
            end
          end ) ;


const cache = Dict{BigInt, Tuple{Bool, BigInt}}()

Base.reverse(n::Integer) = parse(BigInt, string(n) |> reverse)
function lychrel(n::BigInt)::Tuple{Bool, BigInt}
    if haskey(cache, n)
        return cache[n]
    end

    r = reverse(n)
    rst = (true, n)
    seen = Set{BigInt}()
    for i in 0:500
        n += r
        r = reverse(n)
        if n == r
            rst = (false, big(0))
            break
        end
        if haskey(cache, n)
            rst = cache[n]
            break
        end
        push!(seen, n)
    end

    for bi in seen
        cache[bi] = rst
    end
    return rst
end

seeds   = BigInt[]
related = BigInt[]
palin   = BigInt[]

for n in big.(1:10000)
    t = lychrel(n)
    if ! t[1]
        continue
    end
    if n == t[2]
        push!(seeds, n)
    else
        push!(related, n)
    end

    if n == t[2]
        push!(palin, t[2])
    end
end

println(length(seeds),   " lychrel seeds: ", join(seeds, ", "))
println(length(related), " lychrel related")
println(length(palin),   " lychrel palindromes: ", join(palin, ", "))


// version 1.0.6

import java.math.BigInteger

const val ITERATIONS = 500
const val LIMIT = 10000

val bigLimit = BigInteger.valueOf(LIMIT.toLong())

// In the sieve,  0 = not Lychrel, 1 = Seed Lychrel, 2 = Related Lychrel
val lychrelSieve    = IntArray(LIMIT + 1)  // all zero by default
val seedLychrels    = mutableListOf<Int>()
val relatedLychrels = mutableSetOf<BigInteger>()

fun isPalindrome(bi: BigInteger): Boolean {
    val s = bi.toString()
    return s == s.reversed()
}

fun lychrelTest(i: Int, seq: MutableList<BigInteger>){
    if (i < 1) return
    var bi = BigInteger.valueOf(i.toLong())
    (1 .. ITERATIONS).forEach {
        bi += BigInteger(bi.toString().reversed())
        seq.add(bi)
        if (isPalindrome(bi)) return
    }
    for (j in 0 until seq.size) {
        if (seq[j] <= bigLimit) lychrelSieve[seq[j].toInt()] = 2
        else break
    }
    val sizeBefore = relatedLychrels.size
    relatedLychrels.addAll(seq)  // if all of these can be added 'i' must be a seed Lychrel
    if (relatedLychrels.size - sizeBefore == seq.size) {
        seedLychrels.add(i)
        lychrelSieve[i] = 1
    }
    else {
        relatedLychrels.add(BigInteger.valueOf(i.toLong()))
        lychrelSieve[i] = 2
    }
}

fun main(args: Array<String>) {
    val seq  = mutableListOf<BigInteger>()
    for (i in 1 .. LIMIT)
        if (lychrelSieve[i] == 0) {
           seq.clear()
           lychrelTest(i, seq)
        }
    var related = lychrelSieve.count { it == 2 }
    println("Lychrel numbers in the range [1, $LIMIT]")
    println("Maximum iterations = $ITERATIONS")
    println("\nThere are ${seedLychrels.size} seed Lychrel numbers, namely")
    println(seedLychrels)
    println("\nThere are also $related related Lychrel numbers in this range")
    val palindromes = mutableListOf<Int>()
    for (i in 1 .. LIMIT)
        if (lychrelSieve[i] > 0 && isPalindrome(BigInteger.valueOf(i.toLong()))) palindromes.add(i)
    println("\nThere are ${palindromes.size} palindromic Lychrel numbers, namely")
    println(palindromes)
}