ΤΕΣΤ (ΑΣΚΗΣΕΙΣ) ONLINE
31 Tests / Διαγωνίσματα

Ενότητα 7 – Δραστηριότητες – Σελίδα 87-89 – ΠΛΗΡΟΦΟΡΙΚΗ Γ΄ ΓΥΜΝΑΣΙΟΥ – Απαντήσεις – Λύσεις – ΠΛΗΡΟΦΟΡΙΚΗ Γ΄ ΓΥΜΝΑΣΙΟΥ

(Πηγή: Βιβλίο Μαθητή, Πληροφορική Γ΄ Γυμνασίου, Ενότητα 7 «Επιστημονικός Προγραμματισμός», σελ. 87-89. Οι 3 «Δραστηριότητες» παρακάτω βρίσκονται μέσα στη θεωρία της §7.2· ακολουθούν οι 6 ερωτήσεις της §7.3 (σελ. 89) για το μοντέλο εκθετικής μετάδοσης. Η «Άσκηση» της §7.4 λύνεται σε ξεχωριστή ενότητα. Οι εκφωνήσεις είναι αυτούσιες από το σχολικό βιβλίο.)

Δραστηριότητες Κεφαλαίου 7

Δραστηριότητα 1 (τροποποίηση προγράμματος brute force για τρεις νέες εξισώσεις) (σελ. 87)

Τροποποιήστε το παραπάνω πρόγραμμα ώστε να λύνει τις εξισώσεις:

α) 26x – 260 = 0

β) 10x² – 50x + 60 = 0

γ) x³ – 9x² + 26x – 24 = 0

Σκέψη / Μεθοδολογία: «Το παραπάνω πρόγραμμα» αναφέρεται στο δεύτερο κουτί κώδικα της σελίδας (αυτό που λύνει σωστά την x²-5x+6=0 με τη μορφή if x*x-5*x+6==0:), όχι στο πρώτο παράδειγμα της Εικόνας 7.3 (10x+5=105) όπου ο τυπωμένος κώδικας έχει τη συνθήκη if 10*x+5==5:, που δεν αντιστοιχεί στην εξίσωση 10x+5=105 — και οι δύο Δραστηριότητες 1 και 2 ζητούν εξισώσεις ήδη διατυπωμένες στη μορφή «...=0», ίδια μορφή με το σωστό δεύτερο παράδειγμα. Η μέθοδος παραμένει η εξαντλητική αναζήτηση: δοκιμάζουμε κάθε ακέραιο x από 1 έως 1.000.000 και τυπώνουμε όσους μηδενίζουν το αριστερό μέλος της εξίσωσης. Και οι τρεις εξισώσεις εδώ έχουν θετικές ακέραιες λύσεις μέσα σε αυτό το εύρος, άρα το πρόγραμμα τις εντοπίζει κανονικά, χωρίς καμία τροποποίηση στο εύρος του βρόχου.

Λύση:

α) 26x – 260 = 0:

for x in range(1, 1000001):
    if 26*x - 260 == 0:
        print("x =", x)

Εκτέλεση: τυπώνει μία μόνο γραμμή, «x = 10» (το ίδιο προκύπτει και με άλγεβρα: 26x=260 ⇒ x=10).

β) 10x² – 50x + 60 = 0:

for x in range(1, 1000001):
    if 10*x*x - 50*x + 60 == 0:
        print("x =", x)

Εκτέλεση: τυπώνει δύο γραμμές, «x = 2» και «x = 3» (η εξίσωση απλοποιείται σε x²-5x+6=0, δηλαδή (x-2)(x-3)=0 — ακριβώς το ήδη λυμένο παράδειγμα του κυρίως κειμένου, πολλαπλασιασμένο επί 10).

γ) x³ – 9x² + 26x – 24 = 0:

for x in range(1, 1000001):
    if x**3 - 9*x**2 + 26*x - 24 == 0:
        print("x =", x)

Εκτέλεση: τυπώνει τρεις γραμμές, «x = 2», «x = 3», «x = 4» (η εξίσωση παραγοντοποιείται ως (x-2)(x-3)(x-4)=0).

Και στις τρεις περιπτώσεις χρησιμοποιείται το ίδιο εύρος range(1, 1000001) που χρησιμοποιεί το βιβλίο — καμία λύση δεν χρειάζεται αρνητικούς αριθμούς ή δεκαδικά, άρα το αρχικό πρόγραμμα δουλεύει αμετάβλητο εκτός από τη γραμμή της συνθήκης if.

Τελική απάντηση: α) 26x-260=0 → x = 10. β) 10x²-50x+60=0 → x = 2 και x = 3. γ) x³-9x²+26x-24=0 → x = 2, x = 3 και x = 4. Σε κάθε περίπτωση αλλάζει μόνο η γραμμή της συνθήκης if μέσα στον ίδιο βρόχο for x in range(1, 1000001), ώστε να ελέγχει το αριστερό μέλος της αντίστοιχης εξίσωσης (γραμμένης στη μορφή «...=0»).

Πρόσεξε:

  • Ο εκθέτης γράφεται στην Python με ** (π.χ. x**3, όχι x^3 όπως στα Μαθηματικά) — το x² του βιβλίου στη γλώσσα Python γίνεται x*x ή x**2.
  • Το εύρος range(1, 1000001) παραμένει το ίδιο σε όλα τα ερωτήματα, γιατί όλες οι ζητούμενες λύσεις είναι θετικοί ακέραιοι μέσα σε αυτό το διάστημα — δεν χρειάζεται καμία επέκταση του εύρους εδώ (σε αντίθεση με τη Δραστηριότητα 2).
  • Η εξίσωση (β) 10x²-50x+60=0 έχει τον συντελεστή 10 μπροστά, αλλά αυτό ΔΕΝ αλλάζει τις λύσεις της (x=2,3) σε σχέση με την απλοποιημένη x²-5x+6=0 — πολλαπλασιασμός και των δύο μελών με σταθερά δεν αλλάζει τις ρίζες.

Δραστηριότητα 2 (τέσσερις εξισώσεις χωρίς εντοπίσιμη ακέραια λύση στο brute force) (σελ. 87)

Τροποποιήστε το παραπάνω πρόγραμμα ώστε να λύνει τις εξισώσεις:

α) 4x + 20 = 0

β) 2x – 1 = 0

γ) 4x – 1 = 0

δ) x² – 2 = 0

Τι πρόβλημα παρατηρείτε κατά την εκτέλεσή τους; Γιατί συμβαίνει αυτό; Ποια λύση προτείνετε σε κάθε περίπτωση;

Σκέψη / Μεθοδολογία: Λύνουμε πρώτα κάθε εξίσωση με άλγεβρα, ΠΡΙΝ τρέξουμε το πρόγραμμα, ώστε να ξέρουμε τι να περιμένουμε: α) 4x=-20 ⇒ x=-5 (αρνητικός ακέραιος)· β) 2x=1 ⇒ x=0,5 (μη ακέραιος)· γ) 4x=1 ⇒ x=0,25 (μη ακέραιος)· δ) x²=2 ⇒ x=±√2≈±1,41421356 (άρρητος, δεν γράφεται ποτέ ακριβώς ως πεπερασμένο δεκαδικό). Το πρόγραμμα-πρότυπο ελέγχει ΜΟΝΟ ακέραιες τιμές x από 1 έως 1.000.000 (θετικές). Άρα ΚΑΜΙΑ από τις 4 πραγματικές λύσεις δεν μπορεί ποτέ να εντοπιστεί από αυτόν τον βρόχο, ανεξάρτητα από το πόσο τον επεκτείνουμε προς τα πάνω.

Λύση:

α) 4x+20=0:

for x in range(1, 1000001):
    if 4*x + 20 == 0:
        print("x =", x)

Εκτέλεση: ΔΕΝ τυπώνεται τίποτα. Η πραγματική λύση είναι x=-5, αρνητικός αριθμός, ενώ ο βρόχος range(1, 1000001) ελέγχει μόνο θετικούς ακέραιους (1,2,3,...,1000000) — ποτέ δεν φτάνει στο -5.

β) 2x-1=0:

for x in range(1, 1000001):
    if 2*x - 1 == 0:
        print("x =", x)

Εκτέλεση: ΔΕΝ τυπώνεται τίποτα. Η πραγματική λύση είναι x=0,5, δηλαδή δεκαδικός αριθμός· το range() παράγει ΜΟΝΟ ακέραιους (1,2,3,...), άρα το 0,5 δεν ελέγχεται ποτέ.

γ) 4x-1=0:

for x in range(1, 1000001):
    if 4*x - 1 == 0:
        print("x =", x)

Εκτέλεση: ΔΕΝ τυπώνεται τίποτα, για τον ίδιο λόγο — η λύση x=0,25 δεν είναι ακέραιος.

δ) x²-2=0:

for x in range(1, 1000001):
    if x*x - 2 == 0:
        print("x =", x)

Εκτέλεση: ΔΕΝ τυπώνεται τίποτα. Εδώ το πρόβλημα είναι ακόμα πιο θεμελιώδες: η λύση √2=1,41421356… είναι άρρητος αριθμός, δηλαδή έχει άπειρα μη περιοδικά δεκαδικά ψηφία — ΔΕΝ γράφεται ποτέ ακριβώς ούτε καν ως δεκαδικός αριθμός πεπερασμένης ακρίβειας, πόσο μάλλον ως ακέραιος.

Τι πρόβλημα παρατηρείτε / Γιατί συμβαίνει αυτό (κοινή διάγνωση και στις 4 περιπτώσεις): ο βρόχος for x in range(1, 1000001) ελέγχει ΜΟΝΟ θετικούς ακέραιους αριθμούς. Όποτε η πραγματική λύση μιας εξίσωσης είναι αρνητική, δεκαδική ή άρρητη, το πρόγραμμα δεν θα την εντοπίσει ΠΟΤΕ, όσο μεγάλο εύρος κι αν δοκιμάσουμε προς τα πάνω — το πρόβλημα δεν είναι το «πλήθος» των δοκιμών αλλά το «είδος» των τιμών που δοκιμάζονται.

Ποια λύση προτείνετε σε κάθε περίπτωση:

  • α) Επεκτείνουμε το εύρος ώστε να περιλαμβάνει και αρνητικούς ακέραιους, π.χ. for x in range(-1000000, 1000001).
  • β)/γ) Ο βρόχος πρέπει να δοκιμάζει και δεκαδικούς αριθμούς με αρκετά μικρό βήμα — π.χ. βήμα 0.01, με x = i/100 για κάθε i του range(-100000, 100001) (δηλαδή x από -1000 έως 1000), ώστε να περιλαμβάνονται οι τιμές 0.5 και 0.25 (με βήμα 0.1 η λύση 0.25 της (γ) θα «προσπεραστεί») — και να ελέγχει την ισότητα με ανοχή σφάλματος (π.χ. abs(4*x - 1) < 0.0001) αντί για ==, αφού η ακριβής αριθμητική ισότητα με δεκαδικά είναι αναξιόπιστη λόγω σφαλμάτων στρογγυλοποίησης (floating point).
  • δ) Επειδή η λύση είναι άρρητη, καμία εξαντλητική αναζήτηση (ούτε με ακέραιους ούτε με δεκαδικό βήμα) δεν θα δώσει ποτέ την ΑΚΡΙΒΗ τιμή — προτείνεται είτε αλγεβρική επίλυση (x = math.sqrt(2) στην Python) είτε αναζήτηση με ανοχή σφάλματος που θα δώσει μια ΠΡΟΣΕΓΓΙΣΤΙΚΗ λύση (π.χ. x=1,41421356, που ικανοποιεί την εξίσωση με πολύ μικρό σφάλμα).

Τελική απάντηση: Καμία από τις 4 εξισώσεις δεν εμφανίζει καμία λύση όταν τρέξουμε το πρόγραμμα, γιατί ο βρόχος for x in range(1, 1000001) δοκιμάζει ΜΟΝΟ θετικούς ακέραιους αριθμούς, ενώ οι πραγματικές λύσεις είναι: α) x=-5 (αρνητικός), β) x=0,5 (μη ακέραιος), γ) x=0,25 (μη ακέραιος), δ) x=±√2≈±1,4142 (άρρητος). Προτεινόμενες λύσεις: για την (α) επεκτείνουμε το εύρος ώστε να περιλαμβάνει αρνητικούς αριθμούς· για τις (β)/(γ) δοκιμάζουμε δεκαδικές τιμές με μικρό βήμα και ελέγχουμε ισότητα με ανοχή σφάλματος (abs(...) < όριο) αντί για ==· για τη (δ) καμία εξαντλητική αναζήτηση δεν βρίσκει ποτέ την ακριβή άρρητη λύση — χρειάζεται αλγεβρική επίλυση (π.χ. math.sqrt) ή αποδοχή προσεγγιστικής λύσης με ανοχή σφάλματος.

Πρόσεξε:

  • Το «καμία έξοδος» ΔΕΝ σημαίνει ότι το πρόγραμμα έχει σφάλμα (bug) — εκτελείται κανονικά, απλώς καμία τιμή του εύρους δεν ικανοποιεί ποτέ τη συνθήκη, οπότε το σώμα του if δεν εκτελείται καμία φορά.
  • Η χρήση == για σύγκριση δεκαδικών αριθμών είναι γενικά επικίνδυνη πρακτική στον προγραμματισμό, ακόμα κι όταν θεωρητικά «θα έπρεπε» να ταιριάζουν, λόγω της πεπερασμένης ακρίβειας αναπαράστασης των δεκαδικών (floating point) στον υπολογιστή.
  • Η πρόταση λύσης είναι εξ ορισμού ενδεικτική/ανοιχτού τύπου — υπάρχουν κι άλλες αποδεκτές τεχνικές (π.χ. αλγεβρική επίλυση με τον τύπο των ριζών αντί για brute force, χρήση της βιβλιοθήκης sympy), αρκεί να εξηγούν σωστά γιατί αποτυγχάνει η αρχική μέθοδος.

Δραστηριότητα 3 (γιατί το άνω όριο είναι 1.000.001 + εκτέλεση τριών προγραμμάτων range()) (σελ. 88)

Να διερευνήσετε γιατί στα παραπάνω προγράμματα στη γλώσσα Python η εντολή επανάληψης έχει άνω όριο 1.000.001 και όχι 1.000.000.

Στο περιβάλλον προγραμματισμού Thonny ή σε κάποιον online διερμηνευτή της Python δοκιμάστε να εκτελέσετε τα παρακάτω προγράμματα και σχολιάστε τα αποτελέσματά τους.

for x in range(1, 1000001):
    if x*x-5*x+6 == 0:
        print( "x = ", x )

for x in range(5, 12):
    print( "x = ", x )

for x in range(12):
    print( "x = ", x )

Σκέψη / Μεθοδολογία: Το κλειδί είναι ότι στην Python η συνάρτηση range(αρχή, τέλος) παράγει τιμές από το «αρχή» ΜΕΧΡΙ ΚΑΙ το «τέλος-1» — το δεξί όριο ΔΕΝ συμπεριλαμβάνεται ποτέ (είναι «ανοιχτό» διάστημα στα δεξιά). Άρα αν θέλουμε ο βρόχος να ελέγξει και τον ακέραιο 1.000.000 ο ίδιος, πρέπει το δεύτερο όρισμα να είναι 1.000.001 (1.000.000+1), όχι 1.000.000. Με ένα μόνο όρισμα, το range(N) ισοδυναμεί με range(0, N) — δηλαδή ξεκινά αυτόματα από το 0.

Λύση:

Επαλήθευση με κώδικα:

print(1000000 in range(1, 1000001))   # True
print(1000000 in range(1, 1000000))   # False

Το τελευταίο στοιχείο του range(1, 1000001) είναι πράγματι το 1.000.000, ενώ το τελευταίο στοιχείο του range(1, 1000000) θα ήταν το 999.999 — δηλαδή αν το βιβλίο είχε γράψει 1.000.000 ως άνω όριο, ο αριθμός 1.000.000 ΠΟΤΕ δεν θα ελεγχόταν από το πρόγραμμα, και μια εξίσωση με μοναδική λύση ακριβώς x=1.000.000 δεν θα εντοπιζόταν.

Πρόγραμμα 1 — for x in range(1, 1000001): if x*x-5*x+6==0: print("x = ", x). Εκτέλεση: τυπώνει ακριβώς δύο γραμμές:

x =  2
x =  3

Πρόκειται για την ίδια εξίσωση x²-5x+6=0 του κυρίως κειμένου της §7.2, με τις ήδη γνωστές λύσεις 2 και 3.

Πρόγραμμα 2 — for x in range(5, 12): print("x = ", x). Εκτέλεση: τυπώνει 7 γραμμές, τις τιμές 5, 6, 7, 8, 9, 10, 11 (από το 5 μέχρι το 11, αφού το 12 αποκλείεται ως δεξί όριο).

Πρόγραμμα 3 — for x in range(12): print("x = ", x). Εκτέλεση: τυπώνει 12 γραμμές, τις τιμές 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 (η μονή παράμετρος 12 παίζει τον ρόλο του «τέλος», ενώ η «αρχή» παίρνει αυτόματα την προεπιλεγμένη τιμή 0 — γι' αυτό η λίστα ξεκινά από το 0, όχι το 1).

Σύγκριση Προγραμμάτων 2 και 3: το range(5,12) και το range(12) έχουν το ΙΔΙΟ δεξί όριο (12, αποκλειστικό) αλλά διαφορετική αρχή (5 έναντι της προεπιλογής 0) — αυτό εξηγεί γιατί το Πρόγραμμα 3 έχει 5 περισσότερες γραμμές εξόδου από το Πρόγραμμα 2 (τις τιμές 0,1,2,3,4 που προηγούνται του 5).

Τελική απάντηση: Το άνω όριο είναι 1.000.001 (όχι 1.000.000) επειδή το range(αρχή, τέλος) στην Python ΑΠΟΚΛΕΙΕΙ πάντα το δεύτερο όριο· άρα, για να ελεγχθεί ο ίδιος ο αριθμός 1.000.000, το όρισμα «τέλος» πρέπει να είναι 1.000.001. Εκτέλεση προγραμμάτων: το 1ο τυπώνει «x = 2» και «x = 3» (λύσεις της x²-5x+6=0)· το 2ο [range(5,12)] τυπώνει τους αριθμούς 5 έως 11· το 3ο [range(12)] τυπώνει τους αριθμούς 0 έως 11, επειδή η μονή παράμετρος του range() ορίζει μόνο το τέλος και η αρχή γίνεται αυτόματα 0.

Πρόσεξε:

  • Δεν πρόκειται για ιδιοτροπία ή σύμβαση του βιβλίου — είναι θεμελιώδης κανόνας της γλώσσας Python: range(a, b) παράγει πάντα a, a+1, …, b-1, ΠΟΤΕ το ίδιο το b.
  • Το range(N) με μία μόνο παράμετρο ΔΕΝ σημαίνει «από το 1 έως το Ν» αλλά «από το 0 έως το Ν-1» — συνηθισμένη πηγή λαθών (off-by-one) σε αρχάριους προγραμματιστές.
  • Στο πρόγραμμα της §7.3 (εκθετική μετάδοση ιού) το range(μέρες), με μία μόνο παράμετρο, επαναλαμβάνει το σώμα του βρόχου ακριβώς «μέρες» φορές (i = 0, 1, …, μέρες−1).

Ερωτήσεις 1-6 της §7.3 (εκθετική μετάδοση του ιού) (σελ. 89)

Ένας μεταδοτικός ιός έχει τα εξής χαρακτηριστικά:

• Κάθε άνθρωπος που έχει μολυνθεί από τον ιό μπορεί να τον μεταδώσει την επόμενη μέρα σε 2 ακόμα ανθρώπους με τους οποίους έχει έρθει σε επαφή.

• Κάθε άνθρωπος είναι μεταδοτικός μόνο για μια ημέρα, για την επόμενη της μόλυνσης.

Θέλουμε να σχεδιάσουμε ένα υπολογιστικό μοντέλο με βάση το οποίο θα μπορούμε να υπολογίζουμε εύκολα πόσα κρούσματα έχουμε κάθε μέρα και πόσα συνολικά. Θα χρειαστεί να συμπληρώσουμε τον παρακάτω πίνακα (Αριθμός ημέρας | Ημερήσια κρούσματα | Συνολικά κρούσματα: 1 | 1 | 1 — 2 | 2 | 1+2=3 — 3 | 4 | 1+2+4=7 — και κενές γραμμές για τις ημέρες 4, 5, 6, 8, 10, …, 20, Ν).

  1. Σε πόσες μέρες θα έχουν μολυνθεί όλοι οι κάτοικοι της χώρας μας, που είναι περίπου \(10^7\);

  2. Να γράψετε ένα πρόγραμμα το οποίο θα δέχεται το πλήθος των ημερών, και θα εμφανίζει πόσοι θα έχουν μολυνθεί μετά από ένα μήνα.

  3. Καθώς υπολογίζετε το πλήθος των μολυσμένων ανθρώπων σε κάθε βήμα, σκεφτείτε ποιες πράξεις επαναλαμβάνονται κάθε φορά και τι μεταβλητές χρειάζεστε.

  4. Τι αλλαγές πρέπει να κάνετε στο πρόγραμμα, αν εμφανιστεί μια νέα μετάλλαξη του ιού η οποία είναι δύο φορές πιο μεταδοτική; Δηλαδή κάθε άνθρωπος μολύνει σε μια μέρα τέσσερις συνανθρώπους του;

  5. Πόσες μέρες χρειάζονται τώρα για να μολυνθεί όλη η χώρα με τη νέα μετάλλαξη;

  6. Πόσες μέρες/μήνες χρειάζονται για να μολυνθεί ο πληθυσμός ολόκληρου του πλανήτη με αυτή τη νέα μετάλλαξη; Συμφωνεί αυτή η πρόβλεψη με την πραγματικότητα; Γιατί; Τι δεν έχει προβλεφθεί στο μοντέλο;

Σκέψη / Μεθοδολογία: Κάθε μέρα τα νέα (ημερήσια) κρούσματα διπλασιάζονται, γιατί κάθε μολυσμένος μολύνει 2 νέους την επόμενη μέρα και μετά παύει να είναι μεταδοτικός: 1, 2, 4, 8, … Άρα την ημέρα Ν τα ημερήσια κρούσματα είναι \(2^{N-1}\) και τα συνολικά είναι το άθροισμα \(1+2+4+\dots+2^{N-1} = 2^N - 1\). Με αυτούς τους τύπους συμπληρώνουμε τον πίνακα και απαντάμε στα ερωτήματα, βρίσκοντας την πρώτη μέρα που το σύνολο ξεπερνά τον πληθυσμό. Για τη μετάλλαξη με 4 νέες μολύνσεις ανά άτομο, τα ημερήσια κρούσματα γίνονται \(4^{N-1}\) και τα συνολικά \(\frac{4^N-1}{3}\).

Λύση:

Συμπλήρωση του πίνακα (ημέρα | ημερήσια κρούσματα | συνολικά κρούσματα):

Αριθμός ημέρας Ημερήσια κρούσματα Συνολικά κρούσματα
1 1 1
2 2 3
3 4 7
4 8 15
5 16 31
6 32 63
8 128 255
10 512 1.023
20 524.288 1.048.575
Ν \(2^{N-1}\) \(2^N - 1\)
  1. Ψάχνουμε το μικρότερο Ν με \(2^N - 1 \geq 10^7\). Την 23η μέρα τα συνολικά κρούσματα είναι \(2^{23} - 1 = 8.388.607\) (λιγότερα από \(10^7\)), ενώ την 24η μέρα είναι \(2^{24} - 1 = 16.777.215\). Άρα όλοι οι κάτοικοι της χώρας θα έχουν μολυνθεί σε 24 μέρες.

  2. Το πρόγραμμα (όπως το ενδεικτικό πρόγραμμα Python του βιβλίου) διαβάζει το πλήθος των ημερών και υπολογίζει τα συνολικά κρούσματα· για έναν μήνα δίνουμε 30 ημέρες:

μέρες = int(input("Δώσε τον αριθμό των ημερών: "))
Ημερήσια_κρούσματα = 1
Συνολικά_κρούσματα = 0
for i in range(μέρες):
    Συνολικά_κρούσματα += Ημερήσια_κρούσματα
    Ημερήσια_κρούσματα = 2*Ημερήσια_κρούσματα
print("Συνολικά νόσησαν = ", Συνολικά_κρούσματα)

Με είσοδο 30 το πρόγραμμα εμφανίζει «Συνολικά νόσησαν = 1073741823», δηλαδή \(2^{30} - 1 = 1.073.741.823\) άνθρωποι μετά από έναν μήνα.

  1. Σε κάθε βήμα επαναλαμβάνονται δύο πράξεις: προσθέτουμε τα ημερήσια κρούσματα στα συνολικά (Συνολικά_κρούσματα += Ημερήσια_κρούσματα) και διπλασιάζουμε τα ημερήσια κρούσματα για την επόμενη μέρα (Ημερήσια_κρούσματα = 2*Ημερήσια_κρούσματα). Χρειαζόμαστε τις μεταβλητές: μέρες (πλήθος ημερών), Ημερήσια_κρούσματα (αρχική τιμή 1), Συνολικά_κρούσματα (αρχική τιμή 0) και τον μετρητή i της επανάληψης.

  2. Αλλάζουμε μόνο τον πολλαπλασιαστή της δεύτερης εντολής μέσα στην επανάληψη από 2 σε 4: Ημερήσια_κρούσματα = 4*Ημερήσια_κρούσματα.

  3. Με τη νέα μετάλλαξη τα συνολικά κρούσματα την ημέρα Ν είναι \(\frac{4^N-1}{3}\). Την 12η μέρα είναι 5.592.405 (λιγότερα από \(10^7\)) και την 13η μέρα 22.369.621. Άρα χρειάζονται 13 μέρες για να μολυνθεί όλη η χώρα.

  4. Με πληθυσμό του πλανήτη περίπου 8 δισεκατομμύρια (\(8 \cdot 10^9\)): την 17η μέρα τα συνολικά κρούσματα είναι 5.726.623.061 και την 18η μέρα 22.906.492.245, άρα το μοντέλο προβλέπει ότι σε 18 μέρες (λιγότερο από 3 εβδομάδες) θα έχει μολυνθεί όλος ο πλανήτης.

Η πρόβλεψη αυτή δε συμφωνεί με την πραγματικότητα. Το μοντέλο δεν έχει προβλέψει, για παράδειγμα, ότι: κάποιοι από όσους έρχεται σε επαφή ένας μολυσμένος έχουν ήδη νοσήσει ή έχουν ανοσία· οι άνθρωποι δεν έρχονται όλοι σε επαφή μεταξύ τους (αποστάσεις, σύνορα, διαφορετικές χώρες)· λαμβάνονται μέτρα προστασίας (μάσκες, απομόνωση, εμβόλια)· ο αριθμός των ανθρώπων που μολύνει κάθε ασθενής δεν είναι πάντα ακριβώς ο ίδιος. Γι' αυτό η πραγματική εξάπλωση είναι πολύ πιο αργή από την εκθετική πρόβλεψη του απλού μοντέλου.

Τελική απάντηση: Ημέρα Ν: ημερήσια κρούσματα \(2^{N-1}\), συνολικά \(2^N - 1\) (π.χ. ημέρα 4: 8 και 15, ημέρα 10: 512 και 1.023, ημέρα 20: 524.288 και 1.048.575). 1) 24 μέρες (\(2^{24} - 1 = 16.777.215 \geq 10^7\)). 2) Πρόγραμμα με επανάληψη for που προσθέτει τα ημερήσια κρούσματα στα συνολικά και διπλασιάζει τα ημερήσια· για 30 ημέρες εμφανίζει 1.073.741.823. 3) Επαναλαμβάνονται η πρόσθεση στα συνολικά και ο διπλασιασμός των ημερήσιων· μεταβλητές: μέρες, Ημερήσια_κρούσματα, Συνολικά_κρούσματα, i. 4) Ο πολλαπλασιαστής 2 γίνεται 4. 5) 13 μέρες. 6) Περίπου 18 μέρες για 8 δισεκατομμύρια ανθρώπους· η πρόβλεψη δε συμφωνεί με την πραγματικότητα, γιατί το μοντέλο αγνοεί την ανοσία όσων έχουν ήδη νοσήσει, τις περιορισμένες επαφές, τα μέτρα προστασίας και τη διαφορετική συμπεριφορά κάθε ανθρώπου.

Πρόσεξε:

  • Τα συνολικά κρούσματα της ημέρας Ν είναι \(2^N - 1\), όχι \(2^N\): ξεκινάμε από 1 κρούσμα την 1η μέρα και το άθροισμα \(1+2+\dots+2^{N-1}\) είναι κατά 1 μικρότερο από τη δύναμη \(2^N\).
  • Στο ερώτημα 1 ζητείται η πρώτη μέρα στην οποία τα ΣΥΝΟΛΙΚΑ (όχι τα ημερήσια) κρούσματα φτάνουν τον πληθυσμό.
  • Στο πρόγραμμα, η σειρά των δύο εντολών μέσα στην επανάληψη έχει σημασία: πρώτα προσθέτουμε τα ημερήσια κρούσματα της μέρας στα συνολικά και μετά τα διπλασιάζουμε για την επόμενη μέρα.
  • Ο πληθυσμός του πλανήτη (περίπου 8 δισεκατομμύρια) είναι στρογγυλεμένη τιμή· με μικρή διαφορά στον πληθυσμό η απάντηση παραμένει περίπου 18 μέρες.
ΠΛΗΡΟΦΟΡΙΚΗ Γ' ΓΥΜΝΑΣΙΟΥ - ΣΧΟΛΙΚΟ ΒΙΒΛΙΟ ΜΑΘΗΤΗ (PDF)