Το Στέκι των Πληροφορικών

Γενικό Λύκειο => Γ΄ Λυκείου => Δομή επανάληψης => Μήνυμα ξεκίνησε από: Petran στις 09 Μαΐου 2006, 04:04:36 ΜΜ

Τίτλος: HElp please :)
Αποστολή από: Petran στις 09 Μαΐου 2006, 04:04:36 ΜΜ
Μπορείτε να βοηθήσετε ??
Να γραφεί αλγόριθμος που να διαβάζει έναν ακέραιο θετικό αριθμό
Με άγνωστο αριθμό ψηφίων
και να εμφανίζει τον ανάποδό του

πχ 12345670321  και να εμφανίζει  12307654321
Ευχαριστώ
Τίτλος: Απ: HElp please :)
Αποστολή από: filippos στις 09 Μαΐου 2006, 04:22:48 ΜΜ
Μια γρήγορη λύση:

Κώδικας (ΓΛΩΣΣΑ) [Επιλογή]
ΠΡΟΓΡΑΜΜΑ Αντιστροφή_Ακεραίου
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: αριθμός, ανάποδο
ΑΡΧΗ
  ΔΙΑΒΑΣΕ αριθμός
  ανάποδο <- 0
  ΟΣΟ αριθμός <> 0 ΕΠΑΝΑΛΑΒΕ
    ανάποδο <- ανάποδο*10 + αριθμός MOD 10
    αριθμός <- αριθμός DIV 10
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  ΓΡΑΨΕ  ανάποδο
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ
Τίτλος: Απ: HElp please :)
Αποστολή από: gpapargi στις 10 Μαΐου 2006, 10:44:58 ΠΜ
Η λύση του που παρουσίασε ο Φίλιππος είναι πολύ κομψή!

Βέβαια είναι λίγο δύσκολο ο μαθητής να τη σκεφτεί από μόνος του (αυτή η αριστερή ολίσθηση που πετυχαίνει με πολ/σμό με 10). Μια λύση που σκέφτονται οι μαθητές ευκολότερα είναι να μετρήσεις τα ψηφία του αριθμού. (Πχ αυξάνεις το ι μέχρι το 10^ι να ξεπεράσει τον αριθμό).

Μετά κόβεις ένα ένα τα ψηφία από το τέλος του αριθμού (υπόλοιπο με 10), τα πολ/ζεις με την κατάλληλη δύναμη του 10 (πχ σε 6ψήφιο αριθμό το τελευταίο ψηφίο θα το πολ/σεις με την 5 η δύναμη του 10, το προτελευταίο στην 4 η κλπ)
και τα προσθέτεις μεταξύ τους.

Όχι τόσο ευφυής λύση όσο η προηγούμενη (αφού θέλει 2 εντολές επανάληψης) αλλά ίσως πιο πιθανό να τη σκεφτεί μόνος του ο μαθητής κυρίως επειδή ανάγεται σε ασκήσεις που έχει κάνει.

Και για να ξεσκουριάσουμε λίγο θέτω ένα γρίφο (για όποιον θέλει να ασχοληθεί) που σχετίζεται λίγο με το θέμα αλλά σαφώς ξεφεύγει από τα πλαίσια του μαθήματος:

Μπορείτε να φτιάξετε ένα τύπο που να δίνει το πλήθος των ψηφίων ενός ακέραιου αριθμού (χωρίς επαναληπτική διαδικασία); Δηλαδή να γραφτεί μια εντολή σε ΓΛΩΣΣΑ της μορφής

πλήθος_ψηφίων < - [τύπος]
Τίτλος: Απ: HElp please :)
Αποστολή από: andreas_p στις 10 Μαΐου 2006, 11:36:50 ΠΜ
Petran, Καλημέρα

Μια άλλη λύση, ίσως πιο κατανοητή από το μέσο μαθητή  :

ΠΡΟΓΡΑΜΜΑ Αντίστροφος
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: αριθμός, νέος, κ, ψηφίο , πλ, χ, ψ
ΑΡΧΗ
  ΑΡΧΗ_ΕΠΑΝΑΛΗΨΗΣ
    ΓΡΑΨΕ 'Δώσε θετικό ακέραιο : '
    ΔΙΑΒΑΣΕ αριθμός
  ΜΕΧΡΙΣ_ΟΤΟΥ  αριθμός > 0
! για να μην τον χάσω
  χ <- αριθμός
! Πλήθος ψηφίων
  πλ <- 0
  ΟΣΟ χ > 0 ΕΠΑΝΑΛΑΒΕ
    χ <- χ DIV 10
    πλ <- πλ+1
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  ΓΡΑΨΕ 'Πλήθος ψηφίων = ', πλ
! Βρίσκω τον αντίστροφο
  νέος <- 0
  ΓΙΑ ψ ΑΠΟ πλ-1 ΜΕΧΡΙ 0  ΜΕ_ΒΗΜΑ -1
    ψηφίο <- αριθμός MOD 10
    νέος <- νέος + ψηφίο*Α_Μ((10^ψ))
    αριθμός <- αριθμός DIV 10
  ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
  ΓΡΑΨΕ  νέος
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ  Αντίστροφος
Τίτλος: Απ: HElp please :)
Αποστολή από: andreas_p στις 10 Μαΐου 2006, 11:53:38 ΠΜ
Προς : fipillo

Πώς μπορώ  στο παρόν forum,
να παρουσιάζω τον κώδικα  σε ΓΛΩΣΣΑ
σε μορφή (όπως είναι στο περιβάλλον του Διερμηνευτή )
"προγραμματιστική" και όχι απλά κειμένου ;

Τίτλος: Απ: HElp please :)
Αποστολή από: alkisg στις 10 Μαΐου 2006, 12:43:53 ΜΜ
@andreas_p: για χρωματισμό δες τις οδηγίες στο σχετικό θέμα: //index.php?topic=405
Τίτλος: Απ: HElp please :)
Αποστολή από: filippos στις 10 Μαΐου 2006, 11:26:49 ΜΜ
κάτι τέτοιο εννοείς Γιώργο;

Κώδικας (ΓΛΩΣΣΑ) [Επιλογή]

ΠΡΟΓΡΑΜΜΑ Ψηφία
ΜΕΤΑΒΛΗΤΕΣ
  ΑΚΕΡΑΙΕΣ: αριθμός, Πλήθος_Ψηφίων
ΑΡΧΗ
  ΔΙΑΒΑΣΕ αριθμός
  Πλήθος_Ψηφίων <- Α_Μ(ΛΟΓ(αριθμός*10)/ΛΟΓ(10))
  ΓΡΑΨΕ Πλήθος_Ψηφίων
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ
Τίτλος: Απ: HElp please :)
Αποστολή από: gpapargi στις 11 Μαΐου 2006, 09:16:54 ΠΜ
Σε παραδέχομαι Φίλιππε   ;)

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

Ξεκινάμε από μια μικρή παρατήρηση υπό μορφή παραδείγματος.
Κάθε τριψήφιος αριθμός είναι μεταξύ του 100 και του 1000. Δηλαδή ισχύει:

10^2 <= 3_ψήφιος < 10^3

Που εύκολα γενικεύεται για ν ψηφία:

10^(ν-1) <= ν_ψήφιος < 10^ν

Παίρνουμε το λογάριθμο με βάση το 10 (έστω log με λατινικούς χαρακτήρες) στην παραπάνω σχέση (η φορά της ανισότητας δεν αλλάζει γιατί η λογαριθμική συνάρτηση με βάση το 10 είναι γνησίως αύξουσα):

Log(10^(ν-1)) <= log(ν_ψήφιος) < log(10^ν)

Εφαρμόζοντας τις ιδιότητα του λογαρίθμου που θέλει τον εκθέτη να βγαίνει έξω από το λογάριθμο και το log10 να είναι ίσο με ένα έχουμε:

ν-1 <= log(ν_ψήφιος) < ν

Αφού ο δεκαδικός λογάριθμος του αριθμού με ν ψηφία είναι ανάμεσα στο ν και στο ν-1 τότε το ακέραιο μέρος του θα είναι ν-1.

Άρα

[log(ν_ψήφιος)] = ν-1

Λύνοντας ως προς ν έχουμε:

ν = [log(ν_ψήφιος)] + 1

Επειδή η ΓΛΩΣΣΑ δεν υποστηρίζει δεκαδικό λογάριθμο αλλά μόνο φυσικό (με βάση το e) χρειαζόμαστε τον τύπο αλλαγής βάσης. Έτσι έχουμε

ν = [ln(ν_ψήφιος)/ln(10)] + 1

Για να καταλήξουμε στον τύπο του Φίλιππου βάζουμε 1 μέσα στο ακέραιο μέρος, κάνουμε ομόνυμα τα κλάσματα και γράφουμε το ln(ν_ψήφιος) + ln(10) σαν ln(ν_ψήφιος * 10).

Με αυτό το τέχνασμα της λογαρίθμισης μπορούμε να βρούμε πόσα ψηφία έχουν (δηλαδή τι τάξη μεγέθους έχουν) τεράστιοι αριθμοί γραμμένοι σε εκθετική μορφή (πχ ο 9^9^9^9). Μέχρι να φτάσουν στο σημείο οι υπολογιστές να χειρίζονται τέτοιους αριθμούς, στηριζόμαστε στη μαθηματική έμπνευση.
Τίτλος: Απ: HElp please :)
Αποστολή από: andreas_p στις 11 Μαΐου 2006, 11:38:53 ΠΜ
Άλκη, ευχαριστώ.
Τίτλος: Απ: HElp please :)
Αποστολή από: P.Tsiotakis στις 11 Μαΐου 2006, 06:49:37 ΜΜ
Αλγόριθμος Αντιστροφή
  Διάβασε αριθμός  ! θετικός
  ψηφία <-- 0
  Όσο αριθμός <> 0 επανάλαβε
    ψηφία <-- ψηφία +1
    ΠΙΝ[ψηφία] <-- αριθμός mod 10
    αριθμός <-- αριθμός div 10
  Τέλος_επανάληψης
  νέος <- 0
  Για ι από 1 μέχρι ψηφία
    νέος <-- νέος + ΠΙΝ[ι] * 10^(ψηφία – ι)
  Τέλος_επανάληψης
  Εκτύπωσε νέος
Τέλος Αντιστροφή
Τίτλος: Απ: HElp please :)
Αποστολή από: andreas_p στις 12 Μαΐου 2006, 09:36:10 ΠΜ
Κώδικας (ΓΛΩΣΣΑ) [Επιλογή]

ΠΡΟΓΡΑΜΜΑ Αντίστροφος
ΜΕΤΑΒΛΗΤΕΣ
 ΑΚΕΡΑΙΕΣ: αριθμός, νέος, κ, ψηφίο , πλ, χ, ψ
ΑΡΧΗ
 ΑΡΧΗ_ΕΠΑΝΑΛΗΨΗΣ
   ΓΡΑΨΕ 'Δώσε θετικό ακέραιο : '
   ΔΙΑΒΑΣΕ αριθμός
 ΜΕΧΡΙΣ_ΟΤΟΥ  αριθμός > 0
! για να μην τον χάσω
 χ <- αριθμός
! Πλήθος ψηφίων
 πλ <- 0
 ΟΣΟ χ > 0 ΕΠΑΝΑΛΑΒΕ
   χ <- χ DIV 10
   πλ <- πλ+1
 ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
 ΓΡΑΨΕ 'Πλήθος ψηφίων = ', πλ
! Βρίσκω τον αντίστροφο
 νέος <- 0
 ΓΙΑ ψ ΑΠΟ πλ-1 ΜΕΧΡΙ 0  ΜΕ_ΒΗΜΑ -1
   ψηφίο <- αριθμός MOD 10
   νέος <- νέος + ψηφίο*Α_Μ((10^ψ))
   αριθμός <- αριθμός DIV 10
 ΤΕΛΟΣ_ΕΠΑΝΑΛΗΨΗΣ
 ΓΡΑΨΕ  νέος
ΤΕΛΟΣ_ΠΡΟΓΡΑΜΜΑΤΟΣ  Αντίστροφος

Τίτλος: Απ: HElp please :)
Αποστολή από: andreas_p στις 12 Μαΐου 2006, 10:01:19 ΠΜ
Συγνώμη, για τα δοκιμαστικά.
Αν και θα μπορούσαν να είχαν γίνει με το 'Προεπισκόπηση'.
Τίτλος: Απ: HElp please :)
Αποστολή από: alkisg στις 12 Μαΐου 2006, 11:02:01 ΠΜ
Αντρέα τα έσβησα, πάντως μπορείς να πατάς και το κουμπί "Τροποποίηση" αν θες να αλλάξεις τα μηνύματά σου εκ των υστέρων.
Τίτλος: Απ: HElp please :)
Αποστολή από: andreas_p στις 12 Μαΐου 2006, 12:55:07 ΜΜ
Άλκη, ευχαριστώ.

Επίσης,

το πρόγραμμα σου 'Διερμηνευτής της Γλώσσας'  "ΒΑΛΣΑΜΟ"

κυρίως για τους μέτριους μαθητές.

Με τη βηματική εκτέλεση, αντιλαμβάνονται πλήρως  την κλήση  των

υποπρογραμμάτων καθώς επίσης και την επιστροφή στο κύριο πρόγραμμα.

Μια σκέψη μου : Σε επόμενη έκδοση , αν είναι εφικτό, να γίνεται  και η παρουσίαση της σχέσης  "Διαδικασίες -Στοίβα χρόνου εκτέλεσης".

Ανδρέας
Τίτλος: Απ: HElp please :)
Αποστολή από: filippos στις 12 Μαΐου 2006, 01:40:31 ΜΜ
Συμφωνώ απόλυτα με τον Ανδρέα.

Η μεθοδική χρήση του διερμηνευτή, ειδικά από τις προηγούμενες τάξης (Γ' Γυμνασία, Α' & Β' Λυκείου) είναι πράγματι ΒΑΛΣΑΜΟ για την κατανόηση βασικών αλγοριθμικών τεχνικών.

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

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

Βέβαια, it's up to ʼλκης ;)
Τίτλος: Απ: HElp please :)
Αποστολή από: alkisg στις 14 Μαΐου 2006, 05:52:30 ΠΜ
@andreas_p, @filippos: ευχαριστώ για τα καλά σας λόγια. Αυτή τη στιγμή η στοίβα χρόνου εκτέλεσης φαίνεται μόνο από το κουτί "Κληθέντα υποπρογράμματα" του Διερμηνευτή, στο οποίο εμφανίζονται όλες οι (εμφωλευμένες) κλήσεις που έχουν γίνει... Επίσης, διαλέγοντας ένα υποπρόγραμμα από το ίδιο κουτί, εμφανίζονται στην καρτέλα "Μεταβλητές" οι τιμές των μεταβλητών του υποπρογράμματος της συγκεκριμένης κλήσης που επιλέχθηκε...

Όμως δεν μπορώ να φανταστώ κάποιο interface που να δίνει καλύτερα τη σχέση κλήσης/στοίβας από τον πίνακα τιμών.
Αν ευκαιρείτε, κοιτάξτε λίγο το topic Μορφή του πίνακα τιμών (//index.php?topic=396.0) καθώς και το παράδειγμα που δίνω στο https://alkisg.mysch.gr/pivakas_timwv.htm (https://alkisg.mysch.gr/pivakas_timwv.htm).
Αν σ' αυτό το παράδειγμα προσθέσουμε και αυτά που λέει ο Φίλιππος (αριθμούς γραμμών της κλήσης), νομίζω ότι είμαστε εντάξει όσον αφορά στην αναπαράσταση... Τι λέτε;