Παρασκευή 18 Δεκεμβρίου 2015

Πρώτοι Αριθμοί ΙΙ (πρόγραμμα με τρεις συναρτήσεις) - Dangling Else

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

Η παραλλαγή της Α εδώ είναι ότι έγινε συνάρτηση που διαβάζει ένα χ, τον αριθμό "όριο" και επιστρέφει ένα πίνακα. Ο πίνακας μπορεί να έχει μηδενικά στοιχεία. Άν έχει στοιχεία τότε από αυτά επιλέγουμε τυχαία ένα.
Χρησιμοποιούμε το $(4) στην Τύπωσε που βάζει το σύστημα να τυπώνει σε στήλες με αναλογική γραφή. Χρησιμοποιούμε εισαγωγή ακεραίου (δεν γίνεται να πάρει τελεία, η τελεία είναι το σημείο δεκαδικών στη γλώσσα Μ2000, και όχι το κόμμα).
Έχουμε φτιάξει άλλες δυο συναρτήσεις:
Η Συνάρτηση ΠάρεΑκέραιο%() που έχουμε εδώ μας δίνει έναν ακέραιο σίγουρα! Δεν δέχεται εισαγωγή άλλη και αν πατήσουμε Esc τότε θα πάρουμε την τιμή 100 (η εσωτερική μεταβλητή Πεδίο  γίνεται  99 αν πατήσουμε το Esc)
H Διάλεξε$() παίρνει μια συνθήκη και δυο εκφράσεις αλφαριθμητικών, αν η συνθήκη είναι αληθής τότε επιστρέφει το πρώτο αποτέλεσμα. Και οι δυο εκφράσεις θα υπολογιστούν. Χρησιμοποιούμε το σωρό τιμών που σε μια συνάρτηση περιέχει στην αρχή μόνο ότι περνάμε σαν παράμετρους. Στη Μ2000 οι παράμετροι δεν γράφονται απ' ευθείας σε μεταβλητές, αλλά στο σωρό τιμών. Είναι στο προγραμματιστή το δικαίωμα να κάνει κάτι με τις παραμέτρους. Αν καλέσουμε την συνάρτηση με περισσότερες παραμέτρους δεν το βλέπει ως λάθος η Μ2000. Η κλήση γίνεται χωρίς έλεγχο! Υπάρχουν τρόποι να δει κανείς τι έχει, ως παραμέτρους και να αποφασίσει τι να κάνει. Μια συνάρτηση διαγράφει το σωρό της στην επιστροφή (εκτός από μια ειδική περίπτωση που δεν θα αναφερθεί εδώ)

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

Στη συνάρτηση Α χρησιμοποιούμε την Αν χωρίς την Τότε αλλά με την Αλλιώς, δηλαδή όταν δεν ισχύει η συνθήκη! Έτσι αντί να γράψουμε Αν συνθήκη τότε {}  Αλλιώς Τύπωσε 1 διαγράφουμε το άχρηστο τότε {} και γίνεται Αν συνθήκη Αλλιώς Τύπωσε 1.
Δείτε σε ορισμένα Αλλιώς στην ίδια γραμμή να έχουμε άνω κάτω τελεία. Θα εκτελεστούν αυτές οι δυο εντολές σαν να ήταν σε μπλοκ εντολών π.χ θα μπορούσαμε να το γράψουμε έτσι:
Αν ι(ι) Αλλιώς{ ι(δ)=ι : δ++ }  
Αλλά επειδή το αλλιώς είναι στο τέλος παίρνει όλη τη γραμμή για εκείνο.(το ιδιο ισχύει για το Τότε)
Αν ι(ι) Αλλιώς ι(δ)=ι : δ++ Εδώ είναι καλό να αναφερθεί το Dangling Else Problem
Στη Μ2000 δεν μπορούμε να βάλουμε αυτό (στις νεότερες εκδόσεις μπορούμε):
if a then b else c
αλλά
if a then {b} else c
ή
if a then {b} else {c}

Σε άλλες γλώσσες το πρόβλημα είναι ότι χωρίς τις αγκύλες που υποχρεωτικά μπαίνουν στην Μ2000 δεν φαίνεται τι θα γίνει στο παρακάτω:
if a then if b then s else s2
Ποιο θα είναι δηλαδή σωστό, το πρώτο:
if a then (if b then s) else s2
      ή το δεύτερο
if a then (if b then s else s2)
Στην Μ2000 γίνεται αμέσως φανερό!
Αν Χ=5 Τότε Αν Υ=3 Τότε{ Τύπωσε 1 } Αλλιώς Τύπωσε 2
Αν Χ=5 Τότε { Αν Υ=3 Τότε Τύπωσε 1 } Αλλιώς Τύπωσε 2

Παράδειγμα σε νεότερο διερμηνευτή

// Εδώ φτιάχνονται ειδικά μπλοκ από τον διερμηνευτή κατά την εκτέλεση
// στο μέρος μετά την Τότε ή την Αλλιώς πριν την εκτέλεση
// Μπορούμε δηλαδή να έχουμε εντολή Πρός
// Ειδικά για άλμα σε αριθμητική ετικέτα την Προς μπορούμε
// να μην την γράψουμε πχ Αν Χ=5 Τότε 100 Αλλιώς 150
// Εδώ εντολές όπως Ξεκίνα, Έξοδος, Συνέχισε, Κυκλικά
// Restart, Exit, Continue, Loop παίζουν στο μπλοκ της Αν
// και όχι μέσα στο ειδικό μπλοκ.
Χ=10
Υ=3
// Δεν τυπώνει κάτι
Αν Χ=5 Τότε Αν Υ=3 Τότε Τύπωσε 1 Αλλιώς Τύπωσε 2
Χ=5
// Τυπώνει το 1
Αν Χ=5 Τότε Αν Υ=3 Τότε Τύπωσε 1 Αλλιώς Τύπωσε 2
Υ++
// Τυπώνει το 2
Αν Χ=5 Τότε Αν Υ=3 Τότε Τύπωσε 1 Αλλιώς Τύπωσε 2


// Με μορφή πολλαπλών γραμμών χωρίς μπλοκ εντολών
// Η διαφορά με τα μπλοκ είναι ότι μπορούμε με το μπλοκ...
// ... να έχουμε την Προς (Goto). Αν γίνει εδώ θα έχουμε λάθος
// ... γιατί δεν θα έχει βρει ο διερμηνευτής την Τέλος Αν.
// Αυτός ο τρόπος δομής χρησιμοποιεί την ειδική στοίβα επιστροφής
// των ρουτινών, δηλαδή σε χώρο διαφορετικό από την κανονική στοίβα
// επιστροφής του διερμημευτή)
Χ=10
Υ=3
// Δεν τυπώνει κάτι
Αν Χ=5 Τότε
Αν Υ=3 Τότε
Τύπωσε 1
Αλλιώς
Τύπωσε 2
Τέλος Αν
Τέλος Αν
Χ=5
// Τυπώνει το 1
Αν Χ=5 Τότε
Αν Υ=3 Τότε
Τύπωσε 1
Αλλιώς
Τύπωσε 2
Τέλος Αν
Τέλος Αν
Υ++
// Τυπώνει το 2
Αν Χ=5 Τότε
Αν Υ=3 Τότε
Τύπωσε 1
Αλλιώς
Τύπωσε 2
Τέλος Αν
Τέλος Αν
// Εδώ έχουμε μπλοκ
// Μιά εντολή Έξοδος ενεργεί σε αυτό το μπλοκ
// και όχι σε αυτό που είναι η Αν
Χ=10
Υ=3
// Δεν τυπώνει κάτι
Αν Χ=5 Τότε {
Αν Υ=3 Τότε {
Τύπωσε 1
} Αλλιώς {
Τύπωσε 2
}
}
Χ=5
// Τυπώνει το 1
Αν Χ=5 Τότε {
Αν Υ=3 Τότε {
Τύπωσε 1
} Αλλιώς {
Τύπωσε 2
}
}
Υ++
// Τυπώνει το 2
Αν Χ=5 Τότε {
Αν Υ=3 Τότε {
Τύπωσε 1
} Αλλιώς {
Τύπωσε 2
}
}



Στην πρώτη περίπτωση μετά το Τότε δεν ξεκινάμε με αγκύλη άρα δεν μπορεί να έχει δική της Αλλιώς και ότι ακολουθει ανήκει στο Τότε (άρα αν το Χ δεν είναι 5 πάμε στην επόμενη γραμμή) . Στη δεύτερη περίπτωση αν το Χ δεν είναι 5 τότε περνάμε το μπλοκ και βρίσκουμε την Αλλιώς.
Στη συνάρτηση Α βρίσκουμε και την Αλλιώς.Αν και μπορούμε με διαδοχικά Αλλιώς.Αν συνθήκηΝ1 Τότε { } Αλλιώς.Αν συνθήκηΝ2 Τότε ....να έχουμε διαδοχικά τον έλεγχο συνθηκών μέχρι κάποια να ικανοποιηθεί, δηλαδή να είναι αληθής.  Αν εκτελεστεί η Τότε τότε όλες οι Αλλιώς.Αν αφήνονται χωρίς έλεγχο και προχωράει η ροή μετά το τελευταίο.

Το  ι(0)=2,3 είναι μια πολλαπλή καταχώρηση σε πίνακα, το 2 θα πάει στη θέση 0, το 3 στη θέση 1
Η εντολή Πίνακας είναι και redim δηλαδή κάνει αλλαγή διαστάσεων σε πίνακα. Με δ=0 κάνουμε τον πίνακα μηδενικής διάστασης. Στις αλλαγές μεγέθους αν δεν δηλώσουμε τιμή στοιχείου, θα παραμείνουν τα στοιχεία με τις τιμές που έχουν, ή αν βάλουμε και άλλα τότε θα είναι "Empty" άδεια. Ο διερμηνευτής τα άδεια στοιχεία τα λογαριάζει μηδενικά βάσει του τύπου που δηλώνει το όνομα, ενώ κανονικός τύπος (που δεν φαίνεται) είναι ο Variant (δηλαδή τύπος που γίνεται κάθε τύπος). Ετσι μπορούμε να έχουμε μια ομάδα (ένα αντικείμενο) σε ένα στοιχείο πίνακα!
Στην εντολή ΟΘόνη θα δούμε ένα κόμμα χωρίς πρώτη παράμετρο. Ορισμένες εντολές δέχονται κάτι τέτοιο, όταν δεν θέλουμε να αλλάξουμε τιμή από μια υπάρχουσα.  Όμως αυτό δεν συμβαίνει με τις συναρτήσεις χρήστη (εδώ δεν έτυχε να χρησιμοποιηθεί πέρασμα με αναφορά, αλλά μπορούμε να κάνουμε κάτι τέτοιο για τις συναρτήσεις. Οι αναφορές γράφονται ως ισχνές αναφορές στο σωρό τιμών και η Διάβασε εντός της συνάρτησης κάνει τις συνδέσεις! Έτσι μπορούμε να απορρίψουμε αναφορά πριν την συνδέσουμε! Αυτή η λειτουργία της Μ2000 είναι πρωτότυπη και την κάνει να διαφέρει!

Συνάρτηση Α {
       \\ Κόσκινο του Όιλερ
      Διάβασε χ
      Πίνακας ι(χ+2)
       κ=2
       κ2=κ**2
       δ=0
        Αν κ2<χ Τότε {
             Για λ=κ2 έως χ ανά κ { ι(λ)--}
             κ++ : Ενώ ι(κ) {κ++}
             κ2=κ**2: Αν κ2>χ Αλλιώς Ξεκίνα
             Για ι=2 εως χ {
                   Αν ι(ι) Αλλιώς ι(δ)=ι : δ++
             }
      } Αλλιώς.Αν χ>1 Τότε {
            Αν χ>2 Τότε { δ=2: ι(0)=2,3 } αλλιώς δ=1: ι(0)=2
      }
      Πίνακας ι(δ)
      =ι()
}
Συνάρτηση Διάλεξε$ {
      Διάβασε συνθήκη
      \\ αφήνουμε τις άλλες δυο παραμέτρους
      \\ με το αλλιώς πάμε στο όχι συνθήκη
      \\ Η πέτα πετάει τη κορυφή
      Αν συνθήκη Αλλιώς Πέτα
      \\ αν δεν είναι αλφαριθμητικό στη κορυφή θα έχουμε σφάλμα
      =Γράμμα$
}
Συνάρτηση ΠάρεΑκέραιο% {
      Διάβασε Λεζάντα$
      Τύπωσε Λεζάντα$;
      Εισαγωγή ! μια_τιμή%, 5
      Αν Πεδίο=99 τότε μια_τιμή%=100
      Τύπωσε μια_τιμή%
      =μια_τιμή%
}
\\ Κύριο πρόγραμμα
Οθόνη 5,0 : Πένα 14
Αναφορά 2,"Αναζήτηση πρώτου αριθμού από 1 έως ένα όριο"
Τύπωσε $(4),
Πίνακας απ()
όριο%=ΠάρεΑκέραιο%("Δώσε όριο:")
Αναλυτής
απ()=Α(όριο%)
Τύπωσε στρογγ(Φόρτος,2)," msec"
Αν Διάσταση(απ())>0 Τότε {
      ι=Διάσταση(απ(),1)
      Τύπωσε μορφή$("Βρέθηκ{2} {0} πρώτο{1} αριθμο{1}", ι, Διάλεξε$(ι<2,"ς","ι"),Διάλεξε$(ι<2,"ε","αν"))
      Τύπωσε μορφή$("Τυχαίος πρώτος στο διάστημα 1 εώς {0}: {1}",όριο%, απ(τυχαίος(1,ι)-1))
      Τύπωσε "Αν θες να δεις την λίστα πάτα το 1"
      Αν κομ$="1" Τότε {
            Οθόνη ,γραμμη
            Για κ=0 έως ι-1: Τύπωσε απ(κ), : Επόμενο κ
            Τύπωσε
      }
} Αλλιώς Τύπωσε "Δεν βρέθηκαν πρώτοι από 1 εώς "; όριο%

 

Δεν υπάρχουν σχόλια:

Δημοσίευση σχολίου

You can feel free to write any suggestion, or idea on the subject.