Δευτέρα 30 Νοεμβρίου 2015

Περί Αριθμητικών Μεταβλητών, Πράξεων, Τελεστών.

Εδώ είναι ένα μάθημα με δοκιμές. Βάζουμε τιμές και βλέπουμε τι γίνεται. Ο καλύτερος τρόπος για να μάθει κανείς είναι το παράδειγμα. Διότι εδώ δεν χρειάζεται η φαντασία αλλά η ουσία, το τι γίνεται δηλαδή και τι οχι.
 Σημασία έχει όμως ο αναγνώστης να κατανοήσει το λεξιλόγιο. Π.χ δείχνω μόνο την αύξηση τιμής σε μεταβλητή όχι τη μείωση. Αν κατανοήσει την αύξηση θέλω να δοκιμάσει αν υπάρχει μείωση και λογικά πώς θα φαίνεται. Δηλαδή θέλω το μυαλό να λειτουργεί με συνειρμό, "είδα αυτό..λες να γίνεται και το άλλο".
Δεν περιγράφονται ολοι οι τελεστές εδώ και όλες οι συναρτήσεις. Για να μην βαρύνει το μάθημα.
Στο τέλος γίνεται αναφορά σε λογικές εκφράσεις (αν και στο κώδικα δεν αναφέρω πουθενά τη λέξη λογική)
Με ενδιαφέρει να δείξω το ζήτημα της στρογγυλοποίησης και το πώς μετατρέπουμε τους αριθμούς με δεκδαδικά σε ακέραιες τιμές (πως διώχνουμε τα δεκαδικά)
Γίνεται και μια αναφορά για τις δεκαεξαδικές τιμές και τα χρώματα.

\\ Μάθημα Η αριθμητική μεταβλητή, Τελεστές και Συναρτήσεις
\\ θα δούμε την μεταβλητή που κρατάει έναν αριθμό
\\ θα δούμε διάφορες χρήσεις, υπό μορφή δοκιμών


\\ το ? είναι συντομογραφία της ΤΥΠΩΣΕ
\\ βάλτε Έξοδος όπου θέλετε να τερματίζει το τμήμα
\\ ώστε να το βλέπετε προοδευτικά..

\\ Απόδοση τιμής
Α=10
? Α ' 10
\\ Απόδοση ή αντικατάσταση τιμής;
\\ Αντικατάσταση θα το λέγαμε αν αυτός ήταν ο στόχος μας
\\ Αλλά ποια τιμή εδώ αντικαθιστούμε; Άρα εδώ λέμε Απόδοση..
\\ δηλαδή δίνουμε μια τιμή.


\\ Αύξηση κατά ένα
Α++
? Α ' 11

\\ Αύξηση κατά δέκα
Α+=10
? Α ' 21

\\ Απόδοση τιμής από την έκφραση Α+10
Α=Α+10
\\ Σε γλώσσες που δεν υπάρχει += λέμε αύξηση επειδή
\\ το καταλαβαίνουμε από την έκφραση
\\ Η Α στην έκφραση Α+10 αφήνει την τιμή της
\\ Πρώτα εκτελείται η έκφραση, και το αποτέλεσμα δίνεται στην Α
? Α '31

\\ Υπάρχει εντολή που καθαρίζει, βάζει αυτό που λέμε αρχική τιμή
\\ στους αριθμούς η αρχική τιμή είναι το μηδέν
Καθαρό Α
? Α '0

\\ Μπορούμε να δώσουμε τιμή απ' ευθείας με έκφραση
\\ το είδαμε με το Α+10, αλλά θα μπορούσε να ήταν κάτι άλλο
\\ μια πιο σύνθετη έκφραση με παρενθέσεις
Α=(5-3)*4/(8-4)
? Α '2

\\ Και το μηδέν είναι μια τιμή ή μια απλή έκφραση!
Α=0
? Α '0

\\ Υπάρχουν και συγκρίσεις που δίνουν τιμές
\\ Αν είναι αληθής τότε δίνουν -1 αλλιώς δίνουν 0
Α=5>3
\\ το 7-(2=5) δεν είναι καθαρή έκφραση σύγκρισης
\\ προσθέτει έναν αριθμό με έναν αριθμό από σύγκριση
\\ βγαίνει αριθμός αλλά δεν έχει νόημα εκτός και αν του δίνουμε εμείς!
? Α, 5<3, 5=3+2, 7-2=5, 7-(2=5) ' -1, 0, -1, -1, 7
Α=Αληθής \\ μοναδιαία σύγκριση - υπάρχουν δυο ποιότητες, -1 και 0
? Α, Ψευδής, Ψευδές, Αληθές
\\ πράξεις με μοναδιαίες συγκρίσεις
? Α και Ψευδές, Α και Αληθές, Α ή Ψευδές, Α ή Αληθές
? Α από Ψευδές ' A xor B  exclusive or αποκλειστικο ή.
\\ πράξεις με συγκρίσεις
Α=Αληθής από Αληθής ' αυτό είναι Ψευδές
\\ Αλλάξτε τις εκφράσεις  να δείτε τι γίνεται
\\ το όχι κάνει αντιστροφή μοναδιαίας σύγκρισης:
\\ το αληθές το κάνει ψευδές, και το ψευδές το κάνει αληθές
? 5>3 ή 2+1=3, 2*3+3=20/2-1 και όχι Α
\\ Υπάρχουν δεκαδικά και πρόσημο (εδώ το -)
\\ το --2=+2 είναι και το -----2=-2
Α=-12.455
? Α, --2=+2, -----2=-2 '-12.455  -1 -1
\\ Ακρίβεια συγκρίσεων σε δεκαδικά, χρήση του διπλού ==
Α=1/3
Τυπωσε Α=1-2/3, Α==1-2/3 ' το πρώτο δίνει Ψευδές, το δεύτερο Αληθές.
\\ Η ισότητα εφαρμόζεται σε αυτό που αποδίδεται από την έκφραση
? (1-2/3)-1/3=0, (1-2/3)=1/3 '' 0 και 0
\\ Όμως δεν μπορούν όλοι οι αριθμοί να αποδοθούν επακριβώς
\\ Έτσι εκεί που ξέρουμε ότι υπάρχουν διαιρέσεις χρησιμοποιούμε το διπλό ίσον
\\ το οποίο συγκρίνει τροποποιημένες τιμές με μια μέθοδο στρογγυλοποίησης.
? (1-2/3)-1/3==0, (1-2/3)==1/3 '' -1 και -1 (κόβει από το 13ο δεκαδικό)
? Στρογγ(1.4555555555555, 5) ' μπορώ να επιλέγω που θα στρογγυλοποιώ
\\ Μπορώ να δώσω τιμή με επιστημονική γραφή με e ή ε για την ύψωση σε δύναμη του δέκα.
Α=1.234523ε+6 ' 1.234523 x 10**6 = 1234523
? Α , 12345.23*10**2, 1.234523*10^6
\\ Μπορώ να δώσω δεκαεξαδική τιμή
Α=0xA ' το αριστερό Α είναι στα ελληνικά, το δεξί στα αγγλικά
? Α ' 10
Δεκαεξ Α, 15, 0x102-0x03, 1024 ' η Δεκαεξ είναι η ? με εξαγωγή σε δεκαεξαδικό
\\ Χρώματα
Α=#010000 ' χρώμα κατά Html
\\ εδώ δίνεται ως αρνητικός επειδή θετικά είναι τα 1 έως 15, τα βασικά χρώματα
\\ RGB τιμές κάθε τιμή 00 έως FF, άρα όλο από #000000 μαύρο εως #FFFFFF άσπρο
\\ στην πραγματικότητα το χρώμα αποθηκεύεται ως BGR
\\ το #0102AA είναι το 0xAA0201 ως απόλυτη αξία
? -Α ' δινει 1, με το - αφαιρούμε το εσωτερικό -
' Εδώ έχουμε ίδια τιμή σε όλα!
? -Χρώμα(0x01, 0x02, 0xAA), -#0102AA, 0xAA0201
e=2.71828182845905 ' πρέπει να την δηλώσουμε ενώ η πι υπάρχει.
? πι, Λογ(10), Λφ(e**2) ' 3.14..., 1, 2
? Συν(45), Ημ(60), Εφαπ(100)
? Τοξ.Εφ(10) ' επιστρέφει τη γωνία σε μοίρες
? Απολ(-34), Ακ(12.34554), Ακ(12.98) ' 34, 12, 12
Κάνε Ακερ(Χ)=ΑΚ(Χ+.5)
? Ακερ(12.34554), Ακερ(12.98) ' 12, 13
\\ δεν χρησιμοποιούμε τη στρογγυλοποίηση για να πάρουμε ακέραια τιμή
\\ μπορεί να δίνει κάποια φορά σωστό αποτέλεσμα
? Στρογγ(12.34554,0), Στρογγ(12.98,0)
\\ αλλά όχι πάντα:
? Στρογγ(1+1/2,0), Στρογγ(2+1/2,0) ' δίνει 2 και 2
? Ακερ(1+1/2,0), Ακερ(2+1/2,0) ' δίνει 2 και 3
? Ρίζα(2), 2**.5, 2**(1/2), 2^(1/2)
? Έγκυρο(Α/0) ' τυπώνει 0 δεν είναι έγκυρο, επειδή έχουμε διαίρεση με το μηδέν
? Εκφρ("Α+34"), Α+34 ' 33   33
? Τυχαίος(10), Τυχαίος(1,5)
? Μικρό.Σειράς(5,2,67,34)
? Μεγάλο.Σειράς(5,2,67,34)
\\ Αλλαγή τιμών δυο μεταβλητών μεταξύ τους
Β=5
Α=6
Άλλαξε Α, Β ' μοντέρνος τρόπος
? Α, Β
\\ παραδοσιακός τρόπος μέσω τρίτης μεταβλητής.
Γ=Β : Β=Α : Α=Γ
? Α, Β
\\ Στο Γ=Β έχουμε κανονικα αυτό Γ=(Β) όπου το Β είναι αποτέλεσμα έκφρασης
\\ Δηλαδή μετά το = ο διερμηνευτής ψάχνει για έκφραση, βρίσκει το Β
\\ παίρνει την τιμή του και ψάχνει για κάτι άλλο, δεν βρίσκει και το δίνει ως αποτέλεσμα
\\ αυτό πάει στο Γ, άρα από το Β στο Γ πάει με δυο αντιγραφές.
\\ Άρα για να αλλάξουμε τιμές με το παραδοσιακό τρόπο θα κάνουμε έξι αντιγραφές
\\ Στην Άλλαξε Α, Β κάνουμε δυο μόνο, πάει η τιμή του Α σε μια προσωρινή,
\\ του Β στο Α και η προσωρινή στο Β, δηλαδή σαν τον παραδοσιακό τρόπο, αν δεν κατανοούσαμε
\\ ότι δεξιά έχουμε εκφράσεις που τυχγάνουν να έχουν μόνο μια μεταβλητή.
\\ Και εδώ οι παρακάτω συναρτήσεις είναι μόνο για μεταβλητές και μάλιστα μόνο για δύο
? Μικρό(Α, Β), Μεγάλο(Α, Β)
\\ Συγκρίσεις μεταβλητών
\\ το <> σημαίνει διάφορο, όχι ίσο, ή μικρό ή μεγάλο
\\ δίνει εδώ: 0, -1, -1, -1, 0, -1
? Α=Β, Α>Β, Β<Α, Α>=Β, Α<=Β, Α<>Β
\\ Στις εκφράσεις οι συγκρίσεις γίνονται σε αποτελέσματα εκφράσεων.
\\ άρα γίνεται αυτό (Α)=(Β) όπου (Α) είναι το αποτέλεσμα της έκφρασης.
\\ Θέλουμε κάτι να γίνεται μόνο σε μεταβλητές (όπως στις Μικρό() και Μεγάλο())
\\ Η Σύγκρινε περιμένει μεταβλητές (ή στοιχεία πίνακων) και συγκρίνει απ' ευθείας τις τιμές τους
\\ Το αποτέλεσμα είναι -1 αν το Α είναι μεγαλύτερο,0 αν είναι ίσα ή 1 αν το Β είναι μεγαλύτερο
? Σύγκρινε(Α,Β)
Α=10.5
Β=3.3
\\ τις τιμές Α και Β τις μετατρέπουν οι ΔΙΑ και ΥΠΟΛΟΙΠΟ (ΥΠΟΛ) σε ακέραιες πρώτα
? Α Διά Β, Α Υπόλοιπο Β, Α Υπολ Β
? 10 δια 2.999 ' δίνει 5  .. 2*5=10
? 10 δια 3 ' δίνει 3
? 1/2+5/2+3 δια 2+10 υπολ 3 ' δίνει 5....0.5+2.5+1+1
? 10 υπολ 3*2+10 υπολ (3*2) ' δίνει 2+4=6
\\ Ο διερμηνευτής δεν χρειάζεται πολλές παρενθέσεις
? 10 υπολ 3*2>10 υπολ 9 ' δίνει -1 (αληθές)
? 10 υπολ 3*2>10 υπολ 9 και 5<3 ' δίνει ψευδές (αληθές και ψευδές δίνει ψευδές)
\\ Το παραπάνω είναι της μορφής:
? 2>1 και 5<3
\\ οι λογικοί τελεστές λειτουργούν με το 0 και το μη μηδέν.
\\ κάθε μη μηδέν είναι αληθές (όχι ειδικά το -1)
\\ δεν ισχύει αυτό για την Όχι (Δεν, Not)
\\ Η όχι κάνει -1*(0)-1=(-1) ή -1*(-1)-1=(0)  δηλαδή -1*(Χ)-1=Υ
\\ το και (And)
? 1 και 1 και' οκ
? 1 και 1 και 0
? 1 και 0 και 0
? 0 και 0 και 0
? 0 και 0 και 1
? 0 και 1 και 1
? 1 και 0 και 1
\\ το ή (Or)
? 1 ή 1 ή 1
? 1 ή 1 ή 0
? 1 ή 0 ή 0
? 0 ή 0 ή 0  ' μόνο εδώ δίνει 0
? 0 ή 0 ή 1
? 0 ή 1 ή 1
? 1 ή 0 ή 1
\\ το από (Xor)
? 1 από 1 από 1 ' οκ
? 1 από 1 από 0
? 1 από 0 από 0 ' οκ
? 0 από 0 από 0
? 0 από 0 από 1 ' οκ
? 0 από 1 από 1
? 1 από 0 από 1
\\ πώς είναι το Not Xor ή το Όχι Από;
\\ πρέπει το όχι να το έχουμε έξω από το Από
\\ όχι ( Α από Β )
\\ αλλιώς το οχι έχει εμβέλεια μέχρι το πρώτο συνθετικό της έκφρασης
\\ Εδώ είναι ο τύπος του Όχι Απο (Xnor) με τα (και, ή, όχι)
κάνε ΌχιΑπό(α, β)=(α και β) ή (όχι α και όχι β)
\\ Τώρα δημιουργούμε το πίνακα αληθείας
\\ θέλουμε ίδιο αποτέλεσμα και στις δυο εκφράσεις
Για ι=-1 έως 0 {
      Για κ=-1 εως 0 {
            ? ">>>>>>", ι,κ
            ? ΌχιΑπό(ι, κ)
            ? όχι (ι από κ)
      }
}



Ειδικός Σωρός-Στοίβα-Ουρά στη Μ2000

(Μια μικρή αλλαγή στην Αναθεώρηση 99, επανέφερα την σταθερότητα της αναθεώρησης 97. στην εντολή κομ$, σε σχέση με τα νήματα)
Το παρακάτω "Σεντόνι" είναι ένα μακρύ παράδειγμα (έχει παύσεις με αναμονή πλήκτρου) για να κατανοήσει κανείς τις λειτουργίες (δεν είναι όλες) του ειδικού σωρού τιμών, της Μ2000 που εμφανίζεται ως στοίβα, ως ουρά ακόμα και ως πίνακας! Στην πράξη εσωτερικά ο σωρός είναι συλλογή (collection) η οποία είναι μια συνδεδεμένη λίστα και το κάθε στοιχείο της είναι ένα αντικείμενο. Άρα όταν γράφουμε στο σωρό κάτι, τρώει αρκετή μνήμη γιατί δημιουργείται ένα αντικείμενο Στις αρχικές εκδόσεις δεν ήταν παρά ένα και μόνο αλφαριθμητικό ο σωρός, τώρα αυτή η παλιά έκδοση μας δίνει τους σωρούς σε αλφαριθμητικά όπως θα δείτε στο τέλος του προγράμματος. Σε άλλο πρόγραμμα θα δείξω πώς επικοινωνούν ασύγχρονα δυο προγράμματα σε Μ2000 μέσω σωληνώσεως (pipe) μεταβιβάζοντας αλφαριθμητικό που είναι σωρός δηλαδή έχει τιμές αριθμητικές και αλφαριθμητικές μαζί, χωρίς να αποτελεί μέρος αρχείου, αλλά ολόκληρο ως μια τιμή μεταβλητής.

Ο σωρός εμφανίστηκε από την πρώτη έκδοση της Μ2000 ως δάνειο από την Forth. και χρησιμοποιείται για το πέρασμα τιμών σε τμήματα και συναρτήσεις. Κάθε τμήμα έχει το σωρό του πατρικού του, παίρνει και δίνει, δηλαδή εξάγει στο πέρας εκτέλεσης. Κάθε συνάρτηση ξεκινάει δικό της σωρό, και στην αναδρομή ξεκινάει νέο σωρό. Κάθε ρουτίνα ανήκει στο τμήμα και βλέπει τον ίδιο σωρό ακόμα και αν κάνει αναδρομή. Κάθε νήμα έχει δικό του σωρό αν και βλέπει τις μεταβλητές και τις ρουτίνες του τμήματος, αλλά κανείς δεν βλέπει το σωρό του! Γενικά σε κάθε περίπτωση ένας μόνο σωρός είναι ορατός. Μπορούμε πρόσκαιρα να ανοίξουμε έναν με την Σωρός Νέος { }. Υπάρχουν εντολές (όπως για τις βάσεις δεδομένων) που η επιστροφή τιμών είναι δυναμική, γίνεται στο σωρό με κορυφή τον αριθμό στοιχείων που ακολουθούν.

Όπως θα παρατηρήσουμε δεν χειριζόμαστε δείκτες στο σωρό. Ούτε για την κορυφή, ούτε για την βάση ή πυθμένα. Αν αναφερθούμε αριθμητικά σε κάποιο στοιχείο τότε το 1 είναι η κορυφή (0 δεν υπάρχει). Διαβάζω από το σωρό σημαίνει "σηκώνω" ταυτόχρονα, δηλαδή πετάω την κορυφή. Το διάβασμα γίνεται πάντα στη κορυφή. Άρα σηκώνουμε πάντα από την κορυφή. Το πώς θα μπει κάτι παίζει. Η Σειρά βάζει στο τέλος, η Βάλε στη κορυφή. Αλλά θα δείτε και άλλες εντολές που βάζουν την κορυφή. Όταν καλώ ένα τμήμα ας πούμε Α 10,20 τότε στη κορυφή θα είναι το 10 μετά το 20 και μετά όλα τα άλλα! Σε μια συνάρτηση...έχουμε καθαρό σωρό άρα δεν θα υπάρχουν "όλα τα άλλα".

Σε μια κλήση ρουτίνας με Διαμέσου και τιμές στο όνομα, θα περάσουν οι τιμές όπως στο τμήμα αλλά σε τοπικές μεταβλητές:
κ=1000
Διαμέσου αλφα(10,20)
Διαμέσου αλφα(10,20)
Τύπωσε κ
ρουτινα αλφα(χ)
      διαβασε τοπικά κ
      τυπωσε 
χ*κ
τελος ρουτίνας

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

Αν στην διάβασε παραπάνω διαγράψουμε τον δείκτη τοπικά τότε η κ θα είναι 20, αλλιώς θα είναι 1000. Αν καλέσουμε την άλφα() χωρίς μια τιμή τότε θα βγει λάθος, Αν περάσουμε δέκα τιμές και δεν  διαβάσουμε τις υπόλοιπες εννιά για να τις "σηκώσουμε" θα μείνουν στο σωρό.

Δυο εντολές δεν υπάρχουν στο πρόγραμμα παρακάτω (εστιάζω στα στοιχεία περισσότερο), η ΠΕΤΑ και η ΠΑΝΩ. Η πρώτη πετάει έναν αριθμό στοιχείων από την κορυφή ΠΕΤΑ 2 πετάει δύο στοιχεία. Η ΠΑΝΩ βγάζει αντίγραφο από μια θέση. Χωρίς νούμερο διπλασιάζει τη κορυφή, και ισούται με το ΠΑΝΩ 1. Με ΠΑΝΩ 2 βγάζουμε αντίγραφο του του δεύτερου το βάζουμε στη κορυφή και το δεύτερο έχει γίνει τρίτο. Αν έχουμε ομάδα ή πίνακα στο σωρό η Πάνω βγάζει αντίγραφο. Αν είναι ομάδα το αντίγραφο είναι σε όλο το βάθος.

(Οι εντολές Πάνω, Φέρε, Φέρεπίσω, παίρνουν και δεύτερη παράμετρο (,Ν) για τον αριθμό των τεμαχίων, ουσιαστικά είναι σαν να εκτελούμε την εντολή Ν φορές)

Στις τελευταίες εκδόσεις της γλώσσας υπάρχει μεταβλητή δείκτης σε αντικείμενο σωρού. Υπάρχουν παραδείγματα στο Εγχειρίδιο και το Μικρό Εγχειρίδιο.

κλάση μια {
      πινακας α(10)
      κ=100
}
Α=μια()
Α.α(5)=μια()
Α.Α(5).κ++
Α.Α(5).Α(3)=μια()
Α.Α(5).Α(3).κ=2000
Τύπωσε Α.Α(5).Α(3).κ
Βάλε Α
Πίνακας Β(10)
Διάβασε Β(3)
Τύπωσε Β(3).Α(5).κ ' 101
Τύπωσε Β(3).Α(5).Α(3).κ ' 2000

Το στοιχείο Β(3) έχει το αντίγραφο της Α σε όλο το βάθος.
Β(4)=Β(3)
Τύπωσε Β(4).Α(5).Α(3).κ ' 2000

Τώρα και το Β(4) έχει ένα αντίγραφο. Αυτό σημαίνει ότι έχει ένα πίνακα α(10) και το κ=100, όπου το Α(5) έχει μια ομάδα με πίνακα Α(10) και κ=101, όπου έχει μια ομάδα στο Α(3) με πίνακα Α(10) και κ=2000. Άρα έχει τρεις πίνακες ο δεύτερος σε ένα στοιχείο του πρώτου και ο τρίτος σε ένα στοιχείο του δεύτερου.


Αντιγράψτε το παρακάτω σε ένα τμήμα (Σ α enter)


Άδειασε ' αυτή η εντολή αδειάζει το σωρό
Οθόνη 5,0
Πένα 14
Πίνακας Κ(20)=4
Βάλε 1,2,3,4,"αλφα", 5,6, Κ()
Σωρός
Διάβασε Β(), Α, Β, Γ$, Δ
Τύπωσε Β(4), Α, Β, Γ$, Δ
κκ$=κομ$ ' περιμένει ένα "κομβίο"...
Πίνακας Β(0) ' μόλις τον άδεισα αλλά δεν μπορώ να τον διαγράψω σαν όνομα
Σωρός Νέος {
      \\ σκιάζω τον σωρό με ένα νέο
      Βάλε 10, 20
      \\ τώρα τον αδειάζω
      Άδειασε
      Τύπωσε Κενό \\ τυπώνει -1
}
Τύπωσε Κενό \\ τυπώνει 0
Τύπωσε Μέγεθος.Σωρού \\τυπώνει 3
Τύπωσε Αριθμός \\ τυπώνει το 3
Τύπωσε Αριθμός \\ τυπώνει το 2
Τύπωσε Αριθμός \\ τυπώνει το 1
κκ$=κομ$
\\ το 1 μπήκε πρώτο και βγήκε τελευταίο, άρα ο σωρός μου είναι:
\\ LIFO και ως LIFO πρέπει να λέγεται ΣΤΟΙΒΑ
\\ Last In First Out
\\ Όμως δεν είναι μόνο LIFO αλλά και FIFO δηλαδή και ΟΥΡΑ
\\ First In First OUT
Άδειασε  \\ η μπορώ να ανοίξω ένα νέο σωρό εδώ
Σειρά 1,2,3,4,5
Ενώ όχι κενό { Τύπωσε Αριθμός }
\\ τελευταίο τυπώνει το 5 άρα έχω FIFO.
\\ Η εντολή ΣΕΙΡΑ προσθέτει κάθε στοιχείο στη βάση ή πυθμένα του σωρού.
\\ Η εντολή ΒΑΛΕ προσθέτει κάθε στοιχείο στη κορυφή του σωρού
\\ Η Διάβασε που βάζει σε μεταβλητές και ο Αριθμός και η Γράμμα$ διαβάζουν από τη κορυφή
\\ Άρα ο σωρός είναι μια διπλή λίστα; Όχι είναι πιο προχωρημένος!
κκ$=κομ$
Βάλε 1,2,3,4,5
Φέρε 3
Τύπωσε Αριθμός ' τυπώνει το 3
Φέρε 3 '' η φέρε φέρνει το ν-οστό στοιχείο στη κορυφή
Τύπωσε Αριθμός ' τυπώνει το 4
ΦέρεΠίσω 3 ' κάνει τη κορυφή το τρίτο στοιχείο
Τύπωσε Αριθμός, Αριθμός, Αριθμός ' τελευταίο τυπώθηκε το 1
κκ$=κομ$
\\ Άρα με τις εντολές Φέρε και ΦέρεΠίσω αλλάζω τη σειρά στα στοιχεία
\\ χωρίς να με ενδιαφέρει τι είναι αυτά, αν είναι απλές μεταβλητές, πίνακες, ομάδες ή αναφορές!
Βάλε 10*3, 1, "α"
Τύπωσε ΕινΑρ ' τυπώνει 0  δεν είναι αριθμός η κορυφή
Τύπωσε ΕινΓρ ' Τυπώνει -1 δεν είναι γράμματα (αλφαριθμητικό) η κορυφή
Τύπωσε Κενό ' Τυπώνει 0  δεν είναι κενός ο σωρός.
Τύπωσε Ταύτιση("ΓΑ") ' τυπώνει -1 γιατί έχουμε γράμματα και αριθμό
Τύπωσε Ταύτιση("ΓΑΑ") ' τυπώνει -1 γιατί έχουμε γράμματα και αριθμό και αριθμό
κκ$=κομ$
\\ μπορούμε να διαβάσουμε χωρίς να σηκώσουμε τις τιμές όπως κάνει η διάβασε, ο αριθμός και η γράμμα$
ι=0
σωρος
Ενώ ι <μέγεθος.σωρού {
      ι++
      Αν σωρουτύπος$(ι)="Number" τότε {
            Τύπωσε ΤιμήΣωρού(ι)
      } Αλλιώς.Αν σωρουτύπος$(ι)="String" τότε {
            Τύπωσε ΤιμήΣωρού$(ι)
      }
}
κκ$=κομ$
\\ Το ίδιο με το παραπάνω με άλλο τρόπο
\\ Η Φάκελος$() χωρίς παρέμετρους δίνει για όλα τα στοιχεία από ένα γράμμα
\\ στα λατινικά NSAG  G για ομάδα/Group A για πίνακα/Array
Α$=Φακελος$()
Αν Α$<>"" τότε {
      Για ι=1 έως Μήκος(Α$) {
            Επίλεξε με Μεσ$(Α$,ι,1)
            με "S"
                  Τύπωσε ΤιμήΣωρού$(ι)
            με "N"
                  Τύπωσε ΤιμήΣωρού(ι)
            Αλλιώς
                  Τύπωσε "Δεν το υποστηρίζω"
            Τέλος Επιλογής
      }
}
κκ$=κομ$
\\ Οι αναφορές στη Μ2000 είναι αλφαρηθμιτικά:
αα=100
Βάλε &αα
Τύπωσε ΤιμήΣωρού$(1)
Διάβασε &ββ
αα+=100
Τύπωσε ββ ' τυπώνει 200


κκ$=κομ$


\\ η αναφορά σε συναρτηση είναι αντιγραφή του ορισμού σε αλφαριθμητικό!
Συνάρτηση Κάπα {
      Διάβασε Χ
      =Χ**2 ' η δύναμη μπαίνει και με ^ και με **
}
Τύπωσε Κάπα(2) ' τυπώνει 4
Βάλε &Κάπα()
\\ Ο ορισμός έχει μια επιπλέον γραμμή για πληροφορίες για το σύστημα που βρίσκει τη θέση του λάθους!
Τύπωσε ΤιμήΣωρού$(1)
\\ Στις συναρτήσεις ομάδων μπαίνει και άλλη πληροφορία που συνδέει τον ορισμό με την ομάδα
\\ ώστε και η συνάρτηση με αναφορά να βλέπει τις κοινές μεταβλητές της ομάδας
Διάβασε &Λάμδα()
Τύπωσε Λάμδα(10) '' τυπώνει 100


κκ$=κομ$


\\ Μέχρι εδώ είδαμε πώς βάζουμε στοιχεία στο σωρό ένα προς ένα, και πώς τα διαβάζουμε
\\ ακόμα είδαμε πως βάζουμε αναφορές σε τιμές
\\ Μπορούμε να δημιουργούμε αλφαριθμητικά με τιμές για σωρό!
\\ Δεν μπορούμε σε αυτά να βάλουμε αντικείμενα, όπως πίνακες και ομάδες.
ΑΑ$=Σωρός$(10,"αλφα",45) ' έχουμε μια λίστα σωρού
Αδειασε
Σωρός ΑΑ$ ' το 10 θα είναι κορυφή
Τύπωσε Μήκος(ΑΑ$) ' το αλφαριθμητικό είναι άδειο
Άδειασε
ΑΑ$=Σωρός$(10,"αλφα",45)
ΒΒ$=Σωρός$(ΑΑ$, Σωρός$(11,"βήτα", 100),ΑΑ$) ' το ΒΒ$ έχει τρία στοιχεία αλφαριθμητικά
ΑΑ$=ΑΑ$+ΑΑ$ ' πρόσθεσα δυο λίστες το ΑΑ$ έχει έξι στοιχεία
Σωρός ΑΑ$, "Α"    
Σωρός ΑΑ$,"ΓΑ"
Φέρε 3 '' αλλιώς θα έχω "άλφα", 45, 10
Διάβασε Α, Β$, Γ
Τύπωσε Α, Β$, Γ
κκ$=κομ$
Σωρός Νέος {
      Σωρός ΑΑ$
      ΦέρεΠίσω 2 ' πάω το 1 στη θέση του 2
      Φέρε 3 '' πάω το 3 στη θέση του 1 άρα άλλαξα το τρίο με το πρώτο!
      ΑΑ$=Σωρός$(Αριθμός, Γράμμα$, Αριθμός)
}
Σωρός ΑΑ$
Διάβασε Α, Β$, Γ
Τύπωσε Α, Β$, Γ
κκ$=κομ$
Σωρος ΒΒ$, "Γ"
\\ θα το βάλω πίσω στη τελευταία θέση
\\ αλλά όχι "γυμνό" αλλά όπως θα το φτιάξει η Σωρός$
\\ τα αλφαριθμητικά έχουν δείκτη μήκους μέσα στο αλφαριθμητικό ως σωρός
\\ έτσι μπορεί να μπει οτιδήποτε, ακόμα και φωλιασμένα άλλα στοιχεία!
ΒΒ$=ΒΒ$+Σωρος$(Γράμμα$)
Σωρός ΒΒ$,"Γ"    ' η ΒΒ$ έχει δυο στοιχεία τώρα και το καθένα έχει τρία
Διαβασε ΓΓ$
Σωρός ΓΓ$ ' τώρα η ΓΓ$ άδειασε
Διάβασε Α, Β$, Γ
Τύπωσε Α, Β$, Γ ' 11,"βήτα", 100
Τύπωσε Φάκελος$(ΒΒ$) ' δίνει SS δηλαδή δυο String (αλφαριθμητικά)


Κυριακή 29 Νοεμβρίου 2015

Συνδεδεμένη Λίστα - Περί Δεικτών (Μέρος Α)

Στο παράδειγμα παρακάτω θέλουμε να δούμε πώς θα βάλουμε μια λίστα τιμών συνδεδεμένες μεταξύ τους με δυο δείκτες, τον δεξιό και τον αριστερό.
Την λίστα την κόβουμε σε δυο λίστες και ζητάμε από μια θέση του κάτω μισού, από 0 έως 4 να πάρουμε το στοιχείο, να το βγάλουμε εκτός λίστας και να το βάλουμε σε μια θέση στην πάνω λίστα. Στην κάτω λίστα η θέση είναι αυτό που δείχνει ο δείκτης, δηλαδή είναι απόλυτη θέση. Στη πάνω λίστα η θέση είναι η νιοστή θέση. Επειδή η πάνω μισή έχει πέντε στοιχεία, οι θέσεις που μια από αυτές δύναται να καταλάβει το στοιχείο από την κάτω λίστα είναι έξι, μια θέση πριν το πρώτο στοιχείο της λίστας και πέντε θέσεις, μια μετά από κάθε στοιχείο της λίστας.



Αρχικά γνωρίζουμε τις θέσεις και μάλιστα γεμίζουμε τους δείκτες με απλό τρόπο, ώστε ο δείκτης -1 να δηλώνει "μη έγκυρο" ή "δεν υπάρχει συνέχεια", ενώ κάθε άλλο νούμερο να δηλώνει θέση στην "μνήμη" εδώ είναι ο πίνακας για μνήμη και σε κάθε στοιχείο βάζουμε μια ομάδα (οι πίνακες στη Μ2000 μπορούν να μεγαλώνουν χωρίς να αντιγράφονται οι ομάδες αλλά οι εσωτερικοί δείκτες στις ομάδες - οι ομάδες σε πίνακες είναι αντικείμενα, αλλά οι εσωτερικοί δείκτες δεν είναι διαχειρίσιμοι από τον χρήστη της Μ2000, αλλά από τον διερμηνευτή)

Η κλάση κόμβος δίνει απλά μια ομάδα με τρεις τιμές, δυο αριθμούς και ένα αλφαριθμητικό για την πληροφορία που φέρει.
Οι πίνακες στη Μ2000 ξεκινούν από 0 και για το λόγο αυτό βάλαμε το -1 να είναι η "μη έγκυρη τιμή δείκτη", ή νούλα, που σημαίνει αποτυχία (και πράγματι στην αγγλική ορολογία λέγεται Null Pointer αυτός ο δείκτης που δείχνει σε μη έγκυρο αντικείμενο).

Nil & Null
Στην ορολογία των προγραμματιστών υπάρχει το Nil από την λατινική Nil που σημαίνει τίποτα ή μηδέν, αλλά όχι μη έγκυρο. Θα μπορούσαμε να πούμε ότι δείκτης 0 είναι μη έγκυρος (δεν θα χρησιμοποιούμε το στοιχείο 0 της μνήμης μας). Τότε αυτός που φέρει το 0 είναι δείκτης NULL ενώ αυτό που περιέχει έχει υπόσταση και είναι το NIL, αυτό που δηλώνει το τίποτα. Άρα όταν μιλάμε για δείκτες ή θα δείχνουν κάτι ή θα είναι NULL, άρα το NULL δηλώνει κατάσταση. Το Nil λοιπόν είναι αναγνωριστικό ποσότητας και δύναται να περιέχεται κάπου. Αν τώρα η κατάσταση δηλώνεται με αριθμό που ποσοτικά είναι το μηδέν ή τίποτα..τότε λέγοντας πως ο δείκτης είναι ο Nil (που συμφωνήσαμε να δηλώνει ότι έχουμε μη έγκυρο δείκτη) τότε ο δείκτης δεν είναι έγκυρος παρόλο που έχει κάποια τιμή. Πράγματι οι θέσεις μνήμης δεν μπορούν να μην έχουν τίποτα, γιατί είναι θέσεις μνήμης άρα θέσεις από κάτι! Ένας δείκτης είναι μια θέση που δείχνει σε μια άλλη θέση. Άρα ένας δείκτης ως θέση οφείλει να έχει κάτι. Αν λοιπόν συμφωνήσουμε στο νούμερο Nil το μηδέν δηλαδή να το λέμε μη έγκυρο δείκτη, τότε έτσι αναγνωρίζουμε το NULL. Εδώ πάμε κόντρα στο ρεύμα (τα Windows δεν χρησιμοποιούν την θέση 0 της μνήμης γιατί έχουν το 0 ως NULL στους δείκτες που χρησιμοποιούν), και έτσι θα βάλουμε το -1 για ένδειξη NULL.

Αλφαριθμητικό κενό!
Αν προσέξουμε λίγο θα δούμε ότι η κλάση κόμβος που γνωρίζουμε ότι δημιουργεί μια συνάρτηση που όταν την καλέσουμε επιστρέφει ένα αντικείμενο "ομάδα", περιέχει τρεις μεταβλητές χωρίς τιμές. Όπως όμως είδαμε παραπάνω δεν υπάρχει κάτι χωρίς τιμή. Εδώ οι τιμές είναι οι μηδενικές. Καλά για τα νούμερα οι μηδενικές τιμές είναι σωστές. Αν και εδώ τα νούμερα θα είναι δείκτες, θα μπορούσαν να είχαν αρχικές τιμές -1 (δηλαδή NULL). Όμως στο παράδειγμά μας δεν μας στεναχωρεί αυτό. Η μεταβλητή όμως που λέγεται πληροφορία$ τι στο καλό έχει μέσα για αρχή; Εδώ λοιπόν είναι καιρός να μάθουμε ότι τα αλφαριθμητικά είναι λίστες καθορισμένου μήκους, και βρίσκονται σε δυο θέσεις. Στη πρώτη θέση υπάρχει ο δείκτης που δείχνει την άλλη θέση, και ένας αριθμός που λέει πόσα γράμματα θα βρούμε εκεί. Η άλλη θέση έχει τουλάχιστον τα γράμματα (ίσως και μερικά βοηθητικά στοιχεία, αλλά εδώ δεν μας ενδιαφέρουν αυτά). Έτσι η μηδενική τιμή για το αλφαριθμητικό είναι ένας NULL δείκτης, που σημαίνει ότι δεν υπάρχει θέση με γράμματα και μπορούμε να έχουμε και τον αριθμό γραμμάτων στο μηδέν (NIL). Ένα NULL (κατάσταση δείκτη) και ένα Nil (ποσότητα γραμμάτων) αρκούν για το κενό αλφαριθμητικό που το συμβολίζουμε έτσι "" με τα αυτάκια ή εισαγωγικά το ένα δίπλα στο άλλο, χωρίς διάστημα μεταξύ τους. Έτσι ακόμα και το κενό αλφαριθμητικό είναι μια πληροφορία, είναι κάτι, και τρώει μνήμη!

Τι συμβαίνει όταν προσθέτουμε ένα χαρακτήρα σε ένα μεγάλο αλφαριθμητικό
Δείτε τώρα τι συμβαίνει όταν πάμε να προσθέσουμε ένα χαρακτήρα. Το σύστημα ψάχνει να βρει χώρο και αντιγράφει ότι έχει το αλφαριθμητικό και στη συνέχεια αυτό που βάζουμε. Πάει μετά στο δείκτη και τον ενημερώνει και βάζει και το σωστό αριθμό στοιχείων. Αυτό που μένει, το προηγούμενο που έδειχνε ο δείκτης το επιστρέφει στο σύστημα. Υπάρχουν αλφαριθμητικά πολλών τύπων, ανάλογα τη περίπτωση, όταν όμως χρησιμοποιούμε γλώσσες όπως η C++. Εδώ λοιπόν στην Μ2000 η μεταφορά ενός αλφαριθμητικού σε ένα άλλο γίνεται με αντιγραφή, ή ακόμα και αν προσθέσουμε ένα μόνο χαρακτήρα, θα πρέπει να γίνει αντιγραφή και του ενός και όλων των άλλων που ήδη υπάρχουν.

Γιατί μας βολεύουν οι δείκτες
Όπου τώρα μιλάγαμε για αλφαριθμητικά ας σκεφτούμε ότι μπορεί να είναι ό,τι άλλο, στοιχεία δηλαδή, με την ιδιότητα ότι "απλώνουν" το ένα μετά το άλλο (αυτό είναι το θέμα με τα αλφαριθμητικά), χωρίς να ξεκινούν με όλο το χώρο, αλλά να παίρνουν χώρο όπως λέμε δυναμικά. Οι πίνακες της Μ2000 πράγματι μεγαλώνουν και αυτό γίνεται με αντιγραφή. Όμως δείτε τι κερδίζουμε με τους δείκτες. Αν ο πίνακας έχει αντικείμενο ή αλφαριθμητικό τότε έχουμε δυο θέσεις, για κάθε στοιχείο, η θέση στον πίνακα που δείχνει τη θέση του αντικειμένου ή αλφαριθμητική. Αυτό λοιπόν που αντιγράφουμε όταν αυξάνουμε τα στοιχεία του πίνακα είναι μόνο έναν δείκτη σε θέση αντικειμένου ή αλφαριθμητικού, όχι τα αντικείμενα ή τα αλφαριθμητικά! Άρα η επέκταση γίνεται γρήγορα επειδή τα πολύ μεγαλύτερα σε μνήμη αντικείμενα ή και αλφαριθμητικά θα μείνουν στην θέση τους.

Τα βασικά για το παράδειγμα
Στο παράδειγμά μας θέλουμε να έχουμε την πληροφορία δεμένη με δείκτες δεξί και αριστερό για να μπορούμε τη λίστα να τη διαβάζουμε από την αρχή ή από το τέλος (τη καλή και την ανάποδη που αναφέρω στο πρόγραμμα). Ενώ αρχικά βγάζουμε ένα στοιχείο από την σύνδεση με απευθείας γνώση της θέσης (αυτό δεν γίνεται σε μια λίστα λειτουργική αλλά εδώ κάνουμε ότι μας αρέσει, γιατί ξέρουμε  ακριβώς τις θέσεις των στοιχείων). Μετά το προσθέτουμε στη "λειτουργική" λίστα όπου δεν ασχολούμαστε με τους πραγματικούς δείκτες, αλλά με μεταβλητές που περιέχουν πραγματικούς δείκτες. Στο παράδειγμα δεν κάνουμε ειδικό έλεγχο περί κενής λίστας. Κενή λίστα θα σήμαινε πως αρκεί και ένας από τους δυο δείκτες να είναι Null (-1 εδώ). Αυτό θα το δούμε στο δεύτερο μέρος που θα προχωρήσω το θέμα.

Στόχος του παραδείγματος
Εδώ μας αρκεί να δούμε ότι ένα στοιχείο με δείκτη από 0 έως 4 θα γίνει μέρος της λίστας που ξεκίνησε από το 5 έως το 9, χωρίς να μετακινηθεί πραγματικά καμία πληροφορία$ (μόνο για να εμφανιστεί αντιγράφεται στην Τύπωσε). Το που θα μπει το καθορίζουμε με το ν-οστό στοιχείο, όπου για ν=0 θα μπει στην αρχή της δεύτερης λίστας, για ν=1 μετά το 1ο,  ώσπου για ν>=5 μετά το 5ο στοιχείο

Αφού λοιπόν ετοιμάσουμε την Μ2000 (τρέξουμε το m2000.exe και βάλουμε το πρόγραμμα στο Α) δίνουμε εντολή:
Α 3, 4
Που σημαίνει πάρε από την απόλυτη θέση 3 και μετέφερε τη πληροφορία μετά το τέταρτο στοιχείο.

Σαν άσκηση θα μπορούσε κανείς το πρώτο νούμερο να το δει σαν το ν-οστό στοιχείο της πρώτης λίστας (Αλλά αφού εδώ σηκώνουμε στοιχεία θα πρέπει να ξεκινάει από 1, αφού 0 στοιχείο δεν υπάρχει).


Γράφουμε το παρακάτω σε ένα τμήμα έστω Α (Σ Α enter)

Αν όχι Ταύτιση("ΑΑ") τότε Λάθος "Δεν βρήκα δυο αριθμούς"
\\ ζητάμε μια θέση από 0 έως 4 - δείκτης
\\ και μια σχετική θέση από 0 έως 5 - θέση στη λίστα
κλάση κόμβος {
δεξιά, αριστερά
πληροφορία$
}
Πίνακας Κόμβοι(10)=κόμβος()
' Συνδέουμε σε μια λίστα απλή όλους τους άδειους κόμβους, και τους γεμίζουμε!
Σειρά "Α","Β","Γ","1","3","9","Κ","Λ","Ω","%"
\\ έχω βάλει ν και μ στο σωρό από την κλήση του τμήματος
Φέρεπίσω 12 ' πάω πίσω το ν δώδεκα θέσεις
Φέρεπίσω 12 ' πάω πίσω το μ δώδεκα θέσεις
\\ άρα διαβάζω από το "Α"
ι=0
Κόμβοι(0).δεξιά=-1
Ενώ ι<9 {
      Διάβασε Κόμβοι(ι).πληροφορία$
      Κόμβοι(ι).Αριστερά=ι+1
      ι++
}
Διάβασε Κόμβοι(ι).πληροφορία$
Κόμβοι(ι).Αριστερά=-1
' ι=9
Επανέλαβε {
      Κόμβοι(ι).δεξιά=ι-1
      ι--
} μέχρι ι=0
\\ Τώρα έχουμε μια συνδεδεμένη λίστα μέσα σε ένα πίνακα.



\\ για να δουλεύει σωστά η λίστα χρειάζονται μερικές ευκολίες
Τμήμα Δείξε.Λίστα.Αρ {
Διαβασε &κ(), π
      Ενώ π>=0 {
            Τύπωσε κ(π).πληροφορία$;
            π=κ(π).Αριστερά
      }
      Τύπωσε
}
Τμήμα Δείξε.Λίστα.Δε {
Διαβασε &κ(), π
      Ενώ π>=0 {
            Τύπωσε κ(π).πληροφορία$;
            π=κ(π).Δεξιά
      }
      Τύπωσε
}
\\ από 0 έως 9
Αναφορά "Η λίστα από τη καλή"
Δείξε.Λίστα.Αρ &Κόμβοι(), 0
\\ από 9 έως 0
Αναφορά "Η λίστα από την ανάποδη"
Δείξε.Λίστα.Δε &Κόμβοι(), 9
\\ θα κόψουμε τη λίστα σε δυο λίστες!
\\ 0 έως 4 ή πρώτη και 5 έως 9 η δεύτερη
Κόμβοι(4).Αριστερά=-1
Κόμβοι(5).Δεξιά=-1
Αναφορά "Η κάτω μισή λίστα από τη καλή"
Δείξε.Λίστα.Αρ &Κόμβοι(), 0
Αναφορά "Η κάτω μισή λίστα από την ανάποδη"
Δείξε.Λίστα.Δε &Κόμβοι(), 4
Αναφορά "Η πάνω μισή λίστα από την καλή"
Δείξε.Λίστα.Αρ &Κόμβοι(), 5
Αναφορά "Η πάνω μισή λίστα από την ανάποδη"
Δείξε.Λίστα.Δε &Κόμβοι(), 9
Αναφορά "θέλω να αφαιρέσω ένα στοιχείο από την πρώτη λίστα"
Δα=0 ' Δείκτης αρχής
Δτ=4 'Δείκτης τέλους
\\ δοκιμάστε για οποιοδήποτε μ από 0 έως 4
\\ προσοχή εδώ ζητάμε το μ πραγματικό στοιχείο
\\ όχι το μ-οστό
\\μ=4
Διάβασε μ
Αναφορά Μορφή$("Θα αφαιρέσω το στοιχείο με δείκτη {0} της λίστας - από 0 έως 4", μ)
αν Κόμβοι(μ).Δεξιά>=0 τότε {
      Κόμβοι(Κόμβοι(μ).Δεξιά).Αριστερά=Κόμβοι(μ).Αριστερά
} αλλιώς Δα=Κόμβοι(μ).Αριστερά
\\ υπάρχει μια ωραία συμμετρία στο κώδικα!
αν Κόμβοι(μ).Αριστερά>=0 τότε {
      Κόμβοι(Κόμβοι(μ).Αριστερά).Δεξιά=Κόμβοι(μ).Δεξιά
} αλλιώς Δτ=Κόμβοι(μ).Δεξιά
Δείξε.Λίστα.Αρ &Κόμβοι(), Δα
Δείξε.Λίστα.Δε &Κόμβοι(), Δτ
\\τώρα έχουμε το μ έξω από την πρώτη λίστα
\\ υπάρχουν 6 θέσεις για να μπει το μ στοιχείο στην λίστα
\\ με τα πέντε στοιχεία. Ή στην αρχή ή μετά από ένα στοιχείο της λίστας
Δα2=5 ' δείκτης αρχής
Δτ2=9 ' δείκτης τέλους
\\ Οπότε ζητάμε ένα ν όπου αν ν=0 τότε βάζουμε στην αρχή
\\ προσοχή εδώ δεν ζητάμε το ν στοιχείο αλλά το ν-οστό στοιχείο
\\ν=1
Διάβασε ν
Αναφορά Μορφή$("Θα προσθέσω το στοιχείο με δείκτη {0} της λίστας στη πάνω λίστα στη σχετική θέση {1}", μ,ν)
Αν ν=0 τότε {
Κόμβοι(μ).δεξιά=-1
Κόμβοι(μ).αριστερά=Δα2
Κόμβοι(Δα2).δεξιά=μ ' εδώ συνδέθηκε το πρώην πρώτο με το νυν πρώτο
Δα2=μ
} αλλιώς {
      \\ τώρα πρέπει να μετράμε
      π=Δα2
      Ενώ π>=0 και ν>0 {
            π=Κόμβοι(π).Αριστερά
            ν--
      }
      Αν π<0 τότε {
            \\ είμαστε στο άκρο, θα βάλουμε εδώ το στοιχείο
            Κόμβοι(μ).αριστερά=-1 \\ δεν έχει άλλο
            Κόμβοι(Δτ2).αριστερά=μ
            Κόμβοι(μ).δεξιά=Δτ2
            Δτ2=μ
     }  Αλλιώς {
             Κόμβοι(κόμβοι(π).δεξιά).αριστερά=μ ' ΄ενώ έδειχνε το π
             Κόμβοι(μ).αριστερά=π '' τώρα ο μ θα δείχνει στο π
             Κόμβοι(μ).δεξιά=Κόμβοι(π).δεξιά ' και ο μ θα δείχνει δεξιά ότι έδειχνε ο π
             Κόμβοι(π).δεξιά=μ '' και ο π θα δείχνει δεξιά το μ
     }
}
Δείξε.Λίστα.Αρ &Κόμβοι(), Δα2
Δείξε.Λίστα.Δε &Κόμβοι(), Δτ2


Πιο πάνω έχω βάλει δυο ΦΕΡΕΠΙΣΩ εντολές για το σωρό (ειδική στοίβα της Μ2000) το οποίο αν θέλουμε βάζουμε το Σωρός Νέος { } και μέσα σε αυτό την εντολή Σειρά. Έτσι δεν πειράζουμε το σωρό όπου είναι τα ν και μ και ακόμα δεν τα έχουμε σηκώσει:

' Συνδέουμε σε μια λίστα απλή όλους τους άδειους κόμβους, και τους γεμίζουμε!
Σωρός Νέος {
      Σειρά "Α","Β","Γ","1","3","9","Κ","Λ","Ω","%"
      ι=0
      Κόμβοι(0).δεξιά=-1
      Ενώ ι<9 {
            Διάβασε Κόμβοι(ι).πληροφορία$
            Κόμβοι(ι).Αριστερά=ι+1
            ι++
      }
      Διάβασε Κόμβοι(ι).πληροφορία$
}


Προσθήκη 2020
Ο κώδικας μπορεί να εκτελεστεί και με αλλαγές στις δομές επανάληψης και επιλογής όπως φαίνονται παρακάτω. Επίσης τα εσωτερικά τμήματα χρησιμοποιούν την λίσα παραμέτρων σε παρενθέσεις η οποία θα γίνει μια Διάβασε όπως στο πάνω πρόβλημα.

Στη δομή επιλογής Αν όταν βγάζουμε τα μπλοκ και χρησιμοποιούμε το Τέλος Αν τότε ο διερμηνευτής χρησιμοποιεί μια διαφορετική εσωτερική δομή, χωρίς μπλοκ. Οπότε αποφεύγουμε τα άλματα με την Προς, διότι αυτά σχετίζονται με το μπλοκ που ανήκει η δομή, και επειδή υπάρχει μέτρημα των Τέλος Αν κατά την εκτέλεση μπορεί να βγει λάθος αν πχ η Προς (Goto) χρησιμοποιηθεί έτσι ώστε να κάνει αλλαγές ροής που δεν περιλάμβάνουν το σωστό αριθμό Τέλος Αν. Στις Επανάλαβε και Ενώ αν και δεν βλέπουμε μπλοκ όταν χρησιμοποιούμε την έκδοση χωρίς αγκύλες ο διερμηνευτής αποδίδει αυτόματα μπλοκ, οπότε τυχόν εντολές για μπλοκ όπως και η ΠΡΟΣ (Goto) λειτουργούν πάντα σωστά.

Αν όχι Ταύτιση("ΑΑ") Τότε Λάθος "Δεν βρήκα δυο αριθμούς"
\\ ζητάμε μια θέση από 0 έως 4 - δείκτης
\\ και μια σχετική θέση από 0 έως 5 - θέση στη λίστα
κλάση κόμβος {
      δεξιά, αριστερά
      πληροφορία$
}
Πίνακας Κόμβοι(10)=κόμβος()
' Συνδέουμε σε μια λίστα απλή όλους τους άδειους κόμβους, και τους γεμίζουμε!
Σειρά "Α","Β","Γ","1","3","9","Κ","Λ","Ω","%"
\\ έχω βάλει ν και μ στο σωρό από την κλήση του τμήματος
Φέρεπίσω 12 ' πάω πίσω το ν δώδεκα θέσεις
Φέρεπίσω 12 ' πάω πίσω το μ δώδεκα θέσεις
\\ άρα διαβάζω από το "Α"
ι=0
Κόμβοι(0).δεξιά=-1
Ενώ ι<9
      Διάβασε Κόμβοι(ι).πληροφορία$
      Κόμβοι(ι).Αριστερά=ι+1
      ι++
Τέλος Ενώ
Διάβασε Κόμβοι(ι).πληροφορία$
Κόμβοι(ι).Αριστερά=-1
' ι=9
Επανέλαβε
      Κόμβοι(ι).δεξιά=ι-1
      ι--
Μέχρι ι=0
\\ Τώρα έχουμε μια συνδεδεμένη λίστα μέσα σε ένα πίνακα.


\\ για να δουλεύει σωστά η λίστα χρειάζονται μερικές ευκολίες
Τμήμα Δείξε.Λίστα.Αρ (&κ(), π){
      Ενώ π>=0
            Τύπωσε κ(π).πληροφορία$;
            π=κ(π).Αριστερά
      Τέλος Ενώ
      Τύπωσε
}
Τμήμα Δείξε.Λίστα.Δε (&κ(), π) {
      Ενώ π>=0
            Τύπωσε κ(π).πληροφορία$;
            π=κ(π).Δεξιά
      Τέλος Ενώ
      Τύπωσε
}
\\ από 0 έως 9
Αναφορά "Η λίστα από τη καλή"
Δείξε.Λίστα.Αρ &Κόμβοι(), 0
\\ από 9 έως 0
Αναφορά "Η λίστα από την ανάποδη"
Δείξε.Λίστα.Δε &Κόμβοι(), 9
\\ θα κόψουμε τη λίστα σε δυο λίστες!
\\ 0 έως 4 ή πρώτη και 5 έως 9 η δεύτερη
Κόμβοι(4).Αριστερά=-1
Κόμβοι(5).Δεξιά=-1
Αναφορά "Η κάτω μισή λίστα από τη καλή"
Δείξε.Λίστα.Αρ &Κόμβοι(), 0
Αναφορά "Η κάτω μισή λίστα από την ανάποδη"
Δείξε.Λίστα.Δε &Κόμβοι(), 4
Αναφορά "Η πάνω μισή λίστα από την καλή"
Δείξε.Λίστα.Αρ &Κόμβοι(), 5
Αναφορά "Η πάνω μισή λίστα από την ανάποδη"
Δείξε.Λίστα.Δε &Κόμβοι(), 9
Αναφορά "θέλω να αφαιρέσω ένα στοιχείο από την πρώτη λίστα"
Δα=0 ' Δείκτης αρχής
Δτ=4 'Δείκτης τέλους
\\ δοκιμάστε για οποιοδήποτε μ από 0 έως 4
\\ προσοχή εδώ ζητάμε το μ πραγματικό στοιχείο
\\ όχι το μ-οστό
\\μ=4
Διάβασε μ
Αναφορά Μορφή$("Θα αφαιρέσω το στοιχείο με δείκτη {0} της λίστας - από 0 έως 4", μ)
Αν Κόμβοι(μ).Δεξιά>=0 Τότε
      Κόμβοι(Κόμβοι(μ).Δεξιά).Αριστερά=Κόμβοι(μ).Αριστερά
Αλλιώς
      Δα=Κόμβοι(μ).Αριστερά
Τέλος Αν
\\ υπάρχει μια ωραία συμμετρία στο κώδικα!
Αν Κόμβοι(μ).Αριστερά>=0 Τότε
      Κόμβοι(Κόμβοι(μ).Αριστερά).Δεξιά=Κόμβοι(μ).Δεξιά
Αλλιώς
      Δτ=Κόμβοι(μ).Δεξιά
Τέλος Αν
Δείξε.Λίστα.Αρ &Κόμβοι(), Δα
Δείξε.Λίστα.Δε &Κόμβοι(), Δτ
\\τώρα έχουμε το μ έξω από την πρώτη λίστα
\\ υπάρχουν 6 θέσεις για να μπει το μ στοιχείο στην λίστα
\\ με τα πέντε στοιχεία. Ή στην αρχή ή μετά από ένα στοιχείο της λίστας
Δα2=5 ' δείκτης αρχής
Δτ2=9 ' δείκτης τέλους
\\ Οπότε ζητάμε ένα ν όπου Αν ν=0 Τότε βάζουμε στην αρχή
\\ προσοχή εδώ δεν ζητάμε το ν στοιχείο αλλά το ν-οστό στοιχείο
\\ν=1
Διάβασε ν
Αναφορά Μορφή$("Θα προσθέσω το στοιχείο με δείκτη {0} της λίστας στη πάνω λίστα στη σχετική θέση {1}", μ,ν)
Αν ν=0 Τότε
      Κόμβοι(μ).δεξιά=-1
      Κόμβοι(μ).αριστερά=Δα2
      Κόμβοι(Δα2).δεξιά=μ ' εδώ συνδέθηκε το πρώην πρώτο με το νυν πρώτο
      Δα2=μ
Αλλιώς
      \\ τώρα πρέπει να μετράμε
      π=Δα2
      Ενώ π>=0 και ν>0
            π=Κόμβοι(π).Αριστερά
            ν--
      Τέλος Ενώ
      Αν π<0 Τότε
            \\ είμαστε στο άκρο, θα βάλουμε εδώ το στοιχείο
            Κόμβοι(μ).αριστερά=-1 \\ δεν έχει άλλο
            Κόμβοι(Δτ2).αριστερά=μ
            Κόμβοι(μ).δεξιά=Δτ2
            Δτ2=μ
     Αλλιώς
             Κόμβοι(κόμβοι(π).δεξιά).αριστερά=μ ' ΄ενώ έδειχνε το π
             Κόμβοι(μ).αριστερά=π '' τώρα ο μ θα δείχνει στο π
             Κόμβοι(μ).δεξιά=Κόμβοι(π).δεξιά ' και ο μ θα δείχνει δεξιά ότι έδειχνε ο π
             Κόμβοι(π).δεξιά=μ '' και ο π θα δείχνει δεξιά το μ
     Τέλος Αν
Τέλος Αν
Δείξε.Λίστα.Αρ &Κόμβοι(), Δα2
Δείξε.Λίστα.Δε &Κόμβοι(), Δτ2