映射输入的ASCII字符


32

确保看到另一个挑战,反向ASCII字符映射

ASCII字符集(美国信息交换标准代码)是使用最广泛的字符编码标准。ASCII码表示计算机,电信设备和其他设备中的文本。

挑战

您面临的挑战是在用户输入ASCII字符集时打印它们的映射。GIF:

gif

用户输入每个ASCII字符后,输出应如下所示:

表

映射

每个字符在16x6逻辑网格上都有一个分配的位置,从左上角的空格字符开始,然后换行以使数字0出现在其下方。

收到可打印的ASCII输入时,请在其分配的屏幕位置打印该ASCII字符,而不删除当前在屏幕上的任何字符。

规则

  • 您的程序仅需要将可打印的ASCII字符映射0x200x7E
  • 在输入所有可打印的ASCII字符之前,您的程序不得终止并继续将字符映射到屏幕。从这里,您的程序可以终止,也可以运行到Neverland中。
  • 您的程序可以按照您喜欢的任何方式将字符映射到电子表格,表格,控制台窗口或图形窗口。
  • 无论您如何显示映射,都必须实时更新(一旦收到用户输入)。
  • 如果您的程序没有以静默方式读取输入,则必须将光标移开,这样文本就不会成为地图的障碍。

救命

这是我用来生成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 if
end loop

可能存在另一种方式来实现所需的输出。您可以选择使用我的算法,也可以使用自己的算法,但是无论如何,输出必须相同。

这是一个有用的ASCII表参考。

计分

每种语言中字节数最少的答案将获胜。玩得开心!


字符之间是否需要有空格?
musicman523

@ musicman523是的,这些是必需的。输出必须与屏幕快照中显示的完全一样。
MD XF

我们是否可以假定终端的背景色?
–totalhuman

是否清除终端,然后为每个字符重新绘制更新的表?
Digital Trauma'6

@DigitalTrauma-每次重画都是可以的-我在沙盒帖子中问过
musicman523

Answers:


3

QBIC53 57字节

为间距增加了4个字节。

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

QBIC开始开发,是QBasic的简写,所以我认为翻译我的QBasic答案将很好地证明这一点。我们已经在字节数节省了40%的功能相同的程序-这甚至当LOCATEASCCHR没有QBIC-功能呢。幸运的是,QBIC可以将代码直接传递给QBasic进行补偿。并排:

QBIC              QBASIC
------------      ------------
{                 DO
locate 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)

18

JavaScript(ES6)+ HTML,114 + 16 = 130字节

@Shaggy节省了16个字节

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>

混搭键盘真是令人难以置信...


9
“我真想这么做”,也许是,也可能不是,“真是令人难以置信地满足于仅仅捣碎键盘”。+1
MD XF

是的,您可以假设只给出了可打印的ASCII。我很确定这是规则#1。
MD XF

您不能只prompt()在循环中使用吗?它将使您免受所有事件处理和HTML的影响。OP似乎允许它。请参阅Mathematica帖子的评论。
阿琼

仅处理可打印的ASCII。如果我们可以假设只给出了可打印的ASCII,则减去7个字节。这似乎没有意义。如果仅处理可打印的ASCII,那么假设可打印的ASCII如何保存任何字节?
Arjun

您应该能够onkeypress自己单独使用,允许您删除body标签。另外,pre标签可以缩短为<pre id=O。虽然,您需要包括结束符>才能使其在代码段中起作用。
毛茸茸的

15

QBasic的4.5,81 85个字节

添加了4个字节以符合间隔规则。

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

输出将如下所示(注意:旧屏幕截图,现在每个字符都由空格分隔):enter image description here

QBasic具有LOCATE命令,在此非常方便。此代码的细分:

DO                          Starts an infinite loop
LOCATE 7,1                  Moves the cursor out of the way
LINE 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

QBasic击败所有人!哇!
Arjun

5
@Arjun您的孩子和您的Java ...
steenbergh

8

Java 8,143字节

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));}}

使用ANSI控制代码 CSI n ; m f设置光标位置并Console.readPassword()以静默方式读取用户输入。输出一些字符:

sscreenshot


1
我第一次看到Java也有机会参加代码竞赛!不错!
LMD

1
+1,从未见过readPassword()那样使用。哦,您似乎在println之后缺少分号。另外,不可能以System.out.printf某种方式代替System.out.println(String.format(吗?您可以使用未使用的空参数来更改()->为。o->
Kevin Cruijssen

@KevinCruijssen固定,谢谢!
害羞的白鲸

6

BrainFuck,355个字节

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

BrainFuck的选项非常有限,因此输出在终端中,并且屏幕上有20个换行符来“清除”屏幕。输入应为ASCII字符,以换行符分隔。

在线尝试!

格式化并记录

这些是我用来编写程序的调试说明。我使用了解释器,该解释器可以选择在每个“〜”字符处打印磁带的状态以进行调试。

[
    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. ]
    <<<<[<<<]<,
]

6

Mathematica,108个字节

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

通过https://sandbox.open.wolframcloud.com/在线尝试

粘贴代码并按时Shift+Enter,将弹出一个对话框,输入"a",例如 character a。该程序将永远运行。

注意:在Wolfram沙箱上,字体的格式与计算机中Mathematica中的字体格式不同。因此行/列间距看起来很奇怪。


这会持续映射每个角色吗?即您是否必须多次运行它才能看到所需的输出?
MD XF

OK只需运行一次,每次按一个输入框,就会出现另一个输入框供您输入输入。
user202729

听起来有效,谢谢。不错的工作!
MD XF

我认为i = ToString @ Input []]会更方便。用户应输入a而不是“ a”
J42161217

或更好的i = InputString []
J42161217

5

Python 2,115个字节

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

在线尝试!

在输入的字符周围需要双引号(单引号或双引号)(TIO版本不需要)。


1
您可以更改raw_inputinput,因为它是社区的普查,你可以假设输入周围有引号如果需要的话。
Caird coinheringaahing

1
听起来不错!在测试时,我只是输入密钥,而对输入{没有匹配项感到不满}
musicman523

4

力量,非竞争性,18个字节

介绍我的新半神秘语言。

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

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

我看不到字符之间的空格...
MD XF

2
@MDXF规范没有说明字符之间的空格。更不用说有很多不使用空格的答案。
Conor O'Brien

3

Haskell,133个字节

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[]

需要一个了解ANSI转义序列的终端。

与在终端会话中关闭回显相比,保持到目前为止已按下的所有键的列表并在每次打印所有键之前清除屏幕的时间要短。后者需要import System.IOhSetEcho stdin(2<1)并且花费太多字节。


3

C,101字节

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);}

这是我用来制作图形的程序。输出如GIF中所示。;)


3

QBasic,62 58字节

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

经过QB64测试。尽管您可能需要对其进行修改以执行CLS在首次运行。

steenbergh的答案类似,但用于一次INPUT$(1)读取一个字符。此方法更短,并且也不会显示任何提示。它也RUN用于无限循环,因为除了屏幕状态外,我们不必在每次迭代之间存储任何状态。


喔不错哟。不知道input$()。我也喜欢TIPS主题。
steenbergh

1

Pascal,112个字符

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.

由于我的Mathematica解决方案在中占用了许多字节divmod并且ToCharacterCode[Input[]],我尝试使帕斯卡另一个答案。但是没有ClrScr我的编译器(FPC),屏幕上会留下一些编译信息。ClrScr;占用7个字节。

*2用于适当的间隔另需2个字节。


1

LOGO,90字节

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

在FMSLogo上尝试。

毕竟,与我的Mathematica和Pascal答案相比,我的Logo解决方案最短。

如果需要隐藏乌龟,则添加3个字节。


1

6502机器代码+ Apple // e ROM,31字节

十六进制转储:

8000- 20 58 FC 20 0C FD 48 38
8008- E9 A0 48 29 0F 0A 85 24
8010- 68 4A 4A 4A 4A 20 5B FB
8018- 68 20 ED FD 4C 03 80

评论程序集:

 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 CURSOR
10          PHA              ; PRESERVE ACC
11          SEC              ; MAKE SURE CARRY IS SET TO SUBTRACT
12          SBC   #" "       ; SUBTRACT CHAR CODE OF SPACE
13          PHA              ; SAVE ACC
14          AND   #$0F       ; GET LOWER 4 BITS TO GET CURSOR X POSITION
15          ASL              ; SHIFT LEFT TO MAKE SPACES BETWEEN CHARS
16          STA   HTAB
17          PLA              ; GET OLD ACC
18          LSR              ; SHIFT HIGH NIBBLE
19          LSR              ; INTO LOW NIBBLE
20          LSR              ; TO GET CURSOR Y POSITION
21          LSR
22          JSR   SETVTAB
23          PLA              ; RESTORE ACC
24 *
25          JSR   COUT
26          JMP   GETINP

GIF演示

如果游标使它无效,这是不带游标的36字节版本:

8000- 20 58 FC AD 00 C0 10 FB
8008- 8D 10 C0 48 38 E9 A0 48
8010- 29 0F 0A 85 24 68 4A 4A
8018- 4A 4A 20 5B FB 68 20 ED
8020- FD 4C 03 80

1

Ruby,79 75 71 + 13 = 84字节

+13个字节用于-rio/console标志。

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

不打高尔夫球

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

1

SmileBASIC 3,82个字节

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

在SmileBASIC字符集中,¥位于\通常的位置。希望这不会完全使这个答案无效。


0

Applesoft BASIC,134字节

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

这是Apple []键盘测试的高尔夫版本,该程序激发了挑战。


实际上,这是134个字节,因为Applesoft BASIC已被标记化。
insert_name_here

@insert_name_here啊,是的。谢谢。
MD XF
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.