LinuxQuestions.org
Download your favorite Linux distribution at LQ ISO.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 11-26-2014, 06:43 AM   #1
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311
Blog Entries: 2

Rep: Reputation: 16
How to make a diamond with progressing & rectracting numbers


I would like to make a diamond with centrally aligned progressing & rectracting numbers, more particularly:
Output: "Please enter height of diamond> "
Input: "4"
Output:
<please see attached picture: DiamondCountingUpThenDown.png>

Currently on the web programiz offers the closest version of this, but still after completing their C Programming Code To Create Pyramid and Structure webpage (<http://www.programiz.com/article/c-programming-pattern>) I still write the below failing program. Note well: "//" and" /* ...*/" are comments.

#include <stdio.h>

int
main()
{
int floor, basement, space, height, apartment=0, countup=0, countdown=0;
/* floor = the floor number, counting from top;
height = height of pyramid(rows);
apartment = field #, assumes pyramid shaped apartment building has same apt # on every floor;
countup = field # before apartment reaches one less than twice the floor number;
countdown = field # starting when apartment number equals one less than twice the floor number
*/

printf("Enter height of pyramid(rows): ");
scanf("%d",&height);
for(floor=1;floor<=height;++floor)
{
for(space=1;space<=height-floor;++space)
{
printf(" ");
++countup;
}
while(apartment!=2*floor-1)
{
if (countup<=height-1) //問題:This line is totally illogical, what function does it serve?
{
printf("%d ",apartment+1);
++countup;
}
else
{
printf("%d ",(apartment-(2*countdown+1))); //Counting down: apartment # is one less than [apt # - (2*countdown#) ]
++countdown;
}
++apartment; // while's loop control variable(prevents infinite loop).
}
countdown=countup=apartment=0;
printf("\n");
}

//Basement levels
//Initialization
//max_space = 1;
countup=countdown=0;

for (basement = height-1; basement >= 1; --basement) //Basement doesn't start at ground level(basement <=height), rather at -1 level, thus "<= height - 1".
{
for (space = 1; space <= basement; ++space)
printf(" ");
++countup;
//max_space++;

while (apartment!=2*basement-1)
{
if(countup<=(height-basement)-1)
{
printf("%d",apartment+1);
++countup;
}
else
{
printf("%d",(apartment-(2*countdown+1))); //Counting down: apartment # is one less than [apt # - (2*countdown#) ]
++countdown;
}
++apartment; // while's loop control variable(prevents infinite loop).
}
countdown=countup=apartment=0;
printf("\n");
}
return 0;
}

/*
TESTING
RESULT FINALFAIL)
Enter height of pyramid(rows): 5

<Please see attached picture: DiamondCountingUpThenDown_Fail.png >

Process returned 0 (0x0) execution time : 6.949 s
Press ENTER to continue.

*/
Attached Thumbnails
Click image for larger version

Name:	DiamondCountingUpThenDown.png
Views:	20
Size:	5.3 KB
ID:	16935   Click image for larger version

Name:	DiamondCountingUpThenDown_Fail.png
Views:	23
Size:	46.7 KB
ID:	16936  
 
Old 11-26-2014, 07:07 AM   #2
grail
LQ Guru
 
Registered: Sep 2009
Location: Perth
Distribution: Manjaro
Posts: 10,007

Rep: Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192Reputation: 3192
Please place the code in [code][/code] tags so it is more readable and no interpretation into smiley faces and the like.
 
1 members found this post helpful.
Old 11-26-2014, 08:00 AM   #3
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Check out this thread, it covers the same for a triangle versus a diamond.

http://www.linuxquestions.org/questi...pt-4175524299/
 
1 members found this post helpful.
Old 11-26-2014, 08:43 AM   #4
psionl0
Member
 
Registered: Jan 2011
Distribution: slackware_64 14.1
Posts: 722
Blog Entries: 2

Rep: Reputation: 124Reputation: 124
I don't think the "apartment complex" analogy helps with understanding this problem.

I would rather use simple variables like "row", "column", "height" and "spaces" (and maybe a loop index counter like "i").
For( ) loops are all that are needed (mixing for's and while's confuses things) and you don't need "countup" and "countdown" variables.
Printing a single row should be made a function.

Clearly, your error is in the "basements" section.

I actually have a program written in basic that does what you want if you want to compare.
 
1 members found this post helpful.
Old 11-26-2014, 09:24 AM   #5
danielbmartin
Senior Member
 
Registered: Apr 2010
Location: Apex, NC, USA
Distribution: Mint 17.3
Posts: 1,881

Rep: Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660Reputation: 660
This code ...
Code:
n=5
awk -v n=$n 'BEGIN{str="         12345678987654321"
  for (j=1;j<=2*n-1;j++) {(j<l=2*n-j)?v=j:v=l; 
    print substr(str,10-n+v,n) substr(str,28-v)}}' >$OutFile
... produced this OutFile ...
Code:
    1          
   121          
  12321          
 1234321          
123454321          
 1234321          
  12321          
   121          
    1
It works for values of n<10.

Daniel B. Martin

Last edited by danielbmartin; 11-26-2014 at 02:26 PM. Reason: Tighten the code
 
1 members found this post helpful.
Old 11-26-2014, 06:11 PM   #6
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311

Original Poster
Blog Entries: 2

Rep: Reputation: 16
Place code in tags: Attempt01

grail,
Re: Please place the code in tags so it is more readable and no interpretation into smiley faces and the like.

Attempt 01:
Code:
#include <stdio.h>

int
main()
{
    int floor, basement, space, height, apartment=0, countup=0, countdown=0;
    /*  floor       = the floor number, counting from top;
        height      = height of pyramid(rows);
        apartment   = field #, assumes pyramid shaped apartment building has same apt # on every floor;
        countup     = field # before apartment reaches one less than twice the floor number;
        countdown   = field # starting when apartment number equals one less than twice the floor number
    */

    printf("Enter height of pyramid(rows): ");
    scanf("%d",&height);
        for(floor=1;floor<=height;++floor)
        {
            for(space=1;space<=height-floor;++space)
            {
                printf("  ");
                ++countup;
            }
            while(apartment!=2*floor-1)
            {
                if (countup<=height-1)  //問題:This line is totally illogical, what function does it serve?
                {
                    printf("%d ",apartment+1);
                    ++countup;
                }
                else
                {
                    printf("%d ",(apartment-(2*countdown+1))); 		//Counting down: apartment # is one less than [apt # - (2*countdown#) ]
                    ++countdown;
                }
                    ++apartment;		// while's loop control variable(prevents infinite loop).
            }
            countdown=countup=apartment=0;
            printf("\n");
        }

    //Basement levels
      //Initialization
        //max_space = 1;
        countup=countdown=0;

      for (basement = height-1; basement >= 1; --basement)              //Basement doesn't start at ground level(basement <=height), rather at -1 level, thus "<= height - 1".
      {
        for (space = 1; space <= basement; ++space)
          printf(" ");
          ++countup;
        //max_space++;

        while (apartment!=2*basement-1)
        {
            if(countup<=(height-basement)-1)
            {
                printf("%d",apartment+1);
                ++countup;
            }
            else
            {
                printf("%d",(apartment-(2*countdown+1)));       //Counting down: apartment # is one less than [apt # - (2*countdown#) ]
                ++countdown;
            }
                ++apartment;   // while's loop control variable(prevents infinite loop).
            }
            countdown=countup=apartment=0;
            printf("\n");
      }
    return 0;
    }
 
Old 11-26-2014, 06:17 PM   #7
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311

Original Poster
Blog Entries: 2

Rep: Reputation: 16
Smile program in basic

Quote:
Originally Posted by psionl0 View Post
I don't think the "apartment complex" analogy helps with understanding this problem.

I would rather use simple variables like "row", "column", "height" and "spaces" (and maybe a loop index counter like "i").
For( ) loops are all that are needed (mixing for's and while's confuses things) and you don't need "countup" and "countdown" variables.

I actually have a program written in basic that does what you want if you want to compare.
psion,
Yes, actually column is the word I was looking for, this is much clearer than apartment number.

I would like to see your basic program for comparison.

Sincerely,
Andrew
 
Old 11-26-2014, 06:59 PM   #8
psionl0
Member
 
Registered: Jan 2011
Distribution: slackware_64 14.1
Posts: 722
Blog Entries: 2

Rep: Reputation: 124Reputation: 124
Here it is. Note that lines 45, 505 and 550 were only necessary because in Blassic, FOR loops always execute at least once. You would not need them in C code.
Code:
     10 INPUT "Height of diamond: ",height
     20 FOR row = 1 TO height
     30   GOSUB 500
     40 NEXT row
     45 IF height = 1 THEN 80
     50 FOR row = height-1 TO 1 STEP -1
     60   GOSUB 500
     70 NEXT row
     80 END
    500 spaces = height - row
    505 IF spaces = 0 THEN 520
    510 FOR i = 1 TO spaces : PRINT "  "; : NEXT i
    520 FOR column = 1 TO row
    530   PRINT column; " ";
    540 NEXT column
    550 IF row = 1 THEN 590
    560 FOR column = row-1 TO 1 STEP -1
    570   PRINT column; " ";
    580 NEXT column
    590 PRINT
    600 RETURN
It took me 10 minutes to convert this code into C.

Last edited by psionl0; 11-26-2014 at 07:04 PM.
 
1 members found this post helpful.
Old 11-28-2014, 07:33 PM   #9
andrew.comly
Member
 
Registered: Dec 2012
Distribution: Trisquel-Mini 7.0, Lubuntu 14.04, Debian lxde 8.0
Posts: 311

Original Poster
Blog Entries: 2

Rep: Reputation: 16
Everyone,
I would like to thank all of you, each person gave me a better idea and I now hereby share my solution to the problem below:

Code:
#include <stdio.h>

int
main()
{
    int row, space, height, column, countup, countdown;
countup=countdown=column=1;


    /*  row       = the row number, counting from top;
        height      = height of pyramid(rows);
        column   = field #, assumes pyramid shaped column building has same apt # on every row;
        countup     = field # before column reaches one less than twice the row number;
        countdown   = field # starting when column number equals one less than twice the row number
    */
    while(1){               //Under the condition that the program runs without error, this loop will enable the user to experiment repeatedly for unlimited multiple times rather than having to exit terminal and then restart the program n times for n runs.
    printf("Enter height of pyramid(rows): ");
    scanf("%d",&height);
        for(row=1;row<=height;++row)            //Row Control
        {
            for(space=1;space<=height-row;++space)
            {
                printf("   ");
                ++countup;
            }
            for(countup=1;column!=2*row;++countup)      /* We always want [2(row)-1] numbers printed given any specific row, and since column starts at 1 (line 7), we want it to stop at [2(row)-1] OR before (2*row).*/
            {
                if (countup<=row)                       /*Notice the example given how the max in each row is the row number.  {given that the row with the highest number(height) is the top row and the lowest number row is on the bottom. }*/
                {
                    printf("%2d ",(countup));
                }                           //ends print countup if loop
                else
                {
                    printf("%2d ",(countup-(2*countdown)));     //Counting down: Displayed number = countup number - twice the countdown number.
                    ++countdown;
                }                           //ends countdown else loop
                ++column;                   //"print number" for(line 26)'s loop control variable (prevents infinite loop.)
            }
            countup=countdown=column=1;
            printf("\n");
        }
//Bottom rows (bottom half)______________________________________________________
        for(row=height-1;row>=1;--row)          //Row Control: Since the top has already included the bottom and broadest row, thus we want to skip the broadest row on the top, thus instead of starting from row=height which is the broadest row, we start from the second broadest row, which is height-1.
        {
            for(space=1; space<=height-row; ++space)		/* Since: 1)row starts from the height's number counting down(line11), 2) upside-down means 0 spaces on the first line and (height - 1) spaces on the last line therefore we write the condition: a) start at 1  b) height - row(from 5 down to 1)*/
            {
                printf("   ");
                ++countup;
            }                                       //ends space loop
            for(countup=1;column!=2*row;++countup)  /* We always want [2(row)-1] numbers printed given any specific row, and since column starts at 1 (line 7), we want it to stop at [2(row)-1] OR before (2*row).*/
            {
                if (countup<=row)		/*Notice the example given how the max in each row is the row number.  {given that the row with the highest number(height) is the top row and the lowest number row is on the bottom. }*/
                {
                    printf("%2d ", countup);
                }                           //ends print countup if loop
                else
                {
                    printf("%2d ",(countup-(2*countdown)));		//Counting down: Displayed number = countup number - twice the countdown number.
                    ++countdown;
                }                           //ends countdown else loop
                ++column;		            //"print number" for(line 50)'s loop control variable (prevents infinite loop.)
                }                       //ends "print number" for loop
                countdown=countup=column=1;
            printf("\n");
        }                               //ends "basement" for loop
        printf("\n");
    }                                   //ends while loop
return 0;
}
Thanks!!!

Andrew

Last edited by andrew.comly; 11-28-2014 at 07:42 PM. Reason: terms, comments
 
Old 11-28-2014, 08:24 PM   #10
psionl0
Member
 
Registered: Jan 2011
Distribution: slackware_64 14.1
Posts: 722
Blog Entries: 2

Rep: Reputation: 124Reputation: 124
Quote:
Originally Posted by andrew.comly View Post
Everyone,
I would like to thank all of you, each person gave me a better idea and I now hereby share my solution to the problem below:
I'm glad your program works for you but I find aspects of it confusing and puzzling.

For example:
Code:
        for(row=1;row<=height;++row)            //Row Control
        {
            for(space=1;space<=height-row;++space)
            {
                printf("   ");
                ++countup;
            }
            for(countup=1;column!=2*row;++countup)
            . . . . . .
Your first for() loop increments countup but doesn't use it and after the loop exits, the second for() loop immediately resets countup.

I am including the C translation of my above code so that you can compare it with your code and see how the efficiency of your code can be improved.
Code:
#include <stdio.h>
#include <stdlib.h>

int main(int, char**);
void printRow(int, int);

int main(int argc, char *argv[]) {
   int row, height;

   if (argc == 1) {
      printf("Enter height of diamond: ");
      scanf("%d", &height);
   } else {
      height = atoi(argv[1]);
   }

   for (row = 1; row <= height; ++row) {
      printRow(row, height);
   }
   for (row = height-1; row > 0; --row) {
      printRow(row, height);
   }
   return 0;
}

void printRow(int row, int height) {
   int i, column, spaces;

   spaces = height - row;
   for (i = 1; i <= spaces; ++i) {
      printf("  ");
   }
   for (column = 1; column <= row; ++column) {
      printf("%d ", column);
   }
   for (column = row-1; column > 0; --column) {
      printf("%d ", column);
   }
   printf("\n");
}
 
Old 12-02-2014, 07:14 AM   #11
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,659
Blog Entries: 4

Rep: Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941Reputation: 3941
Yes ... was this problem shown in Basic BASIC, or in Advanced BASIC? I guess I could go into the other room and look it up, but ...

Hmmm... In the BASIC interpreters that I've used, FOR-loops didn't execute "at least once" if the range was empty. They properly considered the values of the limit-expressions and the sign of the STEP value, and behaved properly in all cases. Did, say, Microsoft put out an interpreter that was broken in that way?

(The very-strangest BASIC interpreter that I ever saw, which honest-to-god was written entirely in COBOL, ... stack of bibles hope-to-die true statement ... also did not have this problem.)

Last edited by sundialsvcs; 12-02-2014 at 07:20 AM.
 
Old 12-02-2014, 07:19 AM   #12
rtmistler
Moderator
 
Registered: Mar 2011
Location: USA
Distribution: MINT Debian, Angstrom, SUSE, Ubuntu, Debian
Posts: 9,882
Blog Entries: 13

Rep: Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930Reputation: 4930
Quote:
Originally Posted by sundialsvcs View Post
Yes ... was this problem shown in Basic BASIC, or in Advanced BASIC? I guess I could go into the other room and look it up, but ...
Forgot to mention that I LOVE the fact that psionl0 posted an actual BASIC program.

Hey, anybody got that in FORTRAN?

Funnily, I did catch the ORIGINAL TRON the other night ...
 
Old 12-02-2014, 08:37 AM   #13
psionl0
Member
 
Registered: Jan 2011
Distribution: slackware_64 14.1
Posts: 722
Blog Entries: 2

Rep: Reputation: 124Reputation: 124
Quote:
Originally Posted by sundialsvcs View Post
Hmmm... In the BASIC interpreters that I've used, FOR-loops didn't execute "at least once" if the range was empty.
Code:
$ blassic

Blassic 0.10.2
(C) 2001-2009 Julian Albo

Ok
10 n = 0
20 for i = 1 to n : print i : next
run
1
Ok
There is no universal standard with something as antique as BASIC and you can't make any assumptions about what an individual programmer will do. BASIC (like FORTH) is simple enough for a programmer of moderate ability to "roll his own" so anything goes.

Quote:
Originally Posted by rtmistler View Post
Forgot to mention that I LOVE the fact that psionl0 posted an actual BASIC program.
Posted by request. I just happened to have that code lying around although it doesn't seem to have inspired the OP to clean up his code much (although he did away with "apartment number").
 
Old 12-02-2014, 10:55 AM   #14
turtleli
Member
 
Registered: Aug 2012
Location: UK
Posts: 206

Rep: Reputation: Disabled
Quote:
Originally Posted by rtmistler View Post
Hey, anybody got that in FORTRAN?
Fortran version (based on psionl0's code):

Code:
program diamond
	implicit none
	character(len=2):: height_string
	integer:: height
	integer:: row

	if (command_argument_count() == 1) then
		call get_command_argument(1, height_string)
		read (height_string, '(I2)') height
	else
		write (*, '(A)', advance="no") "Enter height of diamond: "
		read (*,'(I2)') height
	end if

	do row = 1, height
		call print_row(row, height);
	end do
	do row = height - 1, 1, -1
		call print_row(row, height);
	end do
end program diamond

subroutine print_row(row, height)
	implicit none
	integer, intent(in):: row
	integer, intent(in):: height
	integer:: column
	integer:: spaces
	integer:: i
	
	spaces = height - row;
	do i = 1, spaces
		write (*, '(A)', advance="no") "  "
	end do
	do column = 1, row
		write (*, '(I1, x)', advance="no") column
	end do
	do column = row - 1, 1, -1
		write (*, '(I1, x)', advance="no") column
	end do
	write (*,*)
end subroutine print_row
 
  


Reply

Tags
loops



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
Why PKGBUILD and not ./configure && make && make install? slkrover Arch 2 08-09-2010 03:04 AM
what does make man && make setup check while installing qmail means vitalstrike82 Linux - Software 3 05-26-2009 09:41 AM
Gentoo make & make.conf & emerge Trouble geagon Linux - Newbie 5 10-28-2005 06:33 PM
Look the output of: make dep && make clean bzImage modules modules_install Hell-Shooter Linux - General 2 06-05-2004 05:05 AM
Diamond Stealth II S220 & no RedHat 9.0 Baltazar Zoltar Linux - Hardware 2 02-01-2004 03:15 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 07:05 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration