从地形图显示文本金字塔

时间:2016-04-20 10:34:57

标签: c algorithm

我用C语言写arduino uno。我的想法是从地形图中显示金字塔,所以我拥有的变量就是“种子”。 - 中间值,金字塔大小' sizeP' - 层数和连续多少个字母 - '层'。

代码seedP = 6,sizeP = 3中包含这些值的金字塔看起来像:

44444
45554
45654
45554
44444

以下是代码:

void setup()
   {
     Serial.begin(9600);
     int seedP = 6; //Centre value
     int sizeP = 3; //Amount of layers
     int layer = (sizeP*2)-1;

     for(int i=0; i<layer; i++){
       for(int j=0; j<layer; j++){
           Serial.print(seedP);
       }
       Serial.println();
     }
   }

我仍然无法完全掌握算法的概念,我可以检查第一层和最后一层,然后显示一个满是&#39; 4&#39;在这个例子中,但我不确定如何处理其他图层。现在,代码仅显示5列中的&#6; 6和5行。

编辑:更新了代码,下面是网格

void setup()
   {
     Serial.begin(9600);

     int sizeP = 3; //Amount of layers
     int layer = (sizeP*2)-1;

     int seedP = 6; //Centre value
     int seedX = sizeP-1;
     int seedY = sizeP-1;

     for(int i=0; i<layer; i++){
       for(int j=0; j<layer; j++){
           //i,j = x,y grid
           int distanceX, distanceY, distance; //Distance between a cell and center value
           distanceX = abs(seedX - j);
           distanceY = abs(seedY - i);
           distance = distanceX + distanceY;
       }
       Serial.println();
     }
   }

从每个单元格到中心的值

(0,0)=4, (0,1)=3,   (0,2)=2,  (0,3)=3,  (0,4)=4
(1,0)=3, (1,1)=2,   (1,2)=1,  (1,3)=2,  (1,4)=3
(2,0)=2, (2,1)=1,   (2,2)=0,  (2,3)=1,  (2,4)=2
(3,0)=3, (3,1)=2,   (3,2)=1,  (3,3)=2,  (3,4)=3
(4,0)=4, (4,1)=3,   (4,2)=2,  (4,3)=3,  (4,4)=4

2 个答案:

答案 0 :(得分:4)

很好的谜题,这是我的建议:

#include <stdio.h>
#include <stdlib.h>

/* get the depth relative to the pyramids center, which is at origo */
int depth(int x, int y)
{
    x = abs(x);
    y = abs(y);

    return x > y ? x : y;
}

/* walk from (-(size - 1), size - 1) along the x and y axis, and print
 * the center value minus the current depth */
void pyramid(char center, int size)
{
    int x, y;

    size--;

    for (x = -size; x <= size; x++) {
        for (y = -size; y <= size; y++)
            putchar(center - depth(x, y));
        putchar('\n');
    }
}

int main(int argc, char **argv)
{
    char seedP = argv[1][0];
    int sizeP = strtol(argv[2], NULL, 0);

    pyramid(seedP, sizeP);
}

请注意,此处有 no 错误处理,您最好使用两个参数运行它。

示例:

$ gcc pyramid.c -o pyramid && ./pyramid 6 7
0000000000000
0111111111110
0122222222210
0123333333210
0123444443210
0123455543210
0123456543210
0123455543210
0123444443210
0123333333210
0122222222210
0111111111110
0000000000000

答案 1 :(得分:0)

由于您正在处理串行输出,我建议实现“帧缓冲”对象。

金字塔(前一个正方形内的正方形)被写入“帧缓冲区”。

最后,“帧缓冲区”可以序列化到串口或文本终端。

查看我的建议:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>


typedef struct frame_buffer_s
{
    int ncols;
    int nrows;
    char ** buf;
} frame_buffer_t;


void frame_buffer_destroy( frame_buffer_t * frm )
{
    int i = 0;

    if( frm->buf )
    {
        for( i = 0; i < frm->nrows; i++ )
            if( frm->buf[i] )
                free( frm->buf[i] );

        free( frm->buf );
    }

    free( frm );
}


frame_buffer_t * frame_buffer_create( int ncols, int nrows )
{
    frame_buffer_t * frm = NULL;
    int i = 0;

    frm = (frame_buffer_t*) calloc( 1, sizeof(frame_buffer_t) );

    if( !frm )
        return NULL;

    frm->ncols = ncols;
    frm->nrows = nrows;

    frm->buf = (char**) calloc( nrows, sizeof(char*) );

    if( !frm->buf )
    {
        frame_buffer_destroy( frm );
        return NULL;
    }

    for( i = 0; i < nrows; i++ )
    {
        frm->buf[i] = (char*) calloc( ncols, sizeof(char) );

        if( !frm->buf[i] )
        {
            frame_buffer_destroy( frm );
            return NULL;
        }
    }

    return frm;
}


void frame_buffer_draw_square( frame_buffer_t * this, int row, int col, int size, char ch )
{
    int i = 0;

    size--;

    for( i = 0; i <= size; i++ )
    {
        this->buf[col + i][row] = ch;
        this->buf[col + i][row+size] = ch;
        this->buf[col][row + i] = ch;
        this->buf[col + size][row + i] = ch;
    }
}


void frame_buffer_draw_pyramid( frame_buffer_t * frm, int col, int row, int size, char seed )
{
    int i = 0;

    for( i = 1; i <= size; i++ )
        frame_buffer_draw_square( frm, row + size - i, col + size - i, (i * 2) - 1, seed-- );
}


void frame_buffer_render_terminal( frame_buffer_t * frm )
{
    int col = 0;
    int row = 0;

    for( row = 0; row < frm->nrows; row++ )
    {
        for( col = 0; col < frm->ncols; col++ )
        {
            char ch = frm->buf[col][row];

            printf( "%c", (ch)?ch:' ' );
        }

        printf( "\n" );
    }
}


void frame_buffer_send_serial( frame_buffer_t * frm )
{
    int col = 0;
    int row = 0;

    /* Serial.begin(9600); */

    for( row = 0; row < frm->nrows; row++ )
    {
        for( col = 0; col < frm->ncols; col++ )
        {
            char ch = frm->buf[col][row];

            /* Serial.print( (ch)?ch:' ' ); */
        }

        /* Serial.println(); */
    }
}


int main( int argc, char ** argv )
{
    frame_buffer_t * frm = NULL;

    /* Read command line arguments */
    char seed = argv[1][0];
    int size = strtol(argv[2], NULL, 0);

    /* Create a 20x20 frame buffer */
    frm = frame_buffer_create( 20, 20 );

    /* Draw Pyramid in the frame buffer */
    frame_buffer_draw_pyramid( frm, 0, 0, size, seed );

    /* Write our frame buffer to terminal */
    frame_buffer_render_terminal( frm );

    /* Write our frame buffer to serial output */
    frame_buffer_send_serial( frm );

    /* Destroy frame buffer */
    frame_buffer_destroy( frm );

    return 0;
}

/* eof */

示例:

$ ./pyramid 9 10
0000000000000000000 
0111111111111111110 
0122222222222222210 
0123333333333333210 
0123444444444443210 
0123455555555543210 
0123456666666543210 
0123456777776543210 
0123456788876543210 
0123456789876543210 
0123456788876543210 
0123456777776543210 
0123456666666543210 
0123455555555543210 
0123444444444443210 
0123333333333333210 
0122222222222222210 
0111111111111111110 
0000000000000000000 

$ ./pyramid E 5
AAAAAAAAA           
ABBBBBBBA           
ABCCCCCBA           
ABCDDDCBA           
ABCDEDCBA           
ABCDDDCBA           
ABCCCCCBA           
ABBBBBBBA           
AAAAAAAAA           

希望它有帮助!