Συνήθως βλέπουμε αναθεωρήσεις αλλά όταν κάτι αλλάζει κάτι εσωτερικό, όπως τώρα, αλλάζει η έκδοση.
Αυτό που προστέθηκε είναι ο χειριστής σε εκφράσεις << δείτε (1) και (2) καθώς επίσης έγινε αλλαγή στην Random ώστε να μπορούμε να παράγουμε σταθερές επαναλαμβανόμενες τυχαίες σειρές και υπάρχει και ένα επίπεδο για να διακόψουμε τη παραγωγή να ξεκινήσουμε μια άλλη και να επανέλθουμε στη προηγούμενη (έχει μόνο push-pop)
1. Χρήση σε έκφραση:
Αδειασε
\\ η εντολή Σειρά βάζει στο τέλος του σωρού
\\ έτσι έχουμε FIFO (διαβάζουμε πάντα από κορυφή)
\\ η εντολή Βάλε βάζει στην κορυφή (LIFO)
Σειρά 1,2,3,4
Σωρός \\ εμφανίζει τα 1 2 3 4 (το 1 στην κορυφή)
Άδειασε
Σειρά 1<<2<<3<<4
Σωρός \\ εμφανίζει τα 1 2 3 4 (το 1 στην κορυφή)
\\ ακριβώς το ίδιο γιατί το << κάνει την προηγούμενη τιμή...
\\ ..να μπει στο σωρό με Σειρά
Άδειασε
\\ ομοίως
Σειρά "Α"<<"Β"<<"Γ"<<"Δ"
Σωρός
\\ Υπάρχει διαφορά
Άδειασε
\\ αυτό γίνεται
Σειρά 1,"Α",2,"Β"
Δες οκ {
\\ Αυτό δεν γίνεται
\\ πρέπει να έχουμε ίδιο είδος
Σειρά 1<<"Α"<<2<<"Β"
}
Αν όχι οκ Τότε Τύπωσε Λάθος$ \\ Συντακτικό λάθος
Σωρός
Αυτός ο χειριστής καθώς και η εντολή Try Stream ή Δες Ρεύμα. δημιουργούν προγραμματιστικά κολπάκια, όπως εδώ όπου:
Η a1 είναι μια λάμδα συνάρτηση (function factory) που δίνει έξοδο μια άλλη λάμδα που κρατάει μια τιμή στο χ και κάθε φορά που θα την καλέσουμε θα μειώνεται. Κανονικά μια συνάρτηση δέχεται ένα σωρό με τιμές για εισαγωγή, και τους διαβάζει με διάβασε ή read, αλλά αν υπάρχει ο χειριστής << τότε η Try Stram τρέχει το αριστερό μέρος του χειριστή με τρόπο ώστε να παίρνει την εξαγωγή του στο σωρό, είτε είναι ένα νούμερο είτε έχουν μπει με Data (πάντα στο τέλος του σωρού, έχει σημασία).
Φτιάχνουμε τρεις γεννήτριες την a, b και k με διαφορετική τιμή εκκίνησης.
Επίσης φτιάχνουμε μια ομάδα με μια συνάρτηση που και αυτή χρησιμοποιεί το "ρεύμα" αν υπάρχει.
Κάθε φορά που δέχεται ένα νούμερο για εισαγωγή αλλάζει μια ιδιότητα counter της ομάδας
Αξίζει να δει κανείς της εξαγωγή:
Θα πάρουμ 10+4+3 17 τεμάχια αλλά με τρόπο:
Πρώτα θα πάρουμε ένα από το καθένα, μετά το 3ο το k() δεν θα ξαναδώσει, μετά το 4ο το b() δεν θα ξαναδώσει, και μετά το 10ο το a() δεν θα ξαναδώσει και θα τερματίσει η εισαγωγή!
Αυτός είναι ο χειριστής Insert ή Εισαγωγή.
\\ generator
a1 =lambda -> {
read x
=lambda x ->{
try stream
if x>0 then = x
x--
}
}
\\ stream input
group alfa {
counter
function receive {
{
try stream
if empty then exit
read X
.counter++
print x
loop
}
=.counter
}
}
a=a1(10)
b=a1(4)
k=a1(3)
mm= alfa.receive() << a() << b() << k()
print mm \\ get 17 items
Στο δεύτερο παράδειγμα καθορίζουμε τη μέγιστη εισαγωγή. Το read ? many σημαίνει φτιάξε το many αν δεν υπάρχει και δώσει 0 αν δεν υπάρχει τιμή στο σωρό (δίνει δυνατότητα για προαιρετική (optional) εισαγωγή).
Clear
Function a {
k=0
{
try stream
Read ? b
k+=b*30
=k
}
}
Function Stream1 {
read ? many
k=0
Print "many=";many
if empty then many++
try stream
{
if many=0 then exit
read ? m
k+=m
many--
if not empty then loop
}
=k
}
flush
Print a(), a(3), a(1,2,3,4,5), a(10)
k= stream1(100) << a(1,2)<<3<<4
Print 1*30+2+3+4
Print k
Print stream1(2) <<5<<6
στο παρακάτω δίνουμε 10Χ8 στοιχεία, το 3 στο f δεν κάνει τίποτα, αλλά ας υποθέσουμε ότι είναι αριθμός χειριστής αρχείου για εξαγωγή
aa=lambda k=10 -> {
if k<1 then exit
data 1,2,3,4,5,6,7,8
k--
}
flush
function holder {
read f
p=0
Repeat {
try stream
if empty then exit
read X : p+=X
} Always
=p
}
Print holder(3) << aa()
Παρόμοιο αλλά εδώ δίνουμε μια σειρά αριθμών ενώ ορίζουμε το μέγιστο
k=lambda->{read k1, k2 : for i=k1 to k2 { data i }}
sum=lambda->{
p=0 : max=1
Read ? max
try stream
{
if empty then =0 : exit
read ? x
p+=x
max--
if max>0 then loop
}
=p
}
Print sum(100) << k(1,100) \\ 5050
Αυτό τώρα είναι πιο προχωρημένο! Ο χειριστής << είναι διπλή ενεργείας! Στο παρακάτω παράδειγμα η holder διαβάζει από το ρεύμα μόνο αν έχει το σωστό κλειδί.
Και στις δυο περιπτώσεις δίνουμε το κλειδί στη Holder, την πρώτη φορά το λάθος κλειδί, την δεύτερη το σωστό. Και στις δυο περιπτώσεις δοκιμάζει το ρεύμα.Πριν το κάνει όμως στέλνει στο σωρό το κλειδί, το οποίο διαβάζει η "γεννήτρια" και αν είναι το σωστό δίνει απάντηση αλλιώς τίποτα! Σημειώστε ότι θα δουλέψει ακόμα και αν δεν υπάρχει ρεύμα να πάρει τιμές.
Ο σωρός στις συναρτήσεις είναι πάντα φρέσκος και στο τέλος χάνεται, αλλά δεν συμβαίνει αυτό στην κλήση μετά το <<
aa=lambda k=10 -> {
try {
read k$
if k$ = "Key1" then {
if k<1 then exit
data 1,2,3,4,5,6,7,8
k--
}
}
}
bb=lambda-> {
data 1,2,3
}
flush
Group beta {
counter
function holder {
read mkey$
p=0
Repeat {
push mkey$ \\ send back
try stream
if empty then exit
if not isnum then exit
read X : p+=X
.counter++
} Always
=p
}
}
Print Beta.holder("Key1") << bb()
Print Beta.counter \\0
Print Beta.holder("Key1") << aa()
Print Beta.counter \\ 80 numbers
Beta.counter=0
Print Beta.holder("Key1")
Print Beta.counter \\ 0
2. Χρήση σε πίνακες
Εδώ αντί να βάλουμε = για σταθερή τιμή βάζουμε << που σημαίνει εκτέλεσε για κάθε στοιχείο (χειρίζεται τον πίνακα πάντα ως μονοδιάστατο)
c=lambda X=2 ->{=X: X+=3}
dim a(8,8)<<c()
for j=0 to 7 {
for i=0 to 7 {
print a(i, j),
}
print
}
3. Νέα Random με χρήση του Wichmann-Hill αλγόριθμου (κώδικας γραμμένος σε VB6 από το μέλος Merri στο VbForums, από πρώτη εγγραφή του μέλους anhn)
Αν γράψουμε το πρόγραμμα στο τμήμα Α τότε με Α σκέτο δείχνει την σειρά των 10 ζευγών τυχαίων. Με Α 1 ή άλλο μη μηδενικό νούμερο τότε έχουμε δέκα άλλους τυχαίους ενδιάμεσα, μετά τους πρώτους 5 και μετά συνεχίζουν οι επόμενοι 5 όπως έχουν και χωρίς τους ενδιάμεσους.
Τυχαίος() κάνει τυχαία αρχή (δεν γυρίζει νούμερο)
Τυχαίος(!133123) κάνει νέα αρχή από γνωστό νούμερο (γυρίζει το νούμερο αυτό) ενώ σώνει πρώτα τη θέση της γεννήτριας τυχαίων
Τυχαίος(!) κάνει pop την παλιά θέση της γεννήτριας
Τυχαίος(10) από 0 έως 10
Τυχαίος(-5, 5) από -5 έως 5
Τυχαίος δίνει έναν αριθμό από >=0 έως <1
read ? partial
K=random(!123)
for I=1 TO 5
print random(1, 20), rnd
next I
if partial then {
K=random(!112145)
print K
for I=1 TO 10
print random(1, 20), rnd
next I
k=random(!)
}
for I=1 TO 5
print random(1, 20), rnd
next I
Αυτό που προστέθηκε είναι ο χειριστής σε εκφράσεις << δείτε (1) και (2) καθώς επίσης έγινε αλλαγή στην Random ώστε να μπορούμε να παράγουμε σταθερές επαναλαμβανόμενες τυχαίες σειρές και υπάρχει και ένα επίπεδο για να διακόψουμε τη παραγωγή να ξεκινήσουμε μια άλλη και να επανέλθουμε στη προηγούμενη (έχει μόνο push-pop)
1. Χρήση σε έκφραση:
Αδειασε
\\ η εντολή Σειρά βάζει στο τέλος του σωρού
\\ έτσι έχουμε FIFO (διαβάζουμε πάντα από κορυφή)
\\ η εντολή Βάλε βάζει στην κορυφή (LIFO)
Σειρά 1,2,3,4
Σωρός \\ εμφανίζει τα 1 2 3 4 (το 1 στην κορυφή)
Άδειασε
Σειρά 1<<2<<3<<4
Σωρός \\ εμφανίζει τα 1 2 3 4 (το 1 στην κορυφή)
\\ ακριβώς το ίδιο γιατί το << κάνει την προηγούμενη τιμή...
\\ ..να μπει στο σωρό με Σειρά
Άδειασε
\\ ομοίως
Σειρά "Α"<<"Β"<<"Γ"<<"Δ"
Σωρός
\\ Υπάρχει διαφορά
Άδειασε
\\ αυτό γίνεται
Σειρά 1,"Α",2,"Β"
Δες οκ {
\\ Αυτό δεν γίνεται
\\ πρέπει να έχουμε ίδιο είδος
Σειρά 1<<"Α"<<2<<"Β"
}
Αν όχι οκ Τότε Τύπωσε Λάθος$ \\ Συντακτικό λάθος
Σωρός
Αυτός ο χειριστής καθώς και η εντολή Try Stream ή Δες Ρεύμα. δημιουργούν προγραμματιστικά κολπάκια, όπως εδώ όπου:
Η a1 είναι μια λάμδα συνάρτηση (function factory) που δίνει έξοδο μια άλλη λάμδα που κρατάει μια τιμή στο χ και κάθε φορά που θα την καλέσουμε θα μειώνεται. Κανονικά μια συνάρτηση δέχεται ένα σωρό με τιμές για εισαγωγή, και τους διαβάζει με διάβασε ή read, αλλά αν υπάρχει ο χειριστής << τότε η Try Stram τρέχει το αριστερό μέρος του χειριστή με τρόπο ώστε να παίρνει την εξαγωγή του στο σωρό, είτε είναι ένα νούμερο είτε έχουν μπει με Data (πάντα στο τέλος του σωρού, έχει σημασία).
Φτιάχνουμε τρεις γεννήτριες την a, b και k με διαφορετική τιμή εκκίνησης.
Επίσης φτιάχνουμε μια ομάδα με μια συνάρτηση που και αυτή χρησιμοποιεί το "ρεύμα" αν υπάρχει.
Κάθε φορά που δέχεται ένα νούμερο για εισαγωγή αλλάζει μια ιδιότητα counter της ομάδας
Αξίζει να δει κανείς της εξαγωγή:
Θα πάρουμ 10+4+3 17 τεμάχια αλλά με τρόπο:
Πρώτα θα πάρουμε ένα από το καθένα, μετά το 3ο το k() δεν θα ξαναδώσει, μετά το 4ο το b() δεν θα ξαναδώσει, και μετά το 10ο το a() δεν θα ξαναδώσει και θα τερματίσει η εισαγωγή!
Αυτός είναι ο χειριστής Insert ή Εισαγωγή.
\\ generator
a1 =lambda -> {
read x
=lambda x ->{
try stream
if x>0 then = x
x--
}
}
\\ stream input
group alfa {
counter
function receive {
{
try stream
if empty then exit
read X
.counter++
print x
loop
}
=.counter
}
}
a=a1(10)
b=a1(4)
k=a1(3)
mm= alfa.receive() << a() << b() << k()
print mm \\ get 17 items
Στο δεύτερο παράδειγμα καθορίζουμε τη μέγιστη εισαγωγή. Το read ? many σημαίνει φτιάξε το many αν δεν υπάρχει και δώσει 0 αν δεν υπάρχει τιμή στο σωρό (δίνει δυνατότητα για προαιρετική (optional) εισαγωγή).
Clear
Function a {
k=0
{
try stream
Read ? b
k+=b*30
=k
}
}
Function Stream1 {
read ? many
k=0
Print "many=";many
if empty then many++
try stream
{
if many=0 then exit
read ? m
k+=m
many--
if not empty then loop
}
=k
}
flush
Print a(), a(3), a(1,2,3,4,5), a(10)
k= stream1(100) << a(1,2)<<3<<4
Print 1*30+2+3+4
Print k
Print stream1(2) <<5<<6
στο παρακάτω δίνουμε 10Χ8 στοιχεία, το 3 στο f δεν κάνει τίποτα, αλλά ας υποθέσουμε ότι είναι αριθμός χειριστής αρχείου για εξαγωγή
aa=lambda k=10 -> {
if k<1 then exit
data 1,2,3,4,5,6,7,8
k--
}
flush
function holder {
read f
p=0
Repeat {
try stream
if empty then exit
read X : p+=X
} Always
=p
}
Print holder(3) << aa()
Παρόμοιο αλλά εδώ δίνουμε μια σειρά αριθμών ενώ ορίζουμε το μέγιστο
k=lambda->{read k1, k2 : for i=k1 to k2 { data i }}
sum=lambda->{
p=0 : max=1
Read ? max
try stream
{
if empty then =0 : exit
read ? x
p+=x
max--
if max>0 then loop
}
=p
}
Print sum(100) << k(1,100) \\ 5050
Αυτό τώρα είναι πιο προχωρημένο! Ο χειριστής << είναι διπλή ενεργείας! Στο παρακάτω παράδειγμα η holder διαβάζει από το ρεύμα μόνο αν έχει το σωστό κλειδί.
Και στις δυο περιπτώσεις δίνουμε το κλειδί στη Holder, την πρώτη φορά το λάθος κλειδί, την δεύτερη το σωστό. Και στις δυο περιπτώσεις δοκιμάζει το ρεύμα.Πριν το κάνει όμως στέλνει στο σωρό το κλειδί, το οποίο διαβάζει η "γεννήτρια" και αν είναι το σωστό δίνει απάντηση αλλιώς τίποτα! Σημειώστε ότι θα δουλέψει ακόμα και αν δεν υπάρχει ρεύμα να πάρει τιμές.
Ο σωρός στις συναρτήσεις είναι πάντα φρέσκος και στο τέλος χάνεται, αλλά δεν συμβαίνει αυτό στην κλήση μετά το <<
aa=lambda k=10 -> {
try {
read k$
if k$ = "Key1" then {
if k<1 then exit
data 1,2,3,4,5,6,7,8
k--
}
}
}
bb=lambda-> {
data 1,2,3
}
flush
Group beta {
counter
function holder {
read mkey$
p=0
Repeat {
push mkey$ \\ send back
try stream
if empty then exit
if not isnum then exit
read X : p+=X
.counter++
} Always
=p
}
}
Print Beta.holder("Key1") << bb()
Print Beta.counter \\0
Print Beta.holder("Key1") << aa()
Print Beta.counter \\ 80 numbers
Beta.counter=0
Print Beta.holder("Key1")
Print Beta.counter \\ 0
2. Χρήση σε πίνακες
Εδώ αντί να βάλουμε = για σταθερή τιμή βάζουμε << που σημαίνει εκτέλεσε για κάθε στοιχείο (χειρίζεται τον πίνακα πάντα ως μονοδιάστατο)
c=lambda X=2 ->{=X: X+=3}
dim a(8,8)<<c()
for j=0 to 7 {
for i=0 to 7 {
print a(i, j),
}
}
3. Νέα Random με χρήση του Wichmann-Hill αλγόριθμου (κώδικας γραμμένος σε VB6 από το μέλος Merri στο VbForums, από πρώτη εγγραφή του μέλους anhn)
Αν γράψουμε το πρόγραμμα στο τμήμα Α τότε με Α σκέτο δείχνει την σειρά των 10 ζευγών τυχαίων. Με Α 1 ή άλλο μη μηδενικό νούμερο τότε έχουμε δέκα άλλους τυχαίους ενδιάμεσα, μετά τους πρώτους 5 και μετά συνεχίζουν οι επόμενοι 5 όπως έχουν και χωρίς τους ενδιάμεσους.
Τυχαίος() κάνει τυχαία αρχή (δεν γυρίζει νούμερο)
Τυχαίος(!133123) κάνει νέα αρχή από γνωστό νούμερο (γυρίζει το νούμερο αυτό) ενώ σώνει πρώτα τη θέση της γεννήτριας τυχαίων
Τυχαίος(!) κάνει pop την παλιά θέση της γεννήτριας
Τυχαίος(10) από 0 έως 10
Τυχαίος(-5, 5) από -5 έως 5
Τυχαίος δίνει έναν αριθμό από >=0 έως <1
read ? partial
K=random(!123)
for I=1 TO 5
print random(1, 20), rnd
next I
if partial then {
K=random(!112145)
print K
for I=1 TO 10
print random(1, 20), rnd
next I
k=random(!)
}
for I=1 TO 5
print random(1, 20), rnd
next I
Δεν υπάρχουν σχόλια:
Δημοσίευση σχολίου
You can feel free to write any suggestion, or idea on the subject.