Πέμπτη, 17 Δεκεμβρίου 2015

Πρώτοι Αριθμοί και θέματα Φόρτος και Κλήση Τμήματος σε Τμήμα.

Παρακάτω είναι τρια τμήματα, το Π που μας δίνει τους πρώτους αριθμούς μέχρι ένα όριο με το κόσκινο του Ερατοσθένη, μετά το Α που κάνει το ίδιο αλλά με το κόσκινο του Όιλερ. Στο παράδειγμα ο Γερμανός έχει 10 φορές ταχύτερο αλγόριθμο (περίπου) για τους πρώτους μέχρι το 10000. Αν δώσουμε μια παράμετρο ακόμα, έναν οποιονδήποτε αριθμό τότε εμφανίζονται οι αριθμοί.
Το τρίτο τμήμα καλεί τα άλλα και κάνει αναφορά φόρτου δηλαδή χρόνου για δεδομένη διεργασία. Μια διεργασία που δίνει δεκαπλάσιο χρόνο...έχει δεκαπλάσιο φόρτο. Αν μια άλλη διεργασία γίνονταν παράλληλα τότε ο συνολικός φόρτος θα ήταν ο χρόνος που θα τελείωναν οι διεργασίες. Έτσι παίζει ρόλο ο φόρτος που βρίσκουμε για μια διεργασία, όταν τρέχει μόνη της, και δεν έχει μόνο έννοια απαίτησης σε χρόνο, αλλά επεξεργαστικού φορτίου και οι μονάδες είναι σε χρόνο ανά διεργασία. Αν έχουμε δυο διαφορετικές διεργασίες τότε ο φόρτος είναι συγκρίσημο μέγεθος και αν έχουν το ίδιο αποτέλεσμα και αν έχουν διαφορετικό, γιατί στο διαφορετικό μας ενδιαφέρει η περίπτωση που τρέχουν και οι δύο διεργασίες πόσο τελικά χρόνο θα κάνουν, και ο χρόνος βγαίνει από τον συνολικό φόρτο. Αν μια διεργασία έχει φόρτο 20 sec και μια άλλη 10 sec τότε ή εκτελεστεί η μία μετά την άλλη, διαδοχικά, ή παράλληλα, ο χρόνος θα είναι 30 sec το λιγότερο (μπορεί να είναι μεγαλύτερος λόγω της μετάβασης από την μια διεργασία στην άλλη).
Στο τμήμα Δ καλούμε τα Π και Α. Αλλά δεν τα έχουμε ορίσει ως γενικά. Αυτό συμβαίνει γιατί θα τα γράψουμε σε ένα άρχείο έστω πρώτοι.gsb και θα τα φορτώσουμε από την γραμμή εντολών με Φόρτωσε πρώτοι, Δ και θα φορτωθούν και τα τρία στο επίπεδο 0, δηλαδή σε αυτό που με την Τμήματα ? βλέπουμε τα τμήματα στην οθόνη με τα ονόματά τους. Θα δούμε δηλαδή τα Δ, Α, Π (ανάποδα από τη σειρά που γράφτηκαν στην λίστα τμημάτων). Έτσι στο Δτο Α και Π υπάρχει, είναι ήδη στη λίστα.
Αν θέλαμε να φορτώσουμε μέσα από ένα τμήμα με Θέσε Φόρτωσε πρώτοι, Δ χωρίς να προσθέσουμε τίποτα άλλο στη γραμμή στέλνουμε την Φόρτωσε πρώτοι, Δ μέσω της Θέσε στη γραμμή εντολών, στο επίπεδο 0, άρα όλα τα τμήματα γίνονται γενικά. Στο πέρας του τμήματος που φόρτωσε τα άλλα, ότι νέο δημιουργήθηκε εντός αυτού θα διαγραφεί.

Άλλος τρόπος είναι να τα περάσουμε όλα σε ένα τμήμα και στο τέλος γράφουμε Ένθεση Κώδικα Δ οπότε ο ορισμός του Δ αντιγράφεται στην θέση της Ένθεσης και εκτελείται σαν να μην υπήρχε το Δ, οπότε τα Α και Π είναι προσβάσιμα (αφού τα βλέπει τοπικά).

Άλλος τρόπος είναι να δηλώσουμε τα Α και Π ως γενικά. Τμήμα Γενικό Π {..} Τώρα το Δ μπορεί να καλέσει το Π.


Για τους αλγόριθμους. Χρησιμοποιούμε +1 στους ορισμούς πινάκων γιατί θέλουμε αρχή από το 1. Ουσιαστικά χάνουμε το στοιχείο 0 αλλά δεν μας πειράζει! Έχουμε βάλει ένα όριο μεγέθους. Έχει μπει αυθαίρετα. Εσωτερικά η Μ2000 χρησιμοποιεί Variant 12 bytes..άρα 10000 αριθμοί θέλουν 120 χιλιάδες Bytes. Μέγιστη μνήμη έχουμε τα 2Giga, θα μπορούσαμε να φτιάχναμε 16666 πίνακες των 120 χλιάδων bytes. Ανά πάσα στιγμή σταματάμε το πρόγραμμα με Esc. Μπορούμε να το τρέξουμε με την Δοκιμή, π.χ. Δοκιμή Δ η οποία ανοίγει φόρμα που κοιτάμε το κώδικα που τρέχει (κάντε κλικ στις επιγραφές της φόρμας Δοκιμή, είναι κουμπιά λειτουργιών)

Κοιτάμε στα Π και Α αν υπάρχει δεύτερη αριθμητική παράμετρος στο σωρό τιμών (ειδική στοίβα στην Μ2000). Αν ναι φτιάχνουμε τη Τ. Έτσι η Έγκυρο(Τ) είναι αληθείς. Αν δεν είναι τότε βγαίνουμε από το τμήμα.
Δείτε στο πίνακα του κόσκινου του Ερατοσθένη η αρχική τιμή κάθε στοιχείου είναι 0 ενώ σε εκείνο του Όιλερ είναι 1. Στον Ερατοσθένη ψάχνουμε τα 0. Θα μπορούσαμε να το κάνουμε αλλιώς. Να μια άσκηση! Να κάνουμε στον Όιλερ, τμήμα Α, να δουλεύει με το 0 όπως και του Ερατοσθένη στο τμημα Π.

Τα τμήματα Π, Α και Δ είναι "επιπέδου 0" δηλαδή είναι άμεσα προσβάσιμα από την κονσόλα (το καθένα δεν ανήκει σε άλλο τμήμα). Αυτά τα τμήματα είναι γενικά δηλαδή μπορούν να καλεστούν από άλλα τμήματα. Αν θέλουμε να τα βάλουμε σε ένα τμήμα έστω Κ, τότε πρέπει να δηλώσουμε:
(η κάτω παύλα _ είναι ο δρομέας της κονσόλας που αναβοσβήνει)
 
 >Σ Κ_
 (γράφουμε τα παρακάτω, βάζοντας τον κώδικα του κάθε τμήματος από παρακάτω και πατάμε Esc)
Τμήμα Γενικό Π {
..
}
Τμήμα Γενικό Α {

}
Τμήμα Γενικό Δ {

}
\\ και εδώ καλούμε το Δ
 Δ
>Κ_


Η άλλη περίπτωση είναι να γραφτούν τα Π και Α μέσα στο Δ, οπότε από τη γραμμή εντολών:
>_
>Σ Δ_
(αντιγράφουμε τα Π και Α και το κώδικα του Δ και πατάμε Esc)
>Δ_
Έτσι όταν από το Δ καλούμε τα Α και Π αυτά είναι θεατά γιατί είναι τοπικά!


Φυσικά μπορούμε από τη γραμμή εντολών να δώσουμε αυτό:
>Σ "πρωτοι.gsb"_
και τώρα αντιγράφουμε τα τμήματα όπως είναι και πατάμε Esc
>Φόρτωσε πρωτοι_
Τώρα έχει φορτωθεί το πρόγραμμα (αν θέλουμε πιο πριν: με Νέο καθαρίζουμε ότι πρόγραμμα υπήρχε, με Καθαρό καθαρίζουμε τυχόν γενικές μεταβλητές, με Άδειασε καθαρίζουμε το σωρό τιμών)
Μπορούμε να δούμε τα Τμήματα (με ctrl N ή με ctrl M)

>Τμήματα_
>Δ_

Τμήμα Π {
      \\ Κόσκινο του Ερατοσθένη
      Διάβασε χ
      Αν ταύτιση("Α") τότε Διάβασε Τ
      αν χ>200000 τότε έξοδος
      Πίνακας ι(χ+1)
      κ=2
      κ2=χ δια 2
      Ενώ κ<=κ2 {
            λ=κ+κ
            Ενώ λ<=χ {
                  ι(λ)=1
                  λ+=κ
            }
             κ++
      }
      Αν όχι Έγκυρο(Τ) τότε έξοδος
      Για ι=2 εως χ {
      αν ι(ι)=0 τότε τύπωσε ι,
      }
      τυπωσε
}
Τμήμα Α {
      \\ Κόσκινο του Όιλερ
      Διάβασε χ
      Αν ταύτιση("Α") τότε Διάβασε Τ
      αν χ>200000 τότε έξοδος
      Πίνακας ι(χ+1)=1
      κ=2
      κ2=κ**2
      Ενώ κ2<χ {
            Για λ=κ2 έως χ ανά κ {
                  ι(λ)=0
            }
            Επανέλαβε {
            κ++
            κ2=κ**2
            } μέχρι ι(κ)=1 ή κ2>χ
      }
      Αν όχι Έγκυρο(Τ) τότε έξοδος
      Για ι=2 εως χ {
      αν ι(ι)<>0 τότε τύπωσε ι,
      }
      τυπωσε
      }
Τμήμα Δ {
      Τύπωσε "Δοκιμή Ταχύτητας Εύρεσης 10000 πρώτων αριθμών"
      Όριο=10000
      Αναλυτής
      α Όριο
      Τύπωσε Φόρτος
      Αναλυτής
      π Όριο
      Τύπωσε Φόρτος
      Τύπωσε "Πάτα 1 αν θες να τους δεις, ή άλλο για τερματισμό"
      Αν Κομ$="1" τότε α 10000, 1
}


Η λύση στην άσκηση (τρέχει σε μισό χρόνο):
Τμήμα Α {
      \\ Κόσκινο του Όιλερ
      Διάβασε χ
      Αν ταύτιση("Α") τότε Διάβασε Τ
      αν χ>200000 τότε έξοδος
      Πίνακας ι(χ+1)
      κ=2
      κ2=κ**2
      Ενώ κ2<χ {
            Για λ=κ2 έως χ ανά κ { ι(λ)--}
            Επανέλαβε {
                  κ++
                  κ2=κ**2
            } μέχρι ι(κ)=0 ή κ2>χ
      }
      Αν όχι Έγκυρο(Τ) τότε έξοδος
      Για ι=2 εως χ {
            αν ι(ι) τότε συνέχισε
            τύπωσε ι,
      }
      τυπωσε
}