Escriba el alfabeto, ¡tan rápido como pueda!

44

Su tarea es hacer un programa que mida qué tan rápido puede escribir las letras del alfabeto inglés.

  • El programa sólo aceptará las letras minúsculas aa zen orden alfabético.
  • Cada letra se repite a medida que se escribe en la misma línea (sin nueva línea ni ningún otro separador entre letras).
  • Si escribe un carácter no válido, el programa generará Fail una nueva línea y saldrá.
  • Si escribe las 26 letras, el programa, en una nueva línea , mostrará el tiempo en milisegundos que tomó desde la primera letra hasta la última y saldrá.
  • El temporizador se inicia cuando se escribe la primera letra, a.

Salidas de ejemplo:

b
Fail

abcdefgg
Fail

abcdefghijklmnopqrstuvwxyz
6440

Este es el , por lo que la respuesta más corta en bytes gana.

Danko Durbić
fuente
44
Proyecto relevante que hice hace un tiempo. (el nivel 15 es básicamente esto)
ETHproductions
44
¿Podemos producir Failsin una nueva línea de encabezado? (por ejemplo, abdFail\no abd Fail\n))
scottinet
1
@scottinet, no, el resultado ( Failo milisegundos) debe estar en una nueva línea, como en el ejemplo. La mayoría de las respuestas ya asumen esto.
Danko Durbić
2
-1 ya que esta "nueva" regla no estaba en la especificación original e invalida mis sugerencias sobre una de las respuestas de Python que estaba dentro de las reglas originales.
ElPedro
Esperaba que este fuera un desafío de código más rápido para imprimir el alfabeto.
ATaco

Respuestas:

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

Haga clic en la entrada y comience a escribir! Además, mi escritura apesta; Tomo alrededor de 5 segundos incluso con la práctica. Editar: Guardado 2 bytes gracias a @HermanLauenstein al cambiar de idioma. Guardado 3 bytes gracias a @ qw3n. Guardado 9 bytes gracias a @tsh.

Neil
fuente
1
-2 bytes usando html con una etiqueta de 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 si no se necesita la etiqueta de cierre
Herman L
@HermanLauenstein La etiqueta de cierre parece ser necesaria para un fragmento, al menos, así que lo dejaré.
Neil
2
Esto es demasiado exasperante y divertido al mismo tiempo.
Zenon
1
¿Qué pasa con poner evento en 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
No hace eco del texto en una nueva línea
dkudriavtsev
33

Código de 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 al incorporar funciones y no preocuparse por otras interrupciones CIA2

Demostración en línea (Uso:sys49152)

Captura de pantalla


Explicación:

Este sería un pequeño programa si no fuera por el problema de una medición exacta de milisegundos en el C64. La interrupción del sistema ocurre aproximadamente 60 veces por segundo, lo que ni siquiera está cerca. Así que tenemos que usar un temporizador de hardware aquí que obtiene sus tics de entrada del reloj del sistema.

En una máquina PAL, el reloj del sistema es exactamente 985248 Hz. Inicializar el temporizador a 985, por lo tanto, proporciona algo cerca de tics de milisegundos, pero es un poco demasiado rápido, tendríamos que contar 986 ciclos por cada cuarto tick, o mantener el temporizador durante un solo ciclo. Esto no es posible, pero puede contener el temporizador durante 6 ciclos con la secuencia DEC $DD0E, INC $DD0E: $DD0Ees el registro de control de temporizador con el bit 0 de ponerlo en marcha y apagado, y las dos instrucciones de tomar 6 ciclos, por lo que las escrituras exactos que detener e iniciar el temporizador son exactamente 6 ciclos de diferencia. Por lo tanto, tenemos que ejecutar esta secuencia cada 6 * 4 = 24 tick. Esto todavía no es absolutamenteexacto, el temporizador se retrasará 1 milisegundo después de 8 minutos y 12 segundos, pero probablemente sea lo suficientemente bueno: compensarlo requeriría mucho código.

editar : El valor de inicio para el temporizador debe ser 984, no 985, porque estos temporizadores se disparan "en flujo inferior", por lo que un valor de 0 contará un ciclo más antes de disparar. Código fijo, recuento de bytes sin cambios.

Aquí está el listado de desmontaje comentado:

         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
fuente
66
Bueno, ahora tengo un temporizador de milisegundos algo decente en mi caja de herramientas;) podría ser útil algún día.
Felix Palmen
11
Presta atención, script kiddies. Este es el verdadero golf.
J ...
1
@J ... pude campo aún más por inlining .starttimer- hará pronto :) (y aún más usando el sistema TIcomo este respuesta básica , pero no estoy seguro de que esto es válido, porque se puede hacer mejor en código de máquina )
Felix Palmen
Wow, perdí un factor de 985 al calcular el error en mi medición de tiempo primero; en realidad es bastante bueno de la forma en que es (si cometí otro error en mis cálculos, ¡señale!) :)
Felix Palmen
¿Y ves lo que tiene este tipo en el GITHUB ?: recuperación de arranque de Android ... ¡está completamente loco! favoreció su perfil.
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"

Debe ejecutarse en una terminal.

Prueba de funcionamiento

$ 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
fuente
44
3479es bastante rapido! bien hecho :)
RobAu
¿Se requiere una versión específica de bash o algo así? En 4.4.12, escribir ainmediatamente me da line 1: ((: r=15094100773N: value too great for base (error token is "15094100773N")y sale.
numbermaniac
@numbermaniac La versión de Bash no debería importar, pero la de la datefuerza. El mío es de GNU coreutils 8.23. ¿Qué date +%s%3Nimprime en su sistema?
Dennis
@Dennis que emite 15094104833N: esta es la dateutilidad incorporada en macOS, si eso marca la diferencia.
numbermaniac
1
@numbermaniac BSD dateparece estar usando strftime, que no reconoce %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

Gracias a ovs y ElPedro por arreglar el código y guardar 57 bytes.

LyricLy
fuente
7

SOGL V0.12 , 35 bytes

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

Pruébalo aquí! - haga clic en ejecutar e ingrese el alfabeto en el cuadro de entrada. Tenga en cuenta que puede ser un poco lento porque SOGL solo hace una pausa para la entrada cada 100 tokens ejecutados (y SOGL es bastante lento). Si eso te molesta, corre sleepBI=trueen la consola.

nota: no ejecute esto en el modo de compatibilidad, solo se repetirá para siempre.

Explicación:

"ζ¦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
fuente
@HyperNeutrino Sabía que sería útil: p
dzaima
¿Quién esperaría que SOGL pueda hacer eso ... por cierto, no es "Fail" una palabra en el diccionario?
Erik the Outgolfer
@EriktheOutgolfer bien, se suponía que SOGL era un lenguaje universal, pero eso no funcionó: p
dzaima
Por cierto, no sé si esto es completamente válido, pero de nuevo creo que podría ser un problema con la interfaz y no con el intérprete detrás ...
Erik the Outgolfer
@EriktheOutgolfer, sí, no sé qué tan válido es eso, supongo que estoy esperando el OP. Al principio pensé que esto era algo así como la respuesta HTML, pero es bastante diferente ahora que lo veo
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.

Pruébalo en línea!

Algunos trucos utilizados en el código para jugar golf:

  • Úselo Realcomo una alternativa más corta a TDateTime, porque como se define aquí , TDateTime= Double, que es de tipo coma flotante.
  • En lugar de usar MilliSecondsBetweenpara calcular el intervalo de tiempo, este código multiplica la diferencia entre dos valores de punto flotante 864e5, lo que funciona debido a la forma en que Free Pascal codifica se TDateTimedescribe aquí .

Nota:

  • ReadKeyLa función en realidad no imprime la clave en la consola, por lo que Write(c)es necesaria la escritura manual en la consola .
  • TIO obtiene una puntuación cercana 0por escribir el alfabeto por razones obvias.
  • El programa imprime el tiempo en notación de punto flotante, supongo que está permitido.
usuario75648
fuente
Bienvenido al sitio!
caird coinheringaahing
Puede guardar 1 byte moviendo el for c:='a'to'z'doa la misma línea que a:=Time;.
Ismael Miguel
Tal vez deberías probar en Nowlugar de hacerlo, Timeya que es más corto.
tsh
¿Por qué 86398338? Puedo entender si multiplicas 864e5 ya que hay 864e5 milisegundos en un día. ¿Pero cómo viene este número mágico?
tsh
@tsh Yo tampoco lo sé. Por las pruebas manuales que le sucede a encontrar ese número "mágico", y no sé qué tienda de Pascal TDateTimecomo Double. 864e5suena más correcto, solucionaré los 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();}};}}

Y aquí pensé que la Consola Java ya era detallada.
Dado que Java no tiene forma de escuchar las pulsaciones de teclas en la consola afaik, utilizo una GUI con java.awt.

-78 bytes gracias a @ OlivierGrégoire .

Explicación:

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

Ejemplo de gif de éxito: (Sí, escribo el alfabeto muy lentamente aquí ..)
Nota: Este es un viejo gif. La versión actual ya no imprime pulsaciones de teclas en la consola. Y ya no imprime la hora con dígitos después del punto decimal.

ingrese la descripción de la imagen aquí
Ejemplo de gif de falla:
Nota: Este es un viejo gif. La versión actual ya no imprime pulsaciones de teclas en la consola.

ingrese la descripción de la imagen aquí

Kevin Cruijssen
fuente
2
impresionante respuesta teniendo en cuenta que tiene una interfaz gráfica de usuario!
Pureferret
1
388 bytes . Me tomé la libertad de arreglar tu código además del golf porque lo usaste en setVisible(false)lugar de salir.
Olivier Grégoire
@ OlivierGrégoire Gracias. Olvidé showy dispose, que es incluso más corto que setVisible. Casi nunca uso la GUI de Java ... Y es inteligente usar la inicialización de clase en lugar de ponerla en el método principal. Debo recordar eso.
Kevin Cruijssen
1
@KevinCruijssen Gracias, y no hay problema ;-) Aunque hay algunos comentarios más generales: no necesita enviar las cartas dos veces. El eco ya lo proporciona TextField. Además, puede usar en TextArealugar de TextFieldganar dos bytes. Finalmente, KeyEventtiene un getWhenmétodo que da el tiempo entre época y el evento en milisegundos. Solo necesito usarlos en lugar de System.nanoTime()ganar aún más bytes.
Olivier Grégoire
1
¡De nada! Pero lo bajé aún más a 320 bytes . ;-)
Olivier Grégoire
4

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

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

No probado porque estoy en el móvil y esto no funciona en 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.
fuente
1
+1 para crear un programa funcional sin poder probarlo. Golf: 1) Una forma más corta que he encontrado para producir la excepción: int x=0;y luego lo hago x=1/x;. Esto debería ahorrar 14 bytes. Lamentablemente lo necesitas x. Si intenta hacerlo 1/0, obtiene una división por error de compilación constante cero . 2) -5 bytes para combinar la declaración de ccon la primera ReadKey. 3) Cambio de la condición en el interior ifa ReadKey!=++cy retirar el c++;elseotro -9 bytes.
raznagul
@raznagul Gracias! x=1/xse puede reducir a x/=x. Y agregué using static System.Console;para guardar algunos bytes más :)
Ian H.
Se pueden guardar algunos bytes más al eliminarlos iy usarlos cen la condición de bucle.
raznagul
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 es una variable interna de MSX-BASIC que aumenta en uno cada 20 milisegundos.

Konamiman
fuente
3

C # (.NET Core) , 184 + 13 = 197173 + 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");}

Pruébalo en línea!

Lamentablemente, TIO no puede ejecutar esto, pero es útil para obtener el recuento de bytes.

+13 para using System;

-1 cambiando i==123a i>122. Estuve tentado de hacer esto i>'z'.

Agradecimientos

-10 bytes gracias a @raznagul

Sin golf

()=>{
    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
fuente
1
Puede guardar algunos bytes moviendo ReadKeya la condición de bucle para que pueda eliminar el primero ify el break.
raznagul
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)

EDITAR: 27 bytes guardados gracias a Jordan

Versión sin golf:

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
fuente
3

C (gcc) , 303 bytes

Funciona en sistemas * nix. Código independiente que elimina el modo canónico del terminal actual para permitir la lectura de caracteres sin esperar nuevas líneas:

/! \ Ejecutar este programa hará que el terminal sea casi inutilizable.

#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 y comentó:

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

Solución alternativa (218 bytes):

Si se permite configurar el terminal de antemano, entonces podemos deshacernos de la parte del código que maneja esa parte.

Aquí está el mismo código sin manipulación 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 que funcione:

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

ejemplo de tiempo de ejecución: ingrese la descripción de la imagen aquí

scottinet
fuente
3

Commodore BASIC v2 - 113 bytes

Las letras mayúsculas deben ser desplazadas.
Gracias a Felix Palmen por señalar algunos errores tipográficos, las especificaciones lo
prueban

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
fuente
Haga clic en editar para ver el código de reducción corregido.
NieDzejkob
Bienvenido al sitio! ¿Podría agregar un enlace a un intérprete (si existe) para que otros puedan probar su código?
caird coinheringaahing
Bueno, esto usa el sistema IRQ ( TIse incrementa en él). Considero inadecuado por su falta de precisión, pero supongo que es un juego justo aquí porque simplemente no hay forma de hacerlo mejor en BASIC :) Aún así, pegando esto en el vicio, obtengo un error de sintaxis en 1- ¿alguna ayuda?
Felix Palmen
Lo descubrí yo mismo, tienes un error tipográfico en la línea uno, debería ser 1on-(f=26)gO4:gEa$:ifa$=""tH1Nitpicks: 1.) la salida está en la misma línea, 2.) la salida es todo en mayúsculas - Creo que deberías arreglar eso, no tomará muchos bytes de todos modos :)
Felix Palmen
Abordó los problemas, queda algún error tipográfico?
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)

$|=1no es suficiente para configurar el terminal en modo sin procesar, stty -icanondebe ejecutarse antes o

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

para ver los caracteres en la terminal después de ejecutar el comando: stty echoostty echo icanon

Nahuel Fouilleul
fuente
Bueno viejo ReadKey! Puede guardar algunos bytes aquí y allá, 1e3para 1000, $s||=timey si configura $sprimero y luego llama ReadKey, puede cambiar el mapa un postfix for. Me gustaría decir en dielugar de exit print, pero creo que estás ahí ... Jugué con, printf"\n%i"pero eso terminó siendo más grande, y pensé en usarlo en $-lugar de $s, ¡pero eso fue estúpido! :)
Dom Hastings
@DomHastings, gracias por su ayuda, podría guardar 4 bytes, pero agregué 5 bytes para configurar la entrada sin búfer $|=1;, también $ s || = el tiempo no se puede cambiar del mapa porque el temporizador debe comenzar después de presionar la primera tecla, y dieharía eco Failen stderr en lugar de stdout.
Nahuel Fouilleul
Feliz de ayudar, ¡espero que no te importe que te ofrezca ideas! Sí, es una pena, ¡ exit printes tan largo! Lo siento, no creo que haya explicado mi pensamiento forcorrectamente: $s||=time,ReadKey eq$_||exit print" Fail"for a..zcreo que debería funcionar ... ¡Quizás incluso $|=$s||=...o $|=map...si prefieres ese enfoque! ¡Aunque creo que lo has clavado!
Dom Hastings
$|=map..no establece la entrada sin búfer en la nueva terminal (tuve el error al eliminar, ReadMode 3, porque estaba probando en la misma sesión), y $s||=timeantes de que la primera ReadKey iniciara el temporizador demasiado temprano
Nahuel Fouilleul
Ahh, entendí mal, lo entiendo ahora, no esperé lo suficiente después de comenzar a escribir el script para comprobar eso ... :) Es una pena $|, pero de nuevo, ¡se está almacenando después del ciclo que es demasiado tarde! Estás un paso por delante!
Dom Hastings
2

Aceto , 70 bytes

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

Comienzo estableciendo una marca de captura y reflejando horizontalmente ( @|), si el valor en la pila es verdadero. Inicialmente no lo es, y luego siempre lo será. Saltaremos aquí más tarde si se ingresa una clave incorrecta. Luego, empujamos una a en la pila ( 'a), luego la duplicamos y leemos un solo carácter del usuario ( d,). Si los dos caracteres no son iguales ( =!), "colisionamos" ( $) y volvemos a la marca de captura. De lo contrario, presionamos otra "a" e imprimimos, luego establecemos la hora actual ( 'apT).

Luego ingresamos nuestro "bucle principal": "incrementamos" el carácter actual e "incrementamos" el carácter ( 'apToIc), luego lo duplicamos, leemos un nuevo carácter, lo comparamos y "bloqueamos" si los caracteres no son idénticos ( d,=!$) Si no fallamos, comparamos el carácter actual con "z" ( d'z=|), si no es igual, imprimimos el carácter, luego presionamos un 1 y saltamos "condicionalmente" (en este caso: siempre) al solo oen el código (el comienzo de nuestro bucle principal). Si era igual a z, reflejamos horizontalmente a un espacio vacío en la parte superior. Imprimimos "z", luego presionamos el tiempo actual (menos el tiempo de inicio; t) y luego multiplicamos el número 1000 (obtenido al elevar 10 a la tercera potencia; 91+3F) por él (porque obtenemos segundos, no milisegundos). Luego imprimimos una nueva línea, la hora y salimos (pX)

Si alguna vez fallamos (entrada incorrecta del usuario), saltamos hasta el principio. Dado que ahora tendremos un valor verdadero en la pila, reflejaremos horizontalmente en el u, que invierte la dirección en la que nos movemos. nImprime un carácter de nueva línea, luego empujamos "Fail"la pila, la imprimimos y salimos ( pX).

L3viatán
fuente
1

Mathematica (expresión de cuaderno), 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[]}]]]

Cómo 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 DynamicModulecon un EventHandlerque responde a las pulsaciones de teclas en minúsculas. Las variables x, sy tmantienen presionadas las letras hasta el momento, la hora de inicio y la hora de finalización, respectivamente. Tan pronto como notamos que xes igual a {"a"}, comenzamos el tiempo; mostramos el tiempo total empleado o la cadena construida hasta el momento, o "Fail"dependiendo de qué condición se cumpla.

Podríamos guardar otro byte en t<1lugar de t==0si podemos suponer que nadie es lo suficientemente rápido como para escribir el alfabeto en menos de un segundo :)

Si está probando esto en un cuaderno de Mathematica, tenga en cuenta que debe hacer clic dentro del marco antes de registrar sus pulsaciones de teclas. (Esta es la razón por la que necesitamos el marco para empezar; si Framedno está allí, todo el objeto seleccionado cambia cuando se presiona una tecla, por lo que deja de seleccionarse y tendrá que hacer clic nuevamente).

Misha Lavrov
fuente
1

C #, 154 152 + 13 = 165 bytes

Guardado 2 bytes gracias a los comentarios 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");
}

El código anterior tiene espacios en blanco para que se ajuste en SE sin una barra de desplazamiento. El espacio en blanco no es parte del recuento de bytes

y 13 bytes para using System;

Es similar a la versión de Ayb4btu pero con las siguientes diferencias:

  • Almacenar datetime como un largo, nos permite hacer cun largo también, y atajo la declaración

  • Loop no necesita un descanso por separado

  • En realidad, no es más corto de usar $"interpreted strings"en lugar de agregar una "\ n" necesaria en los milisegundos para convertirla en una cadena para la línea si

  • El uso de un forbucle a veces nos permite guardar caracteres durante un tiempo, aunque creo que este no guardaría el equivalentewhile

De Ayb4btu:

  • s=s==0puede llegar a ser s=s<1y c==123puede llegar a serc>122

Sin golf

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
fuente
Buena solución con cómo lo usaste DateTime. Puede guardar un par de bytes más cambiando s=s==0a s=s<1(contando con el hecho de que s no será negativo) y cambiando i==123a i>122.
Ayb4btu
Además, ¿se ha probado esto? Como descubrí que i<123tenía que ir antes del ReadKey(), de lo contrario, espera a otro personaje después de z antes de mostrar la hora.
Ayb4btu
Extraño, porque al final del alfabeto, zdebería significar readkey.keychar devuelve 122 cuando el usuario escribe z, c también es 122, por lo tanto 'z' == 122tiene éxito, c se incrementa, luego c (ahora 123) se prueba c<123y falla, deteniendo el lazo .. ?
Caius Jard
Tienes razón, me perdí el c++incremento cuando lo estaba mirando. Sin embargo, acabo de probarlo y cuando abcdefghijklmnopqrstuvwxyslo escribo me da un tiempo en lugar de fallar. Creo que es porque caún se incrementa aunque el KeyCharcheque falla, por lo tanto, pasa el c>122cheque.
Ayb4btu
Buen punto: tal vez mover el ++ a la comprobación c <123 mantendrá el bytecount igual y evitará que la c se incremente si el último carácter está mal, no hay tiempo para depurar en este momento, ¡pero lo echaré un vistazo! saludos :)
Caius Jard
0

Processing.org 133 142

primer código no salió

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

No requiere entrada instantánea para la primera tecla

l4m2
fuente