4

I got this assignment in Java and I don't have a single clue on how to do it. The task is to receive an integer n > 0, and to print n number of frames constructed by * inside each other, while the inner frame will have the letter "X" constructed by 4n+1 *. I can't use arrays or strings.

For example: n=1 will print:

*******
*     *
* * * *
*  *  *
* * * *
*     *
*******

n=2 will print:

*************
*           *
* ********* *
* *       * *
* * *   * * *
* *  * *  * *
* *   *   * *
* *  * *  * *
* * *   * * *
* *       * *
* ********* *
*           *
*************

This is what I have so far:

Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
int size = n * 6 + 1;
int x = 1;
int y = 1;

for (int i = 0; i < n; i = i + 1) {
    for (int i3 = 0; i3 < size; i3 = i3 + 1) {
        System.out.print("*");
    }

    System.out.println("");
    y = y + 1;

    for (int i1 = 0; i1 < size - 2; i1 = i1 + 1) {
        System.out.print("*");
        for (int i2 = 0; i2 < size - 2; i2 = i2 + 1) {
            System.out.print(" ");
        }

        System.out.println("*");
        y = y + 1;
    }

    for (int i4 = 0; i4 < size; i4 = i4 + 1) {
        System.out.print("*");
    }
}
  • 4
    You want to try something, anything. Just doing this will give you a better understanding of the problem and help you clarify your issues with this assignment. By posting this without showing your initial efforts, without asking a specific question, you're only hurting yourself. Do yourself a big favor, stretch your brain cells to their capacity and then some! – Hovercraft Full Of Eels Nov 08 '14 at 14:46
  • 1
    OP: unless you provide *what have you tried*, you have a ->100% chance you'll get flagged for off-topic questions. We're not here to do anybody's homework, mind me. The answer to your question is "learn to code first, ask question later". Still, begin with constructing a single frame, then try drawing n frames in each other, then substitute 3 innermost with a cross. Simple as that. –  Nov 08 '14 at 14:51
  • 2
    I think you should first read this http://stackoverflow.com/help/how-to-ask – Code Geek Nov 08 '14 at 14:53
  • Well that is your effort right, `I cant see the point of uploading it`, Now I can't see the point in this. You must tell us your work only then it is possible for others to help. – Code Geek Nov 08 '14 at 14:57
  • @peeskillet Lack of effort is a reason to downvote, not to close a question. – John Kugelman Nov 08 '14 at 14:58
  • 1
    See also: [How do I ask and answer homework questions?](http://meta.stackexchange.com/questions/10811/how-do-i-ask-and-answer-homework-questions) – John Kugelman Nov 08 '14 at 15:00
  • @JohnKugelman in some borderline cases, it actually *can be* a valid reason to close: if the question is formulated poorly, provides no way to know the correct solution, if it's too broad etc. That's the case with most homework questions on SE - yet this question, sadly, is quite valid in itself - that's exactly why I haven't flagged for close... –  Nov 08 '14 at 15:01
  • I have edited my post and added the code I have so far... – Daniel Nahmias Nov 08 '14 at 15:02
  • @DanielNahmias did you already learned about recursion and recursive methods? It'd be quite hard for you to solve your problem without knowing about it (and possibly using it). I'm not saying it's not possible (it certainly is), but that knowledge really comes in handy in cases like this. –  Nov 08 '14 at 15:03
  • You need a plan of attack. How can you break the problem down into smaller pieces? My suggestion: to start with, ignore the X in the middle. Can you write the code to do the boxes? That's a good place to start. – John Kugelman Nov 08 '14 at 15:05
  • We still didn't get to recursion. Iv'e tried to write a code to do the boxes and I faild epicly. – Daniel Nahmias Nov 08 '14 at 15:05
  • It **can** be done without recursion, but will involve writing your dots out on paper for different values of `n` and then thinking through what should go on each line for a given n. Better if you could create a 2- dimensional array of chars for this. – Hovercraft Full Of Eels Nov 08 '14 at 15:10
  • @HovercraftFullOfEels the sad thing is, their teacher obviously want them to do this through loops, without recursion, arrays, strings etc... making the whole problem absurd. It's like giving an engineer a nail and asking to put it in concrete with a glass hammer. It certainly can be done, given enough hammers - but it's still an absurd thing to ask of students IMO. –  Nov 08 '14 at 15:12
  • @vaxquis: it's an exercise in visualization and abstraction, and so has some merit. – Hovercraft Full Of Eels Nov 08 '14 at 15:16
  • 1
    @HovercraftFullOfEels the very same can be said about glass hammers and nails. *chuckle* –  Nov 08 '14 at 15:18

1 Answers1

2

There are many different approaches to this problem. This may not be the best, but it's quite simple and educational IMO.

The main idea is: you don't need to know how to print the entire frame. You only need to know how to print 1/4 of it - then repeat it in reverse X order, then repeat it in reverse Y order. Let's start with drawing X, specifically - one diagonal of it. If the "X" has to have 4n+1 *, it has 4 arms with a stars each and one * in the middle - totaling to 4 * a + 1 stars - so, obviously, 4n+1 == 4a+1, and each arm has to have exactly n *'s. Let's use XY Cartesian coordinate system. Thus, we only have an asterisk if x == y - otherwise we have s space there.

for ( int y = 0; y < n; y++ ) {
  for ( int x = 0; x < n; x++ ) {
    System.out.print( ( x == y ) ? '*' : ' ' );
  }
  System.out.println();
}

Now, let's add a mirror copy to it by iterating in reverse too:

for ( int y = 0; y < n; y++ ) {
  for ( int x = 0; x < n; x++ ) {
    System.out.print( ( x == y ) ? '*' : ' ' );
  }
  for ( int x = n; x >= 0; x-- ) {
    System.out.print( ( x == y ) ? '*' : ' ' );
  }
  System.out.println();
}

Now, let's try to get into valid Cartesian:

int x, y;
for ( y = -n; y <= n; y++ ) {
  for ( x = -n; x < 0; x++ ) {
    System.out.print( ( x == y || x == -y ) ? '*' : ' ' );
  }
  for ( ; x <= n; x++ ) {
    System.out.print( ( x == y || x == -y ) ? '*' : ' ' );
  }
  System.out.println();
}

and, finally, we can figure that it's just

for ( int y = -n; y <= n; y++ ) {
  for ( int x = -n; x <= n; x++ ) {
    System.out.print( hasAsterisk( Math.abs(x), Math.abs(y) ) ? '*' : ' ' );
  }
  System.out.println();
}

with, for example

static boolean hasAsterisk( int x, int y ) {
  return x == y;
}

Extend this code to handle the frames, and you're set. Each "quart part" of the frame is only * for each n, 2n chars total - the cross itself is n in length (see above) plus 1 central asterisk; to sum up, X and Y will range over int [-3n,3n] - call that 3n some m and use it as the range for iteration.

As an additional hint, the formula is different for the inner cross (i.e. abs(x)<n,abs(y)<n), and different for the frames themselves. The formula for the frames can be easily figured out if you notice that it's every second row, in the shape of two asterisk triangles in axis X added to two triangles in axis Y.

return ( x <= n && y <= n ) ? x == y : ( ( x < y ) ? y % 2 == nMod2 : x % 2 == nMod2 );

  • 1
    @vaxquis Brutal and effective. :) – Nolo Nov 08 '14 at 15:37
  • @Daniel Try making a function that returns n number of asterisks or n number of spaces, that will help keep your code cleaner inside the loopy business. – Nolo Nov 08 '14 at 15:37
  • 1
    @Nolo: no, making functions like that is completely unnecessary here IMO; see the complete solution at http://ideone.com/LUaM2R - the entire logic here is 1 line for integer initalization, 2 `for` loops, 2 calls to `Math.abs` and 2 calls to `System.out.print`, 7 lines total... *and* it could be shortened further, I'm just not into golfing homework code *chuckle*. No need to add any helpers, the task is too simple. –  Nov 08 '14 at 16:58
  • Personally, if I were the teacher, I'd ask students to solve this with functional programming (lambdas, streams etc) - functional programming is quite good for math problems. Here you could just stream the x,y set through hasAsterisk as a filter, and then just output what's left of it... –  Nov 08 '14 at 17:03
  • @vaxquis hi, thanks alot for the answer, it really helped. however, can you please further clarify the line "( x <= n && y <= n ) ? x == y : ( ( x < y ) ? y % 2 == nMod2 : x % 2 == nMod2 );" ? we still didn't learn to write "ifs" in that method and im having a hard time to understand it. – Daniel Nahmias Nov 09 '14 at 18:31
  • @DanielNahmias that's for you to figure... learning how to read code is necessary to learn how to write it. I can only say that, obviously, nMod2 = n % 2, and that the operator used is the so-called *ternary operator*, see e.g. Wikipedia about how to read it - then try to rewrite that line using regular ifs and then break it down to pieces. BTW, if the answer *did* help you, accepting it would be nice. –  Nov 09 '14 at 23:57
  • @vaxquis: I agree with you and I think you deserve milk and cookies for utterly laying waste to the problem. But my point was to encourage and challenge the beginner on his level, not discourage him with fits of what may look like cryptic code. He'll run into that soon enough. :) – Nolo Nov 30 '14 at 15:32
  • @Daniel: The ? symbol in Java is referred to as a "ternary operator". It's a sort of shorthand for condensing long if else blocks. Using parentheses around a ternary operation that returns true/false, such as the expression `(blah ? x==y : (/*some other boolean expression*/))`, can itself be feed into a ternary operation by following with another ?. https://docs.oracle.com/javase/tutorial/java/nutsandbolts/op2.html – Nolo Nov 30 '14 at 15:47