Συζητήσεις για το μάθημα και ανακοινώσεις

Χρόνος σε προγράμματα

 
Picture of GEORGIOS GIATILIS
Χρόνος σε προγράμματα
by GEORGIOS GIATILIS - Tuesday, 21 November 2017, 9:20 PM
 

Έχω το εξής πρόβλημα σε ένα πρόγραμμα.Ενώ μου βγαίνουν όλα τα cases ΟΚ και ο tester.py βγαίνει ολόσωστος.Τυπώνεται δηλ:

*****The program has run correctly in all cases

όταν πάω να στείλω το πρόγραμμα είμαι ERROR.Ο τέστερ άλλαξε πριν λίγο και πριν την αλλαγή ήμουν ΟΚ οπότε πήγα να δω που έχω κάνει λάθος.Αρχικά,έτρεξα τον νέο τέστερ(ο οποίος ήταν ο παλιός με κάποια επιπλέον cases) στον οποίο ήμουν πάλι ΟΚ οπότε πήγα μετά και έτρεξα το user.py με δικά μου inputs να δω αν προκύψει κάποιο λάθος κάτι που δεν έγινε.Το μόνο πρόβλημα που παρατήρησα είναι το εξής.Κάνοντας import time και βάζοντας έναν μετρήτη σε seconds για το πρόγραμμα μου κάποια cases έβγαιναν πάνω απο 1.5 seconds ειδικά ένα case έφτανε και τα 4 seconds.Υπάρχει κίνδυνος στο σύστημα αν στέλνω πρόγραμμα που διαρκεί αρκετό χρόνο(για τα δεδόμένα του υπολογιστή)και για αυτόν τον λόγο το σύστημα να κάνει time out χωρίς κάν να τρέχει το πρόγραμμα;Για να το διορθώσω πρέπει να ξαναφτιάξω όλο το πρόγραμμα;

 
Picture of Μιχάλης Κολουντζάκης
Re: Χρόνος σε προγράμματα
by Μιχάλης Κολουντζάκης - Tuesday, 21 November 2017, 9:59 PM
 

Ο tester έχει χρονικό όριο για κάθε πρόγραμμα που ελέγχει. Υπάρχουν δύο λόγοι γι' αυτό: (α) Κάποια προγράμματα πέφτουν σε άπειρο loop και δεν τελειώνουν ποτέ. Αν δεν τα σταματήσει ο tester τότε κι αυτός δε θα τελειώσει ποτέ και (β) Για κάποια προγράμματα υπάρχουν κάποιοι τρόποι να γραφούν που είναι λάθος, και το λάθος φαίνεται σε μεγάλα inputs, όπου ο λάθος τρόπος μπορεί να τρέχει μερικές χιλιάδες φορές πιο αργά από το σωστό.

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

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

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

To output του tester στο πρόγραμμά σου εκεί όπου ελέγχονται είναι:

-------------------Case No 8------------------
Traceback (most recent call last):
File "__testcode__8.py", line 34, in <module>
uuu = merge(L) #### Change this
File "__testcode__8.py", line 16, in merge
L2.append(list(range(i[0],i[1]+1)))
MemoryError
---Case No 8: ERROR

Βλέπεις ότι ούτε καν η μνήμη του υπολογιστή δεν ήταν αρκετή για να τρέξει.