Digita l'alfabeto - il più velocemente possibile!


44

Il tuo compito è creare un programma che misura la velocità con cui puoi digitare le lettere dell'alfabeto inglese.

  • Il programma accetta solo lettere minuscole aa zin ordine alfabetico.
  • Ogni lettera viene ripetuta come digitata sulla stessa riga (senza nuova riga o altri separatori tra le lettere).
  • Se si digita un carattere non valido, il programma verrà emesso Fail su una nuova riga e uscirà.
  • Se si digitano tutte e 26 le lettere, il programma deve, su una nuova riga , generare il tempo in millisecondi impiegato dalla prima all'ultima lettera e uscire.
  • Il timer inizia quando si digita la prima lettera, a.

Esempi di output:

b
Fail

abcdefgg
Fail

abcdefghijklmnopqrstuvwxyz
6440

Questo è , quindi vince la risposta più breve in byte.


4
Progetto pertinente che ho fatto tempo fa. (il 15 ° livello è sostanzialmente questo)
ETHproductions

4
Possiamo produrre Failsenza una rubrica newline? (es. abdFail\no abd Fail\n))
scottinet,

1
@scottinet, no, il risultato ( Failo millisecondi) deve essere su una nuova riga, come nell'esempio. La maggior parte delle risposte lo presuppone già.
Danko Durbić,

2
-1 poiché questa "nuova" regola non era nella specifica originale e invalida i miei suggerimenti su una delle risposte di Python che rientrava nelle regole originali.
ElPedro,

Mi aspettavo che questa fosse una sfida con il codice più veloce per stampare l'alfabeto.
ATaco,

Risposte:


40

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

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

Fai clic sull'input e inizia a digitare! Inoltre, la mia digitazione fa schifo; Prendo circa 5 secondi anche con la pratica. Modifica: salvato 2 byte grazie a @HermanLauenstein cambiando lingua. Salvato 3 byte grazie a @ qw3n. Salvataggio di 9 byte grazie a @tsh.


1
-2 byte utilizzando html con un tag di 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 byte se il tag di chiusura non è necessario
Herman L

@HermanLauenstein Il tag di chiusura sembra essere necessario per uno snippet, almeno, quindi lo lascerò dentro.
Neil,

2
Questo è troppo esasperante e divertente allo stesso tempo.
Zenon,

1
Che ne dici di mettere un evento in input? <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
Non fa eco al testo su una nuova riga
dkudriavtsev,

33

6502 codice macchina (C64 PAL), 189 165 byte

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 byte incorporando le funzioni e non occupandosi di altri interrupt CIA2

Demo in linea (Usage:sys49152)

Immagine dello schermo


Spiegazione:

Questo sarebbe un piccolo programma se non fosse per il problema di una misurazione esatta di millisecondi sul C64. L'interruzione del sistema si verifica circa 60 volte al secondo, che non è nemmeno vicino. Quindi qui dobbiamo usare un timer hardware che ottiene i suoi tick di input dall'orologio di sistema.

Su una macchina PAL, l'orologio di sistema è esattamente 985248 Hz. L'inizializzazione del timer su 985 quindi dà qualcosa di simile ai millisecondi di tick, ma è un po 'troppo veloce, dovremmo contare 986 cicli per ogni quarto tick o tenere il timer per un singolo ciclo. Ciò non è possibile, ma si può tenere il timer per 6 cicli con la sequenza DEC $DD0E, INC $DD0E: $DD0Eè il registro di controllo timer con bit 0 accensione e spegnimento, e entrambe le istruzioni prendere 6 cicli, così le scritture esatte che arresto e avviare il i timer sono esattamente a 6 cicli di distanza. Pertanto dobbiamo eseguire questa sequenza ogni 6 * 4 = 24 tick. Questo non è ancora assolutamenteesatto, il timer resterà indietro di 1 millisecondo dopo 8 minuti e 12 secondi, ma probabilmente è abbastanza buono - compensare quello richiederebbe molto codice.

modifica : il valore iniziale per il timer deve essere 984, non 985, poiché questi timer si attivano "in underflow", quindi un valore pari a 0 conterà un altro ciclo prima dell'attivazione. Codice fisso, conteggio byte invariato.

Ecco la lista dei disassemblaggi commentata:

         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
Bene, ora ho un timer alquanto decente nella mia casella degli strumenti;) potrebbe essere utile un giorno.
Felix Palmen,

11
Presta attenzione, script kiddies. Questo è un vero golf.
J ...

1
@J ... Potrei continuare a golf integrando .starttimer- lo farò presto :) (e ancora di più usando il sistema TIcome questa risposta BASIC , ma non sono sicuro che sia valido, perché puoi fare di meglio nel codice macchina )
Felix Palmen,

Wow, ho perso un fattore di 985 quando ho calcolato l'errore nella mia misurazione del tempo prima - in realtà è abbastanza buono come è (se ho fatto un altro errore nei miei calcoli, per favore, fai notare!) :)
Felix Palmen

E vedi cosa ha questo ragazzo in GITHUB ?: recupero di avvio Android .... è completamente pazzo! ha favorito il suo profilo.
Luciano Andress Martini,

13

Bash + coreutils, 103 99 98 byte

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 essere eseguito in un terminale.

Prova

$ 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è abbastanza veloce! ben fatto :)
RobAu,

C'è una versione specifica di bash richiesta o qualcosa del genere? Il 4.4.12, digitare aimmediatamente mi dà line 1: ((: r=15094100773N: value too great for base (error token is "15094100773N")ed esce.
numbermaniac

@numbermaniac La versione di Bash non dovrebbe avere importanza, ma quella della datepotenza. Il mio proviene da GNU coreutils 8.23. Cosa date +%s%3Nstampa sul tuo sistema?
Dennis,

@Dennis emette 15094104833N- questa è l' dateutilità integrata su macOS, se questo fa la differenza.
numbermaniac

1
@numbermaniac BSD datesembra usare strftime, che non riconosce %N.
Dennis,

9

Python 2 + getch , 116 byte

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

Grazie a ovs ed ElPedro per la correzione del codice e il salvataggio di 57 byte.


7

SOGL V0.12 , 35 byte

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

Provalo qui! - fai clic su Esegui e inserisci l'alfabeto nella casella di input. Nota che potrebbe essere un po 'lento perché SOGL fa una pausa per l'input ogni 100 token eseguiti (e SOGL è piuttosto lento). Se questo ti dà fastidio, esegui sleepBI=truenella console.

nota: non eseguirlo nella modalità di compatibilità: rimarrà in loop per sempre.

Spiegazione:

"ζ¦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 Sapevo che sarebbe tornato utile: p
dzaima,

Chi si aspetterebbe che SOGL sia in grado di farlo ... a proposito, "Fail" non è una parola nel dizionario?
Erik the Outgolfer,

@EriktheOutgolfer bene, SOGL avrebbe dovuto essere un linguaggio per tutti gli usi, ma non ha funzionato: p
dzaima

A proposito, non so se questo è completamente valido, ma poi penso che potrebbe essere un problema con l'interfaccia e non con l'interprete dietro ...
Erik the Outgolfer,

@EriktheOutgolfer sì, non so quanto sia valido, immagino che sto aspettando l'OP. All'inizio ho pensato che fosse qualcosa come la risposta HTML, ma è abbastanza diverso ora che lo guardo
dzaima,

7

Pascal (FPC) , 176 byte

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.

Provalo online!

Alcuni trucchi utilizzati nel codice per il golf:

  • Utilizzare Realcome alternativa più breve a TDateTime, perché come definito qui , TDateTime= Double, che è di tipo a virgola mobile.
  • Invece di utilizzare MilliSecondsBetweenper il calcolo del gap temporale, questo codice moltiplica la differenza tra due valori in virgola mobile per 864e5, che funziona a causa del modo in cui codifica Free Pascal quiTDateTime descritto .

Nota:

  • ReadKeyla funzione in realtà non stampa il tasto sulla console, quindi Write(c)è necessario scrivere manualmente sulla console .
  • TIO ottiene un punteggio vicino 0per aver digitato l'alfabeto per ovvi motivi.
  • Il programma stampa il tempo in notazione a virgola mobile, immagino sia permesso.

Benvenuti nel sito!
caird coinheringaahing il

È possibile salvare 1 byte spostando for c:='a'to'z'dola stessa riga di a:=Time;.
Ismael Miguel,

Forse dovresti provare Nowinvece Timeche perché è più corto.
TSH

Perchè 86398338?? Posso capire se molti 864e5 poiché ci sono 864e5 millisecondi in un giorno. ma come viene questo numero magico?
TSH

@tsh Non lo so neanche io. Con test manuale mi capita di trovare quel numero "magico", e non so come negozio di Pascal TDateTimecome Double. 864e5sembra più corretto, risolverò i problemi.
user75648

5

Java, 404 388 354 348 320 318 byte

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 qui ho pensato che Java Console fosse già prolissa ..
Dato che Java non ha modo di ascoltare in modo grezzo la pressione dei tasti nella Console, utilizzo una GUI con java.awt.

-78 byte grazie a @ OlivierGrégoire .

Spiegazione:

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

Esempio di gif di successo: (Sì, scrivo l'alfabeto abbastanza lentamente qui ..)
Nota: questa è una vecchia gif. La versione corrente non stampa più i tasti premuti sulla console. E non stampa più l'ora con le cifre dopo il punto decimale.

inserisci qui la descrizione dell'immagine
Esempio di GIF di fail:
Nota: questa è una vecchia gif. La versione corrente non stampa più i tasti premuti sulla console.

inserisci qui la descrizione dell'immagine


2
risposta impressionante considerando che ha una gui!
Pureferret,

1
388 byte . Mi sono preso la libertà di correggere il tuo codice oltre al golf perché l'hai usato setVisible(false)invece di uscire.
Olivier Grégoire,

@ OlivierGrégoire Grazie. Dimenticato showe e dispose, che è ancora più breve di setVisible. Non uso quasi mai la GUI di Java .. E intelligente per usare l'inizializzazione di classe invece di metterla nel metodo principale. Dovrei ricordarlo.
Kevin Cruijssen,

1
@KevinCruijssen Grazie e nessun problema ;-) Anche se alcuni commenti più generali: non è necessario emettere le lettere due volte. L'eco è già fornita da TextField. Inoltre, è possibile utilizzare TextAreainvece di TextFieldguadagnare due byte. Infine, KeyEventha un getWhenmetodo che fornisce il tempo tra l'epoca e l'evento in millisecondi. Devo solo usare quelli invece di System.nanoTime()guadagnare ancora più byte.
Olivier Grégoire,

1
Prego! Ma l'ho ottenuto ulteriormente a 320 byte . ;-)
Olivier Grégoire,

4

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

+41 byte per using System;using static System.Console.

Non testato dal momento che sono su cellulare e questo non funziona su 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 per la creazione di un programma funzionante senza poterlo testare. Giocare a golf: 1) Un modo più breve che ho trovato per produrre l'eccezione: int x=0;e poi farlo x=1/x;. Ciò dovrebbe salvare 14 byte. Sfortunatamente hai bisogno x. Se si tenta di 1/0ottenere una divisione per errore di compilatore zero costante . 2) -5 byte per combinare la dichiarazione di ccon la prima ReadKey. 3) Modificare la condizione nella parte interna ifin ReadKey!=++ce rimuovere la c++;elseper altri -9 byte.
raznagul,

@raznagul Grazie! x=1/xpuò essere ridotto a x/=x. E ho aggiunto using static System.Console;per salvare qualche altro byte :)
Ian H.

Alcuni byte in più possono essere salvati rimuovendo ie usando invece cnella condizione loop.
raznagul,

3

MSX-BASIC, 126 caratteri

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

TIME è una variabile interna MSX-BASIC che aumenta di uno ogni 20 millisecondi.


3

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

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

Provalo online!

Sfortunatamente TIO non può eseguirlo, ma è utile per ottenere il conteggio dei byte.

+13 per using System;

-1 cambiando i==123in i>122. Sono stato tentato di farlo i>'z'.

Ringraziamenti

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

1
È possibile salvare alcuni byte spostando la ReadKeycondizione del ciclo in modo da poter rimuovere il primo ife il break.
raznagul,

3

Node.js, 240 213 byte

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: salvato 27 byte grazie alla Giordania

Versione non golfata:

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 byte

Funziona su sistemi * nix. Codice autonomo che rimuove la modalità canonica del terminale corrente per consentire la lettura di caratteri senza attendere le nuove righe:

/! \ L'esecuzione di questo programma renderà il terminale quasi inutilizzabile.

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

Ungolf e commentato:

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

Soluzione alternativa (218 byte):

Se è consentita la configurazione anticipata del terminale, è possibile eliminare la parte di codice che gestisce tale parte.

Ecco lo stesso codice senza manipolazione del terminale:

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

Per farlo funzionare:

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

esempio di runtime: inserisci qui la descrizione dell'immagine


3

Commodore BASIC v2 - 113 byte

Le lettere maiuscole devono essere spostate.
Grazie a Felix Palmen per aver segnalato alcuni errori di battitura, le specifiche lo
provano

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"

Fai clic su Modifica per visualizzare il codice di markdown corretto.
NieDzejkob,

Benvenuti nel sito! Potresti aggiungere un link a un interprete (se ne esiste uno), in modo che altri possano testare il tuo codice?
caird coinheringaahing

Bene, questo utilizza il sistema IRQ ( TIè incrementato in esso) che ho ritenuto inadatto per la sua mancanza di precisione, ma immagino che sia un gioco corretto qui perché non c'è modo di fare di meglio in BASIC :) Tuttavia, incollando questo in vizio, ottengo un errore di sintassi in 1- qualche aiuto?
Felix Palmen,

Ho capito da solo, hai un refuso nella prima riga, dovrebbe essere 1on-(f=26)gO4:gEa$:ifa$=""tH1Nitpicks: 1.) l'output è sulla stessa riga, 2.) l'output è tutto maiuscolo - penso che dovresti sistemarli, non ci vorranno molti byte comunque :)
Felix Palmen,

Risolti i problemi, rimanevano errori di battitura?
lunedì

2

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

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

$|=1non è sufficiente per impostare il terminale in modalità raw, stty -icanondeve essere eseguito prima o

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

per vedere i caratteri nel terminale dopo aver eseguito il comando: stty echoostty echo icanon


Buon vecchio ReadKey! È possibile salvare alcuni byte qua e là, 1e3per 1000, $s||=timee se si imposta $sprima e poi si chiama ReadKey, è possibile passare mapda un postfisso for. Vorrei dire dieinvece di exit print, ma penso che tu sia lì ... Ho armeggiato printf"\n%i"ma quello è finito più grande, e ho pensato di usare $-invece di $s, ma è stato stupido! :)
Dom Hastings,

@DomHastings, grazie per il tuo aiuto, ho potuto salvare 4 byte, ma ho aggiunto 5 byte per impostare un input senza buffer $|=1;, inoltre $ s || = il tempo non può essere scambiato fuori dalla mappa perché il timer deve iniziare dopo la prima pressione del tasto, e dieecheggerebbe Failsu stderr invece che su stdout.
Nahuel Fouilleul,

Felice di aiutarti, spero che non ti dispiaccia che offra idee! Sì, è un peccato, exit printè così lungo! Scusa, non credo di aver spiegato il mio pensiero per il forcorretto: $s||=time,ReadKey eq$_||exit print" Fail"for a..zdovrebbe funzionare penso ... Forse anche $|=$s||=...o $|=map...se preferisci questo approccio! Pensi di averlo praticamente inchiodato però!
Dom Hastings,

$|=map..non imposta input senza buffer nel nuovo terminale (ho riscontrato l'errore durante la rimozione, ReadMode 3, perché stavo testando nella stessa sessione), e $s||=timeprima che ReadKey iniziasse il timer troppo presto
Nahuel Fouilleul,

Ahh, ho capito male, ora capisco, non ho aspettato abbastanza tempo dopo aver iniziato a scrivere script per verificare che ... :) Peccato $|, ma ancora una volta, è archiviato dopo il loop che è troppo tardi! Sei un passo avanti!
Dom Hastings,

2

Aceto , 70 byte

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

@|Comincio impostando un contrassegno di cattura e eseguendo il mirroring in orizzontale ( ), se il valore nello stack è veritiero. Inizialmente non lo è, e poi lo sarà sempre. Torneremo qui più tardi se viene inserita una chiave sbagliata. Quindi, premiamo una a sullo stack ( 'a), quindi la dupliciamo e leggiamo un singolo carattere dall'utente ( d,). Se i due caratteri non sono uguali ( =!), "crash" ( $) e torniamo indietro al segno di cattura. Altrimenti, premiamo un'altra "a" e la stampiamo, quindi impostiamo l'ora corrente ( 'apT).

Quindi entriamo nel nostro "ciclo principale": "incrementiamo" il carattere corrente e "incrementiamo" il carattere ( 'apToIc), quindi lo dupliciamo, leggiamo un nuovo carattere, lo confrontiamo e "blocchiamo" se i caratteri non sono identici ( d,=!$). Se non ci siamo bloccati, confrontiamo il carattere corrente con "z" ( d'z=|), se non è uguale, stampiamo il personaggio, quindi spingiamo un 1 e saltiamo "condizionatamente" (in questo caso: sempre) al carattere solo onel codice (l'inizio del nostro ciclo principale). Se era uguale a z, ci siamo specchiati orizzontalmente su uno spazio vuoto in alto. Stampiamo "z", quindi spingiamo l'ora corrente (meno l'ora di inizio; t) e quindi moltiplichiamo il numero 1000 (ottenuto aumentando 10 alla terza potenza; 91+3F) per esso (perché otteniamo secondi, non millisecondi). Quindi stampiamo una nuova riga, l'ora e l'uscita (pX).

In caso di arresto anomalo (input errato da parte dell'utente), salteremo fino all'inizio. Dato che ora avremo un valore sincero nella pila, ci speccheremo orizzontalmente sulla u, che inverte la direzione in cui ci stiamo muovendo. Stampa nun carattere di nuova riga, quindi spingiamo "Fail"sulla pila, la stampiamo e usciamo ( pX).


1

Mathematica (espressione notebook), 248 byte

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

Come funziona

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 an EventHandlerche risponde ai tasti premuti con lettere minuscole. Le variabili x, se ttengono le lettere premute finora, l'ora di inizio e l'ora di fine, rispettivamente. Non appena notiamo che xè uguale a {"a"}, iniziamo il tempo; visualizziamo il tempo totale impiegato o la stringa costruita finora o in "Fail"base alla condizione soddisfatta.

Potremmo salvare un altro byte con t<1piuttosto che t==0se potessimo presumere che nessuno sia abbastanza veloce da digitare l'alfabeto in meno di un secondo :)

Se lo stai provando su un notebook Mathematica, tieni presente che devi fare clic all'interno del riquadro prima che i tasti premuti vengano registrati. (Questo è il motivo per cui abbiamo bisogno del frame per iniziare; se Framednon c'è, l'intero oggetto selezionato cambia quando viene premuto un tasto, quindi smette di essere selezionato e dovresti fare di nuovo clic.)


1

C #, 154 152 + 13 = 165 byte

Salvato 2 byte grazie ai commenti di 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");
}

Il codice sopra ha spazi bianchi per adattarlo a SE senza una barra di scorrimento. Lo spazio bianco non fa parte del conteggio dei byte

e 13 byte per using System;

È simile alla versione di Ayb4btu ma con le seguenti differenze:

  • Memorizzare datetime come long, ci permette di fare canche long, e abbreviare la dichiarazione

  • Il loop non ha bisogno di una pausa separata

  • In realtà non è più breve da usare $"interpreted strings"rispetto all'aggiunta di un "\ n" necessario nei millisecondi per renderlo una stringa per l'inline se

  • L'uso di un forloop a volte ci consente di salvare i caratteri per un po ', anche se penso che questo non salverebbe sull'equivalentewhile

Da Ayb4btu:

  • s=s==0può diventare s=s<1e c==123può diventarec>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");

Bella soluzione con come hai usato DateTime. Puoi salvare un altro paio di byte cambiando s=s==0in s=s<1(contando sul fatto che s non sarà negativo) e cambiando i==123in i>122.
Ayb4btu,

Inoltre, questo è stato testato? Come ho scoperto che i<123doveva andare prima del ReadKey(), altrimenti aspetta un altro personaggio dopo z prima di visualizzare l'ora.
Ayb4btu,

Strano, perché alla fine dell'alfabeto, zdovrebbe significare readkey.keychar restituisce 122 quando l'utente digita z, c è anche 122, quindi ha 'z' == 122successo, c viene quindi incrementato, quindi c (ora 123) viene testato c<123e fallisce, arrestando il ciclo continuo .. ?
Caius Jard,

Hai ragione, ho perso l' c++incremento mentre lo guardavo. Tuttavia, l'ho appena provato e quando abcdefghijklmnopqrstuvwxyslo digito mi dà un tempo invece di fallire. Credo che sia perché caumenta ancora anche se il KeyCharcontrollo fallisce, quindi passa il c>122controllo.
Ayb4btu,

Un buon punto: forse spostare ++ nel controllo c <123 manterrà lo stesso bytecount e impedirà l'incremento del c se l'ultimo carattere è sbagliato - non c'è tempo per eseguire il debug in questo momento, ma lo darò un'occhiata! evviva :)
Caius Jard

0

Processing.org 133 142

il primo codice non è stato chiuso

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 byte

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

Non richiede input istantaneo per il primo tasto

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.