So you want to generate 10x10 bitmap characters, and presumably already have a method of outputting bitmap data to a display device.
The usual way to do this is to store the pixel data for each character in a const 2D array, with the first index being the character code, and the second being the row (or column) of binary data, where each '1' bit indicates that pixel is on/foreground color and each '0' bit indicates off/background color. Whether you organize the font data by rows or by columns depends on the word => pixel layout of your display device. Your 10 bit data would be zero padded to form 16 bit words that can be stored as uint16_t. Assuming you are using a cross-compiler for an embedded MCU/CPU that supports binary constants, or GCC, and your data is organized by rows, MSB on the left, you can directly enter your font data in the patterns it will be displayed in as binary constants (https://gcc.gnu.org/onlinedocs/gcc/Binary-constants.html) (prefix 0b).
e.g.:
uint16_t letter_L[10]={
0b0100000000,
0b0100000000,
0b0100000000,
0b0100000000,
0b0100000000,
0b0100000000,
0b0100000000,
0b0100000000,
0b0111111111,
0b0000000000
};
which assumes the first column and last row are normally left blank, for seperation from the previous character's bitmap and from the next line of text.
Note that I have shown a single dimension array for a single letter. Unless memory is not a constraint, you wouldn't use raw ASCII for the character coding, as you'd probably want to eliminate the first 32 non-printing characters and may not need the full ASCII character set, so may need to write a mapping function to translate ASCII codes to your character coding.
So you want to generate 10x10 bitmap characters, and presumably already have a method of outputting bitmap data to a display device.
Sorry for misunderstanding maybe I didn't draft my question properly. Like we make pyramids in C programming from ⭐ I am trying to make L from star ⭐
Ah, I've got you - its job interview test coding pattern stupidity.
This certainly wont win you the job, but is almost certainly the simplest/shortest way to output a 10x10 L in * characters!
#include<stdio.h>
int main(){
printf("*\n*\n*\n*\n*\n*\n*\n*\n*\n**********\n");
}
Ah, I've got you - its job interview test coding pattern stupidity.
This certainly wont win you the job, but is almost certainly the simplest/shortest way to output a 10x10 L in * characters!
#include<stdio.h>
int main(){
printf("*\n*\n*\n*\n*\n*\n*\n*\n*\n**********\n");
}
yes it is the easy way but it is not what i want.
This method is not suitable if I want output a 2000x2000 L in * characters!
Now how can we develop algorithm to get this output or what logic would be useful to implement it?
Hi,
I want to make it clear in advance that what I am asking is not homework. I have chosen a problem for myself that I want to solve. I don't need code I need your help to solve problem.
I just want to see how do you think to solve a problem. I think this would be the simplest letter in alphabet to print
I want to draw L pattern in c programming.
I am using nested for loop to create 10 rows and 10 columns
I do not understand what to do so that only the first column and the last row are printed.
You have answered your own question in the red text. Why don't you just write a program that does what the red text says?
In other words:
for rows from 1 to 10:
for columns from 1 to 10:
if first column or last row print '*' else print ' '
Have you tried this, and where are you getting stuck? Please post your code so we can see what you have tried so far.
I often use Netpbm (https://en.wikipedia.org/wiki/Netpbm) image formats for my code and math experiments, especially the binary P6 format with 24-bit RGB color, because it is trivial to output from a program and easy to display, or convert to e.g. PNG or JPEG.
Here, it is the core idea that matters: using an array of some sort, as a canvas to draw to, and then output the contents of that canvas in a suitable format.
If you do not have color, only presence/absence –– foreground/background, asterisk or space ––, then using binary, one bit per pixel (https://en.wikipedia.org/wiki/Pixel), is the most efficient way. This is what Ian.M described in reply #1 (https://www.eevblog.com/forum/programming/how-would-you-draw-l-pattern/msg4355779/#msg4355779).
If you use color, or more generally have more than two states per pixel, then each pixel needs a larger range of values, so it is common to use an array of chars, or perhaps one of the uintN_t exact-size integer types as provided by <stdint.h> or <inttypes.h>.
For example, you could use
const unsigned char canvas[5][4] = {
{ 1, 3, 0, 0 },
{ 4, 6, 0, 0 },
{ 4, 6, 0, 0 },
{ 4, 7, 2, 3 },
{ 7, 8, 8, 9 },
};
If one uses char as the array element type, then one can specify each row as a string. However, then the elements of the array are the numbers corresponding to those characters, most often their ASCII (https://en.wikipedia.org/wiki/ASCII#Printable_characters) code. (Unicode, ISO Western European, and Windows Western European code page character sets are all compatible with ASCII codes – they just extend the ASCII set, basically –, so that's why we still use the ASCII code table even though we usually use much larger character sets nowadays.)
Also, because each string is terminated by a NUL char (0 or '\0'), one should reserve space for that in the horizontal/last dimension.
Now, those digits are actually not random at all. I chose them using the following logic:
1 2 3 ┌ ─ ┐
4 5 6 = │ ╳ │ with 0 as blank
7 8 9 └ ─ ┘
so that logically, the canvas above describes a 4-column, 5-row figure,
┌┐
││
││
│└─┐
└──┘
(For this figure, I used the Unicode Box Drawing (https://en.wikipedia.org/wiki/Box_Drawing) block, which is supported by browsers, but may need extra support from your C code to output from a program, especially if you are using Windows, or use a sensible operating system but not an UTF-8 -based locale.)
The reason for doing that is that if you wanted to output the shape in a very large form, you could then define a set of arrays to describe each pixel in your output. If you make those say 8×8, you could then emit the figure as 40 rows and 32 columns. If those define binary pixels (foreground/background, visible/blank), then you can apply an another level of scaling, by outputting each pixel as a rectangular block of pixels all in that same state.
This last step in scaling is probably what OP is actually looking for right now.
The idea is that when we scale each pixel to R rows and C columns, and we output in row-major order (https://en.wikipedia.org/wiki/Row-_and_column-major_order) (the same order this text is written in, as rows of text from left to right, rows from top to bottom), we repeat each row R times. Within each row, we duplicate each pixel to C.
For example, if we use the array
const unsigned char letter_L[5] = {
1, /* 1 + 0 + 0 + 0 */
1, /* 1 + 0 + 0 + 0 */
1, /* 1 + 0 + 0 + 0 */
1, /* 1 + 0 + 0 + 0 */
15, /* 1 + 2 + 4 + 8 */
};
to encode a 4-column, 5-row canvas in the four least significant bits of unsigned chars (they are guaranteed to have at least 8 bits in C), we can emit it using for example
void output_canvas(const unsigned char *canvas, int rowscale, int colscale, int bit1, int bit0, FILE *out)
{
for (int row = 0; row < 5; row++) {
for (int rowrepeat = 0; rowrepeat < rowscale; rowrepeat++) {
for (int col = 0; col < 4; col++) {
const int bit = (canvas[row] >> col) & 1;
for (int colrepeat = 0; colrepeat < colscale; colrepeat++) {
if (bit) {
fputc(bit1, out);
} else {
fputc(bit0, out);
}
}
}
fputc('\n', out);
}
}
}
so that if you called output_canvas(letter_L, 7, 6, '*', ' ', stdout); you'd get a 7×5=35-row, 6×4=24-column letter L on standard output, consisting of asterisks (*) and spaces ( ).
Consider the four nested loops above. If we added a lookup, so that clear bits are described by one canvas, and set bits by another, both rowscale rows and colscale columns, then bit specifies the lookup canvas, rowrepeat the row within the lookup canvas, and colrepeat the column within the lookup canvas.
If we used a structure to describe a canvas, say
#include <stdlib.h>
#include <limits.h>
typedef unsigned long cell;
#define CELL_BITS (sizeof (unsigned long) * CHAR_BIT)
typedef struct {
int rows;
int columns;
size_t stride; /* Number of data cells per row */
cell *data;
} bitcanvas;
void bitcanvas_set(bitcanvas *canvas, int row, int column)
{
if (canvas && row >= 0 && row < canvas->rows && column >= 0 && column < canvas->columns)
canvas->data[(size_t)row * canvas->stride + (size_t)column / CELL_BITS] |= 1 << (column % CELL_BITS);
}
int bitcanvas_get(bitcanvas *canvas, int row, int column)
{
if (canvas && row >= 0 && row < canvas->rows && column >= 0 && column < canvas->columns)
return (canvas->data[(size_t)row * canvas->stride + (size_t)column / CELL_BITS] >> (column % CELL_BITS)) & 1;
else
return 0;
}
void bitcanvas_free(bitcanvas *canvas)
{
if (canvas) {
free(canvas->data);
canvas->rows = 0;
canvas->columns = 0;
canvas->stride = 0;
canvas->data = NULL;
}
}
int bitcanvas_init(bitcanvas *canvas, int rows, int columns)
{
size_t stride;
/* No canvas? */
if (!canvas)
return -1;
/* We're diligent, and clear the structure to known invalid values first. */
canvas->rows = 0;
canvas->columns = 0;
canvas->stride = 0;
canvas->data = NULL;
/* Invalid size? */
if (rows < 1 || columns < 1)
return -1;
/* Number of cells on each row: columns / BITS_PER_CELL, rounded up. */
stride = ((size_t)columns + BITS_PER_CELL - 1) / BITS_PER_CELL;
/* Allocate canvas data dynamically. */
canvas->data = calloc(stride, (size_t)rows);
if (!canvas->data)
return -1;
canvas->rows = rows;
canvas->columns = columns;
canvas->stride = stride;
return 0;
}
then the scaled output –– drawing one canvas using two other canvases (of the same size) for each pixel –– would be rather straightforward:
void output_mapped_bitcanvas(bitcanvas *canvas, bitcanvas *bit1, bitcanvas *bit0, int pixel1, int pixel0, FILE *out)
{
/* Safety checks first. */
if (!canvas || canvas->rows < 1 || canvas->columns < 1 ||
!bit1 || bit1->rows < 1 || bit1->columns < 1 ||
!bit0 || bit0->rows != bit1->rows || bit0->columns != bit1->columns ||
!out)
return;
for (int row = 0; row < canvas->rows; row++) {
for (int subrow = 0; subrow = bit1->rows; subrow++) {
for (int column = 0; column < canvas->columns; column++) {
bitcanvas *bit = bitcanvas_get(canvas, row, column) ? bit1 : bit0;
for (int subcolumn = 0; subcolumn = bit1->columns; subcolumn++) {
fputc(bitcanvas_get(bit, subrow, subcolumn) ? pixel1 : pixel0, out);
}
}
fputc('\n', out);
}
}
}
where (expression) ? (if-true) : (if-false) is the ternary conditional expression in C. If the expression is true or nonzero, then the statement evaluates to (i]if-true[/i]), otherwise it evaluates to (if-false). Consider it a condensed form of an if statement, except inside an expression so that it always evaluates to one of the results.
The point of this latter part is to show OP exactly why structures and splitting operations into separate functions is so powerful. With a very similar loop that can scale a bitmap using "dumb" repetition, we can scale a bitmap using two other bitmaps to represent each state!
And yes, we could add two or four other bitmaps, to describe each bit in the sub-bitmaps, with not too much effort, but it so quickly becomes so large that standard output no longer suffices. Which brings me a full circle to the beginning of this post, to Netpbm image formats. It would be very straightforward to add a function that saves a bitcanvas as a PBM file. I could then also add a function that creates a new bitmap by doing what output_mapped_bitcanvas() does, describing each pixel/bit in one canvas by one of two other canvases. And even the three-layer one, for those really big images. Finally, add a blit function that copies a canvas to a specific position in another canvas, and you can start building some really complex bitmap images. (It also leads to a fun little rabbit hole called rasterization (https://en.wikipedia.org/wiki/Rasterization), which can easily take years to explore. I'm personally still deep in there somewhere!)
And all this not really that far from the initial asterisk experiments... A lot to learn, for sure, but fun as heck, too.