How would I solve this problem? (print)

Given the width of the rink, w (always more than 2), how would I output the rink following these rules:

If the width of the rink is w characters across, then the rink’s length is 4w - 3 characters.

The characters to be used around the rink are Xs.

The red line is always in the centre of the rink, drawn across using Rs.

The blue lines are always (w - 1) / 2 in distance from the red line, drawn across using Bs.

The result of calculating (w - 1) / 2 should always be rounded to the nearest integer, such that 1.5 rounds up to 2, and 1.4 rounds down to 1, for example.

For reference, in the output below, the blue lines are 2 units away from the red line.

Input:

4

Output:

XXXX
X  X
X  X
X  X
XBBX
X  X
XRRX
X  X
XBBX
X  X
X  X
X  X
XXXX

Code:

void setup() {

  String[] w = loadStrings("file.txt");

  int rinkWidth = Integer.parseInt(w[0]);
  int rinkLength = 4 * rinkWidth - 3;

  printRink(rinkWidth, rinkLength);
}

void printRink(int rinkWidth, int rinkLength) {

  for (int i = 0; i < rinkWidth - 1; i ++) {
    print("X");
  }

  for (int i = 0; i < rinkLength; i ++) {
    print("X" + "\n");
  }
}
Tagged:

Answers

  • edited January 2018

    So you have some code. In that code you have a function to print the rink.

    Does this function print a rink? Not really. It prints two lines of X's - one on one line, and another down several lines.

    The rink, of course, is a rectangle. So you will need to draw the row across as many times as the rink's length.

    This means that you will need to put one of your for loops INSIDE the other for loop. That way the outer loop does each row, and the inner loop does each letter in a row. For example, if I want to print a rectangle of numbers:

    void setup() {
      size(200, 200);
      printRectangleOfNumbers(4, 8);
    }
    
    void draw() {
    }
    
    void printRectangleOfNumbers(int wide, int tall) {
      for (int j = 0; j < tall; j++) {
        for (int i = 0; i < wide; i ++) {
          print( i );
        }
        print("\n");
      }
    }
    

    This is much closer to what you want.

    Next, do some thinking:

    • What symbols should print on the first line of the rink?
    • What symbol should a row always start with?
    • What symbol should a row end with?
    • What symbols should fill the middle of a row otherwise?
    • Which line of symbols will print the red line?
    • How about the blue lines?
    • Can you work those values out ahead of time?
    • Can you check for some condition?
  • @TfGuy44:

    • "X" should print on the first line of the rink
    • A row should always start with "X"
    • A row should always end with "X"
    • B should fill (w-1)/2 away from middle on top and bottom like example. R should fill in the middle like example
    • "R" will print the red line
    • "B" for blue lines
    • Probably, but I don't know how
    • I'm not sure
  • edited January 2018 Answer ✓

    Cool. Let's do the red line then.

    We know how wide the rink is. From that information, we know how long the rink is. We can work out both of these values - as you have done - before we even start to draw the rink.

    We can work out other values about it as well. For example, if the rink length's is rinkLength, we know we are going to put the R's on a line near (rinkLength/2). In fact, we can just go ahead and try it!

    void setup() {
      size(200, 200);
      // Try various sizes to make sure this works.
      printRink(4);
      printSep();
      printRink(5);
      printSep();
      printRink(6);  
    }
    
    void draw() {
    }
    
    void printRink(int wide) { // Given the width
      int tall = (4 * wide) - 3; // Work out the height
      int centerGuess = tall / 2; // Can we find the center?
      for (int j = 0; j < tall; j++) {
        for (int i = 0; i < wide; i ++) {
          if( j == centerGuess ){ // if we think it's the center,
            print( "R" ); // Use R's
          } else { // Otherwise
            print( i ); // Print i's value. Wait, why? Maybe you want something else...
          }
        }
        print("\n");
      }
    }
    
    void printSep(){
      // Just pust some space between different rinks.
      print("\n");
      println( "-----" );
      print("\n");
    }
    

    Be sure to follow the steps in this code! The rink is being drawn one line at a time, one character at a time. First we draw the j = 0'th line. This line has i characters on it. Since j is zero for this line, it's (probably) not the center line, so we will print the values for i. First a 0, then a 1, then a 2, etc, to show that we are printing a certain number of characters on this line.

    Then the i loop is done, and the j loop makes us go to the next line. The i loop now runs again, starting back at 0. And so on.

    Notice the use of a conditional statement. IF we think we're on the center line (a value we've worked out ahead of time and stored in the centerGuess variable), we use R's. If that isn't the case, we do something ELSE: We print the value of i.

    ... This might be too much help. I'm sure if you attempted it now, given that you've seen this example, you should be able to finish it yourself. Post the code of your attempt with additional questions if you need more help.

  • @TfGuy44, how would I make it round to 2, it prints out the Blue Line right beside the red line.

    void setup() {
    
      String[] w = loadStrings("file.txt");
    
      int rinkWidth = Integer.parseInt(w[0]); //Width is 4
    
      printRink(rinkWidth);
    }
    
    void draw() {
    }
    
    void printRink(int wide) { // Given the width
      int tall = (4 * wide) - 3; // Work out the height
      int centerGuess = tall / 2; // Can we find the center?
      int blueLine = (wide-1) / 2;
      for (int j = 0; j < tall; j++) {
        for (int i = 0; i < wide; i ++) {
          if ( j == centerGuess ) { // if we think it's the center,
            print( "R" ); // Use R's
          } else if ( j == centerGuess - blueLine) {
            print( "B" );
          } else { // Otherwise
            print( "X" ); // Print i's value. Wait, why? Maybe you want something else...
          }
        }
        print("\n");
      }
    }
    

    Output:

    XXXX
    XXXX
    XXXX
    XXXX
    XXXX
    BBBB
    RRRR
    XXXX
    XXXX
    XXXX
    XXXX
    XXXX
    XXXX
    
  • The result of calculating (w - 1) / 2 should always be rounded to the nearest integer, such that 1.5 rounds up to 2, and 1.4 rounds down to 1, for example.

    You might want to look at the function round().

  • edited January 2018

    @TfGuy44, I used round(), and it still doesn't work, it is supposed to round to 2 but it is 1:

    void setup() {
    
      String[] w = loadStrings("file.txt");
    
      int rinkWidth = Integer.parseInt(w[0]);
    
      printRink(rinkWidth);
    }
    
    void draw() {
    }
    
    void printRink(int wide) { // Given the width
      int tall = (4 * wide) - 3; // Work out the height
      int centerGuess = tall / 2; // Can we find the center?
      float blueLine = (wide - 1) / 2;
      println(blueLine);
      int blue = round(blueLine);
      println(blue);
      for (int j = 0; j < tall; j++) {
        for (int i = 0; i < wide; i ++) {
          if ( j == centerGuess ) { // if we think it's the center,
            print( "R" ); // Use R's
          } else if ( j == centerGuess - blue) {
            print( "B" );
          } else if ( j == centerGuess + blue) {
            print( "B" );
          } else { // Otherwise
            print( "X" );
          }
        }
        print("\n");
      }
    }
    
  • Nice bug! Can you debug it?

    You'll need to check all the values you're generating!

    What value should blueLine be? What value is it actually?

    Why might a float not be a float?

    Is / 2 the same as / 2.0?

  • edited January 2018

    @TfGuy44, fixed it, but now how would I make the border be only X's and not R, and B at the beginning and end like the example I gave in beginning. Also, remove X's inside the rink.

    This:

    XXXX
    XXXX
    XXXX
    XXXX
    BBBB
    XXXX
    RRRR
    XXXX
    BBBB
    XXXX
    XXXX
    XXXX
    XXXX
    

    To This:

    XXXX
    X  X
    X  X
    X  X
    XBBX
    X  X
    XRRX
    X  X
    XBBX
    X  X
    X  X
    X  X
    XXXX
    
  • Well, you need to check for some more conditions!

    What can you say about the X's on the first row? (Hint: What is the value of j for these X's?)

    What about the X's on the bottom row? (Hint: Again, what is the value of j when these X's are drawn?)

    How about the X's on the left and right? (Hint: The value of j is not the same for these X's... But some other value is! Which other variable can you check? What value does it have for the first character drawn in a line? How about the last character in a line?)

    If you're not drawing an X, or an R, or an B, then you can draw... something else, right? What character can you use to take up the space in the middle?

  • edited January 2018

    @TfGuy44, I finished! Thx for the help

  • Great! Post the finished code here so that other people can see how to do this sort of thing! :-)

Sign In or Register to comment.