6
\$\begingroup\$

Your program must take an alpha/numeric input string and print it sideways (rotated 90 degrees clockwise). So for example, HI, would become:

#####
  #
#####

#####

Rules:

The shortest code wins. For the sake of objectivity this will be the standard font. The input still only has to be alpha-numeric. Capitalization does not matter.

\$\endgroup\$
  • 2
    \$\begingroup\$ I think the key problem here is "legible", which leans on the subjective side. It'd be better to provide an alphabet so we know what each letter should look like, but even then it'd only be a straight-out compression challenge. \$\endgroup\$ – Sp3000 Jun 15 '15 at 10:46
  • 2
    \$\begingroup\$ That makes sense. I went and found a font to eliminate the vagueness. \$\endgroup\$ – Kody King Jun 15 '15 at 11:03
  • 1
    \$\begingroup\$ The font does not have lowercase letters. You should either link to a font that does, or modify your sample output for "Hi". \$\endgroup\$ – Cristian Lupascu Jun 15 '15 at 11:37
  • 2
    \$\begingroup\$ Based on earlier experience, future questions may be: are functions accepted or needs to be a standalone program; can command line parameters be used instead of stdin; can the result returned instead of sent to stdout; number of empty lines between characters/words; is padding accepted/required; are other characters beside “#”, space and newline allowed. Is really irritating after you struggle to golf a solution strictly matching the specification to see someone else forcing the rules and the question owner just nodding that is acceptable too. \$\endgroup\$ – manatwork Jun 15 '15 at 13:55
  • 4
    \$\begingroup\$ This contest would be a lot more enjoyable if the question already contained the 36 characters we have to support. It would also eliminate a few ambiguities, like, e.g., the required width of and padding between two characters. \$\endgroup\$ – Dennis Jun 15 '15 at 14:35
10
\$\begingroup\$

C 550 503

#define L putchar('\n');
c,b,i,j,m[]={0xe9d72e,0x10fd25,0x9ace29,0x556b5,0x4fd184,0x16ad6bd,0x156ae,0xc5e10,0x556aa,0x756a8,0,0,0,0,0,0,0,0xfa51e0,0xaad7e0,0x118c5c0,0xe8c7e0,0x15ad7e0,0x14a53e0,0x16ac5c0,0x1f213e0,0xf8000,0x1e08440,0x11513e0,0x1087e0,0x1f4111f,0x1f223e0,0xe8c62e,0x8a53e0,0xd9462e,0x5d29f,0x12ad6a9,0x1087e10,0xf043e,0x18304d8,0x1c1f07c,0xd909b,0xf14bd,0xcd6b3};main(){for(;;){c=getchar();c=c<48?11:c>90?c-80:c-48;b=0;for(i=0;i<5;i++){for(j=0;j<5;j++)putchar(m[c]&(1<<b++)?35:32);L}L}}

(Incorporated BrainSteel's tips and optimized a bit more)

Here's the non-obfuscated code:

#include <stdio.h>

int map[]
={
    // 0 - 9
    0xe9d72e, 0x10fd25, 0x9ace29, 0x556b5, 0x4fd184, 0x16ad6bd, 0x156ae,     0xc5e10, 0x556aa, 0x756a8,
    // Other stuff
    0,0,0,0,0,0,0,
    // A - Z
    0xfa51e0, 0xaad7e0, 0x118c5c0, 0xe8c7e0, 0x15ad7e0, 0x14a53e0, 0x16ac5c0, 0x1f213e0, 0xf8000, 0x1e08440, 0x11513e0, 0x1087e0, 0x1f4111f, 0x1f223e0, 0xe8c62e, 0x8a53e0, 0xd9462e, 0x5d29f, 0x12ad6a9, 0x1087e10, 0xf043e, 0x18304d8, 0x1c1f07c, 0xd909b, 0xf14bd, 0xcd6b3
};

int main()
{
    for(;;)
    {
        int c = getchar();
        c = c < '0' ? 11 : c > 'Z' ? c - ('0' + 'a' - 'A') : c - '0';
        int bit = 0;
        for(int i=0; i<5; i++)
        {
            for(int j=0; j<5; j++)
                putchar(map[c] & (1 << bit++) ? '#' : ' ');
            putchar('\n');
        }
        putchar('\n');
    }
}

I've encoded the characters the following way: I wrote a C "script" that takes a 5x5 area of characters from STDIN, changes "space" to 0 and anything else to 1, rotates the whole area by 90 degrees and finally puts every cell of the area in one bit of a 32-bit integer (the hex numbers in 'map'). That's how the "script" looks like:

#include <stdio.h>

int main()
{
    int array[5][5];
    for(int i=0; i<5; i++)
    {
        for(int j=0; j<5; j++)
            array[j][i] = (getchar() != ' ');
        getchar();
    }
    int res = 0;
    int bit = 0;
    for(int j=0; j<5; j++)
    {
        for(int i=0; i<5; i++)
            res = res | (array[j][4-i] << bit++);
    }
    printf("0x%x\n", res);
    return 0;
}

I am pretty sure there are FAR smaller programs possible (for example in Perl or Ruby), but this is the best I can come up with right know.

\$\endgroup\$
  • 1
    \$\begingroup\$ Many compilers will allow you to skip the #include <stdio.h> entirely. You can also shorten int m[]={...};int main(){int c,b,i,j;...} to c,b,i,j,m[]={...};main(){...}, since the keyword int is the default if another type isn't specified. \$\endgroup\$ – BrainSteel Jun 15 '15 at 19:15
  • \$\begingroup\$ Welcome to PPCG! Excellent first effort, +1. You could do with more compression of your font data by converting it to a string, which is a fairly standard practice round here. Check my answer for an example. \$\endgroup\$ – Level River St Jun 15 '15 at 19:39
  • \$\begingroup\$ putchar('\n') --> puts("") , b=0;for(i=0;i<5;i++) --> for(i=b=0;i<5;i++) \$\endgroup\$ – Spikatrix Jun 18 '15 at 8:52
7
\$\begingroup\$

Mathematica 120 119

This should work.

g@t_:=GraphicsGrid[Transpose@Reverse@ImageData@Binarize@Rasterize@Style[t,{12,FontFamily->"Pixelette"}] /.{1 ->" ",0-> "#"}]

The function g takes the input text, converts to Pixelette font, rasterizes it, flips it (Reverse and Transpose), examines the array of 1s and 0s, and outputs the ASCII text (as text, not as an image or graphic). GraphicsArray conveniently displays the ASCII output in a table.

I used "HELLO" as the input because each letter in "HI" is horizontally and vertically symmetric, hence HI is a bad choice to use for testing.

g["HELLO"] 

pixelette

\$\endgroup\$
  • 3
    \$\begingroup\$ Interesting, but excluding the font data puts you at a big advantage. My program is 155 code + 180 font data. \$\endgroup\$ – Level River St Jun 15 '15 at 19:35
  • \$\begingroup\$ Your concern was correct with regard to my earlier version. Now Pixelette font is automatically called just as any font might be called. \$\endgroup\$ – DavidC Jun 15 '15 at 22:35
4
\$\begingroup\$

Python 2, 376 364 361 315

This is my first attempt at code golf.

The font is encoded as a single large integer in which each character takes up 25 bits - 5 columns of 5 pixels each. It reads its input from stdin as a Python string (including the quotes).

Updated three times to reduce size. The third update incorporates changes suggested by Sp3000.

for c in input().upper():
 c=ord(c)-48
 if c>9:c-=7
 s,l='',int('17vhur2t4cze6tuj2ja3e1i8luj1b1frxdf9pg8dxjw7ian4517nliqqn8tdogkck15rn5n6vz3l5zf1u10cv5trc4n49xtznzx7egrjllrn8e1nlgyjp3z481ffsqmiw3pj3a538wnhwydpp85o9j85kzqxfl3qop50sokgcvwfn2',36)>>25*c
 for i in range(25):
  s+=' #'[l&1];l/=2
  if i%5>3:print s;s=''
\$\endgroup\$
  • \$\begingroup\$ I think you can also remove line 3 by turning the end of line 4 into 25*(c-7*(c>9)), which gets rid of a few lines of indenting \$\endgroup\$ – Sp3000 Jun 17 '15 at 9:45
3
\$\begingroup\$

C,335

Score excludes whitespace, which is unnecessary and only included for clarity.

In the absence of further info from the OP, I have assumed exactly one blank space is required between characters. If padding is required, backtick (ASCII 96) can be used (not sure how that character will display here.)

After converting to uppercase with c-c/91*32, I search the big string for the required character, and set a pointer to the character after it. This makes it easy to handle the variable width font. It also avoids the need to unite the ASCII ranges for letters and numbers.

The font data is contained, column by column, in the big string. As only 5 bits are required, only ASCII codes 95 and over are used. The next code below 90 signals the end of the character.

The program tends to segfault on characters outside the alphanumeric range.

char*p,s[99],c,i,j,k;
main(){
  for(scanf("%s",&s);c=s[i];i++){
    p=strchr("A~ee~B_uujCnqqqD_qqnE_uuF_eeGnqu}H_dd_I_JhppoK_djqL_ppM_bdb_N_bd_OnqqnP_eebQnqivR_emrSruuiTaa_aaUoppoVclplcWgxgxgX{dd{YwttoZyuus0nyusn1r_p2ryur3quuj4ljk_5wuum6nuuh7aa}c8juuj9buun",c-c/91*32)+1;
    for(;*p>90;p++)for(k=5;k--;k||puts(""))putchar(*p>>k&1?35:32);
    puts(""); 
  }  
}
\$\endgroup\$
  • \$\begingroup\$ Remove the & from scanf. You shouldn't use it when scanning a %s. Or use the dangerous gets in place of scanf. \$\endgroup\$ – Spikatrix Jun 16 '15 at 5:07
  • \$\begingroup\$ It is amazing that you managed to do it in 335 bytes. I am still trying to understand how you did it. It would be even better if it can print out string including white spaces. This program might actually have some real world applications. \$\endgroup\$ – some user Jun 19 '15 at 5:59
  • \$\begingroup\$ @someuser if you want to support the space character all you need to do is add a space followed by n backticks (ASCII 96)to the big string (where n is the width of the space character desired.) With the suggestion from CoolGuy I could save 8 bytes, and there's a further 1 byte to be saved by putting p=strchr() inside the following for loop bracket, so the program could actually be shorter. \$\endgroup\$ – Level River St Jun 19 '15 at 23:53
1
\$\begingroup\$

Java 8 - 404

First time posting here. This program takes a single argument on the command line. Java 8 is required (Java 7 can be used at a cost of 3 additional characters).

class A{public static void main(String[]a){a[0].chars().forEach(c->{String o="";c-=c>57?c>90?87:55:48;for(char d:">AA>09O1009CE90AEE:06:BO0MEEF0>EE20@@GH0:EE:08EE>0?DD?0OEE:0>AAA0OAA>0OEE00ODD00>AEG0O44O0O0000211N0O4:A0O1100O848OO84O0>AA>0ODD80>AB=0ODF909EEB0@@O@@N11N0H616HL3L3LK44K0M55N0CEEI0".substring(c*=5, c+5).toCharArray()){for(d-=48;d>0;d/=2)o+=d%2==1?'#':32;o+="\n";}System.out.println(o);});}}

Unobfuscated version:

class A {
    public static void main(String[] a) {
        a[0].chars().forEach(
                c -> {
                    String o = "";
                    c -= c > 57 ? c > 90 ? 87 : 55 : 48;
                    for (char d: (">AA>09O1009CE90AEE:06:BO0MEEF0>EE20@@GH0:EE:08EE>0?DD?0"
                            + "OEE:0>AAA0OAA>0OEE00ODD00>AEG0O44O0O0000211N0O4:A0O1100O848O"
                            + "O84O0>AA>0ODD80>AB=0ODF909EEB0@@O@@N11N0H616HL3L3LK44K0M55N0"
                            + "CEEI0").substring(c *= 5, c + 5).toCharArray())
                    {
                        for (d -= 48; d > 0; d /= 2)
                            o += d % 2 == 1 ? ' ' : 32;
                        o += "\n";
                    }
                    System.out.println(o);
                }
        );
    }
}

Each row of pixels is encoded in the 5 least significant bits of a byte in the long string, and ASCII '0' is added to make the string contain only printable characters. The code simply translates each character in the input string to an index into the string, iterating through the 5 bytes representing the respective character, and decoding them using the reverse process. There are more compact encodings, but they would be more complex to decode and would probably inflate the code size too much to be worthwhile.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.