10
\$\begingroup\$

In Map inputted ASCII characters, I asked you to .. map inputted ASCII characters. This time, you will do the opposite, by immediately mapping all ASCII characters, and then mapping spaces over them.

This program will have practical uses, such as seeing what characters you have left in a challenge submission.

Challenge

Your job is to write a program that un-maps inputted ASCII characters. As soon as the program is run, it will display this exact map (except color, font, size, etc.):

step 1

Each time the user inputs a printable ASCII character, you will print a space over it.

gif

Rules

  • The initial output must be exactly as shown in the first image above: a 6x16 grid with ASCII characters in their respective positions, with the space (32) at the top left and the tilde (126) at one character left from the bottom right.
  • Your program only needs to display the printable ASCII characters, 0x20 to 0x7E.
  • Your program must not terminate and continue to print spaces over characters until all printable ASCII characters have been overwritten. From here, your program can either terminate or run off into Neverland.
  • Your reverse map 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.

Here's a useful ASCII table for reference.

Scoring

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

noodle person
12.5k1 gold badge31 silver badges90 bronze badges
asked Aug 2, 2017 at 17:03
\$\endgroup\$
8
  • \$\begingroup\$ Note to potential DV-ers or duplicate voters - it would be more difficult to port an answer on codegolf.stackexchange.com/q/124306/61563 to here than it would be to write your own answer. The answers over there read input and then use the input to print to the screen. Answers here have to print to the screen without input (using a different loop mechanism) and then test each inputted character for its location, then print a different character. \$\endgroup\$ Commented Aug 2, 2017 at 17:05
  • \$\begingroup\$ Can we assume that the user presses enter after he entered 1 character? \$\endgroup\$ Commented Aug 2, 2017 at 17:07
  • \$\begingroup\$ @Mr.Xcoder Yes, that's fine for languages that cannot take input in realtime. \$\endgroup\$ Commented Aug 2, 2017 at 17:09
  • \$\begingroup\$ @Mr.Xcoder See rule 1 - Your program only needs to display the printable ASCII characters, 0x20 to 0x7E \$\endgroup\$ Commented Aug 2, 2017 at 17:10
  • 3
    \$\begingroup\$ @MDXF It's still strikingly similar to the original challenge. I just need to print the ascii characters to the correct positions, then, instead of putting the user's input in the correct spot, I just use a space instead. \$\endgroup\$ Commented Aug 2, 2017 at 17:22

11 Answers 11

6
\$\begingroup\$

x86-16 Machine Code, 62 bytes

Hex dump:

BC0100B101B07EBAFE0581EAE00080EA02B402CD1085E4750830E439C5750A30C0B40ACD1084C074094884D275E085D275D831C031E4CD1630E489C5EBC7

Assembly:

mov sp, 0x0001 ; Stack pointer is used as a flag; 0 - Print all characters, 1 - Delete specific character
mov cl, 0x01 ; Number of characters to print per interrupt call
printString:
 mov al, 0x7E ; Last character to print
 mov dx, 0x05FE ; Row: 0x05, Collumn: 0xFE
 printRow:
 sub dx, 0x00E0 ; Decrement row number + 2 extra characters
 printChar:
 sub dl, 0x02 ; Decrement collumn index + 1 space
 mov ah, 0x02 ; Prepare for interrupt call, 0x02 - Set cursor position
 int 0x10 ; BIOS interrupt
 test sp, sp ; Are we printing all characters or removing specific character
 jnz print ; In first case just print it and go on
 xor ah, ah ; Otherwise reset the upper byte of ax (shorter than "and ax, 0x00FF")
 cmp bp, ax ; Is the current character same as the input character
 jne after ; If no, continue searching
 xor al, al ; If yes, remove it
 print:
 mov ah, 0x0A ; Prepare for print
 int 0x10 ; Print
 test al, al ; If we found target character
 jz loop ; then stop searching
 after:
 dec ax ; Shorter than "dec, al"
 test dl, dl ; Is it the last character in the row
 jnz printChar ; If no, continue searching
 test dx, dx ; Is it last char
 jnz printRow ; If no, go to next row
loop:
 xor ax, ax ; Remove "ah" cache
 xor sp, sp ; Reset sp (it will never become 1 again)
 int 0x16 ; BIOS interrupt for reading keyboard input
 xor ah, ah ; Again reset "ah", because BIOS may change it
 mov bp, ax ; Save it in stack base pointer
 jmp printString ; Remove the character from the list

enter image description here

answered Aug 2, 2017 at 18:19
\$\endgroup\$
2
\$\begingroup\$

SOGL V0.12, 23 bytes

] ~Δ8«n"5αx203⁄1‘→č@ŗ░T

Try it Here!

Takes input in the input box. I hope that it isn't too big of an issue that characters can be deleted :p

Explanation:

] do.. while (popping (which makes the stack not blow up luckily :D))
 ~Δ push the ascii characters (range("~"))
 8«n split into lines of length 16
 "...‘ push "inputs.value" (could be 2 bytes less if my dictionary contained the word "inputs". I even added "input", but only now realise that the input box is id=inputs :/)
 → evaluate as JavaScript, then push the result
 č chop into characters
 @ŗ replace each of the characters in the array with space
 ░ clear the output
 T output without popping (so do..while continues looping)
answered Aug 2, 2017 at 17:56
\$\endgroup\$
2
\$\begingroup\$

C++ (Visual C++), 253 (@Step Hen) (削除) 261 (削除ここまで) bytes

#include<cstdlib>
#include<iostream>
#include<conio.h>
int main(){char a[0x5E];for(int i=0;i<0x5E;i++)a[i]=(char)(i+0x20);while(true){system("cls");for(int i=0;i<0x5E;i++)if(i&&!(i%16))printf("\n%c ",a[i]);else printf("%c ",a[i]);a[_getch()-0x20]=' ';}}
answered Aug 3, 2017 at 0:04
\$\endgroup\$
1
  • \$\begingroup\$ Welcome to PPCG! I believe you can remove the spaces after the #includes, as well as i + 0x20 -> i+0x20. I could be wrong though. \$\endgroup\$ Commented Aug 3, 2017 at 0:09
1
\$\begingroup\$

Python 3, 116 bytes

o='\n'.join(''.join(map(chr,range(i,16+i)))for i in range(32,124,16))[:-1]
while 1:print(o);o=o.replace(input()," ")

Try it online!

answered Aug 2, 2017 at 19:57
\$\endgroup\$
1
\$\begingroup\$

Python 2, 132 bytes

Saved 4 bytes thanks to @alleks!

s=''
for i in range(32,128,16):s+=' '.join(map(chr,range(i,i+16)))+'\n'
while 1:print s[:-2];i=2*ord(input())-64;s=s[:i]+' '+s[i+1:]

Try it online!

answered Aug 2, 2017 at 18:22
\$\endgroup\$
4
  • \$\begingroup\$ This prints a 0x7f after the tilde, just fyi \$\endgroup\$ Commented Aug 2, 2017 at 18:48
  • \$\begingroup\$ @ConorO'Brien Oops, fixed \$\endgroup\$ Commented Aug 2, 2017 at 19:02
  • 1
    \$\begingroup\$ Any reason you couldn't just add [:-2] after print s instead? \$\endgroup\$ Commented Aug 3, 2017 at 0:43
  • \$\begingroup\$ @alleks that makes too much sense that's why \$\endgroup\$ Commented Aug 3, 2017 at 8:22
1
\$\begingroup\$

JavaScript (ES6) + HTML, (削除) 139 (削除ここまで) (削除) 136 (削除ここまで) 116 + (削除) 10 (削除ここまで) 16 = 132 bytes

-3 bytes thanks to @Shaggy.
-14 bytes inspired by @Arnauld.

for(i=32;i<127;)O[h="innerText"]+=String.fromCharCode(i++)+(i%16?" ":`
`);onkeypress=e=>O[h]=O[h].replace(e.key," ")
<pre id=O></pre>

Closing pre tag is required in this case, since we need the innerText value to start totally empty.

answered Aug 2, 2017 at 22:52
\$\endgroup\$
5
  • \$\begingroup\$ Save 2 bytes with O[h="innerHTML"]=a=[...Array(95)].map(). \$\endgroup\$ Commented Aug 3, 2017 at 8:20
  • \$\begingroup\$ And I think you can save another byte by getting rid of a completely. \$\endgroup\$ Commented Aug 3, 2017 at 8:26
  • 1
    \$\begingroup\$ @Shaggy Thanks, I was using the extra a variable because innerHTML was turning & into &amp;, along with some others. Switching to innerText fixed that. \$\endgroup\$ Commented Aug 3, 2017 at 10:20
  • \$\begingroup\$ You can move i to the global scope to save 2 bytes: map(_=>String.fromCharCode(i++)+(i%16?...),i=32) \$\endgroup\$ Commented Aug 4, 2017 at 9:58
  • \$\begingroup\$ @Arnauld Using that idea, I could just remove the whole array mapping and use a for loop instead. Thanks! \$\endgroup\$ Commented Aug 4, 2017 at 15:13
1
\$\begingroup\$

QBasic, 107 bytes

An anonymous function that takes as keystrokes, and erases an ASCII table

FOR x=32TO 126
L x
?CHR$(x)
NEXT
DO
L ASC(Input$(1))
?" "'<- `"` included for highlighting only
LOOP
SUB L(x)
LOCATE x16円-1,2*(x MOD 16)+1
END SUB

-8 bytes thanks to @DLosc

answered Jun 29, 2018 at 18:18
\$\endgroup\$
2
  • \$\begingroup\$ @DLosc - I had not even considered using a Sub there - Great solution. Unfortunately, we do have to count the End Sub as the community has decided that autocompletion is not valid (at least with VBA, but I am sure that it applies here as well) \$\endgroup\$ Commented Jul 10, 2018 at 17:27
  • \$\begingroup\$ Huh, that's interesting--I hadn't realized there was a distinction between autoformatting and autocompletion. Good to know. \$\endgroup\$ Commented Jul 12, 2018 at 14:33
0
\$\begingroup\$

C# (.NET Core), (138 + using System;) 151 bytes

()=>{var j="";for(int i=32;i<127;i++){if(i%16<1)j+='\n';j+=(char)i+" ";}while(1>0){Console.Write(j);j=j.Replace(Console.ReadLine()," ");}}

Try it online!

answered Aug 2, 2017 at 18:48
\$\endgroup\$
5
  • \$\begingroup\$ 130 bytes \$\endgroup\$ Commented Aug 3, 2017 at 8:12
  • \$\begingroup\$ Oh but you need to include using System; into your byte count if you haven't already (I forgot to add it into the count above). \$\endgroup\$ Commented Aug 3, 2017 at 8:16
  • \$\begingroup\$ @TheLethalCoder That's why it says 138+using System; \$\endgroup\$ Commented Aug 3, 2017 at 10:46
  • \$\begingroup\$ I mainly meant it because I forgot to add in the using into my byte count above. \$\endgroup\$ Commented Aug 3, 2017 at 10:49
  • \$\begingroup\$ Oh. Didn't see your first comment there. I like the abuse of the infinite for loop there :) \$\endgroup\$ Commented Aug 3, 2017 at 10:51
0
\$\begingroup\$

Node.js (削除) 233 (削除ここまで) 212 bytes

Saved 21 bytes thanks to @thePirateBay

This works, I'm still trying to find an online option as all the repls I've found hijack stdin.

a=[];l=_=>console.log(a.join``);for(i=32;i<127;i++)(x=String.fromCharCode(i)),a.push(i%16?x:x+'\n');l();b=require('readline');b.createInterface(process.stdin).on('line',c=>(a=a.join``.replace(c,' ').split``),l())

Try it online

answered Aug 2, 2017 at 22:41
\$\endgroup\$
5
  • \$\begingroup\$ Online version can be found on TIO. Just a few notes: you can save more than 30 bytes by rearranging your identifiers and removing unnecesary parts. You don't need variable b at all, and you are also using uninitialized identifier readline (not sure if it is compatible with version on TIO). You also don't need variable r at all, instead of && at the end, you can use , and rearrange parentheses. Same with the && at the beginning. Also, no need for process.stdout in readline interface, etc........... \$\endgroup\$ Commented Aug 2, 2017 at 23:17
  • \$\begingroup\$ @ThePirateBay without process.stdout it throws (at least on my version of node). The readline thing was a typo (hit ctrl-z too many times). I'll change the &&s. \$\endgroup\$ Commented Aug 2, 2017 at 23:21
  • \$\begingroup\$ Readline module doesn't require process.stdout. You can read the specification. It may throw an error if you messed something up with the rest of your code or if you are using old/inconsistent version of Node.js. \$\endgroup\$ Commented Aug 2, 2017 at 23:23
  • \$\begingroup\$ @thePirateBay Must be my node, I'm 6.9.1 on MacOS... just tried it again and createInterface apparently returns undefined if you omit the second param. I went ahead and removed it though per the docs you linked. As far as TIO goes, how do you make it interactive? \$\endgroup\$ Commented Aug 2, 2017 at 23:26
  • \$\begingroup\$ Here is using only 191 bytes, but I am sure at least 10 more bytes can be saved. Sorry, im too bored now to continue golfing this: for(a=[],l=_=>console.log(a.join``),i=32;i<127;x=String.fromCharCode(i++),a.push(i&15?x:x+'\n'));l();require('readline').createInterface(process.stdin).on('line',c=>(a[a.indexOf(c)]=' ',l)()) \$\endgroup\$ Commented Aug 2, 2017 at 23:33
0
\$\begingroup\$

65c02 machine code + Apple //e ROM, 52 (47?) bytes

Hex dump:

8000- 20 58 FC A9 A0 20 20 80
8008- 20 ED FD 1A C9 FF D0 F5
8010- AD 00 C0 10 FB 8D 10 C0
8018- 20 20 80 20 57 DB 80 F0
8020- 48 38 E9 A0 48 29 0F 0A
8028- 85 24 68 4A 4A 4A 4A 20
8030- 5B FB 68 60

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 OUTSP = $DB57 ; APPLESOFT ROUTINE THAT OUTPUTS A SPACE
 6 KBD = $C000 ; KEY LAST PRESSED
 7 KBSTROBE = $C010 ; ACCESS TO RESET "NEW KEY PRESSED" INDICATOR
 8 ORG 8000ドル
 9 JSR HOME
10 * PRINT INITIAL CHARACTER MAP
11 LDA #" "
12 LOOP JSR CHARPOS
13 JSR COUT
14 INC ; INCREMENT ACCUMULATOR
15 CMP #"~"+1
16 BNE LOOP
17 * WAIT FOR KEYPRESS
18 GETCH LDA KBD ; GET LAST KEY PRESSED
19 BPL GETCH ; READ AGAIN IF KEYPRESS IS NOT NEW
20 STA KBSTROBE ; RESET "NEW KEYPRESS" INDICATOR
21 JSR CHARPOS
22 JSR OUTSP
23 BRA GETCH
24 * SUBROUTINE TO POSITION CURSOR TO PRINT OVER CHARACTER IN ACCUMULATOR
25 CHARPOS PHA ; PRESERVE ACC
26 SEC ; MAKE SURE CARRY IS SET TO SUBTRACT
27 SBC #" " ; SUBTRACT CHAR CODE OF SPACE
28 PHA ; SAVE ACC
29 AND #0ドルF ; GET LOWER 4 BITS TO GET CURSOR X POSITION
30 ASL ; SHIFT LEFT TO MAKE SPACES BETWEEN CHARS
31 STA HTAB
32 PLA ; GET OLD ACC
33 LSR ; SHIFT HIGH NIBBLE
34 LSR ; INTO LOW NIBBLE
35 LSR ; TO GET CURSOR Y POSITION
36 LSR
37 JSR SETVTAB
38 PLA ; RESTORE ACC
39 RTS

This has no cursor whatsoever. I also have a 47 byte version which might be valid, depending on what is meant by "put the cursor out of the way, so the text won't get in the way of the map":

8000- 20 58 FC A9 A0 20 1B 80
8008- 20 ED FD 1A C9 FF D0 F5
8010- 20 0C FD 20 1B 80 20 57
8018- DB 80 F5 48 38 E9 A0 48
8020- 29 0F 0A 85 24 68 4A 4A
8028- 4A 4A 20 5B FB 68 60

This puts a cursor at the character after the character you type (which is the space between characters), so it won't overwrite any of the actual characters in the map. Whether this is valid or not is up to the creator of the challenge.

answered Aug 3, 2017 at 8:27
\$\endgroup\$
0
\$\begingroup\$

Python 2, 96 bytes

from textwrap import*
a=fill(str(bytearray(range(32,127))),16)
while 1:a=a.replace(input(a),' ')

Try it online! Output looks iffy on TIO (because input is passed from a file), but it’s fine interactively. I hope 'A'\n, 'B'\n etc is an okay input format.

answered Aug 3, 2017 at 9:33
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy 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.