@(deffilter abbr
   ("IK" "I know an old lady who swallowed a") ("SW" "She swallowed the")
   ("SS" "she swallowed") ("CA" "to catch the") ("XX" "Perhaps she'll die")
   ("C" "cow") ("G" "goat") ("D" "dog") ("T" "cat") ("R" "bird")
   ("S " "spider ") ("F" "fly"))
@(bind lastverse
   ("IK C"
    "I don't know how SS the C"
    "SW C CA G"
    "SW G CA D"
    "SW D CA T"
    "SW T CA R"
    "SW R CA S"
    "SW S CA F"
    "But I don't know why SS that F"
    "XX"
    ""
    "IK horse"
    "She's alive and well of course!"))
@(bind animal_line
  ("G: Opened her throat and down went the G!"
   "D: What a hog to swallow a D!"
   "T: Imagine that! She swallowed a T!"
   "R: How absurd to swallow a R!"
   "S: That wriggled and jiggled and tickled inside her"
   "F: But I don't know why SS the F"))
@(define expand_backwards (song lengthened_song done))
@  (local line2 line3 verse rest animal previous_animal previous_animal_verse)
@  (next :list song)
@  (cases)
IK @animal
@line2
SW @animal CA @previous_animal
@    (maybe)
But @(skip)F
@    (end)
@    (collect)
@    verse
@    (until)

@    (end)
@    (collect)
@    rest
@    (end)
@    (next :list animal_line)
@    (skip)
@previous_animal: @previous_animal_verse
@    (output :into lengthened_song)
IK @previous_animal
@previous_animal_verse
@      (repeat)
@      verse
@      (end)

@      (repeat)
@      song
@      (end)
@    (end)
@    (bind done nil)
@ (or)
IK @(skip)
@line2
XX
@    (bind lengthened_song song)
@    (bind done t)
@ (end)
@(end)
@(define expand_song (in out))
@  (local lengthened done)
@  (expand_backwards in lengthened done)
@  (cases)
@    (bind done nil)
@    (expand_song lengthened out)
@  (or)
@    (bind out lengthened)
@  (end)
@(end)
@(expand_song lastverse song)
@(output :filter abbr)
@  (repeat)
@song
@  (end)
@(end)


animals=(fly spider bird cat dog pig goat cow donkey horse)
comments=("I don't know why she swallowed that fly"
          "That wriggled and jiggled and tickled inside her"
          "Quite absurd, to swallow a bird"
          "How about that, to swallow a cat"
          "What a hog, to swallow a dog"
          "Her mouth was so big to swallow a pig"
          "She just opened her throat to swallow a goat."
          "I don't know how she swallowed a cow."
          "It was rather wonky to swallow a donkey"
          "She's dead, of course!")
include=(2 2 1 1 1 1 1 1 1 0)

for (( i=0; i<${#animals[@]}; ++i )); do
   echo "There was an old lady who swallowed a ${animals[i]}"
   echo "${comments[i]}"
   if (( include[i] )); then
     if (( i )); then
       for (( j=i-1; j>=0; --j )); do
         echo "She swallowed the ${animals[j+1]} to catch the ${animals[j]}"
         if (( include[j] > 1 )); then
           echo "${comments[j]}"
         fi
       done
     fi
     echo "Perhaps she'll die"
     echo
   fi
done


decl string<> reason creatures comments
append "She swallowed the " " to catch the " reason
append "fly" "spider" "bird" "cat" "dog" "goat" "cow" "horse" creatures
append "I don't know why she swallowed that fly.\nPerhaps she'll die\n" comments
append "That wiggled and jiggled and tickled inside her" comments
append "How absurd, to swallow a bird" comments
append "Imagine that. She swallowed a cat" comments
append "What a hog to swallow a dog" comments
append "She just opened her throat and swallowed that goat" comments
append "I don't know how she swallowed that cow" comments
append "She's dead of course" comments

decl int max
set max (size creatures)
for (decl int i) (< i max) (inc i)
        out "There was an old lady who swallowed a " creatures<i> endl console
        out comments<i> endl console
        decl int j
        for (set j i) (and (> j 0) (< i (- max 1))) (dec j)
                out reason<0> creatures<j> reason<1> creatures<(int (- j 1))> endl console
                if (= j 1)
                        out comments<(int (- j 1))> endl console
                end if
        end for
end for
in string console


const (
    name = 0
    lyric = 1
    animals = [
            ["fly", "I don't know why she swallowed a fly. Perhaps she'll die."],
            ["spider", "That wiggled and jiggled and tickled inside her."],
            ["bird", "How absurd, to swallow a bird."],
            ["cat", "Imagine that, she swallowed a cat."],
            ["dog", "What a hog, to swallow a dog."],
            ["goat", "She just opened her throat and swallowed that goat."],
            ["cow", "I don't know how she swallowed that cow."],
            ["horse", "She's dead, of course."],
        ]
)

fn main() {
    for i, animal in animals {
        println("There was an old lady who swallowed a ${animal[name]},")
        if i > 0 {
            println(animal[lyric])
        }
        // Swallowing the last animal signals her death, cutting the
        //  lyrics short.
        if i+1 == animals.len {
            break
        }
        for j := i; j > 0; j-- {
            println("She swallowed the ${animals[j][name]} to catch the ${animals[j-1][name]},")
        }
        println("${animals[0][lyric]}\n")
    }
}


var animals = ["fly", "spider", "bird", "cat","dog", "goat", "cow", "horse"]

var phrases = [
    "",
    "That wriggled and jiggled and tickled inside her",
    "How absurd to swallow a bird",
    "Fancy that to swallow a cat",
    "What a hog, to swallow a dog",
    "She just opened her throat and swallowed a goat",
    "I don't know how she swallowed a cow",
    "\n  ...She's dead of course"
]

var sing = Fn.new {
     for (i in 0..7) {
       System.print("There was an old lady who swallowed a %(animals[i]);")
       if (i > 0) System.print("%(phrases[i])!")
       if (i == 7) return
       System.print()
       if (i > 0) {
           for (j in i..1) {
               System.write("  She swallowed the %(animals[j]) to catch the %(animals[j - 1])")
               System.print((j < 3) ? ";" :",")
               if (j == 2) System.print("  %(phrases[1])!")
           }
       }
       System.print("  I don't know why she swallowed a fly - Perhaps she'll die!\n")
    }
}

sing.call()


waitChar equ &BB06
PrintChar equ &BB5A

org &8000

	ld ix,VerseTable
	ld iy,OldLadyLookup
	ld b,8                 ;8 verses total

outerloop_song:
	    push bc
		    ld a,(ix+0)
		    ld c,a        ;get the low byte of verse ptr
		    ld a,(ix+1)
		    ld b,a        ;get the high byte
		    ;bc = the memory location of Verse1
		    call loop_meta_PrintString
		    inc ix
		    inc ix  ;next verse
	    pop bc

	    call WaitChar   ;wait for user to press any key before continuing so they
                            ;    have time to read it.

	djnz outerloop_song

ReturnToBasic:
		ret
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; SUBROUTINES ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
loop_meta_PrintString:
		ld a,(bc)
		or a		;compare A to 0. 0 is the null terminator for verses.
		ret z
		cp 255		;255 means "goto the verse specified after the 255"
		jr z,GotoPreviousVerse
		ld (smc_loop_meta_PrintString_alpha+2),a
		;use self modifying code to point IY's offset to the correct
		;	song line, without changing IY itself.
		inc a
		ld (smc_loop_meta_PrintString_beta+2),a
smc_loop_meta_PrintString_alpha:
		ld a,(iy+0)	;the "+0" gets clobbered with the desired lyric low byte
		ld L,a
smc_loop_meta_PrintString_beta:
		ld a,(iy+0)	;the "+0" gets clobbered with the desired lyric high byte
		ld H,a
		call PrintString	;now print the string in HL.
		inc bc
		jp loop_meta_PrintString
;;;;;;;;;;;;;;;;;;;;;;;
GotoPreviousVerse:
	inc bc		;advance past &FF opcode
	ld a,(bc)       ;get low byte
	ld e,a
	inc bc		;advance to high byte
	ld a,(bc)
	ld d,a
	push de
	pop bc
	inc bc		;advance past "There was an old lady who..."
	jp loop_meta_PrintString

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PrintString:
	ld a,(hl)
	or a
	ret z
	call PrintChar
	inc hl
	jr PrintString

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	DATA     ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
VerseTable:
	word Verse1,Verse2,Verse3,Verse4,Verse5,Verse6,Verse7,Verse8
Verse1:
	byte 2,4,40,6,40,0				;fly
Verse2:
	byte 2,8,40,10,40,36,8,38,255			;spider
	word Verse1
Verse3:
	byte 2,12,40,14,40,36,12,38,255			;bird
	word Verse2
Verse4:
	byte 2,16,40,18,40,36,16,38,255			;cat
	word Verse3
Verse5:
	byte 2,20,40,22,40,36,20,38,255			;dog
	word Verse4
Verse6:
	byte 2,24,40,26,40,36,24,38,255			;goat
	word Verse5
Verse7:
	byte 2,28,40,30,40,36,28,38,255			;cow
	word Verse6
Verse8:
	byte 2,32,40,34,0				;horse

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

OldLadyLookup:
		word null		;0
		word OldLady		;2
		word Fly		;4
		word Fly2		;6
		word Spider		;8

		word Spider2		;10
		word Bird		;12
		word Bird2		;14
		word Cat		;16
		word Cat2		;18

		word Dog		;20
		word Dog2		;22
		word Goat		;24
		word Goat2		;26
		word Cow		;28

		word Cow2		;30
		word Horse		;32
		word Horse2		;34
		word Catch1		;36
		word Catch2		;38

		word Song_NewLine	;40

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
null:
		byte 0
OldLady:
		byte "There was an old lady who swallowed a ",0
Fly:
		byte "fly",0
Fly2:
		byte "I don't know why she swallowed a fly, perhaps she'll die.",0
Spider:
       		byte "spider",0
Spider2:
		byte "It wiggled and jiggled and tickled inside her.",0
Bird:
        	byte "bird",0
Bird2:
		byte "How absurd, to swallow a bird.",0
Cat:
        	byte "cat",0
Cat2:
		byte "Imagine that, she swallowed a cat.",0
Dog:
       		byte "dog",0
Dog2:
		byte "What a hog, to swallow a dog.",0
Goat:
        	byte "goat",0
Goat2:
		byte "She just opened her throat and swallowed a goat.",0
Cow:
        	byte "cow",0
Cow2:
		byte "I don't know how she swallowed a cow.",0
Horse:
        	byte "horse",0
Horse2:
		byte "She's dead, of course.",0
Catch1:
		byte "She swallowed the ",0
Catch2:
		byte " to catch the ",0
Song_NewLine:
		byte 13,10,0		;control codes for a new line.


var ZLib=Import("zeelib"), MsgHash=Import("zklMsgHash");
text:=
  "eJztlE1uwyAQhdflFOOVNyhXyLap1FV7AWKIoaFMBFjIt++M7YVpLfVHilQp2cHMg3l8T+IA"
  "54AFVAD0GrzSIxSLkIryHovRoODkRykOoDG0eVYXO0KyZqXKtFt0/WBS4nbrPWhndoKK3w5J"
  "F6dNlA/i1aoMJbq+99wIGt5W6+y6M69dSKQHa+JOvHxxMl8GGaFTubNrd9d9xdFFLcUjq45p"
  "iJotLP2l22zY5XptdqHxaxjyP8GgcXT4XfUuGLqNdjUO6m/RoHJtdoZ6M9g09lI8j5Ia9AoF"
  "lvY1OFJsgaNybXcK4LYA/4Bvj4zlaUgZ8GIC1SzbsBEZN9n/LN5izfXa+hTbPZQ/fxZY+HDB"
  "wPMtqesBk2K/+V+QtvI7B3zP7OqZWYzJTI7aBNooLQFPlMdA5aYRH3dS5jc=";

MsgHash.base64decode(text) :
ZLib.Inflator().write(_).close().read().text.println();


with Ada.Calendar; use Ada.Calendar;

package Messages is
   type Message is tagged record
      Timestamp : Time;
   end record;

   procedure Print(Item : Message);
   procedure Display(Item : Message'Class);

   type Sensor_Message is new Message with record
      Sensor_Id : Integer;
      Reading : Float;
   end record;

   procedure Print(Item : Sensor_Message);

   type Control_Message is new Message with record
      Actuator_Id : Integer;
      Command     : Float;
   end record;

   procedure Print(Item : Control_Message);

end Messages;


MODE ENTITY = STRUCT([6]CHAR name, INT creation);
FORMAT entity repr = $"Name: "g", Created:"g$;
MODE PERSON = STRUCT(ENTITY entity, STRING email);
FORMAT person repr = $f(entity repr)", Email: "g$;

PERSON instance1 := PERSON(ENTITY("Cletus", 20080808), "[email protected]");
print((name OF entity OF instance1, new line));

ENTITY instance2 := ENTITY("Entity",20111111);
print((name OF instance2, new line));

FILE target;
INT errno := open(target, "rows.dat", stand back channel); # open file #

#  Serialise #
put(target,(instance1, new line, instance2, new line));
printf(($"Serialised..."l$));

close(target); # flush file stream #
errno := open(target, "rows.dat", stand back channel); # load again #

# Unserialise #
PERSON i1;
ENTITY i2;
get(target,(i1, new line, i2, new line));
printf(($"Unserialised..."l$));

printf((person repr, i1, $l$));
printf((entity repr, i2, $l$))


using System;
using System.IO;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;

namespace Object_serialization
{
  [Serializable] public class Being
  {
    public bool Alive { get; set; }
  }

  [Serializable] public class Animal: Being
  {
    public Animal() { }

    public Animal(long id, string name, bool alive = true)
    {
      Id = id;
      Name = name;
      Alive = alive;
    }

    public long Id { get; set; }
    public string Name { get; set; }

    public void Print() { Console.WriteLine("{0}, id={1} is {2}",
      Name, Id, Alive ? "alive" : "dead"); }
  }

  internal class Program
  {
    private static void Main()
    {
      string path =
        Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+"\\objects.dat";

      var n = new List<Animal>
              {
                new Animal(1, "Fido"),
                new Animal(2, "Lupo"),
                new Animal(7, "Wanda"),
                new Animal(3, "Kiki", alive: false)
              };

      foreach(Animal animal in n)
        animal.Print();

      using(var stream = new FileStream(path, FileMode.Create, FileAccess.Write))
        new BinaryFormatter().Serialize(stream, n);

      n.Clear();
      Console.WriteLine("---------------");
      List<Animal> m;

      using(var stream = new FileStream(path, FileMode.Open, FileAccess.Read))
        m = (List<Animal>) new BinaryFormatter().Deserialize(stream);

      foreach(Animal animal in m)
        animal.Print();
    }
  }
}


#include <string>
#include <fstream>
#include <boost/serialization/string.hpp>
#include <boost/archive/text_oarchive.hpp>
#include <boost/archive/text_iarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <iostream>

class Employee {
public :
   Employee( ) { }

   Employee ( const std::string &dep , const std::string &namen )
      : department( dep ) , name( namen ) {
	 my_id = count++ ;
      }

   std::string getName( ) const {
      return name ;
   }

   std::string getDepartment( ) const {
      return department ;
   }

   int getId( ) const {
      return my_id ;
   }

   void setDepartment( const std::string &dep ) {
      department.assign( dep ) ;
   }

   virtual void print( ) {
      std::cout << "Name: " << name << '\n' ;
      std::cout << "Id: " << my_id << '\n' ;
      std::cout << "Department: " << department << '\n' ;
   }

   virtual ~Employee( ) { }
   static int count ;
private :
   std::string name ;
   std::string department ;
   int my_id ;
   friend class boost::serialization::access ;

   template <class Archive>
      void serialize( Archive &ar, const unsigned int version ) {
	 ar & my_id ;
	 ar & name ;
	 ar & department ;
      }

} ;

class Worker : public Employee {
public :
   Worker( const std::string & dep, const std::string &namen ,
	 double hourlyPay ) : Employee( dep , namen ) , salary( hourlyPay) { }

   Worker( ) { }

   double getSalary( ) {
      return salary ;
   }

   void setSalary( double pay ) {
      if ( pay > 0 )
	 salary = pay ;
   }

   virtual void print( ) {
      Employee::print( ) ;
      std::cout << "wage per hour: " << salary << '\n' ;
   }
private :
   double salary ;
   friend class boost::serialization::access ;
   template <class Archive>
      void serialize ( Archive & ar, const unsigned int version ) {
	 ar & boost::serialization::base_object<Employee>( *this ) ;
	 ar & salary ;
      }
} ;

int Employee::count = 0 ;

int main( ) {
   std::ofstream storefile( "/home/ulrich/objects.dat"  ) ; //creating objects of base class
   const Employee emp1( "maintenance" , "Fritz Schmalstieg"  ) ;
   const Employee emp2( "maintenance" , "John Berry" ) ;
   const Employee emp3( "repair" , "Pawel Lichatschow" ) ;
   const Employee emp4( "IT" , "Marian Niculescu" ) ;
   const Worker worker1( "maintenance" , "Laurent Le Chef" , 20 ) ;//creating objects of derived class
   const Worker worker2 ( "IT" , "Srinivan Taraman" , 55.35 ) ;
   boost::archive::text_oarchive oar ( storefile ) ;//starting serialization into designated file
   oar << emp1 ;
   oar << emp2 ;
   oar << emp3 ;
   oar << emp4 ;
   oar << worker1 ;
   oar << worker2 ;
   storefile.close( ) ;
   std::cout << "Reading out the data again\n" ;
   Employee e1 , e2 , e3 , e4 ; //creating instances of base class objects for deserialization
   Worker w1, w2 ; // same for objects of derived class
   std::ifstream sourcefile( "/home/ulrich/objects.dat"  ) ;
   boost::archive::text_iarchive iar( sourcefile ) ;//starting deserialization
   iar >> e1 >> e2 >> e3 >> e4 ;
   iar >> w1 >> w2 ;
   sourcefile.close( ) ;
   std::cout << "And here are the data after deserialization!( abridged):\n" ;
   e1.print( ) ;
   e3.print( ) ;
   w2.print( ) ;
   return 0 ;
}


USING: combinators combinators.short-circuit formatting fry
grouping grouping.extras kernel literals math math.functions
math.parser math.ranges qw regexp sequences sequences.deep
sequences.extras sets splitting unicode ;
IN: rosetta-code.numerical-suffixes

CONSTANT: test-cases {
    qw{ 2greatGRo 24Gros 288Doz 1,728pairs 172.8SCOre }
    qw{ 1,567 +1.567k 0.1567e-2m }
    qw{ 25.123kK 25.123m 2.5123e-00002G }
    qw{ 25.123kiKI 25.123Mi 2.5123e-00002Gi +.25123E-7Ei }
    qw{ -.25123e-34Vikki 2e-77gooGols }
    qw{
        9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!!
        9!!!!!!!!!
    }
}

CONSTANT: alpha {
    { "PAIRs" 2 } { "DOZens" 12 } { "SCOres" 20 }
    { "GRoss" 144 } { "GREATGRoss" 1,728 }
    ${ "GOOGOLs" 10 100 ^ }
}

CONSTANT: metric qw{ K M G T P E Z Y X W V U }

! Multifactorial
: m! ( n degree -- m ) neg 1 swap <range> product ;

! Separate a number from its suffix(es).
! e.g. "+1.567k" -> 1.567 "k"
: num/suffix ( str -- n suffix(es) )
    dup <head-clumps> <reversed> { } like "" map-like
    [ string>number ] map [ ] find [ tail* ] dip swap ;

! Checks whether str1 is an abbreviation of str2.
! e.g. "greatGRo" "GREATGRoss" -> t
: abbrev? ( str1 str2 -- ? )
    {
        [ [ >upper ] [ [ LETTER? ] take-while head? ] bi* ]
        [ [ length ] [email protected] <= ]
    } 2&& ;

! Convert an alpha suffix to its multiplication function.
! e.g. "Doz" -> [ 12 * ]
: alpha>quot ( str -- quot )
    [ alpha ] dip '[ first _ swap abbrev? ] find nip second
    [ * ] curry ;

! Split a suffix composed of metric and binary suffixes into its
! constituent parts. e.g. "Vikki" -> { "Vi" "k" "ki" }
: split-compound ( str -- seq )
    R/ (.i|.)/i all-matching-subseqs ;

! Convert a metric or binary suffix to its multiplication
! function. e.g. "k" -> [ 10 3 ^ * ]
: suffix>quot ( str -- quot )
    dup [ [ 0 1 ] dip subseq >upper metric index 1 + ] dip
    length 1 = [ 3 * '[ 10 _ ^ * ] ] [ 10 * '[ 2 _ ^ * ] ] if ;

! Apply suffix>quot to each member of a sequence.
! e.g. { "Vi" "k" "ki" } ->
! [ [ 2 110 ^ * ] [ 10 3 ^ * ] [ 2 10 ^ * ] ]
: map-suffix ( seq -- seq' ) [ suffix>quot ] [ ] map-as ;

! Tests whether a string is composed of metric and/or binary
! suffixes. e.g. "Vikki" -> t
: compound? ( str -- ? )
    >upper metric concat "I" append without empty? ;

! Convert a float to an integer if it is numerically equivalent
! to an integer. e.g. 1.0 -> 1, 1.23 -> 1.23
: ?f>i ( x -- y/n )
    dup >integer 2dup [ number= ] 2dip swap ? ;

! Convert a suffix string to a function that performs the
! calculations required by the suffix.
! e.g. "!!!" -> [ 3 m! ], "kiKI" -> [ 2 10 ^ * 2 10 ^ * ]
: parse-suffix ( str -- quot )
    {
        { [ dup empty? ] [ drop [ ] ] }
        { [ dup first CHAR: ! = ] [ length [ m! ] curry ] }
        { [ dup compound? ] [ split-compound map-suffix ] }
        [ alpha>quot ]
    } cond flatten ;

GENERIC: commas ( n -- str )

! Add commas to an integer in triplets.
! e.g. 1567 -> "1,567"
M: integer commas number>string <reversed> 3 group
    [ "," append ] map concat reverse rest ;

! Add commas to a float in triplets.
! e.g. 1567.12345 -> "1,567.12345"
M: float commas number>string "." split first2
    [ string>number commas ] dip "." glue ;

! Parse any number with any numerical or alphabetical suffix.
! e.g. "288Doz" -> "3,456", "9!!" -> "945"
: parse-alpha ( str -- str' )
    num/suffix parse-suffix curry call( -- x ) ?f>i commas ;

: main ( -- )
    test-cases [
        dup [ parse-alpha ] map
        "Numbers: %[%s, %]\n Result: %[%s, %]\n\n" printf
    ] each ;

MAIN: main


Class Serialize.Employee Extends %SerialObject
{

Method %OnNew(ByRef pId As %Integer = 0, pDepartment As %String, pName As %String) As %Status
{
	Do ..IDSet(pId)
	Set pId=pId+1
	Do ..DepartmentSet(pDepartment)
	Do ..NameSet(pName)
	Quit $$$OK
}

Method Print()
{
	Write "[", ..%ClassName(), "]", !
	Write "- ID: "_..IDGet(), !
	Write "- Name: "_..NameGet(), !
	Write "- Department: "_..DepartmentGet(), !
	Quit
}

Property ID As %Integer [ Private ];
Property Name As %String [ Private ];
Property Department As %String [ Private ];

}


(defmacro with-serialization-to-file ((stream pathname) &body body)
  `(with-open-file (,stream ,pathname
                            :element-type '(unsigned-byte 8)
                            :direction :output
                            :if-exists :supersede)
     ,@body))

(defclass entity ()
  ((name :initarg :name :initform "Some entity")))

(defclass person (entity)
  ((name :initarg :name :initform "The Nameless One")))


package test;
message base1 {
	  required int32 i32 = 1;
}
message base2 {
	  repeated base1 rep = 1;
}


def makeEvent(time :int) {
    return def event {
        to __printOn(out) { out.print(`@@$time`) }
        to __optUncall() { return [makeEvent, "run", [time]] }
        to getTime() { return time }
    }
}

def makeArrival(time :int, what :any, position :int) {
    return def arrival extends makeEvent(time) {
        to __printOn(out) {
            out.print(`$what to $position $super`)
        }
        to __optUncall() {
            return [makeArrival, "run", [time, what, position]]
        }

        to getWhat() { return what }
        to getPosition() { return position }
    }
}


package main

import (
    "fmt"
    "math"
    "math/big"
    "strconv"
    "strings"
)

type minmult struct {
    min  int
    mult float64
}

var abbrevs = map[string]minmult{
    "PAIRs": {4, 2}, "SCOres": {3, 20}, "DOZens": {3, 12},
    "GRoss": {2, 144}, "GREATGRoss": {7, 1728}, "GOOGOLs": {6, 1e100},
}

var metric = map[string]float64{
    "K": 1e3, "M": 1e6, "G": 1e9, "T": 1e12, "P": 1e15, "E": 1e18,
    "Z": 1e21, "Y": 1e24, "X": 1e27, "W": 1e30, "V": 1e33, "U": 1e36,
}

var binary = map[string]float64{
    "Ki": b(10), "Mi": b(20), "Gi": b(30), "Ti": b(40), "Pi": b(50), "Ei": b(60),
    "Zi": b(70), "Yi": b(80), "Xi": b(90), "Wi": b(100), "Vi": b(110), "Ui": b(120),
}

func b(e float64) float64 {
    return math.Pow(2, e)
}

func googol() *big.Float {
    g1 := new(big.Float).SetPrec(500)
    g1.SetInt64(10000000000)
    g := new(big.Float)
    g.Set(g1)
    for i := 2; i <= 10; i++ {
        g.Mul(g, g1)
    }
    return g
}

func fact(num string, d int) int {
    prod := 1
    n, _ := strconv.Atoi(num)
    for i := n; i > 0; i -= d {
        prod *= i
    }
    return prod
}

func parse(number string) *big.Float {
    bf := new(big.Float).SetPrec(500)
    t1 := new(big.Float).SetPrec(500)
    t2 := new(big.Float).SetPrec(500)
    // find index of last digit
    var i int
    for i = len(number) - 1; i >= 0; i-- {
        if '0' <= number[i] && number[i] <= '9' {
            break
        }
    }
    num := number[:i+1]
    num = strings.Replace(num, ",", "", -1) // get rid of any commas
    suf := strings.ToUpper(number[i+1:])
    if suf == "" {
        bf.SetString(num)
        return bf
    }
    if suf[0] == '!' {
        prod := fact(num, len(suf))
        bf.SetInt64(int64(prod))
        return bf
    }
    for k, v := range abbrevs {
        kk := strings.ToUpper(k)
        if strings.HasPrefix(kk, suf) && len(suf) >= v.min {
            t1.SetString(num)
            if k != "GOOGOLs" {
                t2.SetFloat64(v.mult)
            } else {
                t2 = googol() // for greater accuracy
            }
            bf.Mul(t1, t2)
            return bf
        }
    }
    bf.SetString(num)
    for k, v := range metric {
        for j := 0; j < len(suf); j++ {
            if k == suf[j:j+1] {
                if j < len(suf)-1 && suf[j+1] == 'I' {
                    t1.SetFloat64(binary[k+"i"])
                    bf.Mul(bf, t1)
                    j++
                } else {
                    t1.SetFloat64(v)
                    bf.Mul(bf, t1)
                }
            }
        }
    }
    return bf
}

func commatize(s string) string {
    if len(s) == 0 {
        return ""
    }
    neg := s[0] == '-'
    if neg {
        s = s[1:]
    }
    frac := ""
    if ix := strings.Index(s, "."); ix >= 0 {
        frac = s[ix:]
        s = s[:ix]
    }
    le := len(s)
    for i := le - 3; i >= 1; i -= 3 {
        s = s[0:i] + "," + s[i:]
    }
    if !neg {
        return s + frac
    }
    return "-" + s + frac
}

func process(numbers []string) {
    fmt.Print("numbers =  ")
    for _, number := range numbers {
        fmt.Printf("%s  ", number)
    }
    fmt.Print("\nresults =  ")
    for _, number := range numbers {
        res := parse(number)
        t := res.Text('g', 50)
        fmt.Printf("%s  ", commatize(t))
    }
    fmt.Println("\n")
}

func main() {
    numbers := []string{"2greatGRo", "24Gros", "288Doz", "1,728pairs", "172.8SCOre"}
    process(numbers)

    numbers = []string{"1,567", "+1.567k", "0.1567e-2m"}
    process(numbers)

    numbers = []string{"25.123kK", "25.123m", "2.5123e-00002G"}
    process(numbers)

    numbers = []string{"25.123kiKI", "25.123Mi", "2.5123e-00002Gi", "+.25123E-7Ei"}
    process(numbers)

    numbers = []string{"-.25123e-34Vikki", "2e-77gooGols"}
    process(numbers)

    numbers = []string{"9!", "9!!", "9!!!", "9!!!!", "9!!!!!", "9!!!!!!",
        "9!!!!!!!", "9!!!!!!!!", "9!!!!!!!!!"}
    process(numbers)
}


(define (person->string self) (format "%a : person." (person-name self)))
(define (writer->string self) (format "%a:  writer of %a."
			(person-name self)
			(writer-books self)))
(define  (father->string self) (format "%a: father of %a."
			(person-name self)
			(map person-name (father-children self))))

; 'classes' definition, with inheritance.
; a writer is a person, too.
(struct person (name)  #:tostring person->string)
(struct writer person (books) #:tostring writer->string)
(struct father person (children)  #:tostring father->string)

(define simon (writer "Simon" '(my-life my-wife my-bike)))
(define elvis (person "Elvis"))
(define papa (father "papa" (list simon elvis)))

(local-put-value 'simon simon "objects.dat")
📕 local-db: local-put:unknown store : "objects.dat"
;; forgot to create the store. Create it :
(local-make-store "objects.dat") → "objects.dat"

(local-put-value 'simon simon "objects.dat")
(local-put-value 'elvis elvis "objects.dat")
(local-put-value 'papa papa   "objects.dat")

;; inspect
simon → Simon: writer of (my-life my-wife my-bike).
papa → papa: father of (Simon Elvis).
elvis → Elvis : person.


-module( object_serialization ).

-export( [task/0] ).

-record( entity, {name, date} ).
-record( person, {entity, email} ).

task() ->
	Person = #person{entity=#entity{name="Cletus", date=20080808}, email="[email protected]"},
	print( Person ),
	Entity = #entity{name="Entity", date=20111111},
	print( Entity ),
	ok = file:write_file( "objects.dat", erlang:term_to_binary([Person, Entity]) ),
	{ok, Binary} =  file:read_file( "objects.dat" ),
	[New_person, New_entity] = erlang:binary_to_term( Binary ),
	io:fwrite( "Deserialized\n" ),
	print( New_person ),
	print( New_entity ).

print( #entity{name=Name, date=Date} ) ->
	io:fwrite( "Entity: " ),
	io:fwrite( "name: ~p, date: ~p~n", [Name, Date] );
print( #person{entity=Entity, email=Email} ) ->
	io:fwrite( "Person: " ),
	print( Entity ),
	io:fwrite( "\temail: ~p~n", [Email] ).


using Formatting

partialsuffixes = Dict("PAIR" => "PAIRS", "SCO" => "SCORES", "DOZ" => "DOZENS",
                    "GR" => "GROSS", "GREATGR" => "GREATGROSS", "GOOGOL" => "GOOGOLS")
partials = sort(collect(keys(partialsuffixes)), lt=(a,b)->length(a)<length(b), rev=true)

multicharsuffixes = Dict("PAIRS" => 2, "SCORES" => 20, "DOZENS" => 12, "GROSS" => 144,
                         "GREATGROSS" => 1728, "GOOGOLS" => BigInt(10)^100)

twocharsuffixes = Dict(
    "KI" => BigInt(2)^10, "MI" => BigInt(2)^20, "GI" => BigInt(2)^30, "TI" => BigInt(2)^40,
    "PI" => BigInt(2)^50, "EI" => BigInt(2)^60, "ZI" => BigInt(2)^70, "YI" => BigInt(2)^80,
    "XI" => BigInt(2)^90, "WI" => BigInt(2)^100, "VI" => BigInt(2)^110, "UI" => BigInt(2)^120)
twosuff = collect(keys(twocharsuffixes))

onecharsuffixes = Dict("K" => 10^3, "M" => 10^6, "G" => 10^9, "T" => 10^12, "P" => 10^15,
                       "E" => 10^18, "Z" => 10^21, "Y" => BigInt(10)^24,
                       "X" => BigInt(10)^27, "W" => BigInt(10)^30,
                       "V" => BigInt(10)^33, "U" => BigInt(10)^36)
onesuff = collect(keys(onecharsuffixes))

function firstsuffix(s, x)
    str = uppercase(s)
    if str[1] == '!'
        lastbang = something(findfirst(x -> x != '!', str), length(str))
        return prod(x:-lastbang:1) / x, lastbang
    end
    for pstr in partials
        if match(Regex("^" * pstr), str) != nothing
            fullsuffix = partialsuffixes[pstr]
            n = length(pstr)
            while n < length(fullsuffix) && n < length(str) && fullsuffix[n+1] == str[n+1]
                n += 1
            end
            return BigInt(multicharsuffixes[fullsuffix]), n
        end
    end
    for pstr in twosuff
        if match(Regex("^" * pstr), str) != nothing
            return BigInt(twocharsuffixes[pstr]), 2
        end
    end
    for pstr in onesuff
        if match(Regex("^" * pstr), str) != nothing
            return BigInt(onecharsuffixes[pstr]), 1
        end
    end
    return 1, length(s)
end

function parsesuffix(s, x)
    str = s
    mult = BigInt(1)
    n = 1
    while n <= length(str)
        multiplier, n = firstsuffix(str, x)
        mult *= multiplier
        str = str[n+1:end]
    end
    mult
end

function suffixednumber(s)
    if (endnum = findlast(isdigit, s)) == nothing
        return NaN
    end
    x = BigFloat(replace(s[1:endnum], "," => ""))
    return x * (endnum < length(s) ? parsesuffix(s[endnum + 1:end], x) : 1)
end

const testcases =
["2greatGRo   24Gros  288Doz  1,728pairs  172.8SCOre",
 "1,567      +1.567k    0.1567e-2m",
 "25.123kK    25.123m   2.5123e-00002G",
 "25.123kiKI  25.123Mi  2.5123e-00002Gi  +.25123E-7Ei",
 "-.25123e-34Vikki      2e-77gooGols",
 "9!   9!!   9!!!   9!!!!   9!!!!!   9!!!!!!   9!!!!!!!   9!!!!!!!!   9!!!!!!!!!"]

function testsuffixes()
    for line in testcases
        cases = split(line)
        println("Testing: ", string.(cases))
        println("Results: ", join(map(x -> format(suffixednumber(x), commas=true), cases), "  "), "\n")
    end
end

testsuffixes()


import re, strutils, parseutils, tables, math
const input = """
    2greatGRo   24Gros  288Doz  1,728pairs  172.8SCOre
    1,567      +1.567k    0.1567e-2m
    25.123kK    25.123m   2.5123e-00002G
    25.123kiKI  25.123Mi  2.5123e-00002Gi  +.25123E-7Ei
    -.25123e-34Vikki      2e-77gooGols
    9!   9!!   9!!!   9!!!!   9!!!!!   9!!!!!!   9!!!!!!!   9!!!!!!!!   9!!!!!!!!!
    """
let
  abbrAlpha = re(r"(PAIR)(s)?$|(SCO)(r|re|res)?$|(DOZ)(e|en|ens)?$|(GR)(o|os|oss)?$|(GREATGR)(o|os|oss)?$|(GOOGOL)(s)?$",
      flags = {reIgnoreCase})
  metricBinary = re(r"[KMGTPEZYXWVU]i?", flags = {reIgnoreCase})
  factorial = re"!+$"
const
  alphaValues = [2e0, 20e0, 12e0, 144e0, 1728e0, 1e100]
  metricBinaryValueTab = {"K": 10.0^3, "KI": 2.0^10, "M": 10.0^6, "MI": 2.0^20,
      "G": 10.0^9, "GI": 2.0^30, "T": 10.0^12, "TI": 2.0^40, "P": 10.0^15,
      "PI": 2.0^50, "E": 10.0^18, "EI": 2.0^60, "Z": 10.0^21, "ZI": 2.0^70,
      "Y": 10.0^24, "YI": 2.0^80, "X": 10.0^27, "XI": 2.0^90, "W": 10.0^30,
      "WI": 2.0^100, "V": 10.0^33, "VI": 2.0^110, "U": 10.0^36,
      "UI": 2.0^120}.toTable
var
  matches: array[12, string]
  res, fac: float
  suffix: string
proc sepFloat(f: float): string =
  var
    s = $f
    i, num: int
  num = parseInt(s, i)
  if num == 0:
    return s
  else:
    return insertSep($i, ',', 3)&s[num..^1]
for line in input.splitLines():
  if not isEmptyOrWhiteSpace(line):
    echo("Input:\n", line, "\nOutput:")
    var output = "    "
    for raw_number in line.replace(",", "").splitWhiteSpace():
      suffix = raw_number[parseutils.parseFloat(raw_number, res)..^1].toUpper()
      if suffix.match(abbrAlpha, matches):
        for i, v in matches.mpairs():
          if i mod 2 == 0 and not v.isEmptyOrWhiteSpace():
            res*=alphaValues[i div 2]
            v = ""
            break
      elif suffix.match(factorial):
        fac = abs(res)-toFloat(len(suffix))
        while fac > 0:
          res*=fac
          fac-=toFloat(len(suffix))
      elif suffix.match(metricBinary):
        for m in suffix.findAll(metricBinary):
          res*=metricBinaryValueTab[m]
      output &= sepFloat(res)&"  "
    echo(output)


USING: accessors combinators.extras io io.encodings.binary
io.files io.files.info kernel prettyprint serialize ;
IN: rosetta-code.object-serialization

! Define two classes, item and armor. armor is a subclass of
! item.

TUPLE: item name value ;
TUPLE: armor < item physical-resistance fire-resistance ;

! Define boa constructors for both classes using C: shorthand.
! boa means By Order of Arguments, and yes, this is a pun on boa
! constrictors.

C: <item> item
C: <armor> armor

! Create three example items and print them out
! non-destructively.

"Fish scales" 0.05 <item>
"Gold piece" 1 <item>
"Breastplate of Ashannar" 50,000 55 30 <armor>
[ [ . ] keep ] [email protected] nl

! Serialize the three objects to a binary file named
! objects.dat.

"Serializing objects to objects.dat . . . " print
"objects.dat" binary [ [ serialize ] [email protected] ] with-file-writer

! Check that objects.dat exists.

"objects.dat exists? " write "objects.dat" exists? .
"Size on disk: " write "objects.dat" file-info size>> pprint
" bytes" print nl

! Deserialize three objects from objects.dat.

"Deserializing objects from objects.dat . . . " print nl
"objects.dat" binary [ [ deserialize ] thrice ] with-file-reader

! Print out deserialized objects.

[ . ] [email protected]


package main

import (
    "encoding/gob"
    "fmt"
    "os"
)

type printable interface {
    print()
}

func main() {
    // create instances
    animals := []printable{
        &Animal{Alive: true},
        &Cat{},
        &Lab{
            Dog:   Dog{Animal: Animal{Alive: true}},
            Color: "yellow",
        },
        &Collie{Dog: Dog{
            Animal:           Animal{Alive: true},
            ObedienceTrained: true,
        }},
    }

    // display
    fmt.Println("created:")
    for _, a := range animals {
        a.print()
    }

    // serialize
    f, err := os.Create("objects.dat")
    if err != nil {
        fmt.Println(err)
        return
    }
    for _, a := range animals {
        gob.Register(a)
    }
    err = gob.NewEncoder(f).Encode(animals)
    if err != nil {
        fmt.Println(err)
        return
    }
    f.Close()

    // read
    f, err = os.Open("objects.dat")
    if err != nil {
        fmt.Println(err)
        return
    }
    var clones []printable
    gob.NewDecoder(f).Decode(&clones)
    if err != nil {
        fmt.Println(err)
        return
    }

    // display
    fmt.Println("\nloaded from objects.dat:")
    for _, c := range clones {
        c.print()
    }
}

type Animal struct {
    Alive bool
}

func (a *Animal) print() {
    if a.Alive {
        fmt.Println("   live animal, unspecified type")
    } else {
        fmt.Println("   dead animal, unspecified type")
    }
}

type Dog struct {
    Animal
    ObedienceTrained bool
}

func (d *Dog) print() {
    switch {
    case !d.Alive:
        fmt.Println("   dead dog")
    case d.ObedienceTrained:
        fmt.Println("   trained dog")
    default:
        fmt.Println("   dog, not trained")
    }
}

type Cat struct {
    Animal
    LitterBoxTrained bool
}

func (c *Cat) print() {
    switch {
    case !c.Alive:
        fmt.Println("   dead cat")
    case c.LitterBoxTrained:
        fmt.Println("   litter box trained cat")
    default:
        fmt.Println("   cat, not litter box trained")
    }
}

type Lab struct {
    Dog
    Color string
}

func (l *Lab) print() {
    var r string
    if l.Color == "" {
        r = "lab, color unspecified"
    } else {
        r = l.Color + " lab"
    }
    switch {
    case !l.Alive:
        fmt.Println("   dead", r)
    case l.ObedienceTrained:
        fmt.Println("   trained", r)
    default:
        fmt.Printf("   %s, not trained\n", r)
    }
}

type Collie struct {
    Dog
    CatchesFrisbee bool
}

func (c *Collie) print() {
    switch {
    case !c.Alive:
        fmt.Println("   dead collie")
    case c.ObedienceTrained && c.CatchesFrisbee:
        fmt.Println("   trained collie, catches frisbee")
    case c.ObedienceTrained && !c.CatchesFrisbee:
        fmt.Println("   trained collie, but doesn't catch frisbee")
    case !c.ObedienceTrained && c.CatchesFrisbee:
        fmt.Println("   collie, not trained, but catches frisbee")
    case !c.ObedienceTrained && !c.CatchesFrisbee:
        fmt.Println("   collie, not trained, doesn't catch frisbee")
    }
}


with javascript_semantics
include builtins/bigatom.e
{} = ba_scale(34)   -- (min rqd for accuracy on the "Vikki" test)
                    -- (the default is 25, not quite enough here)

constant suffixes = {{"GREATGRoss",7,1728},
                     {"GOOGOLs",6,ba_new("1e100")},
                     {"SCOres",3,20},
                     {"DOZens",3,12},
                     {"GRoss",2,144},
                     {"PAIRs",4,2},
                     "KMGTPEZYXWVU"}

function decode(string suffix)
    bigatom res = BA_ONE
    suffix = upper(suffix)
    while length(suffix)>0 do
        bool found = false
        for i=length(suffix) to 2 by -1 do
            for s=1 to length(suffixes)-1 do
                if i<=length(suffixes[s][1])
                and i>=suffixes[s][2]
                and suffix[1..i]=upper(suffixes[s][1][1..i]) then
                    res = ba_mul(res,suffixes[s][3])
                    suffix = suffix[i+1..$]
                    found = true
                    exit
                end if
            end for
            if found then exit end if
        end for
        if not found then
            integer k = find(suffix[1],suffixes[$])
            if k=0 then ?9/0 end if
            if length(suffix)>=2 and suffix[2]='I' then
                res = ba_mul(res,ba_power(1024,k))
                suffix = suffix[3..$]
            else
                res = ba_mul(res,ba_power(1000,k))
                suffix = suffix[2..$]
            end if
        end if
    end while
    return res
end function

function facto(bigatom n, integer f)
    if f!=0 then
        bigatom nf = ba_sub(n,f)
        while ba_compare(nf,2)>=0 do
            n = ba_mul(n,nf)
            nf = ba_sub(nf,f)
        end while
    end if
    return n
end function

constant test_cases = """
2greatGRo  24Gros  288Doz  1,728pairs  172.8SCOre
1,567  +1.567k  0.1567e-2m
25.123kK  25.123m  2.5123e-00002G
25.123kiKI  25.123Mi  2.5123e-00002Gi  +.25123E-7Ei
-.25123e-34Vikki  2e-77gooGols
9! 9!! 9!!! 9!!!! 9!!!!! 9!!!!!! 9!!!!!!! 9!!!!!!!! 9!!!!!!!!!
0.017k!!
"""
constant tests = split(substitute(test_cases,"\n"," "),no_empty:=true)

for i=1 to length(tests) do
    string test = tests[i], suffix = "", facts = ""
    for f=length(test) to 1 by -1 do
        if test[f]!='!' then
            {test,facts} = {test[1..f],test[f+1..$]}
            exit
        end if
    end for
    for d=length(test) to 1 by -1 do
        integer digit = test[d]
        if digit>='0' and digit<='9' then
            {test,suffix} = {test[1..d],test[d+1..$]}
            exit
        end if
    end for
    bigatom n = ba_new(substitute(test,",",""))
    n = ba_mul(n,decode(suffix))
    n = facto(n,length(facts))
    string ns = ba_sprintf("%,B",n)
    printf(1,"%30s : %s\n",{tests[i],ns})
end for


class Entity implements Serializable {
    static final serialVersionUID = 3504465751164822571L
    String name = 'Thingamabob'
    public String toString() { return name }
}

class Person extends Entity implements Serializable {
    static final serialVersionUID = -9170445713373959735L
    Person() { name = 'Clement' }
    Person(name) { this.name = name }
}


{-# LANGUAGE DeriveGeneric #-}

module Main (main) where

import qualified Data.ByteString.Lazy as ByteString (readFile, writeFile)
import           Data.Binary (Binary)
import qualified Data.Binary as Binary (decode, encode)
import           GHC.Generics (Generic)

data Employee =
    Manager String String
    | IndividualContributor String String
    deriving (Generic, Show)
instance Binary Employee

main :: IO ()
main = do
    ByteString.writeFile "objects.dat" $ Binary.encode
        [ IndividualContributor "John Doe" "Sales"
        , Manager "Jane Doe" "Engineering"
        ]

    bytes <- ByteString.readFile "objects.dat"
    let employees = Binary.decode bytes
    print (employees :: [Employee])


from functools import reduce
from operator import mul
from decimal import *

getcontext().prec = MAX_PREC

def expand(num):
    suffixes = [
        #     (name, min_abbreviation_length, base, exponent)
        ('greatgross', 7, 12, 3),
        ('gross', 2, 12, 2),
        ('dozens', 3, 12, 1),
        ('pairs', 4, 2, 1),
        ('scores', 3, 20, 1),
        ('googols', 6, 10, 100),
        ('ki', 2, 2, 10),
        ('mi', 2, 2, 20),
        ('gi', 2, 2, 30),
        ('ti', 2, 2, 40),
        ('pi', 2, 2, 50),
        ('ei', 2, 2, 60),
        ('zi', 2, 2, 70),
        ('yi', 2, 2, 80),
        ('xi', 2, 2, 90),
        ('wi', 2, 2, 100),
        ('vi', 2, 2, 110),
        ('ui', 2, 2, 120),
        ('k', 1, 10, 3),
        ('m', 1, 10, 6),
        ('g', 1, 10, 9),
        ('t', 1, 10, 12),
        ('p', 1, 10, 15),
        ('e', 1, 10, 18),
        ('z', 1, 10, 21),
        ('y', 1, 10, 24),
        ('x', 1, 10, 27),
        ('w', 1, 10, 30)
    ]

    num = num.replace(',', '').strip().lower()

    if num[-1].isdigit():
        return float(num)

    for i, char in enumerate(reversed(num)):
        if char.isdigit():
            input_suffix = num[-i:]
            num = Decimal(num[:-i])
            break

    if input_suffix[0] == '!':
        return reduce(mul, range(int(num), 0, -len(input_suffix)))

    while len(input_suffix) > 0:
        for suffix, min_abbrev, base, power in suffixes:
            if input_suffix[:min_abbrev] == suffix[:min_abbrev]:
                for i in range(min_abbrev, len(input_suffix) + 1):
                    if input_suffix[:i+1] != suffix[:i+1]:
                        num *= base ** power
                        input_suffix = input_suffix[i:]
                        break
                break

    return num

test = "2greatGRo   24Gros  288Doz  1,728pairs  172.8SCOre\n\
        1,567      +1.567k    0.1567e-2m\n\
        25.123kK    25.123m   2.5123e-00002G\n\
        25.123kiKI  25.123Mi  2.5123e-00002Gi  +.25123E-7Ei\n\
        -.25123e-34Vikki      2e-77gooGols\n\
        9!   9!!   9!!!   9!!!!   9!!!!!   9!!!!!!   9!!!!!!!   9!!!!!!!!   9!!!!!!!!!"

for test_line in test.split("\n"):
    test_cases = test_line.split()
    print("Input:", ' '.join(test_cases))
    print("Output:", ' '.join(format(result, ',f').strip('0').strip('.') for result in map(expand, test_cases)))


lin_z_=:5!:5
serializeObject=:3 :0
  p=. copath y
  d=. ;LF;"1(,'=:';lin__y)"0 nl__y i.4
  '(',(5!:5<'p'),')(copath[[email protected]])cocreate ''''',,d,LF
)

deserializeObject=:3 :0
  o=.conl 1
  0!:100 y
  (conl 1)-.o
)

coclass'room'
  create=:3 :'size=:y'
  print=:3 :'''room size '',":size'

coclass'kitchen'
  coinsert'room'
  print=:3 :'''kitchen size '',":size'

coclass'kitchenWithSink'
  coinsert'kitchen'
  print=:3 :'''kitchen with sink size '',":size'

cocurrent'base'

R=:'small' conew 'room'
K=:'medium' conew 'kitchen'
S=:'large' conew 'kitchenWithSink'
print__R''
print__K''
print__S''

(;<@serializeObject"0 R,K,S) 1!:2 <'objects.dat'

'r1 k1 s1'=: <"0 deserializeObject 1!:1<'objects.dat'
print__r1''
print__k1''
print__s1''


import java.io.*;

// classes must implement java.io.Serializable in order to be serializable
class Entity implements Serializable {
    // it is recommended to hard-code serialVersionUID so changes to class
    // will not invalidate previously serialized objects
    static final long serialVersionUID = 3504465751164822571L;
    String name = "Entity";
    public String toString() { return name; }
}

class Person extends Entity implements Serializable {
    static final long serialVersionUID = -9170445713373959735L;
    Person() { name = "Cletus"; }
}

public class SerializationTest {
    public static void main(String[] args) {
        Person instance1 = new Person();
        System.out.println(instance1);

        Entity instance2 = new Entity();
        System.out.println(instance2);

        // Serialize
        try {
            ObjectOutput out = new ObjectOutputStream(new FileOutputStream("objects.dat")); // open ObjectOutputStream

            out.writeObject(instance1); // serialize "instance1" and "instance2" to "out"
            out.writeObject(instance2);
            out.close();
            System.out.println("Serialized...");
        } catch (IOException e) {
            System.err.println("Something screwed up while serializing");
            e.printStackTrace();
            System.exit(1);
        }

        // Deserialize
        try {
            ObjectInput in = new ObjectInputStream(new FileInputStream("objects.dat")); // open ObjectInputStream

            Object readObject1 = in.readObject(); // read two objects from "in"
            Object readObject2 = in.readObject(); // you may want to cast them to the appropriate types
            in.close();
            System.out.println("Deserialized...");

            System.out.println(readObject1);
            System.out.println(readObject2);
        } catch (IOException e) {
            System.err.println("Something screwed up while deserializing");
            e.printStackTrace();
            System.exit(1);
        } catch (ClassNotFoundException e) {
            System.err.println("Unknown class for deserialized object");
            e.printStackTrace();
            System.exit(1);
        }
    }
}


use Rat::Precise;

my $googol = 10**100;
«PAIRs 2 SCOres 20 DOZens 12 GRoss 144  GREATGRoss 1728 GOOGOLs $googol»
  ~~ m:g/ ((<.:Lu>+) <.:Ll>*) \s+ (\S+) /;

my %abr = |$/.map: {
    my $abbrv = .[0].Str.fc;
    my $mag   = +.[1];
    |map { $abbrv.substr( 0, $_ ) => $mag },
    .[0][0].Str.chars .. $abbrv.chars
}

my %suffix = flat %abr,
(<K  M  G  T  P  E  Z  Y  X  W  V  U>».fc  Z=> (1000, * * 1000 … *)),
(<Ki Mi Gi Ti Pi Ei Zi Yi Xi Wi Vi Ui>».fc Z=> (1024, * * 1024 … *));

my $reg = %suffix.keys.join('|');

sub comma ($i is copy) {
    my $s = $i < 0 ?? '-' !! '';
    my ($whole, $frac) = $i.split('.');
    $frac = $frac.defined ?? ".$frac" !! '';
    $s ~ $whole.abs.flip.comb(3).join(',').flip ~ $frac
}

sub units (Str $str) {
    $str.fc ~~ /^(.+?)(<alpha>*)('!'*)$/;
    my ($val, $unit, $fact) = $0, $1.Str.fc, $2.Str;
    $val.=subst(',', '', :g);
    if $val ~~ m:i/'e'/ {
        my ($m,$e) = $val.split(/<[eE]>/);
        $val = ($e < 0)
            ?? $m * FatRat.new(1,10**-$e)
            !! $m * 10**$e;
    }
    my @suf = $unit;
    unless %suffix{$unit}:exists {
        $unit ~~ /(<$reg>)+/;
        @suf = $0;
    }
    my $ret = $val<>;
    $ret = [*] $ret, |@suf.map: { %suffix{$_} } if @suf[0];
    $ret = [*] ($ret, * - $fact.chars …^ * < 2) if $fact.chars;
    $ret.?precise // $ret
}

my $test = q:to '===';
2greatGRo   24Gros  288Doz  1,728pairs  172.8SCOre
1,567      +1.567k    0.1567e-2m
25.123kK    25.123m   2.5123e-00002G
25.123kiKI  25.123Mi  2.5123e-00002Gi  +.25123E-7Ei
-.25123e-34Vikki      2e-77gooGols
9!   9!!   9!!!   9!!!!   9!!!!!   9!!!!!!   9!!!!!!!   9!!!!!!!!   9!!!!!!!!!
.017k!!
===

printf "%16s: %s\n", $_, comma .&units for $test.words;

# Task required stupid layout
# say "\n In: $_\nOut: ", .words.map({comma .&units}).join('  ') for $test.lines;


abstract type Hello end

struct HelloWorld <: Hello
    name::String
    HelloWorld(s) = new(s)
end

struct HelloTime <: Hello
    name::String
    tnew::DateTime
    HelloTime(s) = new(s, now())
end

sayhello(hlo) = println("Hello to this world, $(hlo.name)!")

sayhello(hlo::HelloTime) = println("It is now $(now()). Hello from back in $(hlo.tnew), $(hlo.name)!")

h1 = HelloWorld("world")
h2 = HelloTime("new world")

sayhello(h1)
sayhello(h2)

fh = open("objects.dat", "w")
serialize(fh, h1)
serialize(fh,h2)
close(fh)

sleep(10)

fh = open("objects.dat", "r")
hh1 = deserialize(fh)
hh2 = deserialize(fh)
close(fh)

sayhello(hh1)
sayhello(hh2)


// version 1.2.0

import java.io.*

open class Entity(val name: String = "Entity"): Serializable {
    override fun toString() = name

    companion object {
        val serialVersionUID = 3504465751164822571L
    }
}

class Person(name: String = "Brian"): Entity(name), Serializable {
    companion object {
        val serialVersionUID = -9170445713373959735L
    }
}

fun main(args: Array<String>) {
    val instance1 = Person()
    println(instance1)

    val instance2 = Entity()
    println(instance2)

    // serialize
    try {
        val out = ObjectOutputStream(FileOutputStream("objects.dat"))
        out.writeObject(instance1)
        out.writeObject(instance2)
        out.close()
        println("Serialized...")
    }
    catch (e: IOException) {
        println("Error occurred whilst serializing")
        System.exit(1)
    }

    // deserialize
    try {
        val inp = ObjectInputStream(FileInputStream("objects.dat"))
        val readObject1 = inp.readObject()
        val readObject2 = inp.readObject()
        inp.close()
        println("Deserialized...")
        println(readObject1)
        println(readObject2)
    }
    catch (e: IOException) {
        println("Error occurred whilst deserializing")
        System.exit(1)
    }
    catch (e: ClassNotFoundException) {
        println("Unknown class for deserialized object")
        System.exit(1)
    }
}


/* Object serialization, in Neko */

var file_open = $loader.loadprim("[email protected]_open", 2)
var file_write = $loader.loadprim("[email protected]_write", 4)
var file_read = $loader.loadprim("[email protected]_read", 4)
var file_close = $loader.loadprim("[email protected]_close", 1)

var serialize = $loader.loadprim("[email protected]", 1)
var unserialize = $loader.loadprim("[email protected]", 2)

/* Inheritance by prototype */
proto = $new(null)
proto.print = function () { $print(this, "\n") }

obj = $new(null)
obj.msg = "Hello"
obj.dest = $array("Town", "Country", "World")

$objsetproto(obj, proto)
$print("Original:\n")
obj.print()

/* Serialize the object */
var thing = serialize(obj)
var len = $ssize(thing)

/* To disk */
var f = file_open("object-serialization.bin", "w")
file_write(f, thing, 0, len)
file_close(f)

/* Load the binary data into a new string space */
f = file_open("object-serialization.bin", "r")
var buff = $smake(len)
file_read(f, buff, 0, len)
file_close(f)

/* Unserialize the object into a new variable */
var other = unserialize(buff, $loader)
$print("deserialized:\n")
other.print()


/*REXX pgm converts numbers (with commas) with suffix multipliers──►pure decimal numbers*/
numeric digits 2000                              /*allow the usage of ginormous numbers.*/
@.=; @.1= '2greatGRo   24Gros  288Doz  1,728pairs  172.8SCOre'
     @.2= '1,567      +1.567k    0.1567e-2m'
     @.3= '25.123kK    25.123m   2.5123e-00002G'
     @.4= '25.123kiKI  25.123Mi  2.5123e-00002Gi  +.25123E-7Ei'
     @.5= '-.25123e-34Vikki      2e-77gooGols'
     @.6=  9!   9!!   9!!!   9!!!!   9!!!!!   9!!!!!!   9!!!!!!!   9!!!!!!!!   9!!!!!!!!!

parse arg x                                      /*obtain optional arguments from the CL*/
if x\==''  then do;    @.2=;     @.1=x           /*use the number(s) specified on the CL*/
                end                              /*allow user to specify their own list.*/
                                                 /* [↓]  handle a list or multiple lists*/
    do  n=1  while @.n\=='';     $=              /*process each of the numbers in lists.*/
    say 'numbers= '      @.n                     /*echo the original arg to the terminal*/

        do j=1  for words(@.n);  y= word(@.n, j) /*obtain a single number from the input*/
        $= $  ' 'commas( num(y) )                /*process a number; add result to list.*/
        end   /*j*/                              /* [↑]  add commas to number if needed.*/
                                                 /* [↑]  add extra blank betweenst nums.*/
    say ' result= '      strip($);   say         /*echo the result(s) to the terminal.  */
    end       /*n*/                              /* [↑]  elide the  pre-pended  blank.  */
exit                                             /*stick a fork in it,  we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
isInt:  return datatype( arg(1), 'Whole')        /*return 1 if arg is an integer,  or 0 */
isNum:  return datatype( arg(1), 'Number')       /*   "   "  "  "   " a  number.    " " */
p:      return word( arg(1), 1)                  /*pick 1st argument  or  2nd argument. */
ser:    say;   say '***error*** '  arg(1);           say;            exit 13
shorten:procedure; parse arg a,n;      return left(a,  max(0, length(a) - p(n 1) ) )
/*──────────────────────────────────────────────────────────────────────────────────────*/
$fact!: procedure; parse arg x _ .;    L= length(x);    n= L - length(strip(x, 'T', "!") )
        if n<=-n | _\=='' | arg()\==1  then return x;   z= left(x, L - n)
        if z<0 | \isInt(z)             then return x;   return $fact(z, n)
/*──────────────────────────────────────────────────────────────────────────────────────*/
$fact:  procedure; parse arg x _ .;  arg ,n ! .;     n= p(n 1);    if \isInt(n)  then n= 0
        if x<-n | \isInt(x) |n<1 | _||!\=='' |arg()>2  then return x||copies("!",max(1,n))
        s= x // n;   if s==0  then s= n          /*compute where to start multiplying.  */
        != 1                                     /*the initial factorial product so far.*/
                   do j=s  to x  by n;   != !*j  /*perform the actual factorial product.*/
                   end   /*j*/                   /*{operator  //  is REXX's ÷ remainder}*/
        return !                                 /* [↑]  handles any level of factorial.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
$sfxa:  parse arg u,s 1 c,m;   upper u c         /*get original version & upper version.*/
        if pos( left(s, 2), u)\==0  then do j=length(s)   to compare(s, c)-1   by -1
                                         if right(u, j) \== left(c, j)  then iterate
                                         _= left(u, length(u) - j)        /*get the num.*/
                                         if isNum(_)  then return m * _   /*good suffix.*/
                                         leave                            /*return as is*/
                                         end
        return arg(1)                            /* [↑]  handles an alphabetic suffixes.*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
$sfx!:  parse arg y;                     if right(y, 1)=='!'  then y= $fact!(y)
        if \isNum(y)  then y=$sfxz();    if isNum(y)  then return y;       return $sfxm(y)
/*──────────────────────────────────────────────────────────────────────────────────────*/
$sfxm:  parse arg z 1 w;     upper w;    @= 'KMGTPEZYXWVU';                       b= 1000
        if right(w, 1)=='I'  then do;    z= shorten(z);      w= z;    upper w;    b= 1024
                                  end
        _= pos( right(w, 1), @);         if _==0      then return arg(1)
        n= shorten(z);  r= num(n, , 1);  if isNum(r)  then return r * b**_
        return arg(1)                            /* [↑]  handles metric or binary suffix*/
/*──────────────────────────────────────────────────────────────────────────────────────*/
$sfxz:  return $sfxa( $sfxa( $sfxa( $sfxa( $sfxa( $sfxa(y, 'PAIRs', 2),   'DOZens', 12), ,
           'SCores', 20),   'GREATGRoss',  1728),     'GRoss', 144),     'GOOGOLs', 1e100)
/*──────────────────────────────────────────────────────────────────────────────────────*/
commas: procedure;  parse arg _;    n= _'.9';      #= 123456789;      b= verify(n, #, "M")
        e= verify(n, #'0', ,   verify(n, #"0.", 'M') )  -  4         /* [↑]  add commas.*/
           do j=e  to b  by -3;   _= insert(',', _, j);     end  /*j*/;           return _
/*──────────────────────────────────────────────────────────────────────────────────────*/
num:    procedure; parse arg x .,,q;         if x==''  then return x
        if  isNum(x)  then return  x/1;      x= space( translate(x, , ','), 0)
        if \isNum(x)  then x= $sfx!(x);      if isNum(x)  then return x/1
        if q==1  then return x
        if q==''  then call ser "argument isn't numeric or doesn't have a legal suffix:" x


import marshal, streams

type
  Base = object of RootObj
    name: string
  Descendant = object of Base
proc newBase(): Base = Base(name: "base")
proc newDescendant(): Descendant = Descendant(name: "descend")
proc print(obj: Base) =
  echo(obj.name)

var
  base = newBase()
  descendant = newDescendant()
print(base)
print(descendant)

var strm = newFileStream("objects.dat", fmWrite)
store(strm, (base, descendant))
strm.close()

var t: (Base, Descendant)
load(newFileStream("objects.dat", fmRead), t)
print(t[0])
print(t[1])


bundle Default {
  class Thingy {
    @id : Int;

    New(id : Int) {
      @id := id;
    }

    method : public : Print() ~ Nil {
      @id->PrintLine();
    }
  }

  class Person from Thingy {
    @name : String;

    New(id : Int, name : String) {
      Parent(id);
      @name := name;
    }

    method : public : Print() ~ Nil {
      @id->PrintLine();
      @name->PrintLine();
    }
  }

  class Serial {
    function : Main(args : String[]) ~ Nil {
      t := Thingy->New(7);
      p := Person->New(13, "Bush");

      s := IO.Serializer->New();
      s->Write(t->As(Base));
      s->Write(p->As(Base));

      writer := IO.FileWriter->New("objects.dat");
      writer->WriteBuffer(s->Serialize());
      writer->Close();

      buffer := IO.FileReader->ReadBinaryFile("objects.dat");
      d := IO.Deserializer->New(buffer);

      t2 := d->ReadObject()->As(Thingy);
      t2->Print();
      p2 := d->ReadObject()->As(Person);
      p2->Print();
    }
  }
}


import "/big" for BigRat
import "/str" for Str
import "/fmt" for Fmt

var abbrevs = {
    "PAIRs": [4, 2], "SCOres": [3, 20], "DOZens": [3, 12],
    "GRoss": [2, 144], "GREATGRoss": [7, 1728], "GOOGOLs": [6, 1e100]
}

var metric = {
    "K": 1e3,  "M": 1e6,  "G": 1e9,  "T": 1e12, "P": 1e15, "E": 1e18,
    "Z": 1e21, "Y": 1e24, "X": 1e27, "W": 1e30, "V": 1e33, "U": 1e36
}

var b = Fn.new { |e| BigRat.two.pow(e) }

var binary = {
    "Ki": b.call(10), "Mi": b.call(20),  "Gi": b.call(30),  "Ti": b.call(40),
    "Pi": b.call(50), "Ei": b.call(60),  "Zi": b.call(70),  "Yi": b.call(80),
    "Xi": b.call(90), "Wi": b.call(100), "Vi": b.call(110), "Ui": b.call(120)
}

var googol = BigRat.fromDecimal("1e100")

var fact = Fn.new { |num, d|
    var prod = 1
    var n = Num.fromString(num)
    var i = n
    while (i > 0) {
        prod = prod * i
        i = i - d
    }
    return prod
}

var parse = Fn.new { |number|
    // find index of last digit
    var i = number.count - 1
    while (i >= 0) {
        if (48 <= number.bytes[i] && number.bytes[i] <= 57) break
        i = i - 1
    }
    var num = number[0..i]
    num = num.replace(",", "") // get rid of any commas
    var suf = Str.upper(number[i+1..-1])
    if (suf == "") return BigRat.fromDecimal(num)
    if (suf[0] == "!") {
        var prod = fact.call(num, suf.count)
        return BigRat.new(prod)
    }
    for (me in abbrevs) {
        var kk = Str.upper(me.key)
        if (kk.startsWith(suf) && suf.count >= me.value[0]) {
            var t1 = BigRat.fromDecimal(num)
            var t2 = (me.key != "GOOGOLS") ? BigRat.fromDecimal(me.value[1]) : googol
            return t1 * t2
        }
    }
    var bf = BigRat.fromDecimal(num)
    for (me in metric) {
        var j = 0
        while (j < suf.count) {
            if (me.key == suf[j]) {
                if (j < suf.count-1 && suf[j+1] == "I") {
                    bf = bf * binary[me.key + "i"]
                    j = j + 1
                } else {
                    bf = bf * me.value
                }
            }
            j = j + 1
        }
    }
    return bf
}

var process = Fn.new { |numbers|
    System.write("numbers =  ")
    for (number in numbers) Fmt.write("$s   ", number)
    System.write("\nresults =  ")
    for (number in numbers) {
        var res = parse.call(number)
        if (res.isInteger) {
            Fmt.write("$,s  ", res.toDecimal(50))
        } else {
            var sres = Fmt.swrite("$,s", res.truncate.toDecimal)
            Fmt.write("$s  ", sres + res.fraction.abs.toDecimal(50)[1..-1])
        }
    }
    System.print("\n")
}

var numbers = ["2greatGRo", "24Gros", "288Doz", "1,728pairs", "172.8SCOre"]
process.call(numbers)

numbers = ["1,567", "+1.567k", "0.1567e-2m"]
process.call(numbers)

numbers = ["25.123kK", "25.123m", "2.5123e-00002G"]
process.call(numbers)

numbers = ["25.123kiKI", "25.123Mi", "2.5123e-00002Gi", "+.25123E-7Ei"]
process.call(numbers)

numbers = ["-.25123e-34Vikki", "2e-77gooGols"]
process.call(numbers)

numbers = ["9!", "9!!", "9!!!", "9!!!!", "9!!!!!", "9!!!!!!", "9!!!!!!!", "9!!!!!!!!", "9!!!!!!!!!"]
process.call(numbers)


#import <Foundation/Foundation.h>

// a fantasy two level hierarchy
@interface Animal : NSObject <NSCoding>
{
  NSString *animalName;
  int numberOfLegs;
}
- (instancetype) initWithName: (NSString*)name andLegs: (NSInteger)legs;
- (void) dump;
@end

@implementation Animal
- (instancetype) initWithName: (NSString*)name andLegs: (NSInteger)legs
{
  if ((self = [super init])) {
    animalName = name;
    numberOfLegs = legs;
  }
  return self;
}
- (void) dump
{
  NSLog(@"%@ has %d legs", animalName, numberOfLegs);
}
// ========
- (void) encodeWithCoder: (NSCoder*)coder
{
  [coder encodeObject: animalName forKey: @"Animal.name"];
  [coder encodeInt: numberOfLegs forKey: @"Animal.legs"];
}
- (instancetype) initWithCoder: (NSCoder*)coder
{
  if ((self = [super init])) {
    animalName = [coder decodeObjectForKey: @"Animal.name"];
    numberOfLegs = [coder decodeIntForKey: @"Animal.legs"];
  }
  return self;
}
@end

@interface Mammal : Animal <NSCoding>
{
  BOOL hasFur;
  NSMutableArray *eatenList;
}
- (instancetype) initWithName: (NSString*)name hasFur: (BOOL)fur;
- (void) addEatenThing: (NSString*)thing;
@end

@implementation Mammal
- (instancetype) init
{
  if ((self = [super init])) {
    hasFur = NO;
    eatenList = [[NSMutableArray alloc] initWithCapacity: 10];
  }
  return self;
}
- (instancetype) initWithName: (NSString*)name hasFur: (BOOL)fur
{
  if ((self = [super initWithName: name andLegs: 4])) {
    hasFur = fur;
    eatenList = [[NSMutableArray alloc] initWithCapacity: 10];
  }
  return self;
}
- (void) addEatenThing: (NSString*)thing
{
  [eatenList addObject: thing];
}
- (void) dump
{
  [super dump];
  NSLog(@"has fur? %@", (hasFur) ? @"yes" : @"no" );
  NSLog(@"it has eaten %d things:", [eatenList count]);
  for ( id element in eatenList )
    NSLog(@"it has eaten a %@", element);
  NSLog(@"end of eaten things list");
}
// ========= de/archiving
- (void) encodeWithCoder: (NSCoder*)coder
{
  [super encodeWithCoder: coder];
  [coder encodeBool: numberOfLegs forKey: @"Mammal.hasFur"];
  [coder encodeObject: eatenList forKey: @"Mammal.eaten"];
}
- (instancetype) initWithCoder: (NSCoder*)coder
{
  if ((self = [super initWithCoder: coder])) {
    hasFur = [coder decodeBoolForKey: @"Mammal.hasFur"];
    eatenList = [coder decodeObjectForKey: @"Mammal.eaten"];
  }
  return self;
}
@end

int main()
{
  @autoreleasepool {

    // let us create a fantasy animal
    Animal *anAnimal = [[Animal alloc]
	         initWithName: @"Eptohippos"
	         andLegs: 7
	        ];
    // for some reason an Eptohippos is not an horse with 7 legs,
    // and it is not a mammal, of course...

    // let us create a fantasy mammal (which is an animal too)
    Mammal *aMammal = [[Mammal alloc]
	        initWithName: @"Mammaluc"
	        hasFur: YES
	       ];
    // let us add some eaten stuff...
    [aMammal addEatenThing: @"lamb"];
    [aMammal addEatenThing: @"table"];
    [aMammal addEatenThing: @"web page"];

    // dump anAnimal
    NSLog(@"----- original Animal -----");
    [anAnimal dump];

    // dump aMammal...
    NSLog(@"----- original Mammal -----");
    [aMammal dump];

    // now let us store the objects...
    NSMutableData *data = [[NSMutableData alloc] init];
    NSKeyedArchiver *arch = [[NSKeyedArchiver alloc]
			      initForWritingWithMutableData: data];
    [arch encodeObject: anAnimal forKey: @"Eptohippos"];
    [arch encodeObject: aMammal forKey: @"Mammaluc"];
    [arch finishEncoding];
    [data writeToFile: @"objects.dat" atomically: YES];

    // now we want to retrieve the saved objects...
    NSData *ldata = [[NSData alloc]
		       initWithContentsOfFile: @"objects.dat"];
    NSKeyedUnarchived *darch = [[NSKeyedUnarchiver alloc]
	                         initForReadingWithData: ldata];
    Animal *archivedAnimal = [darch decodeObjectForKey: @"Eptohippos"];
    Mammal *archivedMammal = [darch decodeObjectForKey: @"Mammaluc"];
    [darch finishDecoding];

    // now let's dump/print the objects...
    NSLog(@"\n");
    NSLog(@"----- the archived Animal -----");
    [archivedAnimal dump];
    NSLog(@"----- the archived Mammal -----");
    [archivedMammal dump];

  }
  return EXIT_SUCCESS;
}


var [const] BI=Import.lib("zklBigNum");  // GMP
var kRE,kD, aRE,aD;

kRE,kD = ki();
aRE,aD = abrevCreate();

fcn naSuffixes(numStr){
   var [const]
     numRE=RegExp(0'^([+-]*\.*\d+[.]*\d*E*[+-]*\d*)^),
     bangRE=RegExp(0'^(!+)^);

   nstr:=(numStr - " ,").toUpper();
   numRE.search(nstr);
   nstr,r := nstr[numRE.matched[0][1],*], numRE.matched[1];
   if(r.matches("*[.E]*")) r=r.toFloat();  // arg!
   if(r.matches("*[.E]*")) r=r.toFloat();  // arg!
   else 		   r=BI(r);

   reg z;
   do{
      z=nstr;	// use this to see if we actually did anything
      if(aRE.search(nstr)){
	 ns,k := aRE.matched;	// ((0,3),"SCO")
	 re,b := aD[k];		// (RegExp("R|RE|RES"),BI(20)),
	 nstr  = nstr[ns[1],*];
	 if(re.search(nstr)) nstr=nstr[re.matched[0][1],*]; # remove abbrev tail
	 r=r*b;
         continue;
      }else if(kRE.search(nstr)){
	 r*=kD[kRE.matched[1]];	    // "K":1000 ...
	 nstr=nstr[kRE.matched[0][1],*];
         continue;
      }else if(bangRE.search(nstr)){  // floats are converted to int
	 n,k,z := r.toInt(), bangRE.matched[0][1], n - k;
	 r,nstr = BI(n), nstr[k,*];
	 while(z>0){ r.mul(z); z-=k; }
         continue;
      }
   }while(nstr and z!=nstr);
   r
}

fcn ki{  // case insensitive: k, ki,
   ss:="K M G T P E Z Y X W V U".split();
   d:=Dictionary();
   ss.zipWith(d.add,[3..3*(ss.len()),3].apply(BI(10).pow));    # E:1e+18
   ss.apply("append","I")
      .zipWith(d.add,[10..10*(ss.len()),10].apply(BI(2).pow)); # EI:1.15292e+18
   re:="([%s]I\\?)".fmt(ss.concat());  // "([KMGTPEZYXWVU]I\?)"
   return(RegExp(re),d);
}
fcn abrevCreate{
   var upDown=RegExp("([A-Z]+)(.*)");
   s:="PAIRs 2; SCOres 20; DOZens 12; GREATGRoss 1728; GRoss 144; GOOGOLs 10e100".split(";");
   abrevs,re := Dictionary(), Sink(String);
   foreach an in (s){
      a,n := an.split();
      upDown.search(a);
      u,d := upDown.matched[1,2];
      d=d.len().pump(List,  // "R|RE|RES"
         '+(1),d.get.fp(0),"toUpper").reverse().concat("|");
      abrevs.add(u,T(RegExp(d),BI(n)));
      re.write(u," ");
   }
   // "PAIR|SCO|DOZ|GR|GREATGR|GOOGOL"
   re=RegExp("(%s)".fmt(re.close().strip().replace(" ","|")));
   return(re,abrevs);
}


type entity = { name : string }

let create_entity () = { name = "Entity" }
let print_entity x = print_endline x.name
let create_person () = { name = "Cletus" }

let instance1 = create_person ()
let instance2 = create_entity ()

(* Serialize *)
let out_chan = open_out_bin "objects.dat";;
output_value out_chan instance1;;
output_value out_chan instance2;;
close_out out_chan;;

(* Deserialize *)
let in_chan = open_in_bin "objects.dat";;
let result1 : entity = input_value in_chan;;
let result2 : entity = input_value in_chan;;
close_in in_chan;;

print_entity result1;;
print_entity result2;;


$ ol
Welcome to Otus Lisp 1.2,
type ',help' to help, ',quit' to end session.
> (define Object (tuple
   '(1 2 3 4)  ; list
   #(4 3 2 1)  ; bytevector
   "hello"     ; ansi string
   "こんにちは"  ; unicode string
   (list->ff '(; associative array
      (1 . 123456)
      (2 . second)
      (3 . "-th-")))
   {(4 . 'sym) ; alternatively declared..
    (5 . +)}   ; ..associative array
   #false      ; value
   -123        ; short number
   123456789012345678901234567890123456789  ; long number
)
;; Defined Object
#((1 2 3 4) #(4 3 2 1) hello こんにちは #ff((1 . 123456) (2 . second) (3 . -th-))
#ff((4 . sym) (5 . #<function>)) #false -123
123456789012345678901234567890123456789)

> (fasl-save Object "/tmp/object.bin")
#true

> (define New (fasl-load "/tmp/object.bin" #false))
;; Defined New
#((1 2 3 4) #(4 3 2 1) hello こんにちは #ff((1 . 123456) (2 . second) (3 . -th-))
#ff((4 . sym) (5 . #<function>)) #false -123
123456789012345678901234567890123456789)

> (equal? Object New)
#true

> ,quit
bye-bye :/
$


{
    package Greeting;
    sub new {
        my $v = "Hello world!\n";
        bless \$v, shift;
    };
    sub stringify {
        ${shift()};
    };
};
{
    package Son::of::Greeting;
    use base qw(Greeting); # inherit methods
    sub new { # overwrite method of super class
        my $v = "Hello world from Junior!\n";
        bless \$v, shift;
    };
};
{
    use Storable qw(store retrieve);
    package main;
    my $g1 = Greeting->new;
    my $s1 = Son::of::Greeting->new;
    print $g1->stringify;
    print $s1->stringify;

    store $g1, 'objects.dat';
    my $g2 = retrieve 'objects.dat';

    store $s1, 'objects.dat';
    my $s2 = retrieve 'objects.dat';

    print $g2->stringify;
    print $s2->stringify;
};


include "builtins/serialize.e"

function randobj()
-- test function (generate some random garbage)
    object res
    if rand(10)<=3 then     -- make sequence[1..3]
        res = {}
        for i=1 to rand(3) do
            res = append(res,randobj())
        end for
    elsif rand(10)<=3 then  -- make string
        res = repeat('A'+rand(10),rand(10))
    else
        res = rand(10)/2    -- half int/half float
    end if
    return res
end function

object o1 = randobj(),
       o2 = randobj(),
       o3 = randobj()

pp({o1,o2,o3},{pp_Nest,1})
integer fh = open("objects.dat", "wb")
puts(fh, serialize(o1))
puts(fh, serialize(o2))
puts(fh, serialize(o3))
close(fh)

?"==="

fh = open("objects.dat", "rb")
?deserialize(fh)
?deserialize(fh)
?deserialize(fh)
close(fh)
{} = delete_file("objects.dat")


$myObj = new Object();
$serializedObj = serialize($myObj);


\ one-dimensional automaton

\ direct map of input state to output state:
{
  "   " : 32,
  "  #" : 32,
  " # " : 32,
  " ##" : 35,
  "#  " : 32,
  "# #" : 35,
  "## " : 35,
  "###" : 32,
} var, lifemap

: transition \ s ix (r:s') -- (r:s')
    >r dup [email protected] n:1- 3 s:slice
    lifemap @ swap caseof
    r> swap [email protected] -rot s:! >r ;

\ run over 'state' and generate new state
: gen \ s -- s'
  clone >r
  dup s:len 2 n:-
  ' transition 1 rot loop
  drop r> ;

: life \ s -- s'
  dup . cr gen  ;

" ### ## # # # #  #  " ' life 10 times
bye


(defun rc-step-r (cells)
   (if (endp (rest cells))
       nil
       (cons (if (second cells)
                 (xor (first cells) (third cells))
                 (and (first cells) (third cells)))
             (rc-step-r (rest cells)))))

(defun rc-step (cells)
   (cons (and (first cells) (second cells))
         (rc-step-r cells)))

(defun rc-steps-r (cells n prev)
   (declare (xargs :measure (nfix n)))
   (if (or (zp n) (equal cells prev))
       nil
       (let ((new (rc-step cells)))
          (cons new (rc-steps-r new (1- n) cells)))))

(defun rc-steps (cells n)
  (cons cells (rc-steps-r cells n nil)))

(defun pretty-row (row)
   (if (endp row)
       (cw "~%")
       (prog2$ (cw (if (first row) "#" "-"))
               (pretty-row (rest row)))))

(defun pretty-output (out)
   (if (endp out)
       nil
       (prog2$ (pretty-row (first out))
               (pretty-output (rest out)))))


(class +Point)
# x y

(dm T (X Y)
   (=: x (or X 0))
   (=: y (or Y 0)) )

(dm print> ()
   (prinl "Point " (: x) "," (: y)) )

(class +Circle +Point)
# r

(dm T (X Y R)
   (super X Y)
   (=: r (or R 0)) )

(dm print> ()
   (prinl "Circle " (: x) "," (: y) "," (: r)) )

(setq
   P (new '(+Point) 3 4)
   C (new '(+Circle) 10 10 5) )

(print> P)
(print> C)

(out "objects.dat"
   (pr (val P) (getl P))
   (pr (val C) (getl C)) )


# Object Serialization in Python
# serialization in python is accomplished via the Pickle module.
# Alternatively, one can use the cPickle module if speed is the key,
# everything else in this example remains the same.

import pickle

class Entity:
	def __init__(self):
		self.name = "Entity"
	def printName(self):
		print self.name

class Person(Entity): #OldMan inherits from Entity
	def __init__(self): #override constructor
		self.name = "Cletus"

instance1 = Person()
instance1.printName()

instance2 = Entity()
instance2.printName()

target = file("objects.dat", "w") # open file

#  Serialize
pickle.dump((instance1, instance2), target) # serialize `instance1` and `instance2`to `target`
target.close() # flush file stream
print "Serialized..."

# Unserialize
target = file("objects.dat") # load again
i1, i2 = pickle.load(target)
print "Unserialized..."

i1.printName()
i2.printName()


# Reference:
# https://docs.raku.org/language/classtut
# https://github.com/teodozjan/perl-store

use v6;
use PerlStore::FileStore;

class Point {
    has Int $.x;
    has Int $.y;
}

class Rectangle does  FileStore {
    has Point $.lower;
    has Point $.upper;

    method area() returns Int {
        ($!upper.x - $!lower.x) * ( $!upper.y - $!lower.y);
    }
}

my $r1 = Rectangle.new(lower => Point.new(x => 0, y => 0),
                      upper => Point.new(x => 10, y => 10));
say "Create Rectangle1 with area ",$r1.area();
say "Serialize Rectangle1 to object.dat";
$r1.to_file('./objects.dat');
say "";
say "take a peek on object.dat ..";
say slurp "./objects.dat";
say "";
say "Deserialize to Rectangle2";
my $r2 = from_file('objects.dat');
say "Rectangle2 is of type ", $r2.WHAT;
say "Rectangle2 area is ", $r2.area();


CHAR FUNC CalcCell(CHAR prev,curr,next)
  IF prev='. AND curr='# AND next='# THEN
    RETURN ('#)
  ELSEIF prev='# AND curr='. AND next='# THEN
    RETURN ('#)
  ELSEIF prev='# AND curr='# AND next='. THEN
    RETURN ('#)
  FI
RETURN ('.)

PROC NextGeneration(CHAR ARRAY s)
  BYTE i
  CHAR prev,curr,next

  IF s(0)<4 THEN RETURN FI
  prev=s(1) curr=s(2) next=s(3)
  i=2
  DO
    s(i)=CalcCell(prev,curr,next)
    i==+1
    IF i=s(0) THEN EXIT FI
    prev=curr curr=next next=s(i+1)
  OD
RETURN

PROC Main()
  DEFINE MAXGEN="9"
  CHAR ARRAY s=".###.##.#.#.#.#..#.."
  BYTE i

  FOR i=0 TO MAXGEN
  DO
    PrintF("Generation %I: %S%E",i,s)
    IF i<MAXGEN THEN
      NextGeneration(s)
    FI
  OD
RETURN


with Ada.Text_IO;  use Ada.Text_IO;

procedure Cellular_Automata is
   type Petri_Dish is array (Positive range <>) of Boolean;

   procedure Step (Culture : in out Petri_Dish) is
      Left  : Boolean := False;
      This  : Boolean;
      Right : Boolean;
   begin
      for Index in Culture'First..Culture'Last - 1 loop
         Right := Culture (Index + 1);
         This  := Culture (Index);
         Culture (Index) := (This and (Left xor Right)) or (not This and Left and Right);
         Left := This;
      end loop;
      Culture (Culture'Last) := Culture (Culture'Last) and not Left;
   end Step;

   procedure Put (Culture : Petri_Dish) is
   begin
      for Index in Culture'Range loop
         if Culture (Index) then
            Put ('#');
         else
            Put ('_');
         end if;
      end loop;
   end Put;

   Culture : Petri_Dish :=
      (  False, True, True,  True, False, True,  True, False, True, False, True,
         False, True, False, True, False, False, True, False, False
      );
begin
   for Generation in 0..9 loop
      Put ("Generation" & Integer'Image (Generation) & ' ');
      Put (Culture);
      New_Line;
      Step (Culture);
   end loop;
end Cellular_Automata;


class Being
  def initialize(specialty=nil)
    @specialty=specialty
  end
  def to_s
    "(object_id = #{object_id})\n"+"(#{self.class}):".ljust(12)+to_s4Being+(@specialty ? "\n"+" "*12+@specialty : "")
  end
  def to_s4Being
    "I am a collection of cooperative molecules with a talent for self-preservation."
  end
end

class Earthling < Being
  def to_s4Being
    "I originate from a blue planet.\n"+" "*12+to_s4Earthling
  end
end

class Mammal < Earthling
  def initialize(type)
    @type=type
  end
  def to_s4Earthling
    "I am champion in taking care of my offspring and eating everything I can find, except mammals of type #{@type}."
  end
end

class Fish < Earthling
  def initialize(iq)
    @iq=(iq>1 ? :instrustableValue : iq)
  end
  def to_s4Earthling
    "Although I think I can think, I can't resist biting in hooks."
  end
end

class Moonling < Being
  def to_s4Being
    "My name is Janneke Maan, and apparently some Earthlings will pay me a visit."
  end
end

diverseCollection=[]
diverseCollection << (marsian=Being.new("I come from Mars and like playing hide and seek."))
diverseCollection << (me=Mammal.new(:human))
diverseCollection << (nemo=Fish.new(0.99))
diverseCollection << (jannakeMaan=Moonling.new)

puts "BEGIN ORIGINAL DIVERSE COLLECTION"
diverseCollection.each do |being|
  puts "",being.to_s
end
puts "END ORIGINAL DIVERSE COLLECTION"
puts "\n"+"*"*50+"\n\n"

#Marshal the diverse Array of beings
File.open('diverseCollection.bin','w') do |fo|
  fo << Marshal.dump(diverseCollection)
end

#load the Array of diverse beings
sameDiverseCollection=Marshal.load(File.read('diverseCollection.bin'))

puts "BEGIN LOADED DIVERSE COLLECTION"
puts(
     sameDiverseCollection.collect do |being|
       being.to_s
     end.join("\n\n")
     )
puts "END LOADED DIVERSE COLLECTION"


serde = { version = "1.0.89", features = ["derive"] }
bincode = "1.1.2"


package require Tcl 8.6
package require TclOO::serializer 0.1

# These classes are inspired by the Perl example
oo::class create Greeting {
    superclass oo::serializable
    variable v
    constructor {} {
        set v "Hello world!"
    }
    method get {} {
        return $v
    }
}
oo::class create SubGreeting {
    superclass Greeting oo::serializable
    variable v
    constructor {} {
        set v "Hello world from Junior!"
    }
}
oo::class create GreetingsHolder {
    superclass oo::serializable
    variable o1 o2
    constructor {greeting1 greeting2} {
        set o1 $greeting1
        set o2 $greeting2
    }
    method printGreetings {} {
        puts [$o1 get]
        puts [$o2 get]
    }
    destructor {
        $o1 destroy
        $o2 destroy
    }
}

# Make some objects and store them
GreetingsHolder create holder [Greeting new] [SubGreeting new]
set f [open "objects.dat" w]
puts $f [oo::serialize holder]
close $f

# Delete the objects
holder destroy

# Recreate the objects from the file and show that they work
set f [open "objects.dat" r]
set obj [oo::deserialize [read $f]]
close $f
$obj printGreetings


INT stop generation = 9;
INT universe width = 20;
FORMAT alive or dead = $b("#","_")$;

BITS universe := 2r01110110101010100100;
   # universe := BIN ( ENTIER ( random * max int ) ); #
INT upb universe = bits width;
INT lwb universe = bits width - universe width + 1;

PROC couple = (BITS parent, INT lwb, upb)BOOL: (
  SHORT INT sum := 0;
  FOR bit FROM lwb TO upb DO
    sum +:= ABS (bit ELEM parent)
  OD;
  sum = 2
);

FOR generation FROM 0 WHILE
  printf(($"Generation "d": "$, generation,
         $f(alive or dead)$, []BOOL(universe)[lwb universe:upb universe],
         $l$));
# WHILE # generation < stop generation DO
  BITS next universe := 2r0;

  # process the first event horizon manually #
  IF couple(universe,lwb universe,lwb universe + 1) THEN
    next universe := 2r10
  FI;

  # process the middle kingdom in a loop #
  FOR bit FROM lwb universe + 1 TO upb universe - 1 DO
    IF couple(universe,bit-1,bit+1) THEN
      next universe := next universe OR 2r1
    FI;
    next universe := next universe SHL 1
  OD;

  # process the last event horizon manually #
  IF couple(universe, upb universe - 1, upb universe) THEN
    next universe := next universe OR 2r1
  FI;
  universe := next universe
OD


import "/json" for JSON
import "io" for File, FileFlags

class Entity {
    construct new(name) {
        _name = name
    }

    name { _name }

    // JSON representation
    toString { "{\"name\": \"%(_name)\"}" }

    // mimics the JSON output
    print() { System.print(this.toString.replace("\"", "")) }

    serialize(fileName) {
        var o = JSON.parse(this.toString)
        File.openWithFlags(fileName, FileFlags.writeOnly) { |file|
            file.writeBytes("%(o)\n")
        }
    }
}

class Person is Entity {
    construct new(name, age) {
        super(name)
        _age = age
    }

    // JSON representation
    toString { "{\"name\": \"%(name)\", \"age\": \"%(_age)\"}" }

    // mimics the JSON output
    print() { System.print(this.toString.replace("\"", "")) }

    serialize(fileName) {
        var o = JSON.parse(this.toString)
        File.openWithFlags(fileName, FileFlags.writeOnly) { |file|
            file.writeBytes("%(o)\n")
        }
    }
}

// create file for serialization
var fileName = "objects.dat"
var file = File.create(fileName)
file.close()

System.print("Calling print methods gives:")

var e = Entity.new("John")
e.print()
e.serialize(fileName)

var p = Person.new("Fred", 35)
p.print()
p.serialize(fileName)

System.print("\nContents of objects.dat are:")
System.print(File.read(fileName))


class [static] ARootClass{ // A top level class, no instances
   class A{ self.println(" constructor"); } // a regular class
   class B(A){ // ditto
      var x;
      fcn init(x=123){ self.x=x }
      fcn toString{ "x is "+x }
   }
}

ARootClass.B(456).println(); // create an instance
   // prints:
   Class(A) constructor
   x is 456

f:=File("object.dat","wb");
Compiler.Asm.writeRootClass(ARootClass,f); // serialize to file
f.close();

f:=File("object.dat","rb");
rc:=Compiler.Asm.readRootClass(f); // read and re-create
   // prints (readRootClass calls all constructors by default):
   Class(A) constructor
f.close();
rc.B().println();  // create a new instance of B
   // prints:
   x is 123


begin
    string(20) state;
    string(20) nextState;
    integer    generation;
    generation := 0;
    state := "_###_##_#_#_#_#__#__";
    while begin
        write( i_w := 1, s_w := 1, "Generation ", generation, state );
        nextState := "____________________";
        for cPos := 1 until 18 do begin
            string(3) curr;
            curr := state( cPos - 1 // 3 );
            nextState( cPos // 1 ) := if curr = "_##" or curr = "#_#" or curr = "##_" then "#" else "_"
        end for_cPos ;
        ( state not = nextState )
    end do begin
        state := nextState;
        generation := generation + 1
    end while_not_finished
end.


evolve: function [arr][
    ary: [0] ++ arr ++ [0]
    ret: new []
    loop 1..(size ary)-2 'i [
        a: ary\[i-1]
        b: ary\[i]
        c: ary\[i+1]

        if? 2 = a+b+c -> 'ret ++ 1
        else          -> 'ret ++ 0
    ]
    ret
]

printIt: function [arr][
    print replace replace join map arr => [to :string] "0" "_" "1" "#"
]

arr: [0 1 1 1 0 1 1 0 1 0 1 0 1 0 1 0 0 1 0 0]
printIt arr

newGen: evolve arr
while [newGen <> arr][
    arr: newGen
    newGen: evolve arr
    printIt newGen
]


n := 22, n1 := n+1, v0 := v%n1% := 0        ; set grid dimensions, and fixed cells

Loop % n {                                  ; draw a line of checkboxes
   v%A_Index% := 0
   Gui Add, CheckBox, % "y10 w17 h17 gCheck x" A_Index*17-5 " vv" A_Index
}
Gui Add, Button, x+5 y6, step               ; button to step to next generation
Gui Show
Return

Check:
   GuiControlGet %A_GuiControl%             ; set cells by the mouse
Return

ButtonStep:                                 ; move to next generation
   Loop % n
      i := A_Index-1, j := i+2, w%A_Index% := v%i%+v%A_Index%+v%j% = 2
   Loop % n
      GuiControl,,v%A_Index%, % v%A_Index% := w%A_Index%
Return

GuiClose:                                   ; exit when GUI is closed
ExitApp


#!/usr/bin/awk -f
BEGIN {
    edge = 1
    ruleNum = 104 # 01101000
    maxGen = 9
    mark = "@"
    space = "."
    initialState = "[email protected]@@[email protected]@[email protected]@[email protected]@[email protected]"
    width = length(initialState)
    delete rules
    delete state

    initRules(ruleNum)
    initState(initialState, mark)
    for (g = 0; g < maxGen; g++) {
        showState(g, mark, space)
        nextState()
    }
    showState(g, mark, space)
}

function nextState(    newState, i, n) {
    delete newState
    for (i = 1; i < width - 1; i++) {
        n = getRuleNum(i)
        newState[i] = rules[n]
    }
    for (i = 0; i < width; i++) { # copy, can't assign arrays
        state[i] = newState[i]
    }
}

# Convert a three cell neighborhood from binary to decimal
function getRuleNum(i,    rn, j, p) {
    rn = 0
    for (j = -1; j < 2; j++) {
        p = i + j
        rn = rn * 2 + (p < 0 || p > width ? edge : state[p])
    }
    return rn
}

function showState(gen, mark, space,    i) {
    printf("%3d: ", gen)
    for (i = 1; i <= width; i++) {
        printf(" %s", (state[i] ? mark : space))
    }
    print ""
}

# Make state transition lookup table from rule number.
function initRules(ruleNum,   i, r) {
    delete rules;
    r = ruleNum
    for (i = 0; i < 8; i++) {
        rules[i] = r % 2
        r = int(r / 2)
    }
}

function initState(init, mark,    i) {
    delete state
    srand()
    for (i = 0; i < width; i++) {
        state[i] = (substr(init, i, 1) == mark ? 1 : 0) # Given an initial string.
        # state[int(width/2)] = '@'  # middle cell
        # state[i] = int(rand() * 100) < 30 ? 1 : 0 # 30% of cells
    }
}


DECLARE FUNCTION life$ (lastGen$)
DECLARE FUNCTION getNeighbors! (group$)
CLS
start$ = "_###_##_#_#_#_#__#__"
numGens = 10
FOR i = 0 TO numGens - 1
	PRINT "Generation"; i; ": "; start$
	start$ = life$(start$)
NEXT i

FUNCTION getNeighbors (group$)
		ans = 0
		IF (MID$(group$, 1, 1) = "#") THEN ans = ans + 1
		IF (MID$(group$, 3, 1) = "#") THEN ans = ans + 1
		getNeighbors = ans
END FUNCTION

FUNCTION life$ (lastGen$)
		newGen$ = ""
		FOR i = 1 TO LEN(lastGen$)
			neighbors = 0
			IF (i = 1) THEN 'left edge
				IF MID$(lastGen$, 2, 1) = "#" THEN
					neighbors = 1
				ELSE
					neighbors = 0
				END IF
			ELSEIF (i = LEN(lastGen$)) THEN 'right edge
				IF MID$(lastGen$, LEN(lastGen$) - 1, 1) = "#" THEN
					neighbors = 1
				ELSE
					neighbors = 0
				END IF
			ELSE 'middle
				neighbors = getNeighbors(MID$(lastGen$, i - 1, 3))
			END IF

			IF (neighbors = 0) THEN 'dies or stays dead with no neighbors
				newGen$ = newGen$ + "_"
			END IF
			IF (neighbors = 1) THEN 'stays with one neighbor
				newGen$ = newGen$ + MID$(lastGen$, i, 1)
			END IF
			IF (neighbors = 2) THEN 'flips with two neighbors
				IF MID$(lastGen$, i, 1) = "#" THEN
					newGen$ = newGen$ + "_"
				ELSE
					newGen$ = newGen$ + "#"
				END IF
			END IF
		NEXT i
		life$ = newGen$
END FUNCTION


arraybase 1
dim start = {0,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,0,1,0,0}
dim sgtes(start[?]+1)

for k = 0 to 9
    print "Generation "; k; ": ";
    for j = 0 to start[?]-1

        if start[j] then print "#"; else print "_";
        if start[j-1] + start[j] + start[j+1] = 2 then sgtes[j] = 1 else sgtes[j] = 0
    next j
    print
    for j = 0 to start[?]-1
        start[j] = sgtes[j]
    next j
next k


@echo off
setlocal enabledelayedexpansion

::THE MAIN THING
call :one-dca __###__##_#_##_###__######_###_#####_#__##_____#_#_#######__
pause>nul
exit /b
::/THE MAIN THING

::THE PROCESSOR
:one-dca
echo.&set numchars=0&set proc=%1

::COUNT THE NUMBER OF CHARS
set bef=%proc:_=_,%
set bef=%bef:#=#,%
set bef=%bef:~0,-1%
for %%x in (%bef%) do set /a numchars+=1

set /a endchar=%numchars%-1
:nextgen
echo.   ^| %proc% ^|
set currnum=0
set newgen=
:editeachchar
	set neigh=0
	set /a testnum2=%currnum%+1
	set /a testnum1=%currnum%-1
	if %currnum%==%endchar% (
		set testchar=!proc:~%testnum1%,1!
		if !testchar!==# (set neigh=1)
	) else (
		if %currnum%==0 (
			set testchar=%proc:~1,1%
			if !testchar!==# (set neigh=1)
		) else (
			set testchar1=!proc:~%testnum1%,1!
			set testchar2=!proc:~%testnum2%,1!
			if !testchar1!==# (set /a neigh+=1)
			if !testchar2!==# (set /a neigh+=1)
		)
	)
	if %neigh%==0 (set newgen=%newgen%_)
	if %neigh%==1 (
		set testchar=!proc:~%currnum%,1!
		set newgen=%newgen%!testchar!
	)
	if %neigh%==2 (
		set testchar=!proc:~%currnum%,1!
		if !testchar!==# (set newgen=%newgen%_) else (set newgen=%newgen%#)
	)
if %currnum%==%endchar% (goto :cond) else (set /a currnum+=1&goto :editeachchar)

:cond
if %proc%==%newgen% (echo.&echo          ...The sample is now stable.&goto :EOF)
set proc=%newgen%
goto :nextgen
::/THE (LLLLLLOOOOOOOOOOOOONNNNNNNNGGGGGG.....) PROCESSOR


      DIM rule$(7)
      rule$() = "0", "0", "0", "1", "0", "1", "1", "0"

      now$ = "01110110101010100100"

      FOR generation% = 0 TO 9
        PRINT "Generation " ; generation% ":", now$
        next$ = ""
        FOR cell% = 1 TO LEN(now$)
          next$ += rule$(EVAL("%"+MID$("0"+now$+"0", cell%, 3)))
        NEXT cell%
        SWAP now$, next$
      NEXT generation%


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

char trans[] = "___#_##_";

#define v(i) (cell[i] != '_')
int evolve(char cell[], char backup[], int len)
{
	int i, diff = 0;

	for (i = 0; i < len; i++) {
		/* use left, self, right as binary number bits for table index */
		backup[i] = trans[ v(i-1) * 4 + v(i) * 2 + v(i + 1) ];
		diff += (backup[i] != cell[i]);
	}

	strcpy(cell, backup);
	return diff;
}

int main()
{
	char	c[] = "_###_##_#_#_#_#__#__\n",
		b[] = "____________________\n";

	do { printf(c + 1); } while (evolve(c + 1, b + 1, sizeof(c) - 3));
	return 0;
}


using System;
using System.Collections.Generic;

namespace prog
{
	class MainClass
	{
		const int n_iter = 10;
		static int[] f = { 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0 };

		public static void Main (string[] args)
		{
			for( int i=0; i<f.Length; i++ )
				Console.Write( f[i]==0 ? "-" : "#" );
			Console.WriteLine("");

			int[] g = new int[f.Length];
			for( int n=n_iter; n!=0; n-- )
			{
				for( int i=1; i<f.Length-1; i++ )
				{
					if ( (f[i-1] ^ f[i+1]) == 1 ) g[i] = f[i];
					else if ( f[i] == 0 && (f[i-1] & f[i+1]) == 1 ) g[i] = 1;
					else g[i] = 0;
				}
				g[0] = ( (f[0] & f[1]) == 1 ) ? 1 : 0;
				g[g.Length-1] = ( (f[f.Length-1] & f[f.Length-2]) == 1 ) ? 1 : 0;

				int[] tmp = f;
				f = g;
				g = tmp;

				for( int i=0; i<f.Length; i++ )
					Console.Write( f[i]==0 ? "-" : "#" );
				Console.WriteLine("");
			}
		}
	}
}


#include <iostream>
#include <bitset>
#include <string>

const int ArraySize = 20;
const int NumGenerations = 10;
const std::string Initial = "0011101101010101001000";

int main()
{
    // + 2 for the fixed ends of the array
    std::bitset<ArraySize + 2> array(Initial);

    for(int j = 0; j < NumGenerations; ++j)
    {
        std::bitset<ArraySize + 2> tmpArray(array);
        for(int i = ArraySize; i >= 1 ; --i)
        {
            if(array[i])
                std::cout << "#";
            else
                std::cout << "_";
            int val = (int)array[i-1] << 2 | (int)array[i] << 1 | (int)array[i+1];
            tmpArray[i] = (val == 3 || val == 5 || val == 6);
        }
        array = tmpArray;
        std::cout << std::endl;
    }
}


shared abstract class Cell(character) of alive | dead {
	shared Character character;
	string => character.string;
	shared formal Cell opposite;
}

shared object alive extends Cell('#') {
	opposite => dead;
}
shared object dead extends Cell('_') {
	opposite => alive;
}

shared Map<Character, Cell> cellsByCharacter = map { for (cell in `Cell`.caseValues) cell.character->cell };

shared class Automata1D({Cell*} initialCells) {

	value permanentFirstCell = initialCells.first else dead;
	value permanentLastCell = initialCells.last else dead;

	value cells = Array { *initialCells.rest.exceptLast };

	shared Boolean evolve() {

		value newCells = Array {
			for (index->cell in cells.indexed)
			let (left = cells[index - 1] else permanentFirstCell,
				right = cells[index + 1] else permanentLastCell,
				neighbours = [left, right],
				bothAlive = neighbours.every(alive.equals),
				bothDead = neighbours.every(dead.equals))
			if (bothAlive)
			then cell.opposite
			else if (cell == alive && bothDead)
			then dead
			else cell
		};

		if (newCells == cells) {
			return false;
		}

		newCells.copyTo(cells);
		return true;
	}

	string => permanentFirstCell.string + "".join(cells) + permanentLastCell.string;
}

shared Automata1D? automata1d(String string) =>
		let (cells = string.map((Character element) => cellsByCharacter[element]))
		if (cells.every((Cell? element) => element exists))
		then Automata1D(cells.coalesced)
		else null;

shared void run() {

	assert (exists automata = automata1d("__###__##_#_##_###__######_###_#####_#__##_____#_#_#######__"));

	variable value generation = 0;
	print("generation ``generation`` ``automata``");
	while (automata.evolve() && generation<10) {
		print("generation `` ++generation `` ``automata``");
	}
}


(ns one-dimensional-cellular-automata
  (:require (clojure.contrib (string :as s))))

(defn next-gen [cells]
  (loop [cs cells ncs (s/take 1 cells)]
    (let [f3 (s/take 3 cs)]
      (if (= 3 (count f3))
        (recur (s/drop 1 cs)
               (str ncs (if (= 2 (count (filter #(= \# %) f3))) "#" "_")))
        (str ncs (s/drop 1 cs))))))

(defn generate [n cells]
  (if (= n 0)
    '()
    (cons cells (generate (dec n) (next-gen cells)))))


 Identification division.
 Program-id. rc-1d-cell.

 Data division.
 Working-storage section.

*> "Constants."
 01 max-gens            pic  999  value   9.
 01 state-width         pic   99  value  20.
 01 state-table-init    pic x(20) value "[email protected]@@[email protected]@[email protected]@[email protected]@[email protected]".
 01 alive               pic    x  value "@".
 01 dead                pic    x  value ".".

*> The current state.
 01 state-gen           pic  999  value   0.
 01 state-row.
    05 state-row-gen   pic zz9.
    05 filler          pic  xx   value ": ".
    05 state-table.
        10 state-cells pic   x   occurs 20 times.

*> The new state.
 01 new-state-table.
    05 new-state-cells pic   x   occurs 20 times.

*> Pointer into cell table during generational production.
 01 cell-index          pic   99.
    88 at-beginning    value  1.
    88 is-inside       values 2 thru 19.
    88 at-end          value 20.

*> The cell's neighborhood.
 01 neighbor-count-def.
   03 neighbor-count      pic   9.
     88 is-comfy        value 1.
     88 is-ripe         value 2.

 Procedure division.
     Perform Init-state-table.
     Perform max-gens times
         perform Display-row
         perform Next-state
     end-perform.
     Perform Display-row.
     Stop run.

 Display-row.
     Move state-gen to state-row-gen.
     Display state-row.

*> Determine who lives and who dies.
 Next-state.
     Add 1 to state-gen.
     Move state-table to new-state-table.

     Perform with test after
         varying cell-index from 1 by 1
         until at-end
         perform Count-neighbors
         perform Die-off
         perform New-births
     end-perform

     move new-state-table to state-table.

*> Living cell with wrong number of neighbors...
 Die-off.
     if state-cells(cell-index) =
     alive and not is-comfy
         then move dead to new-state-cells(cell-index)
     end-if
     .

*> Empty cell with exactly two neighbors are...
 New-births.
     if state-cells(cell-index) = dead and is-ripe
         then move alive to new-state-cells(cell-index)
     end-if
    .
*> How many living neighbors does a cell have?
 Count-neighbors.
     Move 0 to neighbor-count
     if at-beginning or at-end then
         add 1 to neighbor-count
     else
       if is-inside and state-cells(cell-index - 1) = alive
       then
           add 1 to neighbor-count
       end-if
       if is-inside and state-cells(cell-index + 1) = alive
       then
           add 1 to neighbor-count
       end-if
     end-if
     .

*> String is easier to enter, but table is easier to work with,
*> so move each character of the initialization string to the
*> state table.

 Init-state-table.
     Perform with test after
         varying cell-index from 1 by 1
         until at-end
         move state-table-init(cell-index:1)
           to state-cells(cell-index)
      end-perform
      .


(defun value (x)
  (assert (> (length x) 1))
  (coerce x 'simple-bit-vector))

(defun count-neighbors-and-self (value i)
  (flet ((ref (i)
           (if (array-in-bounds-p value i)
               (bit value i)
               0)))
    (declare (inline ref))
    (+ (ref (1- i))
       (ref i)
       (ref (1+ i)))))

(defun next-cycle (value)
  (let ((new-value (make-array (length value) :element-type 'bit)))
    (loop for i below (length value)
          do (setf (bit new-value i)
                   (if (= 2 (count-neighbors-and-self value i))
                       1
                       0)))
    new-value))

(defun print-world (value &optional (stream *standard-output*))
  (loop for i below (length value)
        do (princ (if (zerop (bit value i)) #\. #\#)
                  stream))
  (terpri stream))


void main() {
   import std.stdio, std.algorithm;

   enum nGenerations = 10;
   enum initial = "0011101101010101001000";
   enum table = "00010110";

   char[initial.length + 2] A = '0', B = '0';
   A[1 .. $-1] = initial;
   foreach (immutable _; 0 .. nGenerations) {
      foreach (immutable i; 1 .. A.length - 1) {
         write(A[i] == '0' ? '_' : '#');
         const val = (A[i-1]-'0' << 2) | (A[i]-'0' << 1) | (A[i+1]-'0');
         B[i] = table[val];
      }
      A.swap(B);
      writeln;
   }
}


const ngenerations = 10;
const table = [0, 0, 0, 1, 0, 1, 1, 0];

var a := [0, 0, 1, 1, 1, 0, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 1, 0, 0, 0];
var b := a;

var i, j : Integer;
for i := 1 to ngenerations do begin
   for j := a.low+1 to a.high-1 do begin
      if a[j] = 0 then
         Print('_')
      else Print('#');
      var val := (a[j-1] shl 2) or (a[j] shl 1) or a[j+1];
      b[j] := table[val];
   end;
   var tmp := a;
   a := b;
   b := tmp;
   PrintLn('');
end;