9 Replies - 2213 Views - Last Post: 19 April 2009 - 05:32 PM Rate Topic: -----

#1 Kaji  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 13
  • Joined: 07-April 09

Star Diamond

Post icon  Posted 16 April 2009 - 12:12 PM

I am teaching myself C++ out of How to Program C++ by Deitel & Deitel. In chapter two it has me do the imfamous star dimond. I to use either "*" or " " as output and maximize my use of repetition. And minimize the number of output statements. I just put my code and output in the same place.


#include <iostream>
using namespace std;

int main() {

		int i;
		int j;
		int s;
		int inc = 8;
		int dec = 5;
		int bot = 0;

		for(i = 0; i < 5; i++) {
				for(j=i; j < 4; j++) {
						cout << " ";
				}
				for(s=inc; s < 9; s++) {
						cout << "*";
				}
				cout << "\n";
				inc -= 2;
		}

		for(i = 0; i < 4; i++) {
				for(j=dec; j < 6; j++) {
						cout << " ";
				}
				for(s = bot; s < 7; s++) {
						cout << "*";
				}
				cout << "\n";
				dec -= 1;
				bot += 2;

		}
}
jester@Illusion:~/c$ ./2.58
	*
   ***
  *****
 *******
*********
 *******
  *****
   ***
	*




I got the out put correct but my question is regarding the Maximize your use of repetition. I couldn't imagine a way to do the declineing part of the dimond with out a second set of nested for loops. Share your knowledge 'ole wize D.I.C. fourm.

My out put looked better than that. I think the form screwed it up a little bit.

Is This A Good Question/Topic? 0
  • +

Replies To: Star Diamond

#2 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Star Diamond

Posted 16 April 2009 - 02:48 PM

since I have never actually DONE this before I thought I would take a stab at it:
#include <iostream>

using namespace std;

void outputDiamond(int size);

int main() {
	for (int i= 1; i < 15; i++) {
		outputDiamond(i);
	}
	return 0;
}

void outputDiamond(int size) {
	int maxline = 3 + 2 * (size - 1);
	int center =  maxline / 2;
	int linesize = 1;
	int incSize = 2;
	for (int i = 1; i<maxline*2; i+=2) {
		for (int j = 0; j < (center - linesize/2); j++) {
			cout << " ";
		}
		for (int k = 0; k < linesize; k++) {
			cout << "*";
		}
		cout << endl;
		if (linesize == maxline) { incSize = -incSize; }
		linesize += incSize;
	}
}


I think I can get rid of the 2 inner loops too... lets see:
#include <iostream>

using namespace std;

void outputDiamond(int size);

int main() {
	for (int i= 1; i < 15; i++) {
		outputDiamond(i);
	}
	return 0;
}

void outputDiamond(int size) {
	int maxline = 3 + 2 * (size - 1);
	int center =  maxline / 2;
	int linesize = 1;
	int incSize = 2;
	for (int i = 1; i<maxline*2; i+=2) {
		int theCenterPoint = (center - linesize/2);
		for (int j = 0; j < theCenterPoint + linesize; j++) {
			cout << ((j < theCenterPoint) ? " " : "*");
		}
		cout << endl;
		if (linesize == maxline) { incSize = -incSize; }
		linesize += incSize;
	}
}
That is my version maximizing use of repetition (doing the most per loop).
Was This Post Helpful? 0
  • +
  • -

#3 janotte  Icon User is offline

  • code > sword
  • member icon

Reputation: 990
  • View blog
  • Posts: 5,141
  • Joined: 28-September 06

Re: Star Diamond

Posted 17 April 2009 - 04:13 AM

Or a while loop with an if() statement to set a flag that controls whether we are incrementing or decrementing.
Was This Post Helpful? 0
  • +
  • -

#4 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Star Diamond

Posted 17 April 2009 - 09:30 AM

like so?
*edited to be completely cryptic :)
void outputDiamond(unsigned int s) {
	int ml = 1 + 2 * s, ls = 1, is = 2, i = 0, cp = (ml - ls) / 2;
	while( ls > 0 ) {
		cout << ((i < cp + ls) ? ((i++ < cp) ? ' ' : '*') : (i=0, ((ls == ml) ? is = -is : 0), ls += is, cp = (ml - ls) / 2, '\n'));
	}
}


*I don't know if I can get it much smaller...
Was This Post Helpful? 0
  • +
  • -

#5 janotte  Icon User is offline

  • code > sword
  • member icon

Reputation: 990
  • View blog
  • Posts: 5,141
  • Joined: 28-September 06

Re: Star Diamond

Posted 17 April 2009 - 07:17 PM

View PostNickDMax, on 17 Apr, 2009 - 08:30 AM, said:

like so?
*edited to be completely cryptic :)
void outputDiamond(unsigned int s) {
	int ml = 1 + 2 * s, ls = 1, is = 2, i = 0, cp = (ml - ls) / 2;
	while( ls > 0 ) {
		cout << ((i < cp + ls) ? ((i++ < cp) ? ' ' : '*') : (i=0, ((ls == ml) ? is = -is : 0), ls += is, cp = (ml - ls) / 2, '\n'));
	}
}


*I don't know if I can get it much smaller...



That's the kinda thing I was thinking of (obviously minus the crytpic stuff).
Nice work!
Was This Post Helpful? 0
  • +
  • -

#6 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Star Diamond

Posted 17 April 2009 - 10:29 PM

turns out I did get it a little shorter (though not much)

I made the following repalcement:
(i=0, ((ls == ml) ? is = -is : 0), ls += is, cp = (ml - ls) / 2, '\n')
(i=0, ls += ((ls == ml) ? is = -is : is), cp = (ml - ls) / 2, '\n')

so I have a new challenge -- I want to obfuscate the code so that the program looks something like the diamond. So far my attempts have been pretty sucky. I got this:
#include <iostream>
using namespace std;
o(int oo){int ooo=1+oo+oo,oooo=1,ooooo=2,oooooo=0,ooooooo=(ooo-oooo)/2;
while(oooo>0) {cout<<(oooooo<ooooooo+oooo?(oooooo++<ooooooo?' ':'*'):
(oooooo=0,oooo+=(oooo==ooo?ooooo=-ooooo:ooooo),ooooooo=(ooo-oooo)/2,'\n'));}
return 0;}main(){for (int oooooo=0;oooooo<20;oooooo++) {o(oooooo);}return 0;}
but so far have been unsuccessful in formatting it into a diamond. I think I am headed in the wrong direction. I was thinking that I could use macro concatenation but that requires more ()'s than I thought... anyway... the things that seems fun at 1:30am?
Was This Post Helpful? 0
  • +
  • -

#7 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Star Diamond

Posted 17 April 2009 - 11:10 PM

well... this is harder than I thought... this is what I have so far:
#include <iostream>
using namespace std;
#define oo int
#define x(y, z) y ## z
			 o
			(oo
		   ooo){
		  oo oooo
		 =1+x(ooo+
		,ooo),ooooo
	   =1, oooooo=2,
	  ooooooo=0,x(oo,
	 oooooo ) = ( oooo
	-ooooo)/2;while(x(o
   ,oooo)>0){cout<<(x(o,
   oooooo)<oooooooo+ooooo
  ?(ooooooo++<oooooooo?' '
 :'*') :(ooooooo=0,ooooo+=
  (ooooo==oooo?oooooo=-x(
   o,ooooo) : x(oo,oooo)
	),oooooooo=(x(oooo-
	 , ooooo))/2,'\n')
	  ); }  return 0
	  ;} main(){for
		(oo x(ooooo
		 ,oo=0);x(
		  ooooooo
		   <2,0)
		   ;x(
			 o

,oooooo)++){o(x(o,oooooo));} return 0;}

Was This Post Helpful? 0
  • +
  • -

#8 phixus  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 19-April 09

Re: Star Diamond

Posted 19 April 2009 - 04:03 PM

I did this program my first semester of Introduction to Programming I as an extra credit assignment. It seemed rather difficult, in fact I spent a few hours staring at the code wondering what it was I was doing correctly/incorrectly. This is what I came up with, hope it helps.
int main()  
 {  
   
	 int i , j, height;  
   
   cout<<"Enter a Height for the Diamond: ";  
		 cin>>height;  
		 cout<<endl;  
		 if ((height%2)!=0)
		 {  
			 for(i = 0; i < (height/2 + 1); i++)  
			 {  
				 for(j = i; j < (height/2); j++)	
					 cout << " ";  

				 for(j = 1; j <= (i*2 + 1); j++) 
						cout << "*";  
				 cout << endl;
			   }	  
			 
			 for(i = (height/2); i > 0; i--)  
			 {  
				 for(j = (height/2 + 1); j > i; j--)	
					 cout << " ";  

				 for(j = (i*2 - 1); j > 0; j--)  
						 cout << "*";   
				   
				 cout << endl;  
			 }  
		 }  
		 else  
			 cout<<"Height should be an Odd Number\n"; 
}


Although you may want something a bit different, this one in particular will only output when an odd integer is entered. =)

This post has been edited by phixus: 19 April 2009 - 04:04 PM

Was This Post Helpful? 0
  • +
  • -

#9 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Star Diamond

Posted 19 April 2009 - 05:13 PM

my completed obfuscation:
#include <iostream>
using namespace std;
#define oo int
#define x(y, z) y ## z


			 o
			(oo
		   ooo){
		  oo oooo
		 =1+x(ooo+
		,ooo),ooooo
	   =1, oooooo=2,
	  ooooooo=0,x(oo,
	 oooooo ) = ( oooo
	-ooooo)/2;while(x(o
   ,oooo)>0){cout<<(x(o,
   oooooo)<oooooooo+ooooo
  ?(ooooooo++<oooooooo?' '
 :'*') :(ooooooo=0,ooooo+=
(ooooo == oooo?oooooo=-x(oo
 ,oooo) : oooooo),oooooooo
  =(x(oooo-, ooooo ) )/2,
   '\n')); }  return 0;
	} main(){for(oo x(o
	 ,oooooo=0); x(oo
	  ,ooooo < 20 );
	   x(o, oooooo )
		++) { o( x(
		oooo,  ooo
		 ) ); } x
		  (retur,
		   n ) 0
		   ; }
			;


its basically the code I posted above but obfuscated. Not quite good enough for the IOCCC but still fun for me.
Was This Post Helpful? 0
  • +
  • -

#10 NickDMax  Icon User is offline

  • Can grep dead trees!
  • member icon

Reputation: 2250
  • View blog
  • Posts: 9,245
  • Joined: 18-February 07

Re: Star Diamond

Posted 19 April 2009 - 05:32 PM

this is the source code made readable (and without the ?: operator):
#include <iostream>
using namespace std;
void outputDiamond(unsigned int s) {
	int maxline = 1 + 2 * s, linesize = 1, incSize = 2, i = 0, theCenterPoint = (maxline - linesize) / 2;
	while( linesize > 0 ) {
		if (i < theCenterPoint + linesize) {
			if (i++ < theCenterPoint) { cout << ' '; } else { cout << '*'; }
		} else {
			i=0;
			if(linesize == maxline) { incSize = -incSize; }
			linesize += incSize;
			theCenterPoint = (maxline - linesize) / 2;
			cout << '\n';
		}
	}
}

int main() {
	for (int i = 0; i < 20; i++) {
		outputDiamond(i);
	}
	return 0;
}

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1