ΣΕΤ ΑΣΚΗΣΕΩΝ 2 ΕΡΓΑΣΤΗΡΙΟ ΠΡΟΓΡΑΜΜΑΤΙΣΜΟΥ I, ΑΚΑΔΗΜΑΪΚΟ ΕΤΟΣ 2010-2011 Προθεσµία: 15/11/10, 23:59 Στόχοι Πίνακες Συναρτήσεις Συµβολοσειρές Χρήση µεταβλητών και σταθερών Χρήση τελεστών Χρήση δοµών ελέγχου Φορµαρισµένη είσοδος και έξοδος δεδοµένων Χρήση σχολίων και αναγνωσιµότητα προγράµµατος Πριν ξεκινήσετε Διαβάστε την εκφώνηση προσεκτικά και σχεδιάστε το πρόγραµµά σας στο χαρτί. Μην προσπαθήσετε να γράψετε το πρόγραµµα µια κι έξω. Για κάθε στάδιο που ολοκληρώνετε, βεβαιωθείτε ότι κάνει compile και λειτουργεί σωστά και µετά να προχωράτε στο επόµενο στάδιο. Σε κάθε στάδιο σας δίνουµε µια εκτίµηση της δυσκολίας του (διαβάθµιση από 1 έως 4). Μη διστάζετε να ζητήσετε βοήθεια! Μπορείτε να χρησιµοποιήσετε το forum προγραµµατισµού (http://inf-server.inf.uth.gr/courses/coding/) και φυσικά email. Η εργασία αυτή µπορεί να γίνει είτε ατοµικά είτε σε οµάδες των 2 ατόµων. Μπορείτε να συζητάτε τις ασκήσεις µε συµφοιτητές σας εκτός οµάδας αλλά δεν επιτρέπεται η ανταλλαγή κώδικα µε οποιοδήποτε τρόπο. Δεν είναι απαραίτητο να είστε στην ίδια οµάδα από το πρώτο σετ ασκήσεων. Ξεκινήστε νωρίς! Ο προγραµµατισµός είναι πάντα ΠΟΛΥ πιο χρονοβόρος από ό,τι περιµένετε. Εκπρόθεσµες ασκήσεις δε γίνονται δεκτές.
Άσκηση: Sudoku Εισαγωγή Θα γράψετε ένα πρόγραµµα το οποίο βοηθά το χρήστη να ολοκληρώσει ένα παιχνίδι Sudoku. Αν δε γνωρίζετε πώς παίζεται το Sudoku, πριν συνεχίστε διαβάστε την περιγραφή και τους κανόνες του στο http://www.sudoku.name/rules/el. Το πρόγραµµα θα διαβάζει ένα πλέγµα Sudoku, θα δίνει την ευκαιρία στο χρήστη να σβήσει ή να προσθέσει έναν αριθµό και θα ανιχνεύει αν η προσθήκη του αριθµού είναι έγκυρη. Ακολουθούν λεπτοµερείς οδηγίες για το πώς πρέπει να λειτουργεί το πρόγραµµά σας και στάδια κατασκευής του. ΜΗΝ προσπαθήσετε να γράψετε όλο το πρόγραµµα σε ένα βήµα γιατί θα κάνετε λάθη και θα σας πάρει πολύ περισσότερο χρόνο. Όταν προσδιορίζουµε ότι κάποια λειτουργία πρέπει να γίνει µε χρήση συνάρτησης, είναι υποχρεωτικό να το κάνετε. Πρέπει να αποφασίσετε εσείς τι παραµέτρους χρειάζεται κάθε συνάρτηση, κι αν πρέπει να επιστρέφει κάτι, µε βάση την περιγραφή που σας δίνουµε. Υπάρχουν επιπλέον λειτουργίες στο πρόγραµµα που είναι καλύτερα να γίνουν µέσω συναρτήσεων που θα έχετε κατασκευάσει εσείς. Πρέπει να κρίνετε εσείς πότε είναι καλύτερα να γίνει κάτι µέσω συνάρτησης. Γενικά στα προγράµµατα που γράφετε στον Προγραµµατισµό 1 (στα εργαστήρια, σετ ασκήσεων και εξετάσεις) απαγορεύεται η χρήση καθολικών µεταβλητών, εκτός αν το έχουµε επιτρέψει ρητά. Στο σετ ασκήσεων 2 επιτρέπεται η χρήση ΜΟΝΟ µίας καθολικής µεταβλητής: αυτής όπου αποθηκεύεται ο πίνακας. Στάδιο 1: Εισαγωγή ( ) και εκτύπωση πλέγµατος ( ) Δηλώστε ένα πίνακα µεγέθους 9 9 στον οποίο θα αποθηκευτεί το πλέγµα του παιχνιδιού. Ο πίνακας πρέπει να δηλωθεί ως καθολική µεταβλητή για να υπάρχει σε αυτόν πρόσβαση από όλες τις συναρτήσεις. Γράψτε µια συνάρτηση η οποία διαβάζει 81 ακεραίους από το πληκτρολόγιο και τους αποθηκεύει στον πίνακα. Μεταξύ διαδοχικών ακεραίων υπάρχει whitespace (κενό ή χαρακτήρας αλλαγής γραµµής). Οι τιµές των ακεραίων κυµαίνονται από 0 έως και 9, όπου το 0 σηµαίνει πως στην αντίστοιχη θέση του πλέγµατος Sudoku δεν υπάρχει αριθµός. Δε χρειάζεται να κάνετε έλεγχο για το εύρος της κάθε τιµής. Γράψτε µια συνάρτηση η οποία εκτυπώνει τα περιεχόµενα του πίνακα µε τον παρακάτω τρόπο: Στην πρώτη γραµµή εκτυπώνει τον αύξοντα αριθµό της κάθε στήλης (0 έως και 8). Οι αριθµοί πρέπει να έχουν ίσο κενό µεταξύ τους και όσο χρειάζεται έτσι ώστε ο κάθε αριθµός να βρίσκεται ακριβώς στο κέντρο της στήλης που αντιπροσωπεύει. Στη δεύτερη γραµµή εκτυπώνει µια σειρά από χαρακτήρες '=' Για κάθε γραµµή του πίνακα εκτυπώνει τα περιεχόµενα του πλέγµατος έτσι ώστε κάθε κουτάκι πιάνει τρεις θέσεις αν ένα κουτάκι περιέχει 0, τότε εµφανίζονται µόνο κενά αν ένα κουτάκι περιέχει αριθµό, αυτός εµφανίζεται στο κέντρο του κουτιού ανάµεσα σε διαδοχικά κουτάκια υπάρχει ο χαρακτήρας ' '.
ανάµεσα στις στήλες 2 και 3 και τις στήλες 5 και 6 υπάρχουν δύο χαρακτήρες ' ' αριστερά και δεξιά του πίνακα υπάρχει από ένας χαρακτήρας ' ' µετά την τελευταία στήλη υπάρχει ένα κενό και ο αύξων αριθµός της γραµµής (0 έως και 8) Ανάµεσα σε διαδοχικές γραµµές του πίνακα υπάρχει µια σειρά από χαρακτήρες '-', µε την παρακάτω εξαίρεση: ανάµεσα στις γραµµές 2 και 3 και τις γραµµές 5 και 6 υπάρχει µια σειρά από χαρακτήρες '=' Στην τελευταία γραµµή υπάρχει µια σειρά από χαρακτήρες '=' Οι σειρές από '-' ή '=' πρέπει να έχουν όσο µήκος χρειάζεται για να εµφανιστεί µια γραµµή του πίνακα όπως περιγράφεται πιο πάνω Για ευκολία, δείτε πώς εµφανίζονται οι πίνακες στα αρχεία ελέγχου. Επαλήθευση: Γράψτε µια συνάρτηση main η οποία καλεί πρώτα τη συνάρτηση ανάγνωσης δεδοµένων και µετά τη συνάρτηση εκτύπωσης του πίνακα. Χρησιµοποιήστε τα αρχεία ελέγχου test.1 και test.1.std που βρίσκονται στο φάκελο tests/stadio1 για να επαληθεύσετε την ορθότητα του προγράµµατός σας. Αποθηκεύστε το πρόγραµµά σας σε ένα αρχείο µε όνοµα hw2_version1.c Ολοκληρώστε αυτό το στάδιο και βεβαιωθείτε ότι λειτουργεί σωστά πριν προχωρήσετε στο επόµενο. Στάδιο 2: Αλληλεπίδραση µε το χρήστη ( 1/2 ) Κατασκευάστε ένα αντίγραφο του hw2_version1.c και δώστε του το όνοµα hw2_version2.c. Κάντε τις νέες αλλαγές στον κώδικα στο αρχείο hw2_version2.c. Με αυτό τον τρόπο, αν γίνουν λάθη, θα µπορείτε τουλάχιστον να επανέλθετε στη λύση από το στάδιο 1. Τώρα θα υλοποιήσετε το βασικό µέρος της αλληλεπίδρασης µε το χρήστη. Δώστε ιδιαίτερη σηµασία στη µορφή, περιεχόµενο και ορθογραφία των µηνυµάτων που πρέπει να εκτυπώνονται στην οθόνη, ώστε να ταιριάζουν ακριβώς µε τις προδιαγραφές. Το πρόγραµµα λειτουργεί ως εξής: 1. Εκτυπώνει τον πίνακα 2. Σε νέα γραµµή εκτυπώνει το µήνυµα "What do you want to do?" 3. Διαβάζει την απάντηση του χρήστη, η οποία µπορεί να είναι: insert X in R C εκτυπώνει σε νέα γραµµή το βοηθητικό µήνυµα "TRY: insert X in (R, C)" όπου X, R και C περιγράφονται παρακάτω. ο χρήστης ζητά να τοποθετήσει τον αριθµό Χ στη θέση (R, C) του πίνακα.
το Χ είναι ο ακέραιος που θέλουµε να τοποθετήσουµε σε ένα κουτάκι του πίνακα. Αν το Χ δεν είναι µεταξύ 1 και 9, τότε το πρόγραµµα εκτυπώνει σε νέα γραµµή το µήνυµα "Number out of range. Insert aborted" και επιστρέφει στο βήµα 1. R και C είναι η γραµµή και στήλη αντίστοιχα του πίνακα όπου θα τοποθετηθεί το Χ. Αν σε αυτό το κουτί υπάρχει ήδη µη-µηδενικός αριθµός, το πρόγραµµα εκτυπώνει σε νέα γραµµή το µήνυµα "Non-empty cell. Insert aborted." και επιστρέφει στο βήµα 1. Αν οποιοδήποτε από τα R, C είναι εκτός ορίων του πίνακα, τότε το πρόγραµµα εκτυπώνει σε νέα γραµµή το µήνυµα "Location out of range. Insert aborted" και επιστρέφει στο βήµα 1. Μπορείτε να υποθέσετε ότι αν η πρώτη λέξη που έγραψε ο χρήστης είναι "insert", τότε οπωσδήποτε ακολουθούν ένας ακέραιος, η λέξη "in" και δύο ακόµα ακέραιοι. delete R C quit ο χρήστης ζητά να "σβηστεί" ο αριθµός που βρίσκεται στη θέση (R, C) του πίνακα. εκτυπώνει σε νέα γραµµή το βοηθητικό µήνυµα "TRY: delete (R, C)" όπου R και C περιγράφονται παρακάτω. R και C είναι η γραµµή και στήλη αντίστοιχα του πίνακα από όπου θα σβηστούν τα περιεχόµενα. Αυτό σηµαίνει πως ο αριθµός σε αυτό το κουτί θα πρέπει να γίνει 0. Αν οποιοδήποτε από τα R, C είναι εκτός ορίων του πίνακα, τότε το πρόγραµµα εκτυπώνει σε νέα γραµµή το µήνυµα "Location out of range. Delete aborted" και επιστρέφει στο βήµα 1. Μπορείτε να υποθέσετε ότι αν η πρώτη λέξη που έγραψε ο χρήστης είναι "delete", τότε οπωσδήποτε ακολουθούν δύο ακέραιοι. Ο χρήστης ζητά να τερµατίσει το παιχνίδι. Εκτυπώνεται σε νέα γραµµή το µήνυµα "QUITTING" και σταµατά το παιχνίδι. 4. Πριν τερµατίσει, το πρόγραµµα εκτυπώνει το µήνυµα "Thank you! Play again." Απαίτηση: Το πρόγραµµά σας πρέπει να λειτουργεί σωστά ανεξάρτητα από το αν οι λέξεις insert, delete ή quit έχουν κεφαλαία ή µικρά γράµµατα. Βοήθεια: Χρησιµοποιήστε κατάλληλες συναρτήσεις από τη βιβλιοθήκη string για τη διαχείριση και έλεγχο των συµβολοσειρών. Αν θέλετε, προσπαθήστε να γράψετε το πρόγραµµά σας έτσι ώστε να λειτουργεί σωστά ανεξαρτήτως του αν οι λέξεις insert, delete, quit είναι γραµµένες µε κεφαλαία ή µικρά. Επαλήθευση: Σε κάθε σηµείο που το πρόγραµµά σας ανιχνεύει την επιλογή του χρήστη, προσθέστε απλές printf που εκτυπώνουν ένα µήνυµα επιτυχίας (για παράδειγµα printf("insert OK"); ). Με αυτό τον τρόπο θα επιβεβαιώσετε ότι ανιχνεύεται σωστά η κάθε επιλογή. Αποθηκεύστε το πρόγραµµά σας στο αρχείο µε όνοµα hw2_version2.c Ολοκληρώστε αυτό το στάδιο και βεβαιωθείτε ότι λειτουργεί σωστά πριν προχωρήσετε στο επόµενο.
Στάδιο 3: Εισαγωγή /Σβήσιµο αριθµού και έλεγχος ορθότητας ( ) Κατασκευάστε ένα αντίγραφο του hw2_version2.c και δώστε του το όνοµα hw2.c. Κάντε τις νέες αλλαγές στον κώδικα στο αρχείο hw2.c. Με αυτό τον τρόπο, αν γίνουν λάθη, θα µπορείτε τουλάχιστον να επανέλθετε στη λύση από το στάδιο 2. Αφαιρέστε από τη λύση του σταδίου 2 τα βοηθητικά printf. Σε εκείνα τα σηµεία θα πρέπει να καλείτε κατάλληλες συναρτήσεις. Γράψτε µια συνάρτηση η οποία θα καλείται στην περίπτωση που ο χρήστης έχει ζητήσει να εισάγει ένα αριθµό σε ένα κουτί του πίνακα. Η συνάρτησή σας πρέπει να κάνει τα εξής: 1. Εισάγει τον αριθµό στο κουτί 2. Ελέγχει αν µε την εισαγωγή αυτή παραβιάζονται οι κανόνες του Sudoku. Αν ναι, τότε ξαναβάζει στο κουτί τον αριθµό που υπήρχε πριν. Αυτό το κοµµάτι είναι το πιο δύσκολο σηµείο όλης της άσκησης. Σχεδιάστε τη λογική σας στο χαρτί πριν γράψετε κώδικα! 3. Επιστρέφει µια τιµή που εκφράζει το αν η εισαγωγή έγινε επιτυχώς ή όχι. Στο κυρίως πρόγραµµα, αν η εισαγωγή δεν έχει γίνει επιτυχώς, εκτυπώνεται σε νέα γραµµή το µήνυµα "Incorrect solution", διαφορετικά εκτυπώνεται το µήνυµα "ΟΚ" Βεβαιωθείτε ότι η εισαγωγή νέου στοιχείου λειτουργεί σωστά πριν προχωρήσετε. Γράψτε µια συνάρτηση η οποία θα καλείται στην περίπτωση που ο χρήστης ζήτησε να σβήσει τα περιεχόµενα ενός κουτιού. Η συνάρτησή σας πρέπει να θέτει τα περιεχόµενα του κουτιού σε µηδέν. Αποθηκεύστε το πρόγραµµά σας στο αρχείο µε όνοµα hw2.c Ολοκληρώστε αυτό το στάδιο και βεβαιωθείτε ότι λειτουργεί σωστά πριν προχωρήσετε στο επόµενο. Στάδιο 4: Έλεγχος ορθότητας Το πρόγραµµά σας πρέπει να λειτουργεί σωστά και να εκτυπώνει όλα τα µηνύµατα και αποτελέσµατα µε τον τρόπο που σας περιγράφουµε. Για να µπορέσετε να ελέγξετε την ορθότητα θα σας δώσουµε ενδεικτικά αρχεία εισόδου και εξόδου. Δείτε το φάκελο tests/stadio4 Κάθε αρχείο µε όνοµα test.? περιέχει µια ενδεικτική είσοδο για το πρόγραµµα και κάθε αρχείο µε όνοµα test.?.std περιέχει την αντίστοιχη έξοδο. Το πρόγραµµά σας πρέπει να έχει την ίδια έξοδο µε το δικό µας. Παράδειγµα: Ας υποθέσουµε ότι το εκτελέσιµο πρόγραµµά σας λέγεται hw2, το ενδεικτικό αρχείο εισόδου λέγεται test.1 και το αντίστοιχο αρχείο εξόδου που σας έχουµε δώσει λέγεται test.1.std Η εντολή:./hw2 < test.1 > test.1.out εκτελεί το πρόγραµµά σας µε την ενδεικτική είσοδο test.1 και αποθηκεύει τα αποτελέσµατα στο
αρχείο εξόδου test.1.out Η εντολή diff -iwb test.1.out test.1.std συγκρίνει το δικό σας αρχείο εξόδου µε το δικό µας. Αν υπάρχουν διαφορές, τις εµφανίζει (γραµµήγραµµή). Αν δεν υπάρχουν διαφορές, δεν κάνει τίποτα. Για περισσότερες πληροφορίες δείτε το φυλλάδιο του φροντιστηρίου της 16/10/10 Πρέπει το πρόγραµµα που θα µας παραδώσετε να παράγει έξοδο που δεν έχει διαφορές από τη δική µας. Αρχεία προς παράδοση: hw2.c Πώς να παραδώσετε τη δουλειά σας (Ακολουθείστε τις οδηγίες ακριβώς αλλιώς µπορεί να µη δούµε τα αρχεία σας) Οµάδα ενός ατόµου: Κατασκευάστε ένα φάκελο µε όνοµα επώνυµο_αεμ και αντιγράψτε µέσα σε αυτόν το hw2.c Πηγαίνετε στο φάκελο µέσα στον οποίο βρίσκεται το επώνυµο_αεμ που κατασκευάσατε και γράψτε την παρακάτω εντολή: tar czf epwnumo_aem.tgz epwnumo_aem Στείλτε email στη διεύθυνση ce120lab@gmail.com και ένα αντίγραφο (CC) στον εαυτό σας µε θέµα (subject) "CE120 hw2" και επικολληµένο αρχείο το epwnumo_aem.tgz Οµάδα δύο ατόµων: Κατασκευάστε ένα φάκελο µε όνοµα επώνυµο1_αεμ1_επώνυµο2_αεμ2 και αντιγράψτε µέσα σε αυτόν το hw2.c Πηγαίνετε στο φάκελο µέσα στον οποίο βρίσκεται το επώνυµο_αεμ που κατασκευάσατε και γράψτε την παρακάτω εντολή: tar czf επώνυµο1_αεμ1_επώνυµο2_αεμ2.tgz επώνυµο1_αεμ1_επώνυµο2_αεμ2 Στείλτε email στη διεύθυνση ce120lab@gmail.com και στα δύο µέλη της οµάδας, µε θέµα "CE120 hw2" και επικολληµένο αρχείο το epwnumo1_aem1_epwnumo2_aem2.tgz