尽快输入字母!


44

您的任务是创建一个程序,该程序可以测量您键入英文字母的速度。

  • 该程序只接受小写字母az字母顺序。
  • 每个字母都按在同一行上键入的方式回显(没有换行或字母之间的任何其他分隔符)。
  • 如果键入无效字符,程序将Fail 在新行输出并退出。
  • 如果键入所有26个字母,程序将在新行上输出从第一个字母到最后一个字母所花费的时间(以毫秒为单位),然后退出。
  • 当您输入第一个字母时,计时器开始计时a

输出示例:

b
Fail

abcdefgg
Fail

abcdefghijklmnopqrstuvwxyz
6440

这是,因此最短答案以字节为单位。


4
不久前做了有关的项目。(第15级基本上是这个级别)
ETHproductions

4
我们可以Fail不用标题换行符来输出吗?(例如abdFail\nabd Fail\n))
scottinet

1
@scottinet,不,结果(Fail或毫秒)必须在新行中,如示例中所示。大多数答案已经假定了这一点。
丹科·杜比奇(DankoDurbić),

2
-1,因为此“新”规则不在原始规范中,并且使我对原始规则内的某个Python答案的建议无效。
ElPedro

我期望这是打印字母的最快代码挑战。
ATaco

Answers:


40

HTML(JavaScript的(ES6)),129个 126 117字节

<input id=i onfocus=l=0,n=Date.now onkeypress=event.which-97-l?i.outerHTML='Fail':24<l?i.outerHTML=n()-t:t=l++?t:n()>

单击输入并开始输入!另外,我的打字很烂;即使练习,我也要花费约5秒钟的时间。编辑:通过切换语言,通过@HermanLauenstein节省了2个字节。@ qw3n节省了3个字节。@tsh节省了9个字节。


1
通过使用带有脚本标签的html -2字节:<input id=i><script>l=0;n=Date.now;i.onkeypress=e=>e.charCode-97-l?i.outerHTML='Fail':l>24?i.outerHTML=n()-t:t=l++?t:n()</script>,如果不需要结束标签则为-11字节
Herman L

@HermanLauenstein结束标记,似乎对一个片段是必要的,至少,所以我把它进来
尼尔

2
这太令人生气了,同时又很有趣。
泽农

1
输入事件如何处理?<input id=i onkeypress=event.which-97-l?i.outerHTML='Fail':24<l?i.outerHTML=n()-t:t=l++?t:n() onfocus=l=0,n=Date.now>
tsh

1
不会在新行上回显文本
dkudriavtsev

33

6502机器代码(C64 PAL),189165字节

00 C0 A9 17 8D 18 D0 A9 40 85 FE E6 FE 20 E4 FF F0 FB 20 D2 FF C5 FE 38 D0 38
C9 5A 18 F0 33 C9 41 D0 E8 A9 00 85 FC 85 FD A9 18 85 FB A9 7F 8D 0D DD A9 7F
8D 18 03 A9 C0 8D 19 03 A9 D8 8D 04 DD A9 03 8D 05 DD A9 01 8D 0E DD A9 81 8D
0D DD D0 B9 A9 7F 8D 0D DD A9 47 8D 18 03 A9 FE AD 19 03 CE 0E DD B0 14 A9 0D
20 D2 FF A4 FC A5 FD 20 91 B3 20 DD BD A9 01 A8 D0 04 A9 9D A0 C0 4C 1E AB 48
AD 0D DD 29 01 F0 14 E6 FC D0 02 E6 FD C6 FB D0 0A A9 18 85 FB CE 0E DD EE 0E
DD 68 40 0D C6 41 49 4C 00
  • 通过内联函数而不是其他CIA2中断来处理-24个字节

在线演示(用法:sys49152

屏幕截图


说明:

如果不是因为C64上精确测量毫秒的问题,这将是一个微型程序。系统中断每秒大约发生60次,甚至还没有结束。因此,我们必须在此处使用硬件计时器,该计时器会从系统时钟获取输入滴答。

在PAL机器上,系统时钟精确为985248 Hz。因此,将计时器初始化为985会产生接近毫秒的滴答声,但是它有点太快了,我们必须每四个滴答声计数986个周期,或者将计时器保持一个周期。这是不可能的,但我们可以保持6个周期与序列的计时器DEC $DD0EINC $DD0E$DD0E是位0切换和关闭它的定时器控制寄存器和指令都需要6个周期,因此,其准确写道,停止和启动计时器正好相隔6个周期。因此,我们必须每6 * 4 = 24个刻度执行一次此序列。这仍然不是绝对的确切的说,计时器将在8分12秒后延迟1毫秒,但这可能已经足够了-补偿那将花费很多代码。

编辑:计时器的起始值必须为984,而不是985,因为这些计时器在“下溢时触发”,因此值0将在触发前再计数一个周期。代码固定,字节数不变。

这是评论后的反汇编清单:

         00 C0       .WORD $C000        ; load address
.C:c000  A9 17       LDA #$17           ; mode for upper/lower text
.C:c002  8D 18 D0    STA $D018          ; set in graphics chip
.C:c005  A9 40       LDA #$40           ; initialize expected character
.C:c007  85 FE       STA $FE            ; to 'a' - 1
.C:c009   .mainloop:
.C:c009  E6 FE       INC $FE            ; increment expected character
.C:c00b   .getchar:
.C:c00b  20 E4 FF    JSR $FFE4          ; read character from keyboard
.C:c00e  F0 FB       BEQ .getchar       ; until actual character entered
.C:c010  20 D2 FF    JSR $FFD2          ; output this character
.C:c013  C5 FE       CMP $FE            ; compare with expected
.C:c015  38          SEC                ; set carry as marker for error
.C:c016  D0 38       BNE .result        ; wrong character -> output result
.C:c018  C9 5A       CMP #$5A           ; compare with 'z'
.C:c01a  18          CLC                ; clear carry (no error)
.C:c01b  F0 33       BEQ .result        ; if 'z' entered, output result
.C:c01d  C9 41       CMP #$41           ; compare with 'a'
.C:c01f  D0 E8       BNE .mainloop      ; if not equal repeat main loop
.C:c021  A9 00       LDA #$00           ; initialize timer ticks to 0
.C:c023  85 FC       STA $FC
.C:c025  85 FD       STA $FD
.C:c027  A9 18       LDA #$18           ; counter for adjusting the timer
.C:c029  85 FB       STA $FB
.C:c02b  A9 7F       LDA #$7F           ; disable all CIA2 interrupts
.C:c02d  8D 0D DD    STA $DD0D
.C:c030  A9 7F       LDA #<.timertick   ; set NMI interrupt vector ...
.C:c032  8D 18 03    STA $0318
.C:c035  A9 C0       LDA #>.timertick
.C:c037  8D 19 03    STA $0319          ; ... to our own timer tick routine
.C:c03a  A9 D9       LDA #$D8           ; load timer with ...
.C:c03c  8D 04 DD    STA $DD04
.C:c03f  A9 03       LDA #$03
.C:c041  8D 05 DD    STA $DD05          ; ... 985 (-1) ticks (see description)
.C:c044  A9 01       LDA #$01           ; enable timer
.C:c046  8D 0E DD    STA $DD0E
.C:c049  A9 81       LDA #$81           ; enable timer interrupt
.C:c04b  8D 0D DD    STA $DD0D
.C:c04e  D0 B9       BNE .mainloop      ; repeat main loop
.C:c050   .result:
.C:c050  A9 7F       LDA #$7F           ; disable all CIA2 interrupts
.C:c052  8D 0D DD    STA $DD0D
.C:c055  A9 47       LDA #$47           ; set NMI interrupt vector ...
.C:c057  8D 18 03    STA $0318
.C:c05a  A9 FE       LDA #$FE
.C:c05c  AD 19 03    LDA $0319          ; ... back to system default
.C:c05f  CE 0E DD    DEC $DD0E          ; disable timer
.C:c062  B0 14       BCS .fail          ; if carry set, output fail
.C:c064  A9 0D       LDA #$0D           ; load newline
.C:c066  20 D2 FF    JSR $FFD2          ; and output
.C:c069  A4 FC       LDY $FC            ; load timer value in
.C:c06b  A5 FD       LDA $FD            ; A and Y
.C:c06d  20 91 B3    JSR $B391          ; convert to float
.C:c070  20 DD BD    JSR $BDDD          ; convert float to string
.C:c073  A9 01       LDA #$01           ; load address of
.C:c075  A8          TAY                ; string buffer
.C:c076  D0 04       BNE .out           ; and to output
.C:c078   .fail:
.C:c078  A9 9D       LDA #<.failstr     ; load address of "Fail" string
.C:c07a  A0 C0       LDY #>.failstr     ; in A and Y
.C:c07c   .out:
.C:c07c  4C 1E AB    JMP $AB1E          ; done; OS routine for string output
.C:c07f   .timertick:
.C:c07f  48          PHA                ; save accu
.C:c080  AD 0D DD    LDA $DD0D          ; load interrupt control register
.C:c083  29 01       AND #$01           ; to know whether it was a timer NMI
.C:c085  F0 14       BEQ .tickdone      ; if not -> done
.C:c087  E6 FC       INC $FC            ; increment timer ticks ...
.C:c089  D0 02       BNE .adjusttick
.C:c08b  E6 FD       INC $FD            ; high byte only on overflow
.C:c08d   .adjusttick:
.C:c08d  C6 FB       DEC $FB            ; decrement counter for adjusting
.C:c08f  D0 0A       BNE .tickdone      ; not 0 yet -> nothing to do
.C:c091  A9 18       LDA #$18           ; restore counter for adjusting
.C:c093  85 FB       STA $FB
.C:c095  CE 0E DD    DEC $DD0E          ; halt timer for exactly
.C:c098  EE 0E DD    INC $DD0E          ; 6 cycles
.C:c09b   .tickdone:
.C:c09b  68          PLA                ; restore accu
.C:c09c  40          RTI
.C:c09d   .failstr:
.C:c09d  0D C6 41    .BYTE $0D,"Fa"
.C:c0a0  49 4C 00    .BYTE "il",$00

6
好吧,现在我的工具箱中有一个相当不错的毫秒计时器;)可能会有用。
菲利克斯·帕尔姆

11
注意,脚本小子。这是真正的高尔夫。
J ...

1
@J ...我可以通过内联来进一步打高尔夫.starttimer-很快就会做:)(甚至可以通过使用TI这样的BASIC Answer这样的系统来做进一步的工作,但是我不确定这是否有效,因为您可以在机器代码中做得更好)
费利克斯·帕尔曼

哇,我在第一次计算时间测量中的误差时错过了985的系数,这实际上是非常好的方法(如果我在计算中又犯了一个错误,请指出!):)
菲利克斯·帕尔姆

而且你看到这个家伙在GITHUB中有什么吗?:android boot recovery ....他完全疯了!收藏了他的个人资料。
Luciano Andress Martini

13

Bash + coreutils,103 99 98字节

for((;c==p%26;r=`date +%s%3N`-(s=s?s:r),c=62#$c-9,p++))
{
read -N1 c
}
((c==p))||r=Fail
echo "
$r"

必须在终端中运行。

测试运行

$ bash type.sh
abcdefghijklmnopqrstuvwxyz
3479
$ bash type.sh
abcz
Fail
$ bash type.sh 2>&- # typing '@' would print to STDERR
ab@
Fail
$ bash type.sh
A
Fail

4
3479相当快!做得好:)
RobAu

是否需要特定版本的bash或其他东西?在4.4.12上,a立即输入会提示我line 1: ((: r=15094100773N: value too great for base (error token is "15094100773N")并退出。
numbermaniac

@numbermaniac Bash的版本无关紧要,但date可能是其中之一。我的来自GNU coreutils 8.23。date +%s%3N在您的系统上打印什么?
丹尼斯,

它输出@Dennis- 如果有所不同,15094104833N这是datemacOS上的内置实用程序。
numbermaniac

1
@numbermaniac BSD date似乎正在使用strftime,但无法识别%N
丹尼斯,

9

Python 2 + getch,116字节

import time,getch
t=[i+97-ord(getch.getche())and exit("Fail")or time.time()for i in range(26)]
print(t[-1]-t[0])*1e3

感谢ovs和ElPedro修复了代码并节省了57个字节。


7

SOGL V0.12,35 个字节

"ζ¦F‘→I
]I!}Su[I:lzm≠?■Fail←z=?Suκ←

在这里尝试!-单击运行,然后在输入框中输入字母。请注意,这可能有点滞后,因为SOGL仅在每执行100个令牌时才暂停输入(并且SOGL相当慢)。如果那困扰您,请sleepBI=true在控制台中运行。

注意:请勿在兼容模式下运行它-它将永远循环。

说明:

"ζ¦F‘    push "inputs.value" (yes, that is a word in SOGLs english dictionary)
     →   execute as JS, pushing the inputs contents
      I  named function I


]  }                do while POP is truthy
 I                    execute I
  !                   negate it - check if it's empty
    Su              push the current milliseconds since start
[                   loop
 I                    execute I
  :                   duplicate the result
   l                  let its length
    zm                mold the alphabet to that size
      ≠?              if that isn't equal to one of the result copies
        ■Fail           push "Fail"
             ←          and exit, implicitly outputting that
              z=?     if the other copy is equal to the alphabet
                 Su     push the milliseconds since start
                   κ    subtract the starting milliseconds from that
                    ←   and exit, implicitly outputting the result

@HyperNeutrino我知道它将派上用场:p
dzaima

谁会期望SOGL能够做到这一点...顺便说一句,词典中的单词不是“失败”吗?
暴民埃里克(Erik the Outgolfer)

@EriktheOutgolfer很好,应该说 SOGL 一种通用语言,但是那行不通:p
dzaima

顺便说一句,我不知道这是否完全有效,但我再次认为可能是接口问题,而不是背后的解释器……
Erik the Outgolfer

@EriktheOutgolfer是的,我不知道那是多么有效,我想我正在等待OP。刚开始我以为这就像HTML答案一样,但是现在来看,它
已经大不相同了-dzaima

7

帕斯卡(FPC),176字节

Uses CRT,SysUtils;Var c:char;a:Real;Begin
for c:='a'to'z'do
if c=ReadKey then
begin Write(c);if c='a'then a:=Now;end
else
begin
Write('Fail');Halt;end;Write((Now-a)*864e5)
End.

在线尝试!

高尔夫代码中使用的一些技巧:

  • 使用Real作为短替代TDateTime,因为所定义这里TDateTime= Double,这是浮点型。
  • MilliSecondsBetween该代码没有用于计算时间间隔,而是将两个浮点值之间的差乘以864e5,这是由于此处TDateTime描述的Free Pascal编码方式起作用的。

注意:

  • ReadKey函数实际上不会在控制台上打印键,因此必须使用手动向控制台写入Write(c)
  • 0由于明显的原因,TIO在输入字母时得分接近。
  • 该程序以浮点数表示法打印时间,我想这是允许的。

欢迎光临本站!
caird coinheringaahing

您可以将for c:='a'to'z'do移至与相同的行,以节省1个字节a:=Time;
伊斯梅尔·米格尔

也许您应该尝试Now而不是Time因为它更短。
tsh

为什么86398338?? 我知道您是864e5的倍数,因为一天有864e5毫秒。但是这个魔术数字是怎么来的呢?
tsh

@tsh我也不知道。通过手动测试,我碰巧发现了这个“魔术”数字,而且我不知道Pascal如何存储TDateTimeDouble864e5听起来更正确,我将解决问题。
user75648 '17

5

Java,404 388 354 348 320 318字节

import java.awt.*;import java.awt.event.*;interface M{static void main(String[]a){new Frame(){{add(new TextArea(){{addKeyListener(new KeyAdapter(){long t,i=64;public void keyPressed(KeyEvent e){t=t>0?t:e.getWhen();if(e.getKeyChar()!=++i|i>89){System.out.print(i>89?e.getWhen()-t:"Fail");dispose();}}});}});show();}};}}

在这里,我认为Java控制台已经很冗长了。
由于Java无法原始监听控制台afaik中的按键,因此我将GUI与一起使用java.awt

-78字节,感谢@OlivierGrégoire

说明:

import java.awt.*;                 // Required import for Frame and TextField
import java.awt.event.*;           // Required import for KeyAdapter and KeyEvent
interface M{                       // Class
  static void main(String[]a){     //  Mandatory main-method
    new Frame(){                   //   Create the GUI-Frame
      {                            //    With an initialization-block
        add(new TextArea(){        //     Add an input-field
          {                        //      With it's own initialization-block
            addKeyListener(new KeyAdapter(){
                                   //       Add a KeyAdapter to the input-field
              long t,              //        Long to save the time
                   i=64;           //        Previous character, starting at code of 'a' -1
              public void keyPressed(KeyEvent e){ 
                                   //        Override the keyPressed-method:
                t=t>0?             //         If `t` is already set:
                   t               //          Leave it the same
                  :                //         Else:
                   e.getWhen();    //          Save the current time (== start the timer)
                if(e.getKeyCode()!=++i
                                   //         As soon as an incorrect character is pressed,
                   |i>89){         //         or we've reached 'z':
                  System.out.print(i>89?
                                   //          If we're at 'z':
                    e.getWhen()-t  //           Print the end-time in ms to the Console
                   :               //          Else (an incorrect character was pressed)
                    "Fail");       //           Print "Fail" to the Console
                  dispose();}      //          And exit the application
              }                    //        End of keyPressed-method
            });                    //       End of KeyAdapter
          }                        //      End of input-field initialization-block
        });                        //     End of input-field
        show();                    //     Initially show the Frame
      }                            //    End of Frame initialization-block
    };                             //   End of Frame 
  }                                //  End of main-method
}                                  // End of class

成功的gif示例:(是的,我在这里输入字母的速度非常慢。。)
注意:这是旧的gif。当前版本不再将按键打印到控制台。并且它不再用小数点后的数字打印时间。

在此处输入图片说明
失败的gif示例:
注意:这是旧的gif。当前版本不再将按键打印到控制台。

在此处输入图片说明


2
令人印象深刻的答案,考虑到它的GUI!
Pureferret

1
388个字节。除了打高尔夫球之外,我还自由地修复了您的代码,因为您使用setVisible(false)了退出而不是退出。
奥利维尔·格雷戈尔

@OlivierGrégoire谢谢。忘记了showdispose,甚至比还要短setVisible。我几乎从来没有使用过Java的GUI。并且很聪明地使用类初始化而不是将它放在主方法中。我应该记住这一点。
凯文·克鲁伊森

1
@KevinCruijssen谢谢,没问题;-)尽管有些一般性的评论:您不需要两次输出字母。已经提供了回显功能TextField。另外,您可以使用TextArea而不是TextField获取两个字节。最后,KeyEvent有一个getWhen方法可以给出时间间隔和事件之间的时间(以毫秒为单位)。只需要使用那些而不是System.nanoTime()获得更多的字节。
奥利维尔·格雷戈尔

1
别客气!但是我把它进一步减少到320个字节。;-)
OlivierGrégoire17年

4

C#(.NET Core),245 + 13183 + 41177 + 41字节

的+41个字节using System;using static System.Console

未经测试,因为我在移动设备上,并且无法在TIO上运行。

n=>{int c=ReadKey().KeyChar,x=0;try{if(c!=97)x/=x;var s=DateTime.Now;while(c<149)if(ReadKey().KeyChar!=c++)x/=x;Write((DateTime.Now-s).TotalMilliseconds);}catch{Write("Fail");}}

1
+1用于创建功能正常的程序,而无需对其进行测试。打高尔夫球:1)我发现产生异常的一种较短方法:int x=0;然后做x=1/x;。这将节省14个字节。不幸的是你需要x。如果您尝试执行此操作,1/0则会得到除以零的恒定编译器错误。2)-5个字节,用于将的声明c与first组合ReadKey。3)将内部条件更改为ifReadKey!=++c并再删除c++;else-9个字节。
raznagul

@raznagul谢谢!x=1/x可以减少到x/=x。并且我添加using static System.Console;了保存更多字节的方法:)
Ian H.

通过删除ic在循环条件中使用,可以节省更多的字节。
raznagul

3

MSX-BASIC,126个字符

1C=97:GOSUB3:TIME=0
2IFASC(C$)<>CTHEN?"Fail":ENDELSEIFC=122THEN?TIME*20:ENDELSEC=C+1:GOSUB3:GOTO2
3C$=INKEY$:IFC$=""GOTO3
4RETURN

TIME 是内部MSX-BASIC变量,每20毫秒增加1。


3

C#(.NET Core)184 + 13 = 197 173 + 13 = 186字节

()=>{var s=DateTime.Now;var i=97;while(i<123&&Console.ReadKey().KeyChar==i)if(i++<98)s=DateTime.Now;Console.Write(i>122?$"\n{(DateTime.Now-s).TotalMilliseconds}":"\nFail");}

在线尝试!

不幸的是,TIO无法运行此命令,但是它对于获取字节数非常方便。

+13 using System;

更改i==123为-1 i>122。我很想这么做i>'z'

致谢

-10个字节,感谢@raznagul

不打高尔夫球

()=>{
    var s=DateTime.Now;
    var i=97;

    while(i<123&&Console.ReadKey().KeyChar==i)
        if(i++<98)
            s=DateTime.Now;

    Console.Write(i>122?
        $"\n{(DateTime.Now-s).TotalMilliseconds}":
        "\nFail"
    );
} 

1
您可以通过将ReadKey移至循环条件来保存一些字节,以便删除第一个if和第一个break
raznagul

3

Node.js的,240个 213字节

require('readline',{stdin:i,stdout:o,exit:e}=process).emitKeypressEvents(i)
w=s=>o.write(s)
n=0
i.on('keypress',c=>w(c)&&c.charCodeAt()-97-n?e(w(`
Fail`)):!n++?s=d():n>25&&e(w(`
`+(d()-s)))).setRawMode(d=Date.now)

编辑:由于乔丹节省了27个字节

非高尔夫版本:

const readline = require('readline')

let index = 0
let start

readline.emitKeypressEvents(process.stdin)
process.stdin.setRawMode(true)

process.stdin.on('keypress', character => {
  process.stdout.write(character )

  // Lookup character in ASCII table
  if (character !== String.fromCharCode(97 + index) {
    process.stdout.write('\nFail')
    process.exit()
  }

  index++

  if (index === 1) {
    start = Date.now()
  }

  if (index === 26) {
    process.stdout.write('\n' + (Date.now() - start))
    process.exit()
  }
})

3

C(gcc),303字节

适用于* nix系统。独立代码删除当前终端的规范模式,以允许阅读字符而无需等待换行符:

/!\运行此程序将使终端几乎不可用。

#import <stdlib.h>
#import <termios.h>
#define x gettimeofday(&t,0)
#define r t.tv_sec*1000+t.tv_usec/1000
c,i=97;main(){long s=0;struct termios n;struct timeval t;cfmakeraw(&n);n.c_lflag|=ECHO;tcsetattr(0,0,&n);for(;i<'d';){c=getchar();if(c!=i++)puts("\nFail"),exit(0);x;s=s?:r;}x;printf("\n%ld",r-s);}

取消评论并评论:

// needed in order to make gcc aware of struct termios
// and struct timeval sizes
#import <stdlib.h>
#import <termios.h>

// gets the time in a timeval structure, containing
// the number of seconds since the epoch, and the number
// of µsecs elapsed in that second
// (shorter than clock_gettime)
#define x gettimeofday(&t,0)
// convert a timeval structure to Epoch-millis
#define r t.tv_sec*1000+t.tv_usec/1000

// both integers
// c will contain the chars read on stdin
// 97 is 'a' in ASCII
c,i=97;

main(){
  long s=0; // will contain the timestamp of the 1st char entered
  struct timeval t; // will contain the timestamp read from gettimeofday

  // setting up the terminal
  struct termios n;
  cfmakeraw(&n);//create a raw terminal configuration
  n.c_lflag|=ECHO;//makes the terminal echo each character typed
  tcsetattr(0,0,&n);//applies the new settings

  // from 'a' to 'z'...
  for(;i<'{';){
    // read 1 char on stdin
    c=getchar();

    // if int value of the input char != expected one => fail&exit
    if(c!=i++)puts("\nFail"),exit(0);

    // macro x: get current timestamp
    x;

    // if not already set: set starting timestamp
    s=s?:r;
  }

  // get end of sequence timestamp
  x;

  // prints the end-start timestamps difference
  printf("\n%ld",r-s);
}

替代解决方案(218字节):

如果允许预先配置终端,那么我们可以省去处理那部分代码的那一部分。

这是没有终端操作的相同代码:

#import <stdlib.h>
#define x gettimeofday(&t,0)
#define r t.tv_sec*1000+t.tv_usec/1000
c,i=97;main(){long s=0;struct timeval t;for(;i<'{';){c=getchar();if(c!=i++)puts("\nFail"),exit(0);x;s=s?:r;}x;printf("\n%ld",r-s);}

要使其起作用:

$ gcc golf.c
$ stty -icanon
$ a.out

运行时示例: 在此处输入图片说明


3

Commodore BASIC v2-113字节

大写字母必须转移。
感谢Felix Palmen指出了一些错别字,规格请
尝试一下

0d=64
1on-(f=26)gO5:gEa$:ifa$=""tH1
2iff=0tHt=ti
3f=f+1:ifa$<>cH(d+f)tH6
4?cH(14)a$;:gO1
5?:?(ti-t)/60*1000:eN
6?"Fail"

点击修改以查看更正后的降价代码。
NieDzejkob

欢迎光临本站!您能否将链接添加到解释器(如果存在),以便其他人可以测试您的代码?
caird coinheringaahing

好吧,这使用IRQ系统(TI在其中进行了递增),我认为不合适,因为它缺乏精度,但是我想这很公平,因为在BASIC中根本没有更好的方法:语法错误1-有帮助吗?
菲利克斯·帕尔曼

我自己弄清楚了,第一行中有一个错字,应该是1on-(f=26)gO4:gEa$:ifa$=""tH1Nitpicks:1.)输出在同一行上; 2。)输出是全大写字母-我认为您应该解决这些问题,不会占用很多字节无论如何:)
费利克斯·帕尔默

解决了这些问题,还有错别字吗?
mondlos '17

2

Perl 5中,79 93 31(-MTerm :: ReadKey -mtime ::高分辨率=时间)的字节

$|=1;map{ReadKey eq$_||exit print"
Fail";$s||=time}a..z;print$/,0|1e3*(time-$s)

$|=1不足以将终端设置为原始模式,stty -icanon应在运行之前或

ReadMode 3;map{ReadKey eq$_||exit print"
Fail";print;$s||=time}a..z;print$/,0|1e3*(time-$s)

在运行命令后查看终端中的字符:stty echostty echo icanon


好老ReadKey!你可以在这里保存了几个字节,并且,1e31000$s||=time如果你设置$s,然后再打电话ReadKey,你可以换出map一个后缀for。我想说die而不是exit print,但我想您就在那...我做printf"\n%i"了些修改,但结果却更大了,我考虑过使用$-而不是$s,但这太愚蠢了!:)
Dom Hastings

@DomHastings,谢谢您的帮助,我可以节省4个字节,但是我添加了5个字节来设置无缓冲输入$|=1;,而且$ s || = time不能换出地图,因为计时器必须在按下第一个键之后启动,并且dieFail在stderr而不是stdout上回显。
Nahuel Fouilleul

很高兴为您提供帮助,希望您不介意我提供建议!是的,太遗憾了exit print!对不起,我不认为我解释我的想法的for正确:$s||=time,ReadKey eq$_||exit print" Fail"for a..z要工作,我想......甚至$|=$s||=...或者$|=map...如果你喜欢的方式!认为您几乎已经钉上它了!
Dom Hastings

$|=map..没有在新终端中设置未缓冲的输入(删除时为ReadMode 3,这是错误的,因为我在同一会话中进行测试),并且$s||=time在第一个ReadKey太早启动计时器之前
Nahuel Fouilleul

啊,我误会了,我明白了,开始编写脚本检查之后没有等待足够长的时间... :)可耻的是$|,但同样,它存储在循环之后,为时已晚!您领先一步!
唐·黑斯廷斯

2

Aceto,70个字节

d'|d 't9
$z=p zp1
!=   >#v
d,   1 +
cTpaXpn3
Io$'p"*F
|'!=ilnu
@ad,aF"

@|如果堆栈上的值是真实的,我首先设置一个捕获标记并水平镜像()。最初不是,以后总是如此。如果输入了错误的密钥,我们稍后将跳回到此处。接下来,我们推栈(上一个'a),那么我们复制它和从用户读取单个字符(d,)。如果两个字符不相等(=!),我们将“崩溃”($)并跳回到捕捉标记。否则,我们按下另一个“ a”并打印它,然后设置当前时间('apT)。

然后我们进入“主循环”:我们“增加”当前字符,“增加”字符('apToIc),然后复制它,读取一个新字符,进行比较,如果字符不同则“崩溃”。 (d,=!$)。如果没有崩溃,我们将当前字符与“ z”(d'z=|)进行比较,如果不相等,则打印该字符,然后按下1并“有条件地”跳转(在这种情况下:始终)到仅o在代码中(我们主循环的开始)。如果等于z,我们将水平镜像到顶部的一些空白区域。我们打印“ z”,然后按当前时间(减去开始时间;t),然后将数字乘以1000(将10升至三次方得到91+3F);(因为我们得到秒,而不是毫秒)。然后我们打印换行符,时间并退出(pX)。

如果我们崩溃了(用户输入错误),我们将一直跳到开头。由于现在堆栈上会有一些真实值,因此我们将水平镜像到上u,这将反转我们移入的方向。n打印换行符,然后压入"Fail"堆栈,打印并退出(pX)。


1

Mathematica(笔记本表达式),248个字节

DynamicModule[{x={},s=0,t=0},EventHandler[Framed@Dynamic[If[x=={"a"}&&s<1,s=SessionTime[]];Which[x==a,If[t==0,t=SessionTime[]-s];1000t,x==a~Take~Length@x,""<>x,1>0,"Fail"]],Table[{"KeyDown",c}:>x~AppendTo~CurrentValue@"EventKey",{c,a=Alphabet[]}]]]

这个怎么运作

DynamicModule[{x={},s=0,t=0},
  EventHandler[
    Framed@Dynamic[
      If[x=={"a"} && s<1,s=SessionTime[]];
      Which[
        x==a,If[t==0,t=SessionTime[]-s];1000t,
        x==a~Take~Length@x,""<>x,
        1>0,"Fail"]],
    Table[{"KeyDown",c}:>x~AppendTo~CurrentValue@"EventKey",
      {c,a=Alphabet[]}]]]

一个DynamicModuleEventHandler该响应小写字母按键。变量xs和分别t保持到目前为止按下的字母,开始时间和结束时间。一旦发现x等于{"a"},我们就开始计时。我们将显示花费的总时间,或显示到目前为止构建的字符串,或显示"Fail"是否满足条件。

我们可以节省一个字节,t<1而不是t==0假设没有人能在不到一秒钟的时间内输入字母:)

如果要在Mathematica笔记本中进行尝试,请记住,必须先在框架内单击,然后才能注册按键。(这就是我们需要框架开始的原因;如果Framed不存在该框架,那么当按下一个键时,所选的整个对象都会更改,因此它将停止被选择,而您必须再次单击。)


1

C#,154152 + 13 = 165字节

感谢Ayb4btu的评论,节省了2个字节

x=>{
  long t=0,c=97;
  for(;Console.ReadKey().KeyChar==c++&&c<123;t=t<1?DateTime.Now.Ticks:t);
  Console.Write(c>122?"\n"+(DateTime.Now.Ticks-t)/1e4:"\nFail");
}

上面的代码具有空格,使其适合没有滚动条的SE。空格不是字节数的一部分

和13个字节用于 using System;

它与Ayb4btu的版本相似,但有以下区别:

  • 将日期时间存储为长时,还可以使c长时和声明的快捷方式

  • 循环不需要单独的中断

  • $"interpreted strings"与在毫秒数上添加所需的“ \ n”以使其成为内联字符串相比,使用它实际上并不短

  • for有时使用循环可以使我们节省一段时间的字符,尽管我认为这不会节省等效的字符while

从Ayb4btu:

  • s=s==0可以成为s=s<1并且c==123可以成为c>122

不打高尔夫球

long t=0,c=97;

for (;                                         //no loop vars declared
  Console.ReadKey().KeyChar == c++ && c < 123; //loop test
  t = t < 1 ? DateTime.Now.Ticks : t          //post-loop assigns
) ;                                            //empty loop body!

//now just need to turn ticks into millis, 10,000 ticks per millis
Console.Write(c>122?"\n"+(DateTime.Now.Ticks-t)/1e4:"\nFail");

很好的解决方案DateTime。您可以通过更改s=s==0为来节省更多的字节(以s=s<1s不会为负的事实为基础)并更改i==123i>122
Ayb4btu

另外,这是否经过测试?如我所见,它i<123必须在之前ReadKey(),否则它将在显示时间之前在z之后等待另一个字符。
Ayb4btu

奇怪的是,由于在字母的末尾,z应该表示readkey.keychar在用户键入z时返回122,c也是122,因此'z' == 122成功,然后c递增,然后对c(现在为123)进行测试c<123并失败,从而停止循环..?
凯斯·贾德

没错,我在看c++增量时错过了增量。但是,我只是尝试了一下,当我键入abcdefghijklmnopqrstuvwxys它时给了我一点时间而不是失败。我相信这是因为c即使KeyChar检查失败,仍然会增加,因此通过了c>122检查。
Ayb4btu

好点-也许将++移至c <123检查将使字节数保持不变,并在最后一个字符错误的情况下防止c递增-现在没有时间进行调试,但我来看看!欢呼声:)
Caius Jard

0

Processing.org 133 142

第一个代码没有退出

char k=97;int m;void draw(){if(key==k){m=m<1?millis():m;print(key=k++,k>122?"\n"+(millis()-m):"");}if(m>0&&key!=k-1){print("\nFail");exit();}}

0

GCC,Windows,98字节

t;main(i){for(;i++<27;t=t?:clock())if(95+i-getche())return puts("\nFail");printf("\n%d",clock()-t);}

不需要立即输入第一把钥匙

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.