Digite o alfabeto - o mais rápido possível!

44

Sua tarefa é criar um programa que mede a rapidez com que você pode digitar as letras do alfabeto inglês.

  • O programa só aceitará letras minúsculas apara zem ordem alfabética.
  • Cada letra é repetida conforme digitado na mesma linha (sem nova linha ou qualquer outro separador entre as letras).
  • Se você digitar um caractere inválido, o programa emitirá Fail uma nova linha e sairá.
  • Se você digitar todas as 26 letras, o programa, em uma nova linha , produzirá o tempo em milissegundos que levou da primeira até a última letra e sairá.
  • O timer inicia quando você digita a primeira letra a,.

Exemplo de saídas:

b
Fail

abcdefgg
Fail

abcdefghijklmnopqrstuvwxyz
6440

Isso é , então a resposta mais curta em bytes vence.

Danko Durbić
fonte
4
Projeto relevante que fiz um tempo atrás. (o 15º nível é basicamente isso)
ETHproductions
4
Podemos produzir Failsem uma nova linha de cabeçalho? (ex. abdFail\nou abd Fail\n))
scottinet
1
@ scottinet, não, o resultado ( Failou milissegundos) deve estar em uma nova linha, como no exemplo. A maioria das respostas já assume isso.
Danko Durbić
2
-1, pois essa regra "nova" não estava na especificação original e invalida minhas sugestões em uma das respostas do Python que estavam dentro das regras originais.
ElPedro 31/10/19
Eu esperava que esse fosse um desafio de código mais rápido para imprimir o alfabeto.
ATaco 2/11

Respostas:

40

HTML (JavaScript (ES6)), 129 126 117 bytes

<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()>

Clique na entrada e comece a digitar! Além disso, minha digitação é péssima; Eu levo cerca de 5 segundos, mesmo com a prática. Editar: salvou 2 bytes graças a @HermanLauenstein ao mudar o idioma. Economizou 3 bytes graças a @ qw3n. Economizou 9 bytes graças a @tsh.

Neil
fonte
1
-2 bytes usando html com uma tag script: <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 bytes se não é necessária a marca de fechamento
Herman L
@HermanLauenstein A tag de fechamento parece ser necessária para um trecho, pelo menos, por isso vou deixá-lo em.
Neil
2
Isso é muito irritante e divertido ao mesmo tempo.
Zenon
1
Que tal colocar evento na entrada? <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
Não ecoa o texto em uma nova linha
dkudriavtsev
33

Código da máquina 6502 (C64 PAL), 189 165 bytes

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
  • -24 bytes, incorporando funções e não se importando com outras interrupções da CIA2

Demonstração online (Usage:sys49152)

Captura de tela


Explicação:

Este seria um programa minúsculo, se não fosse pelo problema de uma medição exata de milissegundos no C64. A interrupção do sistema ocorre aproximadamente 60 vezes por segundo, o que nem chega perto. Portanto, temos que usar um temporizador de hardware aqui, que obtém suas marcações de entrada do relógio do sistema.

Em uma máquina PAL, o relógio do sistema é exatamente 985248 Hz. Portanto, inicializar o timer para 985 fornece algo próximo a ticks de milissegundos, mas é um pouco rápido demais, teríamos que contar 986 ciclos para cada quarto tick ou pressionar o timer por um único ciclo. Isso não é possível, mas podemos segurar o temporizador durante 6 ciclos com a seqüência DEC $DD0E, INC $DD0E: $DD0Eé o registro de controle timer com bit 0 ligá-lo dentro e fora, e ambas as instruções demorar 6 ciclos, assim as gravações exatas que parar e iniciar o temporizador são exatamente 6 ciclos separados. Portanto, temos que executar essa sequência a cada 6 * 4 = 24º tick. Isso ainda não é absolutamenteExatamente, o cronômetro ficará 1 milissegundo atrás após 8 minutos e 12 segundos, mas provavelmente é bom o suficiente - compensar isso exigiria muito código.

edit : o valor inicial do timer deve ser 984, e não 985, porque esses timers são acionados "em underflow"; portanto, um valor 0 contará mais um ciclo antes de disparar. Código fixo, contagem de bytes inalterada.

Aqui está a lista de desmontagem comentada:

         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
Felix Palmen
fonte
6
Bem, agora eu tenho um temporizador de milissegundos um tanto decente na minha caixa de ferramentas;) pode ser útil algum dia.
Felix Palmen
11
Preste atenção, crianças de roteiro. Isso é golfe de verdade.
J ...
1
@J ... Eu poderia jogar ainda mais inlining .starttimer- fará em breve :) (e ainda mais usando o sistema TIcomo esta resposta BÁSICA , mas não tenho certeza se isso é válido, porque você pode fazer melhor no código da máquina )
Felix Palmen
Uau, eu perdi um fator de 985 ao calcular o erro na minha medição de tempo primeiro - é realmente muito bom do jeito que é (se eu fiz outro erro nos meus cálculos, por favor, aponte!) :)
Felix Palmen
E você vê o que esse cara tem no GITHUB ?: recuperação de inicialização do Android .... ele é completamente louco! adicionou seu perfil como favorito.
Luciano Andress Martini
13

Bash + coreutils, 103 99 98 bytes

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"

Deve ser executado em um terminal.

Execução de teste

$ 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
Dennis
fonte
4
3479é bem rápido! bem feito :)
RobAu
Existe uma versão específica do bash necessária ou algo assim? No 4.4.12, digitar aimediatamente me dá line 1: ((: r=15094100773N: value too great for base (error token is "15094100773N")e sai.
Numbermaniac #
@numbermaniac A versão do Bash não deveria importar, mas a de datepoder. O meu é do GNU coreutils 8.23. O que é date +%s%3Nimpresso no seu sistema?
Dennis
@Dennis it output 15094104833N- esse é o dateutilitário interno do macOS, se isso faz diferença.
Numbermaniac #
1
@ BSumbermaniac dateparece estar usando strftime, que não reconhece %N.
Dennis
9

Python 2 + getch , 116 bytes

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

Agradecimentos a ovs e ElPedro por corrigir o código e salvar 57 bytes.

LyricLy
fonte
7

SOGL V0.12 , 35 bytes

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

Experimente aqui! - clique em executar e digite o alfabeto na caixa de entrada. Observe que pode ser um pouco lento porque o SOGL apenas pausa para entrada a cada 100 tokens executados (e o SOGL é bastante lento). Se isso lhe incomoda, execute sleepBI=trueno console.

nota: não execute isso no modo de compatibilidade - ele funcionará para sempre.

Explicação:

"ζ¦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
dzaima
fonte
@HyperNeutrino Eu sabia que seria útil: p
dzaima
Quem esperaria que o SOGL fosse capaz de fazer isso ... a propósito, "Fail" não é uma palavra no dicionário?
Erik the Outgolfer
@EriktheOutgolfer bem, o SOGL deveria ser uma linguagem para todos os fins, mas isso não deu certo: p
dzaima
BTW eu não sei se isso é completamente válido, mas, novamente, acho que pode ser um problema com a interface e não o intérprete por trás ...
Erik the Outgolfer
@EriktheOutgolfer Sim, eu não sei o quão válido isso é, acho que estou esperando pelo OP. No começo eu pensei que isso é algo como a resposta HTML, mas é bem diferente agora que eu olho para ela
dzaima
7

Pascal (FPC) , 176 bytes

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.

Experimente online!

Alguns truques usados ​​no código para jogar golfe:

  • Use Realcomo uma alternativa mais curta para TDateTime, porque, conforme definido aqui , TDateTime= Double, que é do tipo de ponto flutuante.
  • Em vez de usar MilliSecondsBetweenpara calcular o intervalo de tempo, esse código multiplica a diferença entre dois valores de ponto flutuante por 864e5, o que funciona devido à maneira como o Free Pascal codifica TDateTimedescrito aqui .

Nota:

  • ReadKeyA função realmente não imprime a chave no console; portanto, Write(c)é necessário escrever manualmente no console .
  • O TIO obtém uma pontuação próxima 0para digitar o alfabeto por motivos óbvios.
  • O programa imprime o tempo em notação de ponto flutuante, acho que é permitido.
user75648
fonte
Bem vindo ao site!
caird coinheringaahing
Você pode economizar 1 byte movendo o for c:='a'to'z'dopara a mesma linha que a:=Time;.
Ismael Miguel
Talvez você devesse tentar, em Nowvez de Timeser mais curto.
tsh
Porque 86398338?? Entendo se você tem vários 864e5, pois existem 864e5 milissegundos em um dia. mas como é que esse número mágico vem?
Tsh
@tsh também não sei. Por testes manuais que acontece para encontrar esse número "mágico", e eu não sei loja como Pascal TDateTimecomo Double. 864e5parece mais correto, vou resolver os problemas.
user75648
5

Java, 404 388 354 348 320 318 bytes

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

E aqui eu pensei que o Java Console já estivesse detalhado.
Como o Java não tem como escutar breves pressionamentos de teclas no console, eu uso uma GUI com java.awt.

-78 bytes graças a @ OlivierGrégoire .

Explicação:

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

Exemplo de gif de sucesso: (Sim, digito o alfabeto bem devagar aqui ..)
Nota: Este é um gif antigo. A versão atual não imprime mais as teclas pressionadas no console. E não imprime mais a hora com dígitos após o ponto decimal.

insira a descrição da imagem aqui
Exemplo de gif de falha:
Nota: este é um gif antigo. A versão atual não imprime mais as teclas pressionadas no console.

insira a descrição da imagem aqui

Kevin Cruijssen
fonte
2
resposta impressionante, considerando que tem um gui!
Pureferret
1
388 bytes . Tomei a liberdade de corrigir seu código, além do golfe, porque você usava em setVisible(false)vez de sair.
Olivier Grégoire
@ OlivierGrégoire Obrigado. Esqueceu showe dispose, que é ainda mais curto que setVisible. Eu quase nunca uso a GUI do Java. E inteligente usar a inicialização de classe em vez de colocá-la no método principal. Eu deveria me lembrar disso.
Kevin Cruijssen 30/10
1
@KevinCruijssen Obrigado, e não há problema ;-) Apesar de alguns comentários mais gerais: você não precisa exibir as letras duas vezes. O eco já é fornecido por TextField. Além disso, você pode usar em TextAreavez de TextFieldobter dois bytes. Por fim, KeyEventpossui um getWhenmétodo que fornece o tempo entre a época e o evento em milissegundos. Só precisa usá-los em vez de System.nanoTime()ganhar ainda mais bytes.
Olivier Grégoire
1
De nada! Mas reduzi-o ainda mais para 320 bytes . ;-)
Olivier Grégoire
4

C # (.NET Core), 245 + 13 183 + 41 177 + 41 bytes

+41 bytes para using System;using static System.Console.

Não testado, pois estou no celular e isso não é executado no 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");}}
Ian H.
fonte
1
+1 para criar um programa em funcionamento sem poder testá-lo. Golfe: 1) Descobri uma maneira mais curta de produzir a exceção: int x=0;e então faça x=1/x;. Isso deve economizar 14 bytes. Infelizmente você precisa x. Se você tentar 1/0obter uma divisão por erro constante do compilador zero . 2) -5 bytes para combinar a declaração de ccom o primeiro ReadKey. 3) Altere a condição no interior ifpara ReadKey!=++ce remova-a c++;elsepara outros -9 bytes.
raznagul 30/10
@raznagul Thanks! x=1/xpode ser reduzido para x/=x. E eu adicionei using static System.Console;para salvar mais alguns bytes :)
Ian H.
Mais alguns bytes podem ser salvos removendo ie usando ca condição de loop.
raznagul 30/10
3

MSX-BASIC, 126 caracteres

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

TIME é uma variável interna do MSX-BASIC que aumenta em um a cada 20 milissegundos.

Konamiman
fonte
3

C # (.NET Core) , 184 + 13 = 197 173 + 13 = 186 bytes

()=>{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");}

Experimente online!

Infelizmente, o TIO não pode executar isso, mas é útil para obter a contagem de bytes.

+13 para using System;

-1 alterando i==123para i>122. Fiquei tentado a fazer isso i>'z'.

Reconhecimentos

-10 bytes graças a @raznagul

Ungolfed

()=>{
    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"
    );
} 
Ayb4btu
fonte
1
Você pode salvar alguns bytes movendo a ReadKeycondição de loop para remover o primeiro ife o break.
raznagul 30/10
3

Node.js, 240 213 bytes

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)

EDIT: Salvo 27 bytes graças a Jordan

Versão não destruída:

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()
  }
})
Saming
fonte
3

C (gcc) , 303 bytes

Funciona em sistemas * nix. Código autônomo que remove o modo canônico do terminal atual para permitir a leitura de caracteres sem aguardar novas linhas:

/! \ A execução deste programa tornará o terminal quase inutilizável.

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

Ungolfed e comentou:

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

Solução alternativa (218 bytes):

Se a configuração prévia do terminal for permitida, poderemos nos livrar da parte do código que manipula essa parte.

Aqui está o mesmo código sem manipulação de terminal:

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

Para fazer funcionar:

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

exemplo de tempo de execução: insira a descrição da imagem aqui

escoteiro
fonte
3

Commodore BASIC v2 - 113 bytes

Letras maiúsculas devem ser deslocadas.
Obrigado a Felix Palmen por apontar alguns erros de digitação, especificações
tente

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"
mondlos
fonte
Clique em editar para ver o código de remarcação corrigido.
NieDzejkob
Bem vindo ao site! Você poderia adicionar um link a um intérprete (se houver), para que outros possam testar seu código?
caird coinheringaahing
Bem, isso usa o sistema IRQ ( TIé incrementado nele). Considero inadequado por sua falta de precisão, mas acho que é um jogo justo aqui, porque não há como fazer melhor no BASIC :) Ainda assim, colando isso no vice, entendo um erro de sintaxe em 1- alguma ajuda?
Felix Palmen
Eu mesmo percebi , você tem um erro de digitação na linha um, deve ser 1on-(f=26)gO4:gEa$:ifa$=""tH1Nitpicks: 1.) a saída está na mesma linha, 2.) a saída é tudo em maiúsculas - acho que você deve corrigir isso, não precisará de muitos bytes de qualquer maneira :)
Felix Palmen
Os problemas foram resolvidos, resta algum erro de digitação?
Mondlos #
2

Perl 5, 79 93 +31 (-MTerm :: ReadKey -MTime :: HiRes = time) bytes

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

$|=1não for suficiente para configurar o terminal no modo bruto, stty -icanondeve ser executado antes ou

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

para ver caracteres no terminal após executar o comando: stty echooustty echo icanon

Nahuel Fouilleul
fonte
Bom velho ReadKey! Você pode salvar alguns bytes aqui e ali, 1e3para e 1000, $s||=timese você definir $sprimeiro e depois ligar ReadKey, poderá trocar o mappara um postfix for. Eu gostaria de dizer em dievez de exit print, mas acho que você está aí ... Eu consertei, printf"\n%i"mas isso acabou maior, e pensei em usar em $-vez de $s, mas isso era estúpido! :)
Dom Hastings
@DomHastings, obrigado por sua ajuda, eu pude salvar 4 bytes, mas adicionei 5 bytes para definir a entrada sem buffer $|=1;, também $ s || = o tempo não pode ser trocado pelo mapa porque o timer deve iniciar após a primeira tecla pressionada e dieecoaria Failem stderr em vez de stdout.
Nahuel Fouilleul
Feliz em ajudar, espero que você não se importe que eu ofereça idéias! Sim, é uma pena, exit printé tão longo! Desculpe, acho que não expliquei foradequadamente o meu pensamento : $s||=time,ReadKey eq$_||exit print" Fail"for a..zdeve funcionar, acho ... Talvez até $|=$s||=...ou $|=map...se você preferir essa abordagem! Acho que você acertou em cheio!
Dom Hastings
$|=map..não define de entrada unbuffered no novo terminal (eu tinha o erro ao remover, ReadMode 3, porque eu estava testando na mesma sessão), e $s||=timeantes da primeira ReadKey iria começar temporizador muito cedo
Nahuel FOUILLEUL
Ahh, eu entendi errado, entendi agora, não esperei muito tempo depois de começar a escrever o script para verificar isso ... :) Que pena $|, mas, novamente, é armazenar após o loop que é tarde demais! Você está um passo à frente!
Dom Hastings
2

Aceto , 70 bytes

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

I começar por definir uma marca de captura e espelhamento horizontalmente ( @|), se o valor na pilha é truthy. Não é inicialmente, e mais tarde sempre será. Voltaremos aqui mais tarde se uma chave errada for digitada. Em seguida, pressionamos um a na pilha ( 'a), duplicamos e lemos um único caractere do usuário ( d,). Se os dois caracteres não forem iguais ( =!), "travaremos" ( $) e voltaremos para a marca de captura. Caso contrário, pressionamos outro "a" e o imprimimos, depois definimos a hora atual ( 'apT).

Então entramos em nosso "loop principal": "incrementamos" o caractere atual e "incrementamos" o caractere ( 'apToIc), depois o duplicamos, lemos um novo caractere, o comparamos e "travamos" se os caracteres não forem idênticos ( d,=!$) Se não travarmos, comparamos o caractere atual com "z" ( d'z=|), se não for igual, imprimimos o caractere, pressionamos 1 e pulamos "condicionalmente" (neste caso: sempre) para o somente ono código (o início do nosso loop principal). Se fosse igual a z, espelhamos horizontalmente em algum espaço vazio no topo. Imprimimos "z", pressionamos o horário atual (menos o horário inicial; t) e multiplicamos o número 1000 (obtido aumentando 10 para a terceira potência; 91+3F) por ele (porque temos segundos, milissegundos). Em seguida, imprimimos uma nova linha, a hora e a saída (pX)

Se alguma vez travarmos (informações incorretas do usuário), pularemos todo o caminho até o início. Como agora teremos algum valor de verdade na pilha, espelharemos horizontalmente na u, o que reverte a direção em que estamos nos movendo. nImprime um caractere de nova linha, empurramos "Fail"a pilha, imprimimos e saímos ( pX).

L3viathan
fonte
1

Mathematica (expressão em notebook), 248 bytes

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

Como funciona

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

A DynamicModulecom um EventHandlerque responde a pressionamentos de teclas de letras minúsculas. As variáveis x, se tmantêm as letras pressionadas até o momento, o horário de início e o horário de término, respectivamente. Assim que percebemos que xsomos iguais {"a"}, começamos a hora; exibimos o tempo total gasto ou a string criada até o momento ou "Fail"dependendo de qual condição seja atendida.

Poderíamos salvar outro byte em t<1vez de t==0assumir que ninguém é rápido o suficiente para digitar o alfabeto em menos de um segundo :)

Se você estiver tentando isso em um notebook Mathematica, lembre-se de que precisa clicar dentro do quadro antes que suas teclas sejam registradas. (Esse é o motivo pelo qual precisamos do quadro; se Framednão estiver lá, o objeto inteiro selecionado será alterado quando uma tecla for pressionada; portanto, ela deixa de ser selecionada e você terá que clicar novamente.)

Misha Lavrov
fonte
1

C #, 154 152 + 13 = 165 bytes

Guardado 2 bytes graças aos comentários de Ayb4btu

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

O código acima possui um espaço em branco para ajustá-lo ao SE sem uma barra de rolagem. Espaço em branco não faz parte da contagem de bytes

e 13 bytes para using System;

É semelhante à versão do Ayb4btu, mas com as seguintes diferenças:

  • Armazenar datetime como um longo, nos permite fazer cum long também, e atalho a declaração

  • O loop não precisa de uma pausa separada

  • Na verdade, não é mais curto de usar do que $"interpreted strings"adicionar um "\ n" necessário nos milissegundos para torná-lo uma string para o inline se

  • forÀs vezes, usar um loop nos permite salvar caracteres por um tempo, embora eu ache que este não economize o equivalentewhile

Partida Ayb4btu:

  • s=s==0pode se tornar s=s<1, e c==123pode se tornarc>122

Ungolfed

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");
Caius Jard
fonte
Solução agradável com a forma como você usou DateTime. Você pode salvar mais alguns bytes alterando s=s==0para s=s<1(contando com o fato de que s não será negativo) e alterando i==123para i>122.
Ayb4btu
Além disso, isso foi testado? Como eu achei que i<123tinha que ir antes do ReadKey(), caso contrário, ele espera por outro caractere após z antes de exibir a hora.
Ayb4btu
Estranho, porque no final do alfabeto, zdeve significar readkey.keychar retorna 122 quando o usuário digita z, c também é 122 e, portanto 'z' == 122, é bem-sucedido, c é incrementado e c (agora 123) é testado c<123e falha, interrompendo o ciclo .. ?
Caius Jard
Você está certo, eu perdi o c++incremento quando estava olhando para ele. No entanto, eu apenas tentei e quando digito abcdefghijklmnopqrstuvwxysme dá um tempo em vez de falhar. Eu acredito que é porque cainda aumenta mesmo que o KeyCharcheque falhe e, portanto, passa no c>122cheque.
Ayb4btu
Bom ponto - talvez mover o ++ para a verificação c <123 mantenha o bytecount o mesmo e impeça que o c aumente se o último caractere estiver errado - não há tempo para depurar agora, mas vou dar uma olhada! Cheers :)
Caius Jard
0

Processing.org 133 142

primeiro código não saiu

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();}}
PrincePolka
fonte
0

GCC, Windows, 98 bytes

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

Não requer entrada instantânea para a primeira chave

l4m2
fonte