Monday, August 15, 2011

CS106A Programming Methodology Problem Solutions: Assignment 1

EDIT: Source code files now available for download!
For the full assignment problem descriptions, click here.

Assignment one has four problems, and to be honest none of them is hard. Still, it took me quite a long time to complete all of them, for there were such strict restrictions on the operators and programming structures that I could use. For instance, I wasn't even allowed to have variables, do-while loops, or the ! and && operators! As a result, some of the solutions weren't as neat as they could have been.

 Anyway, here are my solutions to the problems:
 Problem 1: Collect Newspaper Karel (CollectNewspaperKarel.java)



This problem is extremely simple. As shown in the image above, you basically have to write a program that will let Karel pick up the beeper and return to his orginial position. The world will always be the same, so there's no need to include any if structure at all. Just a straight-forward program that directly tells Karel what to do.
import stanford.karel.*;

public class CollectNewspaperKarel extends SuperKarel {

 public void run() {
   moveToNewsPaper();
   pickUpNewsPaper();
   returnToStartingPoint();
  
 }
 
 //Karel picks up the newspaper
 private void pickUpNewsPaper() {
  pickBeeper();

 }
  
 //Karel returns to original position
 private void returnToStartingPoint() {
  turnAround();
  for (int i=0; i<3; i++) {     move();   }      turnRight();   move();   turnRight();     }    //Karel exits the room and gets to the newspaper  private void moveToNewsPaper() {   turnRight();   move();   turnLeft();      for (int i=0; i<3; i++) {     move();   }     }  }  


Problem Two: Stone Mason Karel (StoneMasonKarel.java)


This problem is also very straight-forward. You basically have to create a program that will make Karel fill up the columns (i.e., 1,5,9,13...).
import stanford.karel.*;

public class StoneMasonKarel extends SuperKarel {

 public void run() {
  repairCurrentColumn();
  while (frontIsClear()){
   repairNextColumn();
  }
 }

//Pre-condition: Karel is at the upper-end of a column, facing North
//Post-condition: Karel is at the lower-end of a column, facing east
public void backToOriginalPosition(){
  turnAround();
  while(frontIsClear()){
   move();
  }
  turnLeft();
}

//Pre-condition: Karel is at the lower-end of a column that may needs to be repaired, facing east
//Post-condition: Karel is at the same position, and the entire column is repaired
public void repairCurrentColumn (){
  turnLeft();
 
  while (frontIsClear()){
   if (noBeepersPresent()){
    putBeeper();
   }
   move();
  }
  //This is to repair the last bit of the column
  if (noBeepersPresent()){
   putBeeper();
  }
 
  backToOriginalPosition();
 
}

/*Pre-condition: Karel is at the lower-end of a certain column that has already
  been repaired, and there is an unrepaired column to the right
 *Post-condition: Karel is has moved to and repaired the adjacent column that is
  east of that certain column, and is at the lower-end of it
 */
public void repairNextColumn(){
  goToNextColumn();
  repairCurrentColumn();
}

//Pre-condition: Karel is facing east, at the bottom on a column, and there is another
//column to the right
//Post-condition: Karel has moved eastward, onto the next column
public void goToNextColumn(){
  for (int i=0; i<4; i++){
   move();
  }
}
}



Problem 3: Checkerboard Karel (CheckerboardKarel.java)


For this problem, you have to create a checker pattern for any given world (even a 1*1 square). Took me a little while to figure out how to decompose this problem.
import stanford.karel.*;

public class CheckerboardKarel extends SuperKarel {

 public void run() {
  finishRow();
  while (frontIsClear()){ //If there's a next row, then finish that row
   goToNextRow();
   if (frontIsClear()){ //In case that the world is a one column-world
    finishRow();
   }
   
  }
   
 }
 
 //Pre-condition: Karel is at a square where a beeper needs to be in place
 //Post-condition: The whole row that the square is in is now completed.
 public void finishRow(){
  putBeeper();
  
  //Put down a beeper every other step
  while (frontIsClear()){
   move();
   
   //If structure in place to ensure that
   //Karel doesn't run into a wall
   if (frontIsClear()){
    move();
    putBeeper();
   }
  }
  faceNorth();
 }
 
 //Pre-Condition: Karel is facing east or west
 //Post-Condition: Karel is facing north
 public void faceNorth (){
  if (facingEast()){
   turnLeft();
  }
  else{
   if (facingWest()){
    turnRight();
   }
  }
 }
 
  //pre-condition: Karel is facing north, with at least
  //a wall beside it
 
  //Post-Conidtion: Karel is facing east or west, with a wall
  //right behind it
                   
 public void turn (){
  
  //The following assignment
  if (leftIsClear()){
   turnLeft();
  }else{
   turnRight();
  }
 }
   
    
  
 
 
 //Pre-condition: There is at least one row above the row that Karel is currently in
 //Post-condition: Karel has moved onto the next row, to a space that needs a beeper
 //                (Exception: when it is in a one-column world, he may move by two rows
 //                instead)
 
 //How this method works:
 //Suppose Karel is at point K. If there is a beeper at point K, Karel will move to
 //point X. Otherwise, it will move to point Y
 //...........XY
 //............K
 
 public void goToNextRow(){
  if (noBeepersPresent()){
   move();
   turn();
  }
  else{
   move();
   turn();
   
   /*If this condition is not satisfied, it means that the world is only
   one-column wide. In this case, Karel will move onto the next available row
   (if there is one)*/
   if (frontIsClear()) {
    move();
   }
   else{
    //Move onto the next row if there is one
    faceNorth();
    if (frontIsClear()) {
     move();
    }
    
   }
    
  }
 }

}



Problem Four: Midpoint Finding Karel (MidpointFindingKarel.java)


The goal of this program is to be able to let Karel find and stop at the midpoint of any given width. The first time it took me more than 1.5 hours to finish all the coding, so I was beyond miserable when the whole file got accidentally deleted. Fortunately, the second time it only took me about 10 to 15 minutes.
import stanford.karel.*;

public class MidpointFindingKarel extends SuperKarel {
//My algorithm is quite simple. running the program and reading the comment lines
//should be enough for you to understand
 
public void run() {
  layBeepers(); //Put one beeper in each square in the row
  cleanUpBeepers(); //Alternately remove one beeper from each end. This way Karel will
         //be removing the beeper at the middle square last
  putBeeper(); //Put one beeper back in the middle square

}

//Put one beeper in each square of the row
public void layBeepers(){
  putBeeper();
  while (frontIsClear()){
   move();
   putBeeper();
  }
  turnAround(); //Turn around so that Karel is facing the center
}

//Only move if front is clear
public void moveIfSafe(){
  if(frontIsClear()){
   move();
  }
}

//Pre-condition: Karel is facing west or east
//Post-condition: Karel is facing south
public void turnSouth(){
  if(facingEast()){
   turnRight();
  }else{
   turnLeft();
  }
 
}

//Turn around, move one space (if possible), and then pick up the beeper (if possible)
public void turnAroundAndPickBeeper(){
  turnAround();
  moveIfSafe();
  if (beepersPresent()){
   pickBeeper();
  }
}

//The purpose of this method is basically to let Karel pick up a beeper from the opposite end
public void pickUpEndBeeper(){
  while (beepersPresent()){//Karel keeps walking until there isn't a beeper at his
                        //location or until he reaches the wall
   if (frontIsClear()){
    move();
   }
   else{
    pickBeeper();
    turnSouth();//Turning south is a signal for "already picked up a beeper)
   }
  }
 
  if (frontIsClear()){
   turnAroundAndPickBeeper();//Turn around and pick up the beeper located at the end
  }
  else{
   if (facingSouth()) //If Karel has already picked up a beeper, then he will
                   //simply change direction
   {
    faceCenter();
   }
   else{
    turnAroundAndPickBeeper();//If not, he will pick up the beeper at the end
   }
   
  }
  
}

//Let Karel face the center
public void faceCenter(){
  if (rightIsClear()){
   turnRight();
  }else{
   turnLeft();
  }

 
}

//Karel alternately picks up a beeper from each end. Eventually, Karely will stop at the
//middle square
public void cleanUpBeepers(){
  while (notFacingSouth()){
  
   pickUpEndBeeper();
   moveIfSafe();
   if (noBeepersPresent()){//If this is satisfied, it means that all beepers have been
                        //cleared
    //Move back to the middle square:
    turnAround();
    moveIfSafe();
    turnSouth();//Since no variable can be used, facing south is the only way
                //to break out of the while loop
   }
  }
 
}
}

Comments (15)

Loading... Logging you in...
  • Logged in as
KarelTheRobot's avatar

KarelTheRobot · 624 weeks ago

Pretty good guide, the code you wrote for assignment 3 was quite genius! I would have never thought to check the last cell in a row to see if Karel put a beeper there already (for the odd-dimensioned worlds).

However I noticed you have a lot of unnecessary code in your MidpointFindingKarel class-- for instance, all of the code you added about solving the case of the first beeper placed in the world that is right up against the lefthand wall can be solved by simply replacing the putBeeper(); method at the beginning of your layBeepers(); method with a move(); method and switching the order of the putBeeper(); and move(); methods inside the while loop of that function. That way, both corners of the world will never have a beeper in them and you don't even need to account for that case. For anyone who's interested, here's my entire source code, which totals 41 lines (I removed the comments for sake of brevity):

import stanford.karel.*;

public class MidpointFindingKarel extends SuperKarel {

public void run() {
fillRowWithBeepers();
while (noBeepersPresent()) {
move();
moveToLastBeeper();
pickUpLastBeeper();
}
}

private void fillRowWithBeepers() {
move();
while (frontIsClear()) {
putBeeper();
move();
}
turnAround();
}

private void moveToLastBeeper() {
while (beepersPresent()) {
if (frontIsClear()) {
move();
}
}
turnAround();
move();
}

private void pickUpLastBeeper() {
if (beepersPresent()) {
pickBeeper();
} else {
putBeeper();
}
}
}
1 reply · active 622 weeks ago
the original post was 2011 .....but the comment/reply is 1 week ago!!!! Can that be? Im doing this course for fun and really enjoying it!!! Would be great to know if there was someone else out there to chat with.
Damo
Just started taking the course through Itunes U. Good to meet someone going through the course to bounce ideas and problems off of. (wish there were more).
Comment back when you have a minute.
....just wondering if you're still active on this page.
I am also taking this class on iTunes U. This has been very helpful for figuring out assignment 3. Thank you for posting this.
Done this course and its real good but let me give you some advise, as a 3 year veteran(lol), persist with it and do it yourself, forget other peoples code, if its tough walk away for a while, its so important that you find the coder inside.
Homer J Simpson
Straightforward's avatar

Straightforward · 597 weeks ago

My problem#3 solution:

import stanford.karel.*;

public class CheckerboardKarel extends SuperKarel {

public void run() {
oddLineDraw();

while(leftIsClear()){
moveUp();
evenLineDraw();
if(leftIsClear()){
moveUp();
oddLineDraw();

}

}

}
private void moveUp(){
turnLeft();
move();
turnRight();

}

private void backStart(){
turnAround();
while(frontIsClear()){
move();
}
turnAround();
}

private void oddLineDraw(){
putBeeper();

while(frontIsClear()){
move();

if(frontIsClear()){
move();
putBeeper();
}

}
backStart();

}

private void evenLineDraw(){

while(frontIsClear()){
move();
putBeeper();

if(frontIsClear()){
move();
}

}
backStart();

}

}
@straigthforward: does your solution also work in a 1x8 box?
1 reply · active 591 weeks ago
My solution works in 1x8, but the rule is that it has to be a square, 5x5, 8x8, 7x7, etc
//This is my solution fot Assigment 1 - 3

import stanford.karel.*;

public class MidpointFindingKarel extends SuperKarel {

public void run() {
turnLeft();
reachMiddle();
getDown();
putBeeper();
}

public void reachMiddle() {

while (frontIsClear()) {
move();
if(frontIsClear()) {move();}
turnRight();
if(frontIsClear()) {move();}
turnLeft();
}

}

public void getDown() {
turnAround();
while(frontIsClear()) {
move();
}
}
}
this is my solution for assignment 1 midpoint finding karel

import stanford.karel.*;

public class MidpointFindingKarel extends SuperKarel {

public void run () {

int count=0;// variable for counting the number of avenues

// move horizontally while incrementing count by 1
while (frontIsClear()){
move();
count++;
}// end while

turnAround();// turn around to face the opposite direction
count/=2;//gets the midpoint by dividing count by 2

//moves forward while decrementing count to end up at the center
while (count!=0){
move();
count--;
}

//puts beeper in the center if there are no beepers present
if (noBeepersPresent()){
putBeeper();
}

}// end run

}// end class
I just started out from the video lecture and with the handouts from CS106A site... just like to share, I know im still newbie and would like to hear from you guys what are your thoughts. Honestly, I havent looked at the solution poste.

/*
* File: CheckerboardKarel.java
* ----------------------------
* When you finish writing it, the CheckerboardKarel class should draw
* a checkerboard using beepers, as described in Assignment 1. You
* should make sure that your program works for all of the sample
* worlds supplied in the starter folder.
*/

import stanford.karel.*;

public class CheckerboardKarel extends SuperKarel {

public void run (){
while ( frontIsClear() ){
fillOddAvenue();
}
}

public void fillOddAvenue() {
if (beepersPresent()){
move();
turnRight();

while (frontIsClear()) {
move();
putBeeper();

if (frontIsClear()){
move();
}
}

} else {
while (frontIsClear()) {
move();
putBeeper();

if (frontIsClear()){
move();
}
}
// turnLeft();
}
if (!frontIsClear() && leftIsClear() )
fillEvenAvenue();
}

public void fillEvenAvenue() {
if (beepersPresent() ){ // we have an even column
turnLeft();
move();
turnLeft();
while (frontIsClear()) {
move();
putBeeper();

if (frontIsClear()){
move();
}
}
turnRight();
} else { //no beeper so it means we have an odd column
if (leftIsClear()){
turnLeft();
move();
turnLeft();

while (frontIsClear()) {
putBeeper();
move();
move();
}
}
putBeeper();
turnRight();
}
}

}
Hi thanks for this site first of all, I am sure more people like me are checking out this site for answers here and there. So this is my solution for Assignment 3, since that took me a long time to figure out.

import stanford.karel.*;

public class CheckerboardKarel extends SuperKarel {

public void run() {
placeBeeperEveryOtherSpot();
while (leftIsClear()){
makeWestUTurn();
placeBeeperEveryOtherSpot();

if (rightIsClear()){
makeEastUTurn();
placeBeeperEveryOtherSpot();
} else {
turnAround();
}
}
}

private void placeBeeperEveryOtherSpot() {

putBeeper();
move();

while (frontIsClear()) {
move();
putBeeper();
move();
}

}

private void makeWestUTurn() {

turnLeft();
move();
turnLeft();

}

private void makeEastUTurn() {

turnRight();
move();
turnRight();

}

}
3 replies · active 396 weeks ago
Sorry I spoke to soon it's still wrong :(.
I think this code should finally work, that was not as easiest as I would think it would be.

/*
* File: CheckerboardKarel.java
* ----------------------------
* When you finish writing it, the CheckerboardKarel class should draw
* a checkerboard using beepers, as described in Assignment 1. You
* should make sure that your program works for all of the sample
* worlds supplied in the starter folder.
*/

import stanford.karel.*;

public class CheckerboardKarel extends SuperKarel {
// Karel will put a beeper(diamond) in every other spot on a blank canvas of any size.
public void run() {

placeBeeperEveryOtherSpot();

}

private void placeBeeperEveryOtherSpot() {

while (frontIsClear()) {

putBeeper();
move();

if (facingEast())
if (frontIsBlocked()) {
if (noBeepersPresent())
makeUTurnWest();
}

if (facingWest())

if (frontIsBlocked()) {
if (noBeepersPresent())
makeUTurnEast();
}
move();
if (frontIsBlocked()) {

makeOddUTurnWest();

}
}

}
// Karel makes a U-Turn to head west and place beepers, when blocked to the east.
private void makeUTurnWest() {

turnLeft();
move();
putBeeper();
turnLeft();
move();

}
// Karel makes a U-Turn to head east and place beepers, when blocked to the west.
private void makeUTurnEast() {

turnRight();
move();
putBeeper();
turnRight();
move();

}

// Karel makes a U-Turn to head west and place beepers, when blocked to the east, on a odd numbered checkerboard.
private void makeOddUTurnWest() {

putBeeper();
turnLeft();
move();
turnLeft();
move();

}

}
Never finished, this should really be it. Fixed for one row going north.

/*
* File: CheckerboardKarel.java
* ----------------------------
* When you finish writing it, the CheckerboardKarel class should draw
* a checkerboard using beepers, as described in Assignment 1. You
* should make sure that your program works for all of the sample
* worlds supplied in the starter folder.
*/

import stanford.karel.*;

public class CheckerboardKarel extends SuperKarel {
// Karel will put a beeper(diamond) in every other spot on a blank canvas of any size.
public void run() {

placeBeeperEveryOtherSpot();

}

private void placeBeeperEveryOtherSpot() {
//while (frontIsBlocked()) for the up hill battle.
while (frontIsBlocked()) {
turnLeft();
}

while (frontIsClear()) {

putBeeper();
move();

if (facingEast())
if (frontIsBlocked()) {
if (noBeepersPresent())
makeUTurnWest();
}

if (facingWest())

if (frontIsBlocked()) {
if (noBeepersPresent())
makeUTurnEast();
}
move();
if (frontIsBlocked()) {

makeOddUTurnWest();

}

}

}
// Karel makes a U-Turn to head west and place beepers, when blocked to the east.
private void makeUTurnWest() {

turnLeft();
move();
putBeeper();
turnLeft();
move();

}
// Karel makes a U-Turn to head east and place beepers, when blocked to the west.
private void makeUTurnEast() {

turnRight();
move();
putBeeper();
turnRight();
move();

}

// Karel makes a U-Turn to head west and place beepers, when blocked to the east, on a .
private void makeOddUTurnWest() {

putBeeper();
turnLeft();
move();
turnLeft();
move();

}

}

Post a new comment

Comments by