Stanford CS106A Assignment 2 Pyramid Solution

31 Oct

The pyramid problem in Assignment 2 is actually pretty difficult for beginners, so I recommend you do the Target problem first. If you were able to figure out the Target problem, move on to this one. Be warned though, this one takes some time to figure out. Here is the problem:

Here is my solution, which you can also find on github:


The key here is to create 2 loops, one for the height part of the pyramid, and one for the width. The height-based loop needs to start with one, while the width-based loop can start with 0. I found it helpful by first writing out the code manually for the first 3 rows that needed to be built and then figuring out the small differences, after which I started over and created the two loops.

<pre>/*
 * File: Pyramid.java
 * Name: 
 * Section Leader: 
 * ------------------
 * This file is the starter file for the Pyramid problem.
 * It includes definitions of the constants that match the
 * sample run in the assignment, but you should make sure
 * that changing these values causes the generated display
 * to change accordingly.
 */

import acm.graphics.*;
import acm.program.*;
import java.awt.*;

public class Pyramid extends GraphicsProgram {

/** Width of each brick in pixels */
	private static final int BRICK_WIDTH = 30;

/** Width of each brick in pixels */
	private static final int BRICK_HEIGHT = 12;

/** Number of bricks in the base of the pyramid */
	private static final int BRICKS_IN_BASE = 14;

	public void run() {
		putAllBricks();
	}
	private void putAllBricks()
	{
		//row - 0-based index of the row 
		//row+1 - The 1-based index of the row
		//brickNum - 0-based index of the brick

		//Loop through the 0-based index of the rows
		for( int row = 0; row &lt; BRICKS_IN_BASE; row++ )
		{
			int bricksInRow = BRICKS_IN_BASE - row;

			//
			// Total number of bricks = row
			//
			for( int brickNum = 0; brickNum &lt; bricksInRow; brickNum++ )
			{
				//1. Calculate the center
				//2. Calculate the starting point based on the center
				//3. Add the number of bricks * brick width to find this brick's location
				int x = ( getWidth()/2 ) - (BRICK_WIDTH * bricksInRow) / 2 + brickNum * BRICK_WIDTH;

				// 
				// Calculate the vertical location of the brick based on the row
				//
				int y = getHeight() - BRICK_HEIGHT * (row+1);

				//
				// Draw the brick
				//
				GRect brick = new GRect( x , y , BRICK_WIDTH , BRICK_HEIGHT );
				add(brick);
			}
		}
	}
}</pre>
Advertisements

32 Responses to “Stanford CS106A Assignment 2 Pyramid Solution”

  1. thegympress March 22, 2012 at 3:32 pm #

    can you explain a little better how the bricks are draw in from the center. for example for brickN in the base, the x and y are still the top left corner right? but if you have found the center of the base for the pyramid how are bricks draw on the left side ? (does that make sense?

    Woudl really appreciate it.

    • Natasha Murashev March 22, 2012 at 9:49 pm #

      I did this a while ago, and am not sure how to answer your question. Try copying and pasting the code and see how the bricks are drawn. Then try to replicate on your own πŸ™‚

  2. thegympress March 23, 2012 at 10:07 am #

    Thanks, good idea.

  3. Valentin March 27, 2012 at 3:07 pm #

    This is my solution to the problem…can anyone care to comment, suggest improvements..

  4. Holly April 13, 2012 at 5:36 pm #

    Hmmm, I came up with a much different solution, that I think is simplier then yours, trying to figure out how github works so I can post a link to see what you think…will post once I figure it out! πŸ™‚

    • Natasha Murashev April 13, 2012 at 5:43 pm #

      Great! I love when people come up with better solutions than mine πŸ™‚ Feel free to also just copy and paste the code in the comments here!

      • Holly April 13, 2012 at 5:50 pm #

        Thanks Natasha, see below. Interested to hear your thoughts (or anyone else’s), as to whether you think it’s a simpler solution or not (maybe it just a different solution!). πŸ™‚

        public class Pyramid extends GraphicsProgram {
        
        /** Width of each brick in pixels */
        	private static final int BRICK_WIDTH = 30;
        
        /** Width of each brick in pixels */
        	private static final int BRICK_HEIGHT = 12;
        
        /** Number of bricks in the base of the pyramid */
        	private static final int BRICKS_IN_BASE = 14;
        	
        	public void run() {
        		pyramidBricks();
        		
        	}
        	private void pyramidBricks(){
        		int numOfBricks = BRICKS_IN_BASE;
        		int numOfRows = BRICKS_IN_BASE;
        		double y = getHeight() - BRICK_HEIGHT;	
        		while (numOfRows &gt; 0) {
        			double x = (getWidth()/2) - ((numOfBricks*BRICK_WIDTH)/2);		
        				for (int i = numOfBricks; i &gt; 0; i--) {
        					GRect brick = new GRect(x, y, BRICK_WIDTH, BRICK_HEIGHT);
        					add(brick);
        					x +=BRICK_WIDTH;
        		}
        				numOfBricks--;
        				numOfRows--;
        				y -= BRICK_HEIGHT;
        		
        			
        		}
        		
        	}
        }
        
      • Holly April 13, 2012 at 8:27 pm #

        > should be the ‘greater then’ symbol, not sure why it doesn’t display correctly here…

      • Holly April 13, 2012 at 8:28 pm #

        Ack, ok, that didn’t work! Now I’m seeing the correct symbol, I’ll try once more ‘>’ should be the ‘greater then’ (>) symbol.

      • Holly April 13, 2012 at 8:30 pm #

        Ack, still didn’t work, I’ll try this, then I’ll stop (hoping this displays with the correct symbol rather then the html code for the symbol):

        while (numOfRows > 0)
        for (int i = numOfBricks; i > 0; i–)

      • Natasha Murashev April 14, 2012 at 6:20 pm #

        Holly, this looks really similar to my code πŸ™‚ You just used a while loop instead of a for loop for one of the loops. I think mine looks a lot more complicated than it is because I put so many comments in it.

  5. Sung Wook Choi April 24, 2012 at 10:59 am #

    Can you help me out with this???
    I have tried to solve pyramid assignment which you completed.
    But I can’t figure out what is wrong with my codes…
    So could you look over and give me some advice??

    
    import acm.graphics.*;
    import acm.program.*;
    
    public class Pyramid extends GraphicsProgram {
    	
    	private static final int Brick_Width = 30;
    	private static final int Brick_Height = 12;
    	private static final int Bricks_In_Base = 14;
    	public void run() {
    		// You fill this in
    		int ctrX = getWidth()/2;
    		int row = Bricks_In_Base;
    		int bricks = Bricks_In_Base;
    		int startY = getHeight()-Brick_Height; //first position of point Y
    		int startX = ctrX-Brick_Width*(Bricks_In_Base/2);//first position of point X
    		for(int j=0;j&lt;row;j++){              /*change row*/
    			int Y=startY+j*(Brick_Height);
    			int X1=startX+j*(Brick_Width/2);
    			for(int i=0;i&lt;bricks;i++){       /*change bricks number*/
    				int X2=X1+i*(Brick_Width);
    				GRect Pyramid=new GRect (X2, Y,Brick_Width,Brick_Height);
    				add(Pyramid);
    			}
    			bricks--;   //change bricks number
    		}
    	}
    }
    
    • Sung Wook Choi April 24, 2012 at 11:52 am #

      oh I found it ~~!!!! I’m sorry ^^;;

  6. ladeer May 21, 2012 at 2:03 am #

    Hi Natasha,
    I am a complete noob to programming/java and struggle to learn it via Stanford’s SEE course. I am extremely grateful for your site providing solutions to the assignments. This really helps me to learn and see what I did wrong/right.
    Here is my solution to the problem. I feel your code is much better than mine, because I declared my variables called x_coor and y_coor outside of the loop, while you declare your x_coor and y_coor (for each rectangle) in the heart of your loop. Essentially I set up the first rectangle’s initial value (the x/y coordinate of the very first rectangle of the bottom row) outside of the loop, then start drawing one by one from left to right, bottom to up. i just feel my code better reflects my thought process, and struggle to write more succinct code like yours that seems counter intuitive to my way of thinking.
    Do you know what I mean? Shall we always strive to write the most succinct code instead of code that reflect our brain?

    public void run() {
    		int canvas_h = getHeight();
    		int canvas_w = getWidth();
    		int y_coor = canvas_h - BRICK_HEIGHT;
    		int x_coor = (canvas_w / 2) - ((BRICKS_IN_BASE*BRICK_WIDTH) / 2);
    		int brick_count = BRICKS_IN_BASE;
    				
    		while (brick_count &gt; 0)
    		{ 
    		
    			for (int i = 0; i &lt; brick_count; i++)
    			{
    				add(new GRect(x_coor, y_coor, BRICK_WIDTH, BRICK_HEIGHT));
    				x_coor = x_coor + BRICK_WIDTH;
    			}
    
    			brick_count = brick_count - 1;
    			x_coor = (canvas_w / 2) - ((brick_count*BRICK_WIDTH) / 2);
    			y_coor = y_coor - BRICK_HEIGHT;
    		}
    
    • Natasha Murashev May 21, 2012 at 6:56 am #

      Hi Ladeer,

      In this case, your code is probably better than mine because I write out your x_coor and y_coor variables 2 times, while you write it out once and just use the simplified x_coor and y_coor version, saving yourself the extra work or rewriting. The only thing I would say is to make sure you have clear comments in your code to clarify what x_coor and y_coor means.

      The best programmers are lazy – this means they figure out clever ways to write the least code.

      Keep up the great work!
      Natasha

  7. Marcus May 29, 2012 at 9:09 am #

    Hi Natasha,

    Your site looks like an excellent resource. I noted your link to the Ruby On Rails course with interest.

    There are lots of germinal coders out there, so I am sure you could provide a great hub, if you felt like starting a Google group or something….oh, here’s my solution…

    
    /*
     * File: Pyramid.java
     * ------------------
     * This program is a stub for the Pyramid problem, which draws
     * a brick pyramid.
     */
    
    import acm.program.*;
    import acm.graphics.*;
    
    /* This class draws a pyramid built of uniformly sized bricks  
     */
    
    public class Pyramid extends GraphicsProgram {
    
    	/*The width of each brick in pixels */
    	 private static final int BRICK_WIDTH = 30;
    
    	/*The height of each brick in pixels*/
    	private static final int BRICK_HEIGHT = 12;
    
    	/* The number of bricks in the base */
    	private static final int BRICKS_IN_BASE = 14;
    
    /* runs program*/
    public void run() {
    	
    		for (int h = 0; h &lt; BRICKS_IN_BASE; h++)
    		{
    				for (int i = 0; i &lt; BRICKS_IN_BASE + (-h); i++)
    				{
    					int k = i * BRICK_WIDTH;
    					int m = h * BRICK_HEIGHT;
    		int x = ((getWidth() - ((BRICKS_IN_BASE + (-h)) * BRICK_WIDTH)) / 2) + k;
    		int y = getHeight() - ((BRICK_HEIGHT + 1) + m);
    		GRect brick = new GRect (x, y, BRICK_WIDTH, BRICK_HEIGHT);
    		add(brick);
    			}
    		}				
    	}	
    }
    
    • Natasha Murashev May 29, 2012 at 10:00 am #

      Thanks! Now that I’m able to build stuff, I’ll think of something to help everyone.

  8. marcus May 29, 2012 at 1:16 pm #

    Good stuff…what do you have in mind?

    in the code examples, less than, (the v on its side) , ‘ < ' , is coming out as ' < '

  9. marcus May 29, 2012 at 1:17 pm #

    I mean < is coming out as <

  10. marcus May 29, 2012 at 1:18 pm #

    lol…ok, I am losing this battle with html, or whatever it is

    < is coming out as & l t ;

    • Natasha Murashev May 29, 2012 at 4:06 pm #

      Haha, no worries. That’s just how it formats the less than and greater than signs.

      Maybe I’ll create a Stackoverflow for beginners + a list of resources or something? Will think about this.

  11. zyxsch July 14, 2012 at 3:26 pm #
    /*
     * File: Pyramid.java
     * Name: 
     * Section Leader: 
     * ------------------
     * This file is the starter file for the Pyramid problem.
     * It includes definitions of the constants that match the
     * sample run in the assignment, but you should make sure
     * that changing these values causes the generated display
     * to change accordingly.
     * 
     * 
     * This one was done on 14.7.2012 by Maciek Grischke - twitter.com/_zyx
     */
    
    import acm.graphics.*;
    import acm.program.*;
    import java.awt.*;
    
    public class Pyramid extends GraphicsProgram {
    	
    /** Width of each brick in pixels */
    	private static final int WIDTH = 28;
    
    /** Width of each brick in pixels */
    	private static final int HEIGHT = 11;
    
    /** Number of bricks in the base of the pyramid */
    	private static final int BRICKS_IN_BASE = 14;
    	
    /**useless */
    	private static final int STEP = 0;
    	
    /** pause time in ms - so you can see the animation */
    	private static final int PAUSE_TIME = 250;
    	
    	public void run() {
    		int baseCenter = getWidth() - ((BRICKS_IN_BASE / 2) * WIDTH); /* baseCenter is where the first brick on the left appears */
    		int bottom = getHeight() - HEIGHT; /* bottom is to get the size of the window vertically, minus the height of the brick */
    		int brix = 14; /* a number for the loop of the main FOR - also required for 'step' */
    		for (int bricks = 14; bricks &gt;= 1; bricks--) { 
    			for (int step = 1; step &lt;= brix; step++) {
    				add(new GRect(baseCenter,bottom,WIDTH,HEIGHT)); /* this places the brick on the left at the bottom */
    				baseCenter += WIDTH; /* this moves the baseCenter one WIDTH horizontically, to the right, 28 pixels in this case */
    				pause(PAUSE_TIME); /* again, this is so you can see the animation πŸ˜‰ */
    			}
    			brix -= 1; /* minus one brick/loop/ */
    			baseCenter -= ((brix * WIDTH) + (WIDTH / 2)); /* moves baseCenter-the point where the new brick starts on each row-half the WIDTH - 14 pixels */
    			bottom -= HEIGHT; /* moves one row up */
    		}
    	}
    }
    
  12. zyxsch July 14, 2012 at 3:29 pm #

    Sorry, coding is great πŸ˜€

    Here is my code here as well http://pastie.org/private/ppm9bchd7oujvni9fczmq

  13. A. Sengor July 16, 2012 at 12:40 pm #

    What do you think of this solution? I wanted to code it as simple as possible.

    	public void run() {
    		for (int j=BRICKS_IN_BASE;j&gt;=1;j--) {
    			for (int i=0;i&lt;j;i++) {
    				double cx = getWidth()/2 - ((double)j/2)*BRICK_WIDTH;
    				double cy = getHeight()-BRICK_HEIGHT;
    				double dx = BRICK_WIDTH;
    				double dy = BRICK_HEIGHT;
    				cx = cx + i*dx;
    				cy = cy - Math.abs(j-BRICKS_IN_BASE)*dy;
    				GRect brick = new GRect(cx,cy,BRICK_WIDTH,BRICK_HEIGHT);
    				add (brick);
    				pause(30);
    			}	
    		}
    	}	
    	
    	private static final int BRICK_WIDTH = 30;
    	private static final int BRICK_HEIGHT = 12;
    	private static final int BRICKS_IN_BASE = 14;
    }
    
    

    After thinking for half an hour why it was building a whole brick's width to the right on every stage instead of half, I just figured that the cast (double) was missing in cx declaration line. Wasn't it supposed to be unnecessary if the value is not losing information? (Beginning of CS106A Lecture 7 by Mehran Salami) It seems that, if the operation (here, division) in which the integer is an operand loses information, you should also cast it.

    • A. Sengor July 17, 2012 at 2:27 am #

      Comparison operators in for loops don’t show in the upper code. Just replace “&gt” with greater sign and “&lt” with less than sign.

  14. Casius September 10, 2012 at 9:53 pm #

    Man oh man, this stuff makes my head explode a bit. I have not finished the assignment on my own and I wouldn’t dare post my code out of shame. I am mostly writing this because I’m starting to feel that I just don’t have the brains for this.

    I am also following the free Stanford course and I think it’s great, I feel giddy when I think of the possibilities of learning to code but there’s only so much ‘head vs wall’ I can take before I feel completely demoralized. I used to be smart but that was so damn long ago I think my brain is just mush by now. I guess my main issue with my ‘progress’ so far is that even though I push my way from assignment to assignment I just don’t understand the ‘method to the madness’. My code is so rudimentary, primitive and long by the time I’m done with an assignment. Then I read other people’s answers and it blows my mind to see the simpler way that everyone else comes up with.

    Guess my question is if maybe this is not for everyone, regardless of how much ‘hard work’ you invest into it.

    • Natasha Murashev September 11, 2012 at 7:35 am #

      Casius,

      You can do it!!!!!! Keep in mind that the Stanford course is a weeder course. The assignments are hard b/c they’re trying to weed out the weaker CS students (not sure how this benefits anyone).

      After you finish the breakout game assignment, they get a lot easier. I also almost gave up more than a few times, but that’s the easy answer. I got help online and from friends and was able to power through it. I’m glad I did, b/c I now absolutely LOVE coding.

      If you’re looking for a simpler course meant for online learning and with a community you can reach out to, check out Udacity.com and Coursera.com.

      Just the fact that you’ve gotten this far shows a lot about your tenacity. I started a group of 45 people when I first started to learn to code, and only about 5 people actually made it past the downloading Eclipse part of the course, and I think only 1 person even made it to Assignment2. So you’re doing an amazing job whether you think so or not.

      This stuff is hard, but it is also one of the most rewarding things you’ll do for yourself. If it was easy, everyone would do it. You’re not alone in feeling this way!!!!! The internet is only documenting people who made it, there are 100s if not 1000s of people who gave up for every person who made it this far.

      • Casius September 11, 2012 at 8:23 am #

        Hey Natasha,

        Thanks for your reply, I was really overwhelmed when I wrote my post but your reply gave me some much needed perspective.

        I knew learning how to code would be hard but at at times I think I just get myself lost in the shuffle. I just found the link to the book used in the class so I hope that helps me fill the gaps.

        Anyhow thanks again for your reply, it was exactly what I needed to hear.

        P.S. love the blog, specially the entry where you mention gaining employment as a software engineer. Very inspirational.

      • Natasha Murashev September 11, 2012 at 8:49 am #

        HI Casius,

        Nice to hear you’ll keep learning! Check out the CS106A resources I have listed on the sidebar, specifically the CS106A Wiki I made: https://github.com/NatashaTheRobot/Stanford-CS-106A/wiki/Stanford-Introduction-To-Computer-Science-Programming-Methodology-CS106A-Class-Guide.

        Also, here’s my full journey of learning: http://www.women2.com/how-i-learned-to-code/. As you can see, I’ve definitely quit a few times, but having a community has really helped me keep going!

  15. errec March 26, 2016 at 6:03 pm #

    import acm.graphics.*;
    import acm.program.*;

    public class Pyramid extends GraphicsProgram {

    public void run() {
    // You fill this in

    int H = 12;
    int L = 30;
    int X = 150;
    int Y = 60;
    int cont1 = 5;

    while(cont1 >= 0){

    int cont2 = cont1;
    int cont3 = cont1;

    while(cont2 >= 0){

    GRect BlocksLeft=new GRect (X+L/2*(-1)*cont2, Y+H*cont3 ,L,H);
    add(BlocksLeft);

    GRect BlocksRight=new GRect (X+L/2*cont2, Y+H*cont3 ,L,H);
    if(cont2 != 0){
    add(BlocksRight);
    }
    cont2 = cont2 – 2;
    }
    cont1–;
    }
    }
    }

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s