Programmeermethoden 2016
Tweede programmeeropgave: Netjes

Inspecteur Netjes De tweede programmeeropgave van het vak Programmeermethoden in het najaar van 2016 heet Netjes: het gaat over netjes afdrukken; zie ook het vierde werkcollege, vijfde werkcollege (de betreffende WWW-bladzijde bevat handige tips evenals testfiles — te zijner tijd!) en zesde werkcollege, en lees geregeld deze pagina op WWW.
Spreek/Vragenuur in zalen 302 ... 309: dinsdag 27, donderdag 29 september, dinsdag 4, donderdag 6, dinsdag 11, donderdag 13 oktober 2016, van circa 15:30 tot 17:00 uur; en vrijdag 14 oktober 2016, vanaf ongeveer 11:15 uur.
BinnenhofI&E-studenten (Den Haag) Vragenmiddag in zaal Paleistuin/Malieveld op donderdag 13 oktober 2016, 14:45-17:30 uur.

Er moet een programma worden geschreven dat een foutloos te compileren C++-programma (bijvoorbeeld een uitwerking van de eerste programmeeropgave) een klein beetje probeert te begrijpen, oftewel een paar zaken doet die een compiler ook moet doen. Het programma moet de invoerfile netjes ingesprongen naar een uitvoerfile kopiëren, en daarbij alle //-commentaar weglaten. Verder moet het programma getallen opsporen, en kijken of deze een speciale eigenschap hebben.
Stel eenvoudige vragen om gegevens van de gebruiker te weten te komen. Het programma leest dan eenmalig de opgegeven invoerfile, en schrijft deze symbool voor symbool op de juiste wijze aangepast weg naar de uitvoerfile; tijdens dit proces wordt om de zoveel regels een rapportje op het scherm afgedrukt.

De volgende drie punten moeten worden gedaan:

1) Commentaar moet verwijderd worden.
Elk commentaar dat begint met // moet niet naar de uitvoerfile worden weggeschreven, maar weggelaten worden. Alleen de regelovergang wordt weer naar de uitvoerfile gekopieerd.
Voor het gemak mag aangenomen worden dat er geen /* ... */ commentaar voorkomt. Als er binnen //-commentaar opnieuw // voorkomt, wordt die volgende // ook gewoon verwijderd. We vatten zelfs // binnen een string op als het begin van commentaar.

2) Inspringen moet netjes geregeld worden.
De bedoeling is dat iedere regel op diepte d even ver inspringt, en wel tab maal d spaties. Hierbij is tab een door de gebruiker te kiezen getal, bijvoorbeeld 3. De diepte d van een regel wordt als volgt bepaald. De eerste regel van het programma is op diepte 0, iedere openingsaccolade { verhoogt de diepte met 1 (één) en iedere sluitaccolade } verlaagt de diepte met 1 (één). Een veranderde diepte merk je pas op de volgende regel (zie verderop hoe we accolades zelf afhandelen).
We nemen aan dat er geen accolades binnen strings (of als karakter '{') voorkomen. Accolades die binnen commentaar staan tellen niet mee voor de berekening van de diepte. De oude regelstructuur van het programma blijft behouden; voor iedere regel geldt dat het eerste karakter ongelijk spatie en TAB ('\t') op positie tab maal d +1 moet komen. Dit karakter kan een regelovergang zijn; zo wordt een oorspronkelijk "lege" regel op diepte d nu een regel met tab maal d spaties, en een regelovergang.
Wellicht ten overvloede, een regel met een stel spaties en TAB's, en dan verder alleen //-commentaar, komt als tab * d spaties in de uitvoerfile.
We nemen aan dat de accolades netjes gepaard zijn.
En op welke positie staat een accolade, als dit het eerste symbool is dat op een regel wordt afgedrukt? We spreken af dat als dit een openings-accolade is hiervoor nog de "oude" diepte wordt gebruikt, en voor een sluit-accolade de "nieuwe". We krijgen dus (waarbij een punt (.) een spatie voorstelt; tab = 3, d = 2):
......if ( x == y )
......{
.........z = 0;
......}

3) Lychrel-getallen moeten worden opgespoord.
Voor elk geheel getal > 0 uit de invoerfile wordt gekeken of het een Lychrel-getal is. Op het scherm wordt afgedrukt wat het aantal iteraties is om tot een palindroom te komen (voor 545 is dit 0, voor 113 is dit 1), of het nummer van de iteratie waarvan het resultaat boven INT_MAX (gebruik include <climits>) uitkomt (voor 196 is dit (waarschijnlijk) 18). Als dit laatste gebeurt, wordt dit erbij vermeld.
Elke directe opeenvolging van cijfers in de invoerfile wordt als een geheel getal opgevat. Neem aan dat ze alle kleiner dan of gelijk aan INT_MAX zijn. Zo bevat 123abcd-"qqq 5"+++uvw-77.88ddd//vb5656 de gehele getallen 123, 5, 77 en 88. Het maakt verder ook niet uit of een getal al dan niet binnen een string staat, het telt gewoon mee. Getallen binnen commentaar worden niet gedaan.

Om de zoveel regels en na afloop moeten op het scherm enkele "statistieken" afgedrukt worden, namelijk het totaal aantal ingelezen karakters (inclusief regelovergangen, spaties en dergelijke), het aantal in de uitvoerfile afgedrukte karakters en het maximale aantal iteraties voor Lychrel-berekeningen met het bijbehorende getal (het laatste als het meer keren hetzelfde maximum was).

Aan de gebruiker wordt vooraf gevraagd hoe de originele invoerfile en de "doelfile" heten (als de invoerfile niet bestaat stopt het programma direct), hoe groot tab moet worden en om de hoeveel regels statistieken moeten worden afgedrukt (bijvoorbeeld 20).

Ter verdere inspiratie, zie het vijfde werkcollege, ook voor voorbeeldfiles. Let op: files van websites kopiëren door met rechter muisknop op de links te klikken, anders (met markeer-copy-paste) gaan spaties/tabs wellicht fout!

Opmerkingen

Uiterste inleverdatum: vrijdag 14 oktober 2016, 17:00 uur.
Manier van inleveren:

  1. Digitaal de C++-code inleveren: stuur een email naar pm@liacs.leidenuniv.nl.
    Stuur geen executable's, lever alleen de C++-file digitaal in! Noem deze bij voorkeur ruttesamsom2.cc, dit voor de tweede opdracht van het duo Rutte-Samsom. De laatst voor de deadline ingeleverde versie wordt nagekeken.
  2. En ook een papieren versie van het verslag (inclusief de C++-code) deponeren in de speciaal daarvoor bestemde doos "Programmeermethoden" in de postkamer van Informatica, kamer 156 van het Snellius-gebouw.
    BinnenhofI&E-studenten (Den Haag) mogen de pdf-versie per email meesturen.
     

    Overal duidelijk datum en namen van de (maximaal twee) makers vermelden, in het bijzonder als commentaar in de eerste regels van de C++-code. Lees bij het zesde werkcollege hoe het verslag eruit moet zien en wat er in moet staan.

Te gebruiken compiler: als hij maar C++ vertaalt; het programma moet in principe zowel op een Linux-machine (met g++) als onder Windows met Code::Blocks draaien. Test dus in principe op beide systemen! Normering: verslag 1; layout 1; commentaar 2; overzichtelijkheid/modulariteit/functies 2; werking 4. Eventuele aanvullingen en verbeteringen: lees deze WWW-bladzijde: www.liacs.leidenuniv.nl/~kosterswa/pm/op2pm.php.