Κυριακή, 29 Ιουλίου 2018

Αναθεώρηση 31 Έκδοση 9.3

Rosettacode.org tasks for M2000: 152

1. Σε αυτήν την αναθεώρηση διορθώθηκαν μερικές "κακοτεχνίες", της 9.3 (δεν υπήρχαν πριν). Επανήλθε η σωστή λειτουργία των Μέλος$() ή Member$() και Μέλους.Τύπος$() ή Member,type$() όταν έχουμε γενική ομάδα (global group), καθώς και το Μακρύς ή Long στη δήλωση μέλους μιας ομάδας (group)

global group alfa {
      Long x=10
      k=lambda->0
      a=(,)
      dim a%(10)
}
for i=1 to group.count(alfa)
      Print member$(alfa, i), member.type$(alfa, i)
next i

2. Διορθώθηκε ο χρωματισμός κειμένου όταν το όνομα μιας συνάρτησης ή ενός τμήματος ξεκίναγε από e ή ε (επειδή το έχουν και οι αριθμοί, ο χρωματιστής...μπερδεύονταν) με συνέπεια το μπλοκ που ακολουθεί να εμφανίζεται ως εντολές (ενώ από λάθος εμφανίζονταν ως κείμενο). Σε εκδόσεις πριν την 9.3 δεν υπήρχε πρόβλημα. Το παρακάτω στην προηγούμενη αναθεώρηση δεν θα χωματίζονταν ως εντολές το μπλοκ μετά το E.

\\ πρόγραμμα εύρεσης του e ανάλογα με το τύπο που εισάγουμε 
Module E {
      Function e (n){
            \\ max 28 for decimal
           n=n/28: For i=27 to 1 :n=1+n/i: next i
           =n
      }
      Print e(1@);
      Print " Decimal"
      Print e(1);
      Print " Double"
      Print e(1~);
      Print " Float"
}
E


3. Προσθήκη στην Τιμή() ή Val().
Με αυτήν την προσθήκη μπορούμε να γνωρίζουμε πόσοι χαρακτήρες δίνουν τον αριθμό που γυρίζει. σε μια τρίτη παράμετρο που περνάει με αναφορά (δεν χρειάζεται το &, αλλά αν μπει δεν πειράζει). Αν γυρίσει -1 τότε σημαίνει ότι δεν βρήκε κανένα χαρακτήρα που να δείχνει αριθμό.
Η Τιμή("α") θα γυρίσει 0, αλλά το α δεν είναι αριθμός. Έστω μ μια μεταβλητή, το Τιμή("α",μ) θα γυρίσει το 0 και στο μ το -1. Το -1 επιλέχθηκε γιατί στο Τιμή("", μ) το 0 θα ήταν το ίδιο όσο το μήκος του αλφαριθμητικού και δεν μας βολεύει για τις παρακάτω συναρτήσεις (έχουν μπει στην βοήθεια για να μπορεί κανείς να τις αντιγράφει). Θυμίζω εδώ ότι τα Αληθές και Ψευδές δεν είναι τύπου Λογικός, αλλά στην μετατροπή γίνονται όπως πρέπει. Επίσης οι συγκρίσεις δίνουν πάντα τύπο λογικό, οπότε αν θέλουμε να δώσουμε την Ψευδές ως τύπος λογικός, και όχι το 0, τότε η Τιμή(0->Λογικός) τον επιστρέφει ως τύπο λογικό με τιμή FALSE.

Οι συναρτήσεις Αριθμός() και ΑκέραιοςΑριθμός() δίνουν λογικό τύπο. Το μόνο ενδιαφέρον για να πάρουμε το 0 ως FALSE είναι στην Τύπωσε, όπου μας δίνει τα Αληθές και Ψευδές αντί των -1 και 0, όταν βλέπει τύπο λογικό. Μάλιστα η Τύπωσε εμφανίζει τα Αληθές/True και Ψευδές/False αν έχουμε επιλέξει τον διακόπτη "+sbl" (ShowBooLean=sbl), με την διακόπτες "+sbl" στην κονσόλα, ή την Θέσε διακόπτες "+sbl" σε τμήμα/συνάρτηση. Μπορούμε να δούμε τη θέση του διακόπτη με την Monitor ή Έλεγχος στη κονσόλα (ή με τη χρήση της Set ή Θέσε, από τμήμα ή συνάρτηση, επειδή αυτή η τελευταία στέλνει την γραμμή ως έχει στον μεταφραστή εντολών της κονσόλας, που διαφέρει κάπως, και αυτός γνωρίζει τις Monitor και Switches).


με ελληνικές εντολές
Συνάρτηση Αριθμός(α$) {
      Κάνε β
      =Τιμή(Ψευδές->Λογικός)
      Δες {
            Αν ΕινΓρ Τότε {
                  z=Τιμή(α$,γράμμα$, β)
            } Αλλιώς.Αν ΕινΑρ Τότε {
                  z=Τιμή(α$,αριθμός, β)
            } Αλλιώς z=Τιμή(α$,"", β)
            =β>Μήκος(α$)
      }
}
Συνάρτηση ΑκέραιοςΑριθμός(α$) {
      Κάνε β
      =Τιμή(Ψευδές->Λογικός)
      Δες {
            z=Τιμή(α$,"Ακ", β)
            =β>Μήκος(α$)
      }
}
Τύπωσε ΑκέραιοςΑριθμός("1221213123213")=Αληθές
Τύπωσε ΑκέραιοςΑριθμός("1221213.123213")=Ψευδές
Τύπωσε Αριθμός("123131232131231231.23123123")=Αληθές
Τύπωσε Αριθμός("-123131232131231231.23123123e112")=Αληθές
Τύπωσε Αριθμός("-123131232131231231.23123123e112", ",")=Ψευδές
Τύπωσε Αριθμός("-123131232131231231.23123123e112", 1036)=Ψευδές
Τύπωσε Αριθμός("-123131232131231231.23123123e112", 1033)=Αληθές
Τύπωσε Τιμή("233.44sec", 1033)=233.44
α$="233.44sec"
β=0
Τύπωσε Τιμή(α$, 1033, β)=233.44
Αν β>0 Τότε Τύπωσε Mid$(α$, β)="sec"
\\ οποιοδήποτε αλφαριθμητικό με μήκος >1 για χαρακτήρα δεκαδικών εξαιρεί τα δεκαδικά.
Τύπωσε Τιμή(α$, "??", β)=233
Αν β>0 Τότε Τύπωσε Mid$(α$, β)=".44sec"



με αγγλικές εντολές:

Function IsNumeric(a$) {
      def m
      =val(false->boolean)
      Try {
            if islet then {
                  z=val(a$,letter$, m)
            } else.if isnum then {
                  z=val(a$,number, m)
            } else z=val(a$,"", m)
            =m>len(a$)
      }
}
Function IsIntegerNumeric(a$) {
      def m
      =val(false->boolean)
      Try {
            z=val(a$,"Int", m)
            =m>len(a$)
      }
}
Print IsIntegerNumeric("1221213123213")=true
Print IsIntegerNumeric("1221213.123213")=false
Print isNumeric("123131232131231231.23123123")=true
Print isNumeric("-123131232131231231.23123123e112")=true
Print isNumeric("-123131232131231231.23123123e112", ",")=false
Print isNumeric("-123131232131231231.23123123e112", 1036)=false
Print isNumeric("-123131232131231231.23123123e112", 1033)=true
Print val("233.44sec", 1033)=233.44
a$="233.44sec"
m=0
Print val(a$, 1033, m)=233.44
if m>0 then Print Mid$(a$, m)="sec"
\\ any string for decimal point with len >1 cut decimals
Print val(a$, "??", m)=233
if m>0 then Print Mid$(a$, m)=".44sec"

Παρασκευή, 27 Ιουλίου 2018

Αναθεώρηση 30 (Έκδοση 9.3)

1. Διόρθωση στην εντολή Εισαγωγή για τις μεταβλητές με το % στο τέλος του ονόματος (ακέραιες, κατά όνομα, αλλά με διάφορους τύπους εσωτερικά).
2. Διόρθωση στα γραφικά στα τόξα και τομείς όταν επιλέγουμε το Ομαλά Ναι (εμφανίζονται βάσει του GDI+ των Windows). Παραμένει ένα ζήτημα: Στο GDI32 (το παλιό αλλά γρήγορο) όταν επιλέγουμε πχ πι/6 (pi/6) σε κύκλο μας δείχνει τις 30 μοίρες (30*6=180 δηλαδή ένα πι - ο κύκλος έχει περιφέρεια 2 πι). Αν τώρα αλλάξουμε το λόγο της κάθετης διαμέτρου με την οριζόντια (για να κάνουμε έλλειψη) το τόξο που διαγράφει για pi/6 δεν ορίζεται από τη γωνία αλλά από την περιφέρεια που τραβάει. Σε αντίθεση στο GDI+ ανεξάρτητα από το λόγο κάθετης με οριζόντιας διαμέτρου, η γωνία παραμένει ίδια. Ακόμα δεν έχω αποφασίσει αν θα το αφήσω έτσι! Διότι ήθελα αυτό που δείχνει η Μ2000 με το GDI32, δηλαδή όπως το έδειχνε από την πρώτη έκδοση, να συνεχίσει να το δείχνει με το GDI+ με τη διαφορά ότι στο δεύτερο υπάρχει ομαλοποίηση στις γραμμές και τα τόξα, για να μην φαίνονται "δοντάκια". Η ουσία είναι ότι τώρα δουλεύει αλλά ειδικά για τα τόξα δεν εμφανίζονται οι γωνίές όπως πρέπει, πρέπει να βρω έναν μαθηματικό τύπο ώστε σε κάθε περίπτωση γωνίας, στο GDI+ να παίρνω τη γωνία εκείνη που θα δίνει ότι και το GDI32. Το ζήτημα πάλι είναι "ποιό είναι το σωστό"; Μήπως πρέπει "επιτέλους" να αλλάξω το GDI32 και να παραμείνει το GDI+ ως έχει;

Κυριακή, 22 Ιουλίου 2018

One QuickSort for Strings and Numeric values, and data in arrays, with no Recursion.

This code is optimized. Run without recursion (use stack for values, which use heap to expand)


Flush
Class Quick {
Private:
      partition=lambda-> {
            Read &A(), p, r : i = p-1 : x=A(r)
            For j=p to r-1 {If .LE(A(j), x) Then i++:Swap A(i),A(j)
            } : Swap A(i+1), A(r) : Push i+2, i
      }
Public:
      LE=Lambda->Number<=Number
      Module ForStrings {
            .partition<=lambda-> {
                  Read &A$(), p, r : i = p-1 : x$=A$(r)
                  For j=p to r-1 {If A$(j)<= x$ Then i++:Swap A$(i),A$(j)
                  } : Swap A$(i+1), A$(r) : Push i+2, i
            }
      }
      Function quicksort {
           Read ref$
           {If Stackitem() >= Stackitem(2) Then Drop 2 : if empty then {Break} else Restart
            over 2,2 : call .partition(ref$) :shift 3 : Restart}
      }
}
Quick=Quick()
Dim A(10)<<Random(50, 100)
rem : A(0):=57, 83, 74, 98, 51, 73, 85, 76, 65, 92
Print A()
Call Quick.quicksort(&A(), 0, Len(A())-1)
Print A()
Quick=Quick()
Function join$(a$()) {
      n=each(a$(), 1, -2)
      k$=""
      while n {
            overwrite k$, ".", n^:=array$(n)
      }
      =k$
}
Stack New {
            Data "1.3.6.1.4.1.11.2.17.19.3.4.0.4" , "1.3.6.1.4.1.11.2.17.19.3.4.0.1", "1.3.6.1.4.1.11150.3.4.0.1"
            Data "1.3.6.1.4.1.11.2.17.19.3.4.0.10", "1.3.6.1.4.1.11.2.17.5.2.0.79", "1.3.6.1.4.1.11150.3.4.0"
            Dim Base 0, arr(Stack.Size)
            i=0 : While not Empty {let arr(i)=piece$(letter$+".", ".") : i++ }
}
\\ change compare function
Quick.LE=lambda (a, b)->{
      Link a, b to a$(), b$()
       def i=-1
       do {
             i++
       } until a$(i)="" or b$(i)="" or a$(i)<>b$(i)
       if b$(i)="" then =a$(i)="":exit
       if a$(i)="" then =true:exit
       =val(a$(i))<=val(b$(i))
}
Call Quick.quicksort(&arr(), 0, Len(arr())-1)
For i=0 to len(arr())-1 {
      Print join$(arr(i))
}
\\ Fresh load
Quick=Quick()
Quick.ForStrings
Dim A$()
A$()=("one","two", "three","four", "five")
Print A$()
Call Quick.quicksort(&A$(), 0, Len(A$())-1)
Print A$()




Τρίτη, 17 Ιουλίου 2018

RosettaCode M2000 Interpreter 95 tasks.

J

Δευτέρα, 16 Ιουλίου 2018

Αναθεώρηση 25 (Έκδοση 9.3)

Διορθώθηκε η String$() ή Επαν$()  που είχε "χαλάσει" από την 20η αναθεώρηση.  Επιπλέον προστέθηκε η δυνατότητα χρησης ANSI αλφαριθμητικών (ένα byte o κάθε χαρακτήρας) με τις MID$(), LEFT$(), RIGHT$(), INSTR(), RINSTR().


Locale 1033
\\ str$(a$) return ANSI from UTF16LE using Locale
\\ chr$(a$) read a$ as ANSI and return a UTF16LE
\\ make an 8bit Ansi string
a$=str$("    Hello  ")
Print Len(a$) =5.5 ' 5.5*2 = 11 bytes
b$=string$(a$,3)
Print Len(b$)=16.5 ' 16.5*2=33 bytes
k$=b$+b$
Print len(k$)=33 ' 33*2 = 66 bytes
Print chr$(mid$(a$, 2,1 as byte))
Print chr$(trim$(a$ as byte))+"OK"
For i=1 to Len(a$)*2
Print chr$(mid$(a$, i, 1 as byte)), i
next i
z$=trim$(a$ as byte)
Print chr$(left$(z$, 3 as byte))+"/"+chr$(right$(z$, 2 as byte))
Print chr$(mid$(z$, 3, 2 as byte))="ll"

\\ string$() used for encode to escape codes/ json escape codes
\\ we use format$ to decode from escape codes to normal
N$=String$({"hello there"})
Print N$="\u0022hello there\u0022"
Print format$(N$)={"hello there"}
N$=String$({"hello there"} as json)
Print N$={\"hello there\"}
Print format$(N$)={"hello there"}

\\ We can use String$ to encode/decode UTF8
\\ M$ are in bytes
M$=String$("GREEK == ΕΛΛΗΝΙΚΑ" as UTF8enc)
Print  Len(M$)= 12.5
Print String$(M$ as UTF8dec)="GREEK == ΕΛΛΗΝΙΚΑ"
Print  Len("GREEK == ΕΛΛΗΝΙΚΑ")=17

\\We can use String$ to encode/decode to BASE64
\\ using ,0 we get compact encode
\\ using ,1, 60 we get  6 lead spaces every line, we get linebreak after 60 symbols
M$=String$("GREEK == ΕΛΛΗΝΙΚΑ" as Encode64, 0)
Print Len(M$)=48
Clipboard M$
Print M$="RwBSAEUARQBLACAAPQA9ACAAlQObA5sDlwOdA5kDmgORAw=="
Print String$(M$ as Decode64)
M$=String$("GREEK == ΕΛΛΗΝΙΚΑ" as Encode64, 0,10)
clipboard M$
report m$
Print M$={          RwBSAEUARQBLACAAPQA9ACAAlQObA5sDlwOdA5kDmgORAw==}






Άλλο Παράδειγμα:
Τοπικό 1032
α$=γραφη$("Γιώργος")
β$=γραφη$("ς")
Τύπωσε Θέση(α$, β$ ως ψηφίο)=7
 


Locale 1032
a$=str$("Γιώργος")
b$=str$("ς")
Print Instr(a$, b$ as byte)=7



\\ check rinstr
Search$ = Str$("aetabetAbet")
Keyword$ = Str$("bet")
Print rinstr(Search$, Keyword$ as byte)=9
Print rinstr(Search$, Keyword$, 1 as byte)=9
Print rinstr(Search$, Keyword$, 2 as byte)=5

Search$ = "aetabetAbet"
Keyword$ ="bet"
Print rinstr(Search$, Keyword$,1 )=9
Print rinstr(Search$, Keyword$,2 )=5

\\ now check instr
Search$ = Str$("aetabetAbet")
Keyword$ = Str$("bet")
Print instr(Search$, Keyword$ as byte)=5
Print instr(Search$, Keyword$, 6 as byte)=9
Print instr(Search$, Keyword$, 1 as byte)=5
Search$ = "aetabetAbet"
Keyword$ ="bet"
Print instr(Search$, Keyword$)=5
Print instr(Search$, Keyword$, 6)=9
Print instr(Search$, Keyword$, 1)=5


 Αναζήτησε$ = Γραφή$("aetabetAbet")
τι$ = Γραφή$("bet")
Τύπωσε ΘέσηΔεξιά(Αναζήτησε$, τι$ ως ψηφίο)=9
Τύπωσε ΘέσηΔεξιά(Αναζήτησε$, τι$, 1 ως ψηφίο)=9
Τύπωσε ΘέσηΔεξιά(Αναζήτησε$, τι$, 2 ως ψηφίο)=5

Αναζήτησε$ = "aetabetAbet"
τι$ ="bet"
Τύπωσε ΘέσηΔεξιά(Αναζήτησε$, τι$,1 )=9
Τύπωσε ΘέσηΔεξιά(Αναζήτησε$, τι$,2 )=5

Αναζήτησε$ = Γραφή$("aetabetAbet")
τι$ = Γραφή$("bet")
Τύπωσε Θέση(Αναζήτησε$, τι$ ως ψηφίο)=5
Τύπωσε Θέση(Αναζήτησε$, τι$, 6 ως ψηφίο)=9
Τύπωσε Θέση(Αναζήτησε$, τι$, 1 ως ψηφίο)=5
Αναζήτησε$ = "aetabetAbet"
τι$ ="bet"
Τύπωσε Θέση(Αναζήτησε$, τι$)=5
Τύπωσε Θέση(Αναζήτησε$, τι$, 6)=9
Τύπωσε Θέση(Αναζήτησε$, τι$, 1)=5






Αναθεώρηση 24 'Εκδοση 9.3 Προσθήκη στις Ομάδες (Αντικείμενα)

Σε αυτήν την αναθεώρηση (από 22 πήγαμε στην 24), έγινε μια προσθήκη για τις ομάδες. Μπορούμε να βάζουμε μια ειδική  συνάρτηση Διαγραφή {} ή Remove {} που καλείται για ένα αντικείμενο που μπορεί να είναι σε πίνακα ή σε μεταβλητή, ως αντικείμενο ή ως δείκτης σε αντικείμενο, μέσω της Καθαρό (ή Clear), εφόσον αυτό το αντικείμενο δεν έχει άλλο δείκτη σε αυτό. Ουσιαστικά η Καθαρό ελέγχει αν το αντικείμενο είναι το τελευταίο βάσει του αριθμού δεικτών που το χρησιμοποιούν και αν ναι τότε καλεί την Καθαρό (αν δεν υπάρχει, δεν πειράζει, δεν βγαίνει λάθος). Η Διαγραφή ή Remove δεν μπορεί να κληθεί με άλλο τρόπο. Το πραγματικό όνομα της συνάρτησης δεν είναι το Διαγραφή ή Remove.

Το σύμβολο << στον ορισμό του πίνακα Α() κάνει τον διερμηνευτή να φτιάχνει ένα νέο αντικείμενο για κάθε στοιχείο του Α(). Αν βάζαμε το = αντί του << τότε θα έφτιαχνε ένα νέο αντικείμενο και θα το αντέγραφε σε όλες τις θέσεις του πίνακα.


Global RefAlfa=0
Class Alfa {
      id
      Remove {
            Print "remove"
            RefAlfa--
      }
Class:
      Module Alfa (.id){
            RefAlfa++
      }
}
\\ Try with false
if True then {
      k->Alfa(2)
} ELse K=Alfa(2)
Dim A(10)<<Alfa(Random(10, 100))
Dim A(12)
A(10)->k
A(11)->k
n=each(A())
While n {
      Print A(n^).id
}
Print "RefAlfa="; RefAlfa
n=each(A())
While n {
      Clear A(n^)
}
Print "RefAlfa="; RefAlfa
Clear k

Print "RefAlfa="; RefAlfa


Πιο απλό πρόγραμμα:

Module Global A {
      Global RefAlfa=0
      Class Alfa {
            id
            Remove {
                  Print "Remove"
                  RefAlfa--
            }      
        Class:
            Module Alfa (.id){
                  RefAlfa++
            }
    
      }
      A->Alfa(3)
      z->A
      Print refAlfa
      Clear A
      Print refAlfa
      Clear Z
      Print refAlfa
}
A

Και σε ελληνικά:

Τμήμα Γενικό βήτα {
      Γενική Μετρητής_Αλφα=0
      Κλάση Άλφα {
            Ένας_Αριθμός
            Διαγραφή {
                  Τύπωσε "Διαγραφή"
                  Μετρητής_Αλφα--
            }      
        Κλάση:
            Τμήμα Άλφα (.Ένας_Αριθμός){
                  Μετρητής_Αλφα++
            }
      }
      α->Αλφα(12345)
      \\ δοκίμασε και με α=Αλφα(12345)
      \\  με α->... η λίστα δείχνει: Μετρητής_Αλφα = 1, ΒΗΤΑ.Α*[Group] δηλαδή το Α είναι δείκτης σε ομάδα
      Λίστα
      \\ με α=... η λίστα δείχνει: Μετρητής_Αλφα = 1, ΒΗΤΑ.Α[Group], ΒΗΤΑ.Α.ΈΝΑΣ_ΑΡΙΘΜΟΣ = 12345
      \\ δηλαδή το α είναι ανοικτό αντικείμενο - συνδεδεμένο με το τμήμα - να γιατί βλέπουμε τη δημόσια Ένας_Αριθμός.
      Τύπωσε Μετρητής_Αλφα=1 ' ok
      \\ φτιάχνουμε έναν δείκτη στο α
      \\ αν το α είναι δείκτης σε κλειστό αντικείμενο, θα έχουμε δείκτη σε κλειστό αντικείμενο, όπως το α->Αλφα(12345)
      \\ αν το α δεν είναι δείκτης, ή είναι δείκτης σε ανοικτό αντικείμενο, τότε το κ θα γίνει δείκτης σε ανοικτό αντικείμενο
      \\ αυτό σημαίνει ότι οι δείκτες είναι "ισχνές αναφορές" και ότι δεν έχουν ισχύ αν τερματίσει αυτό το τμήμα.
      \\ το τελευταίο θα συμβεί με το α=Αλφα(12345).
      κ->α
      Τυπωσε κ=>Ένας_Αριθμός=12345
      \\ βάζουμε στο κ τη κενή ομάδα (θα το κάνει ο διερμηνευτής αυτό, εμείς δίνουμε έναν Μακρύ 32bit, το 0&, μετά το ->)
      κ->0&
      \\ Τώρα μειώθηκε ο αριθμός αναφορών, σε ένα.
      \\ Μόνο η Καθαρό καλεί  τη Διαγραφή
      Καθαρό α ' καλεί την διαγραφή αν είναι ο τελευταίος δείκτης στο αντικείμενο
      Τύπωσε Μετρητής_Αλφα=0
}
Κάλεσε βήτα


Σάββατο, 14 Ιουλίου 2018

Αναθεώρηση 21 (Έκδοση 9.3)

1. Νέα συνάρτηση Δυαδικό.Όχι() ή Binary.Not. Παίρνει ένα ακέραιο 32 bit xωρίς πρόσημο (ή ένα νούμερο ισοδύναμο), και δίνει τον 32 bit χωρίς πρόσημο με αναστροφή όλων των ψηφίων.
Ισχύει το Δυαδικό.Όχι(α)+α=0xFFFFFFFF
 ή
Binary.Not(a)+a=0xFFFFFFFF
Υπάρχει κάτι παρόμοιο, το Δυαδικό.Αντίστροφο(), ή Binary.Neg() το οποίο παίρνει ακέραιο με πρόσημο, τον αναστρέφει ως δυαδικό χωρίς πρόσημο και γυρίζει έναν ακέραιο χωρίς πρόσημο
Ισχύει αυτό:
Δυαδικό.Αντίστροφο(α)+Δυαδικό.Ακέραιο(α)=0xFFFFFFFF
Binary.Neg(a)+uint(a)=0xFFFFFFFF

α=0xFFFFFFFF&   ' Αυτό είναι το -1, δείτε το & στο τέλος, το οποίο δηλώνει ότι είναι σταθερά 32bit, σε δεκαεξαδική μορφή, με πρόσημο.
α=-1221
Τύπωσε Δεκαεξ$(Δυαδικό.Ακέραιο(α))
FFFFFB3B
 
θα δώσει σε δεκαεξαδική μορφή το α, αφού από ακέραιο το μετατρέψει σε δυαδική αναπαράσταση ακέραιου χωρίς πρόσημο (έχει δηλαδή τα ίδια ψηφία).

2. Χρήση του Τοπικού, το κωδικού γλώσσας όταν μετατρέπου αλφαριθμητικά από UTF16LE σε ANSI, και το ανάποδο με τα Γραφή$() και Xar$()  ή Str$() και Chr$()
Στην εξαγωγή αρχείων ANSI ήδη λειτουργούσε η επιλογή του τοπικού, οπότε προστέθηκε και εδώ. Τα παλιά προγράμματα δεν έχουν πρόβλημα συμβατότητας. Το τοπικό ρυθμίζεται και από τις ρυθμίσεις, όταν επιλέγουμε Greek ή Latin, όπου στο Greek θα έχουμε το 1032 και στο Latin το 1033. Υπάρχουν και ως εντολές Greek και Latin. Εκτός από την αλλαγή τοπικού, αυτές βάζουν και τα  μηνύματα των σφαλμάτων και των βασικών διαλόγων στα ελληνικά ή στα αγγλικά ανάλογα.




\\ αν αλλάξουμε το τοπικό σε 1032 θα γραφτεί το peche και όχι το pêche
Τοπικό 1033
α$=γραφή$("pêche")
Τύπωσε Μήκος(α$)*2=5 '  5 Bytes
Τύπωσε Χαρ$(α$)="pêche"
Τύπωσε Μήκος(Χαρ$(α$))*2=10 ' 10 bytes

\\ Φυσικά δεν χρειάζεται το τοπικό όταν γράφουμε κανονικά
α$="pêche"
Τύπωσε Μήκος(α$)*2=10 '  10 Bytes
Τύπωσε α$="pêche"

Τετάρτη, 11 Ιουλίου 2018

Ακολουθία Φιμπονάτσι με μεγάλους ακέραιους.

Ενα πρόγραμμα που δημοσίευσα στο www.rosettacode.org
Δείχνει την ακολουθία Φιμπονάτσι από το 1 έως το 4000. Δουλεύει γρήγορα γιατί αποθηκεύει τις τιμές σε μια Κατάσταση (Inventory). Χωρίς την χρήση του αντικειμένου BigNum δεν θα μπορούσαμε να βγάλουμε πάνω από το 139, ενώ τώρα μπορούμε να δώσουμε όσο θέλουμε το όριο. Το αντικείμενο Bignum  προσθέτει αριθμούς χωρίς όριο ψηφίων! Το πετυχαίνει με την χρήση ενός σωρού τιμών (Stack) όπου κάθε τιμή σε αυτόν έχει 14 ψηφία, εκτός από το τελευταίο που μπορεί να έχει λιγότερα. Το τελευταίο στοιχείο έχει τα πιο σημαντικά νούμερα, ενώ το πρώτο έχει τα πρώτα δεκατέσσερα.
Ο σωρός αυξάνεται καθώς προσθέτουμε περισσότερα ψηφία. Έχουμε ορίσει έναν τελεστή "+" που παίρνει δυο αντικείμενα BigNum και εξάγει ένα άλλο.
Επειδή οι σωροί είναι αντικείμενα με δείκτες, το μέλος a κρατάει δείκτη σε αυτό, και στην αντιγραφή αντιγράφεται ο δείκτης. Έτσι όταν εκτελείται η πρόσθεση, το τρέχον (αριστερά του + αντικείμενο) έχει αντιγραφεί, αλλά ο δείκτης στο σωρό πρέπει να αλλαχθεί και να δείχνει ένα αντίγραφο του σωρού. Αυτό το κάνουμε στην αρχή του κώδικα του τελεστή "+".



Η δομή Class (Κλάση) είναι δυο πράγματα:  Περιέχει έναν ορισμό ομάδας, και είναι ταυτόχρονα και συνάρτηση που επιστρέφει την ομάδα που ορίζει. Η δομή αυτή είναι γενική (δηλαδή τη συνάρτηση μπορούμε να την καλέσουμε από οπουδήποτε), εκτός αν βρίσκεται σε ορισμό ομάδας, οπότε είναι μέλος ομάδας (και αυτή μπορεί να είναι γενική ή τοπική).
Δείτε στον ορισμό ότι υπάρχει μια ετικέτα Class: και η οποία διαχωρίζει τα στοιχεία του ορισμού, με το στοιχεία μετά από αυτήν την ετικέτα να χρησιμοποιούνται μόνο μέσα στην συνάρτηση. Στην επιστροφή της ομάδας από τη συνάρτηση γυρνάνε όλα τα μέλη εκτός από αυτά που δόθηκαν μετά την Class: (ή Κλάση:).
Όταν καλούμε την συνάρτηση BigNum() ο διερμηνευτής φτιάχνει πρώτα την βασική ομάδα, και μετά καλεί το τμήμα (module) με το ίδιο όνομα, με την ιδιαιτερότητα ότι κάθε νέο πράγμα που θα κάνουμε εκεί, για την ομάδα, θα μείνει στην ομάδα, και για το λόγο αυτό λέμε το τμήμα αυτό "κατασκευαστή". Όσες τιμές περάσουμε στην συνάρτηση BigNum() θα πάνε σε αυτό το τμήμα στο σωρό τιμών. Αν αφήσουμε τιμές στο σωρό τιμών στο τμήμα, αυτές θα διαγραφούν μετά την επιστροφή της ομάδας. Εδώ αφήνουμε μόνο ένα αλφαριθμητικό με του χαρακτήρες που δηλώνουν τον μεγάλο αριθμό. Η κατασκευή του εσωτερικού σωρού a, γίνεται σε αυτό το σημείο.

Στη Μ2000 τα ονόματα με κεφαλαία-πεζά δεν ξεχωρίζουν (δηλαδή δεν είναι σημαντικό να διατηρούμε τα κεφαλαία ως κεφαλαία, και τα πεζά ως πεζά στις μεταβλητές και στα τμήματα). Επίσης οι τόνοι αφαιρούνται στα ελληνικά γράμματα, και έτσι ονόματα με ίδια γράμματα με ή χωρίς τόνους αναγνωρίζονται ως ίδια. Σε ετικέτες που χρησιμοποιούμε για διακλαδώσεις, έχει σημασία να κρατάμε ως έχει την ετικέτα (με τους τόνους). Οι ετικέτες μετά την πρώτη αναζήτηση και για όσο τρέχει ένα τμήμα βρίσκονται σε χρόνο Ο(1) με ειδική δομή με πίνακα κατακερματισμού. Τα ονόματα τμημάτων/συναρτήσεων/μεταβλητών επίσης βρίσκονται άμεσα. Ουσιαστικά το μέγεθος των ονομάτων παίζει ρόλο, γιατί μικρό μέγεθος δίνει μικρό χρόνο επιστροφής από την συνάρτηση κατακερματισμού. Ο διερμηνευτής εκτελεί άμεσα (ως κείμενο) το κώδικα, γιατί λόγω του εκπαιδευτικού σκοπού για τον οποίο γράφτηκε, έχει την δυνατότητα να δείχνει τον κώδικα όπως τον εκτελεί. Γράψτε το παρακάτω σε ένα τμήμα έστω Α, με την Σ Α ή Edit a, και μετά την έξοδο από το διορθωτή, με Esc, δώστε αντί για το Α ή a το Δοκιμή Α ή Test a. Η φόρμα ελέγχου έχει τρια αριστερά και τρια δεξιά "πλήκτρα". Τα αριστερά δεν φαίνονται ως πλήκτρα γιατί είναι απλά ενδεικτικά για το ποιο τμήμα τρέχει, ποια εντολή και τη συνέχεια της εντολής. Αν επιλέξουμε τη συνέχεια της εντολής διαδοχικά θα εμφανίζεται πότε ο κώδικας και πότε ο σωρός τιμών (κάθε γραμμή κώδικα βλέπει έναν τρέχον σωρό τιμών).

Class BigNum {
      a=stack
      Function Digits {
            =len(.a)*14-(14-len(str$(stackitem(.a,len(.a)) ,"")))
      }
      Operator "+" (n) {
            \\ we get a copy, but .a is pointer
             \\ we make a copy, and get a new pointer
            .a<=stack(.a)
            acc=0
            carry=0
            const d=100000000000000@
                  k=min.data(Len(.a), len(n.a))
                  i=each(.a, 1,k )
                  j=each(n.a, 1,k)
                  while i, j {
                        acc=stackitem(i)+stackitem(j)+carry
                        carry= acc div d
                        return .a, i^+1:=acc mod d
                  }
                  if len(.a)<len(n.a) Then {
                        i=each(n.a, k+1, -1)
                        while i {
                              acc=stackitem(i)+carry
                              carry= acc div d
                              stack .a {data acc mod d}
                        }
                  } ELse.if len(.a)>len(n.a) Then {
                        i=each(.a, k+1, -1)
                        while i {
                              acc=stackitem(i)+carry
                              carry= acc div d
                              Return .a, i^+1:=acc mod d
                              if carry else exit
                        }     
                  }
                  if carry then stack .a { data carry}
      }
      Function tostring$ {
            if len(.a)=0 then ="0" : Exit
            if len(.a)=1 then =str$(Stackitem(.a),"") : Exit
            document buf$=str$(Stackitem(.a, len(.a)),"")
            for i=len(.a)-1 to 1 {
                  Stack .a {
                        buf$=str$(StackItem(i), "00000000000000")
                  }
            }
            =buf$
      }
      class:
      Module BigNum (s$) {
            s$=filter$(s$,"+-.,")
            if s$<>""  Then {
                  repeat {
                        If len(s$)<14 then Stack .a { Data val(s$) }: Exit
                        Stack .a { Data val(Right$(s$, 14)) }
                        S$=Left$(S$, len(S$)-14)
                  } Until S$=""
            }
      }
}

Inventory K=0:=BigNum("0"),1:=BigNum("1")
fib=Lambda K (x as decimal)-> {
      If Exist(K, x) Then =Eval(K) :Exit
      Ret=If(x>1->Lambda(x-1)+Lambda(x-2), bignum(str$(x,"")))
      Append K, x:=Ret
      =Ret
}
\\ Using this to handle form  refresh by code
Set Fast!
For i=1 to 4000 {
      N=Fib(i)
      Print i
      Print N.tostring$()
      Refresh
}