365 Days of Code - Day 062

Project Status

ProjectLanguageStatusDue DateLatest Update
Personal WebsiteHugoOngoingNoneThe site is live. Continuous improvements ongoing.
Laravel From ScratchLaravel (PHP)In-Progress2026-03-31Episode 8
PRMLaravel (PHP)In-Progress2026-03-31Working alongside other Laravel projects.
Client Website (J.L.)Laravel (PHP)In-Progress2026-03-31Working alongside other Laravel projects.
Project EulerCOngoingNoneWorking on P25. BigInt (AI gen) was a waste of time, need to rewrite
Practice JavaJavaPausedNoneInstalled, need to find a good project.
Practice PythonPythonPausedNoneInstalled, need to find a good project.
Learn GoGoPausedNoneInstalled, work on LDAP Injector from ippsec.
Learn RustRustHaven’t StartedNoneInstalled, will try network protocols after finishing in C and Zig.
Learn ElixirElixirHaven’t StartedNoneInstalled, need a good tutorial project.
Learn HaskellHaskellHaven’t StartedNoneInstalled, need a good tutorial project.
Learn ZigZigHaven’t StartedNoneInstalled, will try network protocols after finishing in C.
Linux+N/AIn-Progress2026-03-31Reading Chapter 4.
Cyber Quest 2026N/AIn-Progress2026-02-28Finished quiz 1 with 75%.
Operating SystemsN/AIn-Progress2026-03-31Reading Chapter 4: Abstraction
Grey-Hat HackingVariousIn-Progress2026-03-31Reading Chapter 8: Threat Hunting Lab
PHP Time TrackerPHPBeta FinishedNoneWorking on a basic level.
HTTP Status Code ReaderCComplete2026-02-18Complete.
ZSH Configurationbash/zshCompleteNoneSort of an ongoing process, but complete for now. Works good.
Network ProtocolsCIn-ProgressNoneWorking on V3, implementing IPv6.
Discinox WebsiteHTML, CSS, JSComplete2026-03-04The site is live.
DiroffTech WebsiteHTML, CSS, JSComplete2026-03-05The site is live. git-lfs needs to be initialized for images.
Automate BackupsbashComplete2026-03-08Backups done.
CodinGameCOngoingNoneCompleted GhostLegs, ASCII Art.

CodinGame - ASCII Art - Part 2

Continuing from yesterday’s effort. I have uppercase letters handled, and now need to handle lowercase and non-alpha characters.

Again, I should be able to turn to some ASCII math to help handle this.

Handling Lowercase and Non-Alpha

The lowercase letters in ASCII produce the same offsets as uppercase, just at a different integer. Just as we used A to do the subtraction, a can be used for the subtraction of lowercase letters. Anything that doesn’t fit between A-Z or a-z is an unknown character, and gets the question mark.

c
char ch = '1';
int n;
if (ch >= 'A' && ch <= 'Z')
{
    n = ch - 'A';
}
else if (ch >= 'a' && ch <= 'z')
{
    n = ch - 'a';
}
else
{
    n = 26;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
char ch = '1';
int n;
if (ch >= 'A' && ch <= 'Z')
{
    n = ch - 'A';
}
else if (ch >= 'a' && ch <= 'z')
{
    n = ch - 'a';
}
else
{
    n = 26;
}

I hardcoded the ch variable to test each of the letters.

Handling Multi-Letter Input

Single characters are handled. Let’s work on a string. We just need to grab each character in the string, and loop over everything.

c
char ch;
char *str = "abc";
int str_len = strlen(str);
int n = 0;
for (int i = 0; i < str_len; ++i)
{
    ch = str[i];
    if (ch >= 'A' && ch <= 'Z')
    {
        n = ch - 'A';
    }
    else if (ch >= 'a' && ch <= 'z')
    {
        n = ch - 'a';
    }
    else
    {
        n = 26;
    }

    for (int j = 0; j < H; ++j)
    {
        for (int k = 0; k < L; ++k)
        {
            fprintf(stderr, "%c", arr[((n * L) + k) + (L * 27 * j)]);
        }
        fprintf(stderr, "\n");
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
char ch;
char *str = "abc";
int str_len = strlen(str);
int n = 0;
for (int i = 0; i < str_len; ++i)
{
    ch = str[i];
    if (ch >= 'A' && ch <= 'Z')
    {
        n = ch - 'A';
    }
    else if (ch >= 'a' && ch <= 'z')
    {
        n = ch - 'a';
    }
    else
    {
        n = 26;
    }

    for (int j = 0; j < H; ++j)
    {
        for (int k = 0; k < L; ++k)
        {
            fprintf(stderr, "%c", arr[((n * L) + k) + (L * 27 * j)]);
        }
        fprintf(stderr, "\n");
    }
}
  • Output:
plaintext
 #
# #
###
# #
# #
##
# #
##
# #
##
 ##
#
#
#
 ##
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
 #
# #
###
# #
# #
##
# #
##
# #
##
 ##
#
#
#
 ##

Oops, we are populating a newline after each character. This is not to straightforward to fix. We may need to write each line, of each character, before the newline. In order to do that, we need to read a character, print the top row, read the next character, continue printing the top row, and so on, for all characters. Then create a newline, and repeat, but for the second row. Similar to how a dot matrix printer works.

And… this ended up being easier than expected to fix. Once I started to analyze the problem, I realized I just needed to pull the height loop and turn it into the outer loop. I didn’t even have to change any of the variable names.

c
for (int j = 0; j < H; ++j)
{
    for (int i = 0; i < str_len; ++i)
    {
        ch = str[i];
        if (ch >= 'A' && ch <= 'Z')
        {
            n = ch - 'A';
        }
        else if (ch >= 'a' && ch <= 'z')
        {
            n = ch - 'a';
        }
        else
        {
            n = 26;
        }

        for (int k = 0; k < L; ++k)
        {
            fprintf(stderr, "%c", arr[((n * L) + k) + (L * 27 * j)]);
        }
    }
    fprintf(stderr, "\n");
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
for (int j = 0; j < H; ++j)
{
    for (int i = 0; i < str_len; ++i)
    {
        ch = str[i];
        if (ch >= 'A' && ch <= 'Z')
        {
            n = ch - 'A';
        }
        else if (ch >= 'a' && ch <= 'z')
        {
            n = ch - 'a';
        }
        else
        {
            n = 26;
        }

        for (int k = 0; k < L; ++k)
        {
            fprintf(stderr, "%c", arr[((n * L) + k) + (L * 27 * j)]);
        }
    }
    fprintf(stderr, "\n");
}

Output with abcABC123:

plaintext
 #  ##   ##  #  ##   ## ### ### ###
# # # # #   # # # # #     #   #   #
### ##  #   ### ##  #    ##  ##  ##
# # # # #   # # # # #
# # ##   ## # # ##   ##  #   #   #
1
2
3
4
5
 #  ##   ##  #  ##   ## ### ### ###
# # # # #   # # # # #     #   #   #
### ##  #   ### ##  #    ##  ##  ##
# # # # #   # # # # #
# # ##   ## # # ##   ##  #   #   #

Perfect. Now let’s try to read in the real string… and we passed with 100%.

Final Code

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

int main()
{
    int L;
    scanf("%d", &L);
    int H;
    scanf("%d", &H); fgetc(stdin);

    char *arr = malloc(L * H * 27 * sizeof(char));

    char T[257] = "";
    scanf("%[^\n]", T); fgetc(stdin);
    for (int i = 0; i < H; i++) {
        char ROW[1025] = "";
        scanf("%[^\n]", ROW); fgetc(stdin);
        // fprintf(stderr, "%s", ROW);
        int row_len = L * 27;
        for (int j = 0; j < row_len; ++j)
        {
            arr[(i * row_len) + j] = ROW[j];
        }
        // for (int j = 0; j < row_len; ++j)
        // {
        //     fprintf(stderr, "%c", arr[(i * row_len) + j]);
        // }
        // fprintf(stderr, "\n");
    }

    char ch;
    // char *str = "abcABC123";
    int str_len = strlen(T);
    int n = 0;
    for (int j = 0; j < H; ++j)
    {
        for (int i = 0; i < str_len; ++i)
        {
            ch = T[i];
            if (ch >= 'A' && ch <= 'Z')
            {
                n = ch - 'A';
            }
            else if (ch >= 'a' && ch <= 'z')
            {
                n = ch - 'a';
            }
            else
            {
                n = 26;
            }

            for (int k = 0; k < L; ++k)
            {
                // fprintf(stderr, "%c", arr[((n * L) + k) + (L * 27 * j)]);
                printf("%c", arr[((n * L) + k) + (L * 27 * j)]);
            }
        }
        // fprintf(stderr, "\n");
        printf("\n");
    }
    // fprintf(stderr, "%i\n", n);

    // fprintf(stderr, "%c%c%c%c\n", arr[((n * L) + 0) + (4 * 27 * 0)], arr[((n * L) + 1) + (4 * 27 * 0)], arr[((n * L) + 2) + (4 * 27 * 0)], arr[((n * L) + 3) + (4 * 27 * 0)]);
    // fprintf(stderr, "%c%c%c%c\n", arr[((n * L) + 0) + (4 * 27 * 1)], arr[((n * L) + 1) + (4 * 27 * 1)], arr[((n * L) + 2) + (4 * 27 * 1)], arr[((n * L) + 3) + (4 * 27 * 1)]);
    // fprintf(stderr, "%c%c%c%c\n", arr[((n * L) + 0) + (4 * 27 * 2)], arr[((n * L) + 1) + (4 * 27 * 2)], arr[((n * L) + 2) + (4 * 27 * 2)], arr[((n * L) + 3) + (4 * 27 * 2)]);
    // fprintf(stderr, "%c%c%c%c\n", arr[((n * L) + 0) + (4 * 27 * 3)], arr[((n * L) + 1) + (4 * 27 * 3)], arr[((n * L) + 2) + (4 * 27 * 3)], arr[((n * L) + 3) + (4 * 27 * 3)]);
    // fprintf(stderr, "%c%c%c%c\n", arr[((n * L) + 0) + (4 * 27 * 4)], arr[((n * L) + 1) + (4 * 27 * 4)], arr[((n * L) + 2) + (4 * 27 * 4)], arr[((n * L) + 3) + (4 * 27 * 4)]);

    // Write an answer using printf(). DON'T FORGET THE TRAILING \n
    // To debug: fprintf(stderr, "Debug messages...\n");

    // fprintf(stderr, "L: %i, H: %i\n", L, H);
    free(arr);
    return 0;
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdbool.h>

int main()
{
    int L;
    scanf("%d", &L);
    int H;
    scanf("%d", &H); fgetc(stdin);

    char *arr = malloc(L * H * 27 * sizeof(char));

    char T[257] = "";
    scanf("%[^\n]", T); fgetc(stdin);
    for (int i = 0; i < H; i++) {
        char ROW[1025] = "";
        scanf("%[^\n]", ROW); fgetc(stdin);
        // fprintf(stderr, "%s", ROW);
        int row_len = L * 27;
        for (int j = 0; j < row_len; ++j)
        {
            arr[(i * row_len) + j] = ROW[j];
        }
        // for (int j = 0; j < row_len; ++j)
        // {
        //     fprintf(stderr, "%c", arr[(i * row_len) + j]);
        // }
        // fprintf(stderr, "\n");
    }

    char ch;
    // char *str = "abcABC123";
    int str_len = strlen(T);
    int n = 0;
    for (int j = 0; j < H; ++j)
    {
        for (int i = 0; i < str_len; ++i)
        {
            ch = T[i];
            if (ch >= 'A' && ch <= 'Z')
            {
                n = ch - 'A';
            }
            else if (ch >= 'a' && ch <= 'z')
            {
                n = ch - 'a';
            }
            else
            {
                n = 26;
            }

            for (int k = 0; k < L; ++k)
            {
                // fprintf(stderr, "%c", arr[((n * L) + k) + (L * 27 * j)]);
                printf("%c", arr[((n * L) + k) + (L * 27 * j)]);
            }
        }
        // fprintf(stderr, "\n");
        printf("\n");
    }
    // fprintf(stderr, "%i\n", n);

    // fprintf(stderr, "%c%c%c%c\n", arr[((n * L) + 0) + (4 * 27 * 0)], arr[((n * L) + 1) + (4 * 27 * 0)], arr[((n * L) + 2) + (4 * 27 * 0)], arr[((n * L) + 3) + (4 * 27 * 0)]);
    // fprintf(stderr, "%c%c%c%c\n", arr[((n * L) + 0) + (4 * 27 * 1)], arr[((n * L) + 1) + (4 * 27 * 1)], arr[((n * L) + 2) + (4 * 27 * 1)], arr[((n * L) + 3) + (4 * 27 * 1)]);
    // fprintf(stderr, "%c%c%c%c\n", arr[((n * L) + 0) + (4 * 27 * 2)], arr[((n * L) + 1) + (4 * 27 * 2)], arr[((n * L) + 2) + (4 * 27 * 2)], arr[((n * L) + 3) + (4 * 27 * 2)]);
    // fprintf(stderr, "%c%c%c%c\n", arr[((n * L) + 0) + (4 * 27 * 3)], arr[((n * L) + 1) + (4 * 27 * 3)], arr[((n * L) + 2) + (4 * 27 * 3)], arr[((n * L) + 3) + (4 * 27 * 3)]);
    // fprintf(stderr, "%c%c%c%c\n", arr[((n * L) + 0) + (4 * 27 * 4)], arr[((n * L) + 1) + (4 * 27 * 4)], arr[((n * L) + 2) + (4 * 27 * 4)], arr[((n * L) + 3) + (4 * 27 * 4)]);

    // Write an answer using printf(). DON'T FORGET THE TRAILING \n
    // To debug: fprintf(stderr, "Debug messages...\n");

    // fprintf(stderr, "L: %i, H: %i\n", L, H);
    free(arr);
    return 0;
}

Top Rated C Solution

I had a look at the top rated C solution for this problem… and this guy fucks (opens in a new tab).

  • Courtesy of Alain-Delpuch
c
#include <stdio.h>
#include <ctype.h>

main() {
    int L,H;
    scanf("%d%d ", &L, &H);

    char ROW[28][L];

    char T[257];
    gets(T);

    while (H--) {
        gets(ROW);
        for (char *p=T;*p;p++) { // for all letters to display
            unsigned int c = toupper(*p) - 'A';
            if ( c > 26 ) c = 26;
            printf("%.*s", L, ROW+c);
        }
        printf("\n"); ;
    }
}
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>
#include <ctype.h>

main() {
    int L,H;
    scanf("%d%d ", &L, &H);

    char ROW[28][L];

    char T[257];
    gets(T);

    while (H--) {
        gets(ROW);
        for (char *p=T;*p;p++) { // for all letters to display
            unsigned int c = toupper(*p) - 'A';
            if ( c > 26 ) c = 26;
            printf("%.*s", L, ROW+c);
        }
        printf("\n"); ;
    }
}

Such elegance.

Related content