37
\$\begingroup\$

Be sure to see the other challenge,Reverse ASCII character map!

The ASCII charset (American Standard Code for Information Interchange) is the most widely-used character encoding standard. ASCII codes represent text in computers, telecommunications equipment, and other devices.

Challenge

Your challenge is to print a mapping of the ASCII character set as the user inputs them. GIF:

gif

After the user enters every ASCII character, the output should look like this:

table

Mapping

Each character has an assigned position on a 16x6 logical grid, starting with the space character in the top left position, and wrapping such that the digit 0 appears below it.

When printable ASCII input is received, print that ASCII character at its assigned screen location without deleting any of the characters currently onscreen.

Rules

  • Your program only needs to map out the printable ASCII characters,0x20 to0x7E.
  • Your program must not terminate and continue to map characters to the screen until all printable ASCII characters have been inputted. From here, your program can either terminate or run off into Neverland.
  • Your program can map characters any way you like, e.g. to a spreadsheet, table, console window, or a graphical window.
  • No matter how you display the mapping, it must be updated in realtime (as soon as it receives user input).
  • If your program does not read input silently, it must put the cursor out of the way, so the text won't get in the way of the map.

Help

Here is the pseudocode algorithm I used to generate the GIF:

loop forever    c = input    y_coord = c / 16    x_coord = c - y * 16    if c is printable        print c at (x_coord * 2 + 1, y_coord + 1)    end ifend loop

There may be another way to achieve the required output. You can choose to use my algorithm or your own, but the output must be the same regardless.

Here's a useful ASCII table reference.

Scoring

The answer with the least bytes in each language wins. Have fun!

askedJun 3, 2017 at 0:03
MD XF's user avatar
\$\endgroup\$
10
  • \$\begingroup\$Do we need to have spaces between the characters?\$\endgroup\$CommentedJun 3, 2017 at 0:28
  • \$\begingroup\$@musicman523 Yep, those are necessary. The output must lookexactly as shown in the screenshots.\$\endgroup\$CommentedJun 3, 2017 at 0:29
  • \$\begingroup\$Are we allowed to assume the terminal's background color?\$\endgroup\$CommentedJun 3, 2017 at 0:38
  • \$\begingroup\$Is clearing the terminal, then redrawing the updated table for each char acceptable?\$\endgroup\$CommentedJun 3, 2017 at 0:40
  • \$\begingroup\$@DigitalTrauma - Redrawing each time is acceptable - I asked in the Sandbox post\$\endgroup\$CommentedJun 3, 2017 at 0:41

19 Answers19

19
\$\begingroup\$

JavaScript (ES6) + HTML, 114 + 16 = 130 bytes

Saved 16 bytes thanks to @Shaggy

a=Array(96).fill` `;onkeypress=k=>(a[k.key.charCodeAt()-32]=k.key,O.innerText=a.join` `.match(/.{1,32}/g).join``)
<pre id=O></pre>

It's so unbelievably satisfying to just mash the keyboard...

answeredJun 3, 2017 at 2:39
ETHproductions's user avatar
\$\endgroup\$
9
  • 10
    \$\begingroup\$"so unbelievably satisfying to just mash the keyboard" may or may not have been what I was going for. +1\$\endgroup\$CommentedJun 3, 2017 at 3:01
  • \$\begingroup\$And yes, you can assume only printable ASCII is given. I'm pretty sure that's rule #1.\$\endgroup\$CommentedJun 3, 2017 at 3:02
  • \$\begingroup\$Can't you just useprompt() within a loop? It will save you from all the event handling and HTML. OP seems to allow it. See the Mathematica post's comments.\$\endgroup\$CommentedJun 3, 2017 at 7:04
  • \$\begingroup\$Only handles printable ASCII; subtract 7 bytes if we can assume only printable ASCII is given That does not seem to make sense. If it only handles printable ASCII, then how can assuming printable ASCII save any bytes?\$\endgroup\$CommentedJun 3, 2017 at 7:07
  • \$\begingroup\$You should be able to just useonkeypress by itself, allowing you to drop thebody tag. Also, thepre tag can be shortened to just<pre id=O. Although, you'll need to include the closing> in order for it to work in a Snippet.\$\endgroup\$CommentedJun 3, 2017 at 9:43
16
\$\begingroup\$

QBasic 4.5,81 85 bytes

Added 4 bytes to comply with the spacing-rule.

DOLOCATE 7,1LINE INPUT A$:i=ASC(A$)LOCATE i\16-1,(i MOD 16+1)*2?CHR$(i)LOOP

And the output will look like this (NOTE: Old screenshot, now every character is separated by a space):enter image description here

QBasic has theLOCATE command, which comes in handy here. A breakdown of this code:

DO                          Starts an infinite loopLOCATE 7,1                  Moves the cursor out of the wayLINE INPUT A$:i=ASC(A$)     LINE INPUT gets user input; we need LINE INPUT instead of regular input                            for support of <space> and <comma>. The ASC() function then takes the                            ASCII value of the first character in the input, so it can deal with                            inputs like 'Hello' - it will take ASC('H') and assign that to 'i'LOCATE i\16-1               Here's the cool bit: LOCATE takes a row and a column to put the cursor on.    ,(i MOD 16+1)*2         Row is determined by dividing the ASC value by 16, minus 1 (SPACE, ASC 32                             is placed on row 1), and for columns we take the modulo plus 1 (Again, SPACE                             mod 16 = 0, plus 1 = column 1). Multiplied by 2 gives us the spacing.                             We move the cursor to 1,2?CHR$(i)                    PRINT a cast of the ASCII value to CHR at the specified location.LOOP                        Ad infinitum
answeredJun 3, 2017 at 8:49
steenbergh's user avatar
\$\endgroup\$
2
  • \$\begingroup\$QBasic beats everyone! Wow!\$\endgroup\$CommentedJun 3, 2017 at 9:12
  • 5
    \$\begingroup\$@Arjun You kids and your Java...\$\endgroup\$CommentedJun 3, 2017 at 10:50
8
\$\begingroup\$

Java 8, 143 bytes

o->{for(;;){char c=System.console().readPassword()[0];if(c>31&c<127)System.out.println(String.format("\u001B[%d;%df%c",c/16+1,(c%16+1)*2,c));}}

Uses theANSI control codeCSI n ; m f to set the cursor position andConsole.readPassword() to read the user input silently. Output of some characters:

sscreenshot

answeredJun 3, 2017 at 13:21
marcelovca90's user avatar
\$\endgroup\$
2
  • 1
    \$\begingroup\$The first time I see that Java has a chance in code golf, too ! Nice !\$\endgroup\$CommentedJun 3, 2017 at 17:27
  • 1
    \$\begingroup\$+1, never seenreadPassword() used like that. Oh, and you seem to be missing a semi-colon after the println. Also, isn't is possible to useSystem.out.printf somehow instead ofSystem.out.println(String.format(? And you can change()-> too-> by usingan unused empty parameter.\$\endgroup\$CommentedJun 27, 2017 at 12:03
7
\$\begingroup\$

BrainFuck, 355 Bytes

>>++++[->++++[->+>++++++<<]<]>>->[-<[-<<<<++++[->++++++++<]]>>>[<<<<<++++++++[->>++<<<+>]>>-<<<++>>]<<[>>>>>>[>>>]>+<<<<<[<<<]<<-]>>>>>>[>>>]++++[-<++++++++>]>[-<+>]<<[<<<]>>]<[-]<<,[[->+>+<<],[-]++++[->>--------<<]>>[>>>>[>>>]+[<<<]<-]>>>>[>>>]<<[-]<[<<<]<<[>>>>>[>>>]<<+<[<<<]<<-]>>>>>[>>>]<<<[[-]<<<]>[.>.>>]++++++++++[->+>++<<]>>[-<.>]<[-]<<<<[<<<]<,]

BrainFuck's options are pretty limited, so output is in the terminal and the screen is "cleared" with 20 newlines. Input should be the ASCII characters, separated by newlines.

Try it online!

Formatted and Documented

These are the debug notes I used to write the program. I usedmy interpreter which can optionally print the state of the tape at every '~' character for debugging.

[    run.bf    codegolf.stackexchange.com/questions/124306/map-inputted-ascii-characters][    Calculate 16 * 6    Resulting tape state:    [0 0 0 0 0 0 16 96 0 0 0 0 ...]               ^    Note that, to obtain a 16-by-6 grid, the 16    immediately to the right is decreased to 15    (since we will decrease it by 1 each loop    until we reach 0 and immediately reset)]>>>>++++[->++++[->+>++++++<<]<]>~[    Our next goal is to make 96 sets of 3 cells each in the pattern [C D 0]    The first cell will represent an entered character--when the corresponding    input on the keyboard is pressed, it will change to the entered key.    The first cell is initialized to 32 (' ').    The second cell will represent the delimiter after that character.    Every 16 cells, this should be 10 for '\n'. Otherwise, it should be 32 for ' '.    The third cell is a buffer cell, used for traversal of the grid. In general,    it should be only temporarily modified and then reset to 0.]>->[-<    [       -<<<<++++[->++++++++<]       [           The second cell of our 3-set should be 32, so the above line           writes 32 to the 3rd cell from the beginning of the tape (0-indexed)       ]    ]    >>>    [       <<<[ The second cell of our 3-set should be 10, and we must reset the line counter ]        <<++++++++[->>++<<<+>]>>-<<<++>>    ]    [ At this point, the delimiting cell we need is two cells to the left. ]    <<[>>>>>>[>>>]>+<<<<<[<<<]<<-]        >>>>>>[>>>]++++[-<++++++++>]    [ Debug Mode: In the previous loop, add a + in the string of 8 +'s to get visible spaces in the grid ($-signs) ]    >[-<+>]<<[<<<]>>][ Go back to the beginning of the tape and clear up the residual '15' ]<[-]~<<,[    [->+>+<<],[-]++++[->>--------<<]    [        Take input such that the state of the tape now looks like this:        [0 0 0 0 0 c c-32 0 32 32 0 32 32 0 32 32 0 ...]                 ^        Where 'c' was the entered character.        We now set up 1's in the buffer zones of the first c-32        3-sets and clear the character that is currently there.        All that is left, then, is to copy c to that location.    ]    [ Set up the row of 1's. ]    >>[>>>>[>>>]+[<<<]<-]    [ Clear the current character. ]    >>>>[>>>]<<[-]~<[<<<]    [ Copy the new character. ]    <<[>>>>>[>>>]<<+<[<<<]<<-]    [ Clean up the 1's. ]    >>>>>[>>>]~<<<[[-]<<<]    [ Print the grid. ]    >[.>.>>]~    [ Print a bunch of newlines ]    ++++++++++[->+>++<<]>>[-<.>]<[-]    [ Take a new input. ]    <<<<[<<<]<,]
answeredJun 3, 2017 at 7:10
BrainSteel's user avatar
\$\endgroup\$
6
\$\begingroup\$

Mathematica, 108 bytes

a=" "~Table~16~Table~6;Dynamic@Grid@a((a[[⌊#/16⌋-1,#~Mod~16+1]]=i)&@ToCharacterCode[i=Input[]];#0[])&[]

Try it online athttps://sandbox.open.wolframcloud.com/

When you paste code and pressShift+Enter, a dialog box will pop up, you enter"a" for example for charactera. The program runs forever.

Note: On Wolfram sandbox, the font is formatted differently from that in Mathematica in my computer. So the line/column spacing may looks weird.

answeredJun 3, 2017 at 2:56
user202729's user avatar
\$\endgroup\$
8
  • \$\begingroup\$Does this continually map out every character? I.e. do you have to run it more than once to see the desired output?\$\endgroup\$CommentedJun 3, 2017 at 4:29
  • \$\begingroup\$You run it once, and each time you pressOK of an input box, another input box appear for you to enter input.\$\endgroup\$CommentedJun 3, 2017 at 4:30
  • \$\begingroup\$I think i = ToString@Input[]] would be more convinient.Users should just type a and not "a"\$\endgroup\$CommentedJun 3, 2017 at 6:09
  • \$\begingroup\$or better i=InputString[]\$\endgroup\$CommentedJun 3, 2017 at 6:19
  • \$\begingroup\$@Jenny_mathy Unfortunately, they are longer.\$\endgroup\$CommentedJun 3, 2017 at 6:38
5
\$\begingroup\$

Python 2, 115 bytes

s='\n'.join([' '*31]*6)while 1: c=input();i=ord(c) if 31<i<128:i-=32;i=i%16*2+i//16*32;s=s[:i]+c+s[i+1:];print s

Try it online!

Requires quotation marks (single or double) around the inputted characters (the TIO version does not).

answeredJun 3, 2017 at 1:06
musicman523's user avatar
\$\endgroup\$
2
  • 1
    \$\begingroup\$You can changeraw_input toinput as it is community census that you can assume the input has quotes around it if needed.\$\endgroup\$CommentedJun 3, 2017 at 1:09
  • 1
    \$\begingroup\$Sounds good! When I was testing I was just entering keys, and it was unhappy that I was entering{ without a matching}.\$\endgroup\$CommentedJun 3, 2017 at 1:14
4
\$\begingroup\$

str, noncompeting, 18 bytes

Presenting my new semi-esoteric language.

#C;dby16#/~2-~u#pq

Animated GIF

#C;dby16#/~2-~u#pq..;                   preamble#C                    clear screen   ...............    main program; each character is pushed to the stack before   d                  duplicate    b                 buffer the character     y                convert to character code      16#/            divmod by 16 (a / b, a % 6)          ~2-~        subtract a / b by 2              u       unbuffer the character               #p     place that character in the given position                 q    "quiet"; disable auto-printing
answeredJun 4, 2017 at 23:44
Conor O'Brien's user avatar
\$\endgroup\$
2
  • \$\begingroup\$I don't see spaces between the characters...\$\endgroup\$CommentedJun 7, 2017 at 16:47
  • 2
    \$\begingroup\$@MDXF The spec says nothing about spaces in between characters. Not to mention there are plenty of answers that don't use spaces.\$\endgroup\$CommentedJun 7, 2017 at 17:09
3
\$\begingroup\$

QBIC,53 57 bytes

Added 4 bytes for the spacing.

{locate 7,1┘_?┘i=asc(A)┘locate i/16-1,(i%16+1)*2┘?chr$(i)

QBIC began development as a shorthand for QBasic, so I thought translating myQBasic answer would demonstrate this nicely. We've saved some 40% in the byte-count for a functionally identical program - and that's even whenLOCATE,ASC, andCHR have no QBIC-functions yet. Fortunately, QBIC can pass code directly to QBasic to compensate for this. A side-by-side:

QBIC              QBASIC------------      ------------{                 DOlocate 7,1        LOCATE 7,1                  note that the lower-case alphabet is left unaltered in QBIC._?                LINE INPUT A$  (LINE INPUT used instead of INPUT to handle comma's)i=asc(A)          i=ASC(A$)locate i/16-1     LOCATE i/16-1   ,(i%16+1)*2       ,(i MOD 16+1)*2?chr$(i)          ?CHR$(i)                  LOOP   (implicitly added to QBIC at EOF)
answeredJun 3, 2017 at 9:30
steenbergh's user avatar
\$\endgroup\$
3
\$\begingroup\$

Haskell, 133 bytes

p=putStr.("\27["++)g l=do c<-getChar;p"2J";mapM h(c:l);g(c:l)h c|(y,x)<-divMod(fromEnum c)16=p$show y++';':show(2*x+1)++'H':[c]g[]

Requires a terminal that understands ANSI escape sequences.

It's shorter to keep a list of all keys pressed so far and clearing the screen before printing all of them each round than turning off the echo in the terminal session. The latter needsimport System.IO andhSetEcho stdin(2<1) which costs too many bytes.

answeredJun 3, 2017 at 11:51
nimi's user avatar
\$\endgroup\$
3
\$\begingroup\$

C, 101 bytes

c,y,x;f(){while(~(c=getchar()))printf("\e[1;20H"),y=c/16,x=c-y*16,printf("\e[%d;%dH%c",y+1,x*2+1,c);}

This was the program I used to make the graphics. Output is as shown in the GIF. ;)

answeredJun 3, 2017 at 15:43
MD XF's user avatar
\$\endgroup\$
2
  • \$\begingroup\$85 bytes\$\endgroup\$CommentedOct 5, 2020 at 4:56
  • \$\begingroup\$Building on @ceilingcat,83 bytes\$\endgroup\$CommentedNov 20, 2020 at 19:31
3
\$\begingroup\$

QBasic,62 58 bytes

a=ASC(INPUT$(1))LOCATE a\16-1,1+2*(a MOD 16)?CHR$(a)RUN

Tested withQB64. Should work fine on regular QBasic, too, although you may want to modify it to do aCLS on the first run.

Similar tosteenbergh's answer, but usesINPUT$(1) to read characters one at a time. This approach is shorter and also displays no prompt. It also usesRUN for the infinite loop, since we don't have to store any state between iterations except the state of the screen.

answeredNov 9, 2017 at 22:22
DLosc's user avatar
\$\endgroup\$
1
  • \$\begingroup\$Wow, nice. Didn't know aboutinput$(). I like the TIPS-topic too btw.\$\endgroup\$CommentedNov 13, 2017 at 10:21
2
\$\begingroup\$

Ruby,7975 71 + 13 = 84 bytes

+13 bytes for-rio/console flag.

loop{$/+=STDIN.getch97.times{|n|print$/[(n+31).chr]||" ",[""][n%16]}}

Ungolfed

loop {  $/ += STDIN.getch  97.times {|n|    print $/[(n+31).chr] || " ", [""][n%16]  }}
answeredNov 9, 2017 at 19:57
Jordan's user avatar
\$\endgroup\$
1
\$\begingroup\$

Pascal, 112 chars

Uses crt;var c:char;Begin ClrScr;repeat c:=ReadKey;GotoXY(ord(c)and$F*2+1,ord(c)shr 4-1);write(c);until 1<0;End.

As my Mathematica solution takes many bytes indiv,mod andToCharacterCode[Input[]], I try making another answer with Pascal. But withoutClrScr my compiler (FPC) left some compile information on the screen.ClrScr; takes 7 bytes.

The*2 used for proper spacing takes another 2 bytes.

answeredJun 4, 2017 at 10:35
user202729's user avatar
\$\endgroup\$
1
\$\begingroup\$

LOGO, 90 bytes

csrt 90keyboardon[invoke[setxy 30*modulo ? 16 -30*int ?/16 label char ?]keyboardvalue]pu

Try it on FMSLogo.

After all, my Logo solution is the shortest, compared with my Mathematica and Pascal answer.

Add 3 bytes if the turtle is required to be hidden.

answeredJun 27, 2017 at 11:32
user202729's user avatar
\$\endgroup\$
1
\$\begingroup\$

6502 machine code + Apple //e ROM, 31 bytes

Hex dump:

8000- 20 58 FC 20 0C FD 48 388008- E9 A0 48 29 0F 0A 85 248010- 68 4A 4A 4A 4A 20 5B FB8018- 68 20 ED FD 4C 03 80

Commented assembly:

 1 HTAB     =     $24        ; HORIZONTAL POSITION OF CURSOR 2 SETVTAB  =     $FB5B      ; SETS VERTICAL POSITION OF CURSOR FROM ACC 3 COUT     =     $FDED      ; OUTPUTS CHARACTER IN ACC 4 HOME     =     $FC58      ; CLEARS SCREEN 5 RDKEY    =     $FD0C      ; GETS CHARACTER FROM KEYBOARD, STORES IN ACC 6          ORG   $8000 7          JSR   HOME 8 GETINP   JSR   RDKEY 9 * POSITION CURSOR10          PHA              ; PRESERVE ACC11          SEC              ; MAKE SURE CARRY IS SET TO SUBTRACT12          SBC   #" "       ; SUBTRACT CHAR CODE OF SPACE13          PHA              ; SAVE ACC14          AND   #$0F       ; GET LOWER 4 BITS TO GET CURSOR X POSITION15          ASL              ; SHIFT LEFT TO MAKE SPACES BETWEEN CHARS16          STA   HTAB17          PLA              ; GET OLD ACC18          LSR              ; SHIFT HIGH NIBBLE19          LSR              ; INTO LOW NIBBLE20          LSR              ; TO GET CURSOR Y POSITION21          LSR22          JSR   SETVTAB23          PLA              ; RESTORE ACC24 *25          JSR   COUT26          JMP   GETINP

GIF demo

If the cursor invalidates it, here's a 36-byte version without a cursor:

8000- 20 58 FC AD 00 C0 10 FB8008- 8D 10 C0 48 38 E9 A0 488010- 29 0F 0A 85 24 68 4A 4A8018- 4A 4A 20 5B FB 68 20 ED8020- FD 4C 03 80
answeredAug 3, 2017 at 12:23
insert_name_here's user avatar
\$\endgroup\$
1
\$\begingroup\$

SmileBASIC 3, 82 bytes

CLS@LC$=INKEY$()IF""!=C$THEN V=ASC(C$)-32LOCATE V MOD 16*2,V DIV 16*2?C$;GOTO@L

In the SmileBASIC character set,¥ is located where\ normally would be; hopefully this doesn't invalidate this answer completely.

answeredJun 26, 2018 at 5:27
snail_'s user avatar
\$\endgroup\$
1
\$\begingroup\$

Japt,63 43bytes

Seeing as I apparently have a reputation for making Japt do things it shouldn't be able to do (continuous input, in this case), golfing from my my phone, and golfing with a feed of beer inside me, it's high time I combined all 3 of those things!

;$oninput=$@OqE¬ËoOx`Í*s.value` 1Ãú ò16 m¸·

Test it (just start typing in the "Notes" field)

answeredNov 20, 2020 at 23:17
Shaggy's user avatar
\$\endgroup\$
2
  • 1
    \$\begingroup\$sooo.. How do we use this?\$\endgroup\$CommentedNov 21, 2020 at 4:21
  • \$\begingroup\$Just start typing in the input field, @Razetime.\$\endgroup\$CommentedNov 21, 2020 at 10:38
0
\$\begingroup\$

Applesoft BASIC, 134 bytes

0TEXT:HOME:PR#01C=PEEK(49152):POKE49168,0:HTAB1:VTAB20:NORMAL:IFC>=128THENC=C-128:INVERSE4Y=INT(C/16):X=C-Y*16:HTABX*2+1:VTABY+1:IFC>=32THEN PRINTCHR$(C):IFC<32THEN PRINTCHR$(127)9GOTO1

This is a golfed version of the Apple ][ keyboard test, the program that inspired the challenge.

answeredJun 3, 2017 at 16:33
MD XF's user avatar
\$\endgroup\$
2
  • \$\begingroup\$This is actually 134 bytes, since Applesoft BASIC is tokenized.\$\endgroup\$CommentedAug 3, 2017 at 23:51
  • \$\begingroup\$@insert_name_here Ah, yes. Thanks.\$\endgroup\$CommentedAug 4, 2017 at 0:30
0
\$\begingroup\$

8086 machine code, MS-DOS .COM, 27 bytes

Runnable in DOSBox. The only assumption about register starting values isAH = 0, which istrue for most DOS isotopes. This, and the fact that only BIOS interrupts are used, means it can be run from a boot sector by changing the first instruction tomov ax, 3 (and theorg of course) at the terrible, terrible cost of one byte.

Expects only printable ASCII characters as input. Does not terminate.

Binary

00000000 : B0 03 CD 10 31 C0 CD 16 50 2C 20 D4 10 D0 E0 92 : ....1...P, .....00000010 : B4 02 CD 10 58 B4 0E CD 10 EB E9                : ....X......

Assembly

org 0x100cpu 8086        mov al, 3       ; Set video mode to 80x25 text    int 0x10        ; Has the desired side-effect of clearing the screen    main_loop:    xor ax, ax      ; Read keystroke into AX    int 0x16        ; AH = scan code, AL = ASCII        push ax         ; Save ASCII code for later    sub al, 32      ; Make ASCII code into range 0..94    aam 0x10        ; AH = AL / 16 (row), AL = AL % 16 (col)    shl al, 1       ; Double column for spacing        xchg ax, dx     ; Move cursor to proper position    mov ah, 2    int 0x10        pop ax          ; Retrieve ASCII code    mov ah, 0x0e    ; Output at cursor position    int 0x10        jmp main_loop
answeredNov 20, 2020 at 20:09
gastropner's user avatar
\$\endgroup\$

Your Answer

More generally…

  • …Please make sure to answer the question and provide sufficient detail.

  • …Avoid asking for help, clarification or responding to other answers (use comments instead).

Draft saved
Draft discarded

Sign up orlog in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

By clicking “Post Your Answer”, you agree to ourterms of service and acknowledge you have read ourprivacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.