🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: be.comp.programming
14 messages
14 total messages Started by -=Bacchant=- Sun, 06 Jul 2003 09:46
Oefening in C++ (schaakbord)
#4691
Author: -=Bacchant=-
Date: Sun, 06 Jul 2003 09:46
18 lines
1598 bytes
Hallo allemaal,

ik ben ijverig bezig C++ te leren,met behulp van het boek "C++" van Leen
Ammeraal , uitgegeven bij academic service.

Hier staat echter een oefening waar ik niet aan uitgeraak, met name op p43
oef 2.9:

"Schrijf een programma dat de getallen n en k inleest en deze gebruikt om
een 'schaakbord' van n*n velden af te drukken.de witte velden  blijven
geheel open en de zwarte bestaan uit  vierkanten van k*k sterretjes.
In de linkerbenedenhoek komt een zwart veld."

Iemand enige suggesties omtrent deze opdracht?

Greetz
-- 
-=Bacchant=-
Re: Oefening in C++ (schaakbord)
#4692
Author: Nicolas Barbier
Date: Sun, 06 Jul 2003 09:57
19 lines
1873 bytes
-=Bacchant=- wrote:

> "Schrijf een programma dat de getallen n en k inleest en deze gebruikt om
> een 'schaakbord' van n*n velden af te drukken.de witte velden  blijven
> geheel open en de zwarte bestaan uit  vierkanten van k*k sterretjes.
> In de linkerbenedenhoek komt een zwart veld."

druk n keer af op aparte regels:
 druk k keer af op aparte regels:
  druk n keer af op dezelfde regel, met als karakter afwisselend ' ' en '*':
   druk k keer af op dezelfde regel: het karakter van de vorige regel.

Dus men steke 4 for-lusjes in elkaar. Als er achter een bepaalde lus een 
nieuwe regel moet begonnen worden, doet men dat. Om bij te houden of men 
bezig is met ' ' of '*' kan men gebruik maken van een boolean of char 
variabele, in combinatie met een if-test of een :? constructie.

-- 
Nicolas Barbier
Re: Oefening in C++ (schaakbord)
#4693
Author: -=Bacchant=-
Date: Sun, 06 Jul 2003 14:54
31 lines
2202 bytes
Even een kleine codedemonstratie?

Als je tijd/goesting hebt natuurlijk...

greetz

-- 
-=Bacchant=-
"Nicolas Barbier" <anti@spam.invalid> schreef in bericht
news:3f07f2cb$0$6524$afc38c87@sisyphus.news.be.easynet.net...
> -=Bacchant=- wrote:
>
> > "Schrijf een programma dat de getallen n en k inleest en deze gebruikt
om
> > een 'schaakbord' van n*n velden af te drukken.de witte velden  blijven
> > geheel open en de zwarte bestaan uit  vierkanten van k*k sterretjes.
> > In de linkerbenedenhoek komt een zwart veld."
>
> druk n keer af op aparte regels:
>  druk k keer af op aparte regels:
>   druk n keer af op dezelfde regel, met als karakter afwisselend ' ' en
'*':
>    druk k keer af op dezelfde regel: het karakter van de vorige regel.
>
> Dus men steke 4 for-lusjes in elkaar. Als er achter een bepaalde lus een
> nieuwe regel moet begonnen worden, doet men dat. Om bij te houden of men
> bezig is met ' ' of '*' kan men gebruik maken van een boolean of char
> variabele, in combinatie met een if-test of een :? constructie.
>
> -- 
> Nicolas Barbier
Re: Oefening in C++ (schaakbord)
#4696
Author: Davy Loots
Date: Sun, 06 Jul 2003 16:44
63 lines
2952 bytes
#include <iostream.h>

int main(int argc, char* argv[])
{
    int k, n;
    cout << "Geef het aantal velden : ";
    cin >> n;
    cout << "Geef het aantal sterretjes per vak : ";
    cin >> k;
    for (int i = 0; i < n; ++i)
    {
        for (int j = 0; j < k; ++j)
        {
            for (int m = 0; m < n; ++m)
                for (int l = 0; l < k; ++l)
                    cout << (((i+m-n)%2)?" ":"*");
            cout << endl;
        }
    }

 return 0;
}


vriendelijke groenten,
davy


"-=Bacchant=-" <bacchantd@hotmail.com> schreef in bericht
news:be9cv4$m$1@reader08.wxs.nl...
> Even een kleine codedemonstratie?
>
> Als je tijd/goesting hebt natuurlijk...
>
> greetz
>
> --
> -=Bacchant=-
> "Nicolas Barbier" <anti@spam.invalid> schreef in bericht
> news:3f07f2cb$0$6524$afc38c87@sisyphus.news.be.easynet.net...
> > -=Bacchant=- wrote:
> >
> > > "Schrijf een programma dat de getallen n en k inleest en deze gebruikt
> om
> > > een 'schaakbord' van n*n velden af te drukken.de witte velden  blijven
> > > geheel open en de zwarte bestaan uit  vierkanten van k*k sterretjes.
> > > In de linkerbenedenhoek komt een zwart veld."
> >
> > druk n keer af op aparte regels:
> >  druk k keer af op aparte regels:
> >   druk n keer af op dezelfde regel, met als karakter afwisselend ' ' en
> '*':
> >    druk k keer af op dezelfde regel: het karakter van de vorige regel.
> >
> > Dus men steke 4 for-lusjes in elkaar. Als er achter een bepaalde lus een
> > nieuwe regel moet begonnen worden, doet men dat. Om bij te houden of men
> > bezig is met ' ' of '*' kan men gebruik maken van een boolean of char
> > variabele, in combinatie met een if-test of een :? constructie.
> >
> > --
> > Nicolas Barbier
>
>
Re: Oefening in C++ (schaakbord)
#4697
Author: Robrecht Jacques
Date: Sun, 06 Jul 2003 20:43
40 lines
2234 bytes
Davy Loots wrote:
> #include <iostream.h>
>
> int main(int argc, char* argv[])
> {
>     int k, n;
>     cout << "Geef het aantal velden : ";
>     cin >> n;
>     cout << "Geef het aantal sterretjes per vak : ";
>     cin >> k;
...

Het is niet nodig om het bord char per char te teken. Bv:

      String stars(k,'*'), spaces(k,' ');
      String odd_line(""), even_line("");
      String odd(""), even("");

      for (int i = 0; i < n-1; ++i)  // loop over columns
          odd_line += ( (i%2) == 0 ? stars : spaces );

      even_line = spaces + odd_line;
      odd_line += ( (n%2) == 0 ? spaces : stars );

      for (int i = 0; i < k; ++i) {  // group 'k' lines together
          even += even_line + endl;
          odd += odd_line + endl;
      }

      for (int i = 0; i < n; ++i)  // loop over rows
          cout << ( ((i+n)%2) == 0 ? odd : even );

>  return 0;
> }

En verdere 'optimalisaties' zijn natuurlijk ook mogelijk. Bv de laatste
loop over 'int i=n; i<2*n; ++i' laten lopen en dan testen op i%2 ipv
(i+n)%2.

Robrecht
Re: Oefening in C++ (schaakbord)
#4741
Author: -=Bacchant=-
Date: Mon, 07 Jul 2003 17:53
51 lines
2670 bytes
bedankt voor jullie antwoorden!!!
Nu kan ik weer voor ene tijdje verder...

greetz

-- 
-=Bacchant=-
"Robrecht Jacques" <Robrecht.Jacques@advalvas.be> schreef in bericht
news:3f088aaa$0$288$ba620e4c@reader1.news.skynet.be...
> Davy Loots wrote:
> > #include <iostream.h>
> >
> > int main(int argc, char* argv[])
> > {
> >     int k, n;
> >     cout << "Geef het aantal velden : ";
> >     cin >> n;
> >     cout << "Geef het aantal sterretjes per vak : ";
> >     cin >> k;
> ...
>
> Het is niet nodig om het bord char per char te teken. Bv:
>
>       String stars(k,'*'), spaces(k,' ');
>       String odd_line(""), even_line("");
>       String odd(""), even("");
>
>       for (int i = 0; i < n-1; ++i)  // loop over columns
>           odd_line += ( (i%2) == 0 ? stars : spaces );
>
>       even_line = spaces + odd_line;
>       odd_line += ( (n%2) == 0 ? spaces : stars );
>
>       for (int i = 0; i < k; ++i) {  // group 'k' lines together
>           even += even_line + endl;
>           odd += odd_line + endl;
>       }
>
>       for (int i = 0; i < n; ++i)  // loop over rows
>           cout << ( ((i+n)%2) == 0 ? odd : even );
>
> >  return 0;
> > }
>
> En verdere 'optimalisaties' zijn natuurlijk ook mogelijk. Bv de laatste
> loop over 'int i=n; i<2*n; ++i' laten lopen en dan testen op i%2 ipv
> (i+n)%2.
>
> Robrecht
>
>
Re: Oefening in C++ (schaakbord)
#4755
Author: Oelewapperke
Date: Thu, 10 Jul 2003 18:27
90 lines
4149 bytes
Davy Loots wrote:

> #include <iostream.h>
> 
> int main(int argc, char* argv[])
> {
>     int k, n;
>     cout << "Geef het aantal velden : ";
>     cin >> n;
>     cout << "Geef het aantal sterretjes per vak : ";
>     cin >> k;
>     for (int i = 0; i < n; ++i)
>     {
>         for (int j = 0; j < k; ++j)
>         {
>             for (int m = 0; m < n; ++m)
>                 for (int l = 0; l < k; ++l)
>                     cout << (((i+m-n)%2)?" ":"*");
>             cout << endl;
>         }
>     }
> 
>  return 0;
> }

opmerking : de correcte code voor iostram te includen is
<c++>
        #include <iostream>
        
        using namsepace std;
</c++>

1 karakter per write instructie (naar de C++ libs, niet naar libc/kernel, 
ik weet het, maar het blijft 1 oproep per karakter) is crimineel 
inefficient. Verder is je programma niet goed opgesplitst (niet dat ik 
beweer dat het nodig is in dit geval, maar het is een goede gewoonte).

<c++>
void drawChessBoard(int numVelden, int numStars)
{
        string starpart;
        string emptypart;
        string line1;           // er zijn twee soorten lijnen
        string line2;

        starpart.reserve(numStars); // beperk de geheugenallocaties tot 1
        emptypart.reserve(numStars);
        line1.reserve(numVelden * numStars);
        line2.reserve(numVelden * numStars);

        for (int i = 0; i < numStars; i++)
        {
                starpart += '*';
                emptypart += ' ';       // enkele aanhalingstekens roepen de char addition op
        }

        for (int i = 0; i < numVelden; i++)
        {
                line1 += ( i % 2 == 0 ? starpart : emptypart);
                line2 += ( i % 2 != 0 ? starpart : emptypart);
        }

        for (int i = 0; i < numVelden; i++)
        {
                for (int j = 0; j < numStars; j++)
                {
                        cout << ( i%2 ? line1 : line2 ) << endl;
                }       
        }
};
</c++>

(meting met "for i in 5 50 500 5000; do echo $i:; time ./chessboard $i 5 > 
/dev/null; done")

numVelden       numStars        chessboard      chessboardoptimized
5               5               0.000           0.000
50              5               0.010           0.000
500             5               1.100           0.010
5000            5               <te lang>       0.080
50000           5               <te lang>       0.630

(dit is dus met compileroptimalisaties af op een heel modern systeem, maar 
compileroptimalisaties kunnen het probleem alleen maar uitstellen naar 
grotere aantallen op lineaire basis, terwijl deze routine exponentieel 
sneller is dan de vorige oplossing) (daarmee bedoel ik dat als je numVelden 
verdubbeld het gegeven programma er 4x langer over doet, terwijl mijn 
versie er slechts dubbel zo lang over zal doen).

Oelewapperke
Re: Oefening in C++ (schaakbord)
#4764
Author: Davy Loots
Date: Fri, 11 Jul 2003 15:54
75 lines
3997 bytes
Ge hebt volledig gelijk. Maar is dit niet wat hoog gegrepen voor iemand die
op bladzijde 43 van zijn eerste C++ boek zit?

Vriendelijke groenten,
Davy

"Oelewapperke" <Oelewapperke@wol.be> schreef in bericht
news:seiPa.14411$7h.14326@afrodite.telenet-ops.be...
> opmerking : de correcte code voor iostram te includen is
> <c++>
>         #include <iostream>
>
>         using namsepace std;
> </c++>
>
> 1 karakter per write instructie (naar de C++ libs, niet naar libc/kernel,
> ik weet het, maar het blijft 1 oproep per karakter) is crimineel
> inefficient. Verder is je programma niet goed opgesplitst (niet dat ik
> beweer dat het nodig is in dit geval, maar het is een goede gewoonte).
>
> <c++>
> void drawChessBoard(int numVelden, int numStars)
> {
>         string starpart;
>         string emptypart;
>         string line1;           // er zijn twee soorten lijnen
>         string line2;
>
>         starpart.reserve(numStars); // beperk de geheugenallocaties tot 1
>         emptypart.reserve(numStars);
>         line1.reserve(numVelden * numStars);
>         line2.reserve(numVelden * numStars);
>
>         for (int i = 0; i < numStars; i++)
>         {
>                 starpart += '*';
>                 emptypart += ' ';       // enkele aanhalingstekens roepen
de char addition op
>         }
>
>         for (int i = 0; i < numVelden; i++)
>         {
>                 line1 += ( i % 2 == 0 ? starpart : emptypart);
>                 line2 += ( i % 2 != 0 ? starpart : emptypart);
>         }
>
>         for (int i = 0; i < numVelden; i++)
>         {
>                 for (int j = 0; j < numStars; j++)
>                 {
>                         cout << ( i%2 ? line1 : line2 ) << endl;
>                 }
>         }
> };
> </c++>
>
> (meting met "for i in 5 50 500 5000; do echo $i:; time ./chessboard $i 5 >
> /dev/null; done")
>
> numVelden       numStars        chessboard      chessboardoptimized
> 5               5               0.000           0.000
> 50              5               0.010           0.000
> 500             5               1.100           0.010
> 5000            5               <te lang>       0.080
> 50000           5               <te lang>       0.630
>
> (dit is dus met compileroptimalisaties af op een heel modern systeem, maar
> compileroptimalisaties kunnen het probleem alleen maar uitstellen naar
> grotere aantallen op lineaire basis, terwijl deze routine exponentieel
> sneller is dan de vorige oplossing) (daarmee bedoel ik dat als je
numVelden
> verdubbeld het gegeven programma er 4x langer over doet, terwijl mijn
> versie er slechts dubbel zo lang over zal doen).
>
> Oelewapperke
Re: Oefening in C++ (schaakbord)
#4767
Author: Nicolas Barbier
Date: Fri, 11 Jul 2003 16:28
29 lines
2612 bytes
Oelewapperke wrote:

> (meting met "for i in 5 50 500 5000; do echo $i:; time ./chessboard $i 5
> > /dev/null; done")
> 
> numVelden       numStars        chessboard      chessboardoptimized
> 5               5               0.000           0.000
> 50              5               0.010           0.000
> 500             5               1.100           0.010
> 5000            5               <te lang>       0.080
> 50000           5               <te lang>       0.630
> 
> (dit is dus met compileroptimalisaties af op een heel modern systeem, maar
> compileroptimalisaties kunnen het probleem alleen maar uitstellen naar
> grotere aantallen op lineaire basis, terwijl deze routine exponentieel
> sneller is dan de vorige oplossing) (daarmee bedoel ik dat als je
> numVelden verdubbeld het gegeven programma er 4x langer over doet, terwijl
> mijn versie er slechts dubbel zo lang over zal doen).

Van numVelden ^ 2 naar numVelden is geen exponentiele verbetering, maar 
slechts een lineaire. Je vergeet ook mee te rekenen dat het uitschrijven 
van een string die dubbel zo lang is ook ongeveer dubbel zo lang gaat duren 
(constante overhead niet meegerekend), _als_ je ook iets nuttig met die 
string gaat doen. Bij het wegschrijven van een string naar /dev/null maakt 
het normaal gezien niet uit hoe groot de string is, dus dat is een fout in 
je benchmark. Maw de orde blijft gelijk.

-- 
Nicolas Barbier
Re: Oefening in C++ (schaakbord)
#4773
Author: Oelewapperke
Date: Fri, 11 Jul 2003 17:45
25 lines
2502 bytes
Nicolas Barbier wrote:
> Van numVelden ^ 2 naar numVelden is geen exponentiele verbetering, maar
> slechts een lineaire. Je vergeet ook mee te rekenen dat het uitschrijven
> van een string die dubbel zo lang is ook ongeveer dubbel zo lang gaat
> duren (constante overhead niet meegerekend), _als_ je ook iets nuttig met
> die string gaat doen. Bij het wegschrijven van een string naar /dev/null
> maakt het normaal gezien niet uit hoe groot de string is, dus dat is een
> fout in je benchmark. Maw de orde blijft gelijk.

Nieuwe benchmark met writen naar een file (wat erger is dan schrijven naar 
het scherm, want bij het scherm kan hij beslissen van grote hoeveelheden 
toch naar /dev/null te schrijven) : 

aantal          Normaal                 Optimized
5               0.000                   0.000
50              0.020                   0.000
500             1.090                   0.020
1000            4.460                   0.010
2000            17.780                  0.040

Het gaat erom dat er een (grote, potentieel 1 jiffie) kost geassocieerd is 
met elke methode oproep, en als je er voor elk karakter 1 doet, verlies je 
veel meer tijd dan als je er maar 1 per lijn doet.

Oelewapperke
Re: Oefening in C++ (schaakbord)
#4774
Author: Oelewapperke
Date: Fri, 11 Jul 2003 17:51
17 lines
1981 bytes
Davy Loots wrote:

> Ge hebt volledig gelijk. Maar is dit niet wat hoog gegrepen voor iemand
> die op bladzijde 43 van zijn eerste C++ boek zit?

Misschien heb je gelijk, maar het is toch veel beter dat hij zo rap 
mogelijk leert dat elke operatie een kost heeft om uit te voeren. (Gelijk 
in het echt he, het is niet omdat iemand voor de eerste keer gaat winkelen, 
dat hij een aparte rit maakt voor elk item hij wilt kopen ;-p)

Daarbij, zo heel ver ging deze optimalisatie niet, ik heb juist 2 loops 
naar buiten gebracht, die 3de kan er ook nog uit, en als je direct met 
char* en strncpy zou werken zou je beide strings in 1 geheugenplaats kunnen 
steken, en het geheel tot 1 systemcall kunnen beperken (met scatter-gather 
io), met slechts marginaal meer geheugengebruik.

Oelewapperke
Re: Oefening in C++ (schaakbord)
#4777
Author: Nicolas Barbier
Date: Fri, 11 Jul 2003 19:03
63 lines
4030 bytes
Oelewapperke wrote:

> Nicolas Barbier wrote:
> 
>> Van numVelden ^ 2 naar numVelden is geen exponentiele verbetering, maar
>> slechts een lineaire. Je vergeet ook mee te rekenen dat het uitschrijven
>> van een string die dubbel zo lang is ook ongeveer dubbel zo lang gaat
>> duren (constante overhead niet meegerekend), _als_ je ook iets nuttig met
>> die string gaat doen. Bij het wegschrijven van een string naar /dev/null
>> maakt het normaal gezien niet uit hoe groot de string is, dus dat is een
>> fout in je benchmark. Maw de orde blijft gelijk.
> 
> Nieuwe benchmark met writen naar een file (wat erger is dan schrijven naar
> het scherm, want bij het scherm kan hij beslissen van grote hoeveelheden
> toch naar /dev/null te schrijven) :

Dit zal in normale omstandigheden de orde enkel omlaag halen, wat niet het 
geval is (zie verder).

> aantal          Normaal                 Optimized
> 5               0.000                   0.000
> 50              0.020                   0.000
> 500             1.090                   0.020
> 1000            4.460                   0.010
> 2000            17.780                  0.040
> 
> Het gaat erom dat er een (grote, potentieel 1 jiffie) kost geassocieerd is
> met elke methode oproep, en als je er voor elk karakter 1 doet, verlies je
> veel meer tijd dan als je er maar 1 per lijn doet.

Aan de tekst van jou voorlaatste post te zien heb je het over orde van 
efficientie: "kunnen het probleem alleen maar uitstellen naar 
grotere aantallen". Die verandert volgens mij dus niet door jou 
optimalisatie.

Afgezien van het feit dat de orde pas bij benchmarks zichbaar wordt bij 
veel grotere getallen, kan je het wegschrijven naar een file van zulke 
kleine hoeveelheden gegevens (ze passen waarschijnlijk in je RAM) niet 
gebruiken als benchmark. Het programma beeindigt namelijk al voordat de 
gegevens echt op je schijf terecht gekomen gaan zijn.

Btw: ik vecht niet aan dat het efficienter is, enkel dat de orde van 
efficientie niet beter is (als je ervan uitgaat dat elk geoutput symbool 
minstens 1 keer gebruikt wordt om er ook daadwerkelijk iets mee te doen).

Mijn benchmark van jou code:

Alles wordt naar een willekeurige X terminal-emulator geschreven, waarvan 
ik denk dat het ongeveer lineaire tijd vraagt in het aantal karakters 
(vooral omdat er verhoudingsgewijs niet veel return-karakters bijzitten). 
De terminal bleef gedurende heel de benchmark op dezelfde positie zichbaar 
op mijn scherm. Niet erg wetenschappelijk, maar wetenschappelijker dan het 
naar een file schrijven argument IMO :-).

250     0m1.222s
500     0m5.513s
1000    0m27.067s
2000    1m52.107s

Dat lijkt mij toch wel relatief kwadratisch.

-- 
Nicolas Barbier
Re: Oefening in C++ (schaakbord)
#4354
Author: -=Bacchant=-
Date: Fri, 22 Aug 2003 18:33
49 lines
2386 bytes
euhm,

bedankt voor al jullie code, maar ik heb het ondertussen al
opgelost(jippie!) met de relatief simpele code:

#include <iostream>
using namespace std;

int main()
{ int n ;char ch ,cg,t,d;

 cout <<"Programma dat een schaakbord tekent van een ingevoerd getal en
teken"
      <<"\nGeef een getal(kleiner dan 9 voor mooi resultaat): ";
 cin >> n;
 cout <<"Geef een teken voor zwart: ";
 cin >> t;
 cout << "Geef een teken voor wit: ";
 cin >>d;

 ch = d;
 cg = ch;
 for(int c=0;c<n;c++){
   for(int k=0;k<n;k++){
     for(int y=0; y<n;y++){
       for(int x=0;x<n;x++){
  cout << ch;
       }
       (ch == t)? (ch = d): (ch = t);
     }
     cout << "\n";
     ch = cg;
   }
   (cg== t)? (cg = d):(cg = t);
   ch = cg;
 }
return 0;
}

Jullie voorbeelden zijn technisch gezien ongetwijfeld veel beter, maar zoals
de heer Loots terecht opmerkte, is dit veel te ingewikkeld voor een
beginnend C++-programmeur...

P.S: Ik vraag me af waarom ik eigenlijk nog C++ leer, iedereen lijkt het al
te kennen...

mvg,

Bacchant
Re: Oefening in C++ (schaakbord)
#4361
Author: Nicolas Barbier
Date: Sat, 23 Aug 2003 15:08
9 lines
1470 bytes
-=Bacchant=- wrote:

> P.S: Ik vraag me af waarom ik eigenlijk nog C++ leer, iedereen lijkt het
> al te kennen...

In een algemene programmeer-groep kan je moeilijk anders verwachten he :-).

-- 
Nicolas Barbier
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads