Tapez l'alphabet - aussi vite que vous le pouvez!

44

Votre tâche consiste à créer un programme qui mesure à quelle vitesse vous pouvez taper les lettres de l’alphabet anglais.

  • Le programme ne doit accepter les lettres minuscules aà zdans l' ordre alphabétique.
  • Chaque lettre est répercutée sur la même ligne (sans nouvelle ligne ni autre séparateur entre les lettres).
  • Si vous tapez un caractère invalide, le programme doit sortir Fail sur une nouvelle ligne et sortir.
  • Si vous tapez toutes les 26 lettres, le programme doit, sur une nouvelle ligne , afficher le temps en millisecondes écoulé de la première à la dernière lettre et quitter.
  • La minuterie démarre lorsque vous tapez la première lettre, a.

Exemple de sorties:

b
Fail

abcdefgg
Fail

abcdefghijklmnopqrstuvwxyz
6440

C'est du , donc la réponse la plus courte en octets est gagnante.

Danko Durbić
la source
4
Projet pertinent que j'ai fait il y a longtemps. (le 15ème niveau est fondamentalement celui-ci)
ETHproductions
4
Peut-on sortir Failsans une nouvelle ligne? (par exemple abdFail\nou abd Fail\n))
scottinet
1
@scottinet, non, le résultat ( Failou les millisecondes) doit figurer sur une nouvelle ligne, comme dans l'exemple. La plupart des réponses supposent déjà cela.
Danko Durbić
2
-1 comme cette "nouvelle" règle n'était pas dans la spécification d'origine et invalide mes suggestions sur l'une des réponses Python qui était dans les règles d'origine.
ElPedro
Je m'attendais à ce que l' impression de l'alphabet soit un défi de code rapide .
ATaco

Réponses:

40

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

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

Cliquez dans l'entrée et commencez à taper! De plus, ma dactylographie est nulle; Je prends environ 5 secondes, même avec la pratique. Edit: 2 octets enregistrés grâce à @HermanLauenstein en changeant de langue. Sauvegardé 3 octets grâce à @ qw3n. Sauvegardé 9 octets grâce à @tsh.

Neil
la source
1
-2 octets en utilisant HTML avec une balise 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 octets si la balise de fermeture n'est pas nécessaire
Herman L
@HermanLauenstein La balise de fermeture semble être nécessaire pour un extrait, au moins, alors je vais la laisser dedans.
Neil
2
C'est trop exaspérant et amusant en même temps.
Zenon
1
Qu'en est-il de mettre l'événement sur l'entrée? <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
Ne fait pas écho au texte sur une nouvelle ligne
dkudriavtsev
33

6502 code machine (C64 PAL), 189 165 octets

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 octets en ajoutant des fonctions et en ne se souciant pas des autres interruptions CIA2

Démo en ligne (Utilisation:sys49152)

Capture d'écran


Explication:

Ce serait un programme minuscule sans le problème de la mesure exacte en millisecondes sur le C64. L'interruption du système se produit environ 60 fois par seconde, ce qui n'est même pas proche. Nous devons donc utiliser ici une minuterie matérielle qui tire ses ticks d’entrée de l’horloge système.

Sur une machine PAL, l’horloge système est exactement de 985248 Hz. Initialiser le minuteur sur 985 donne donc un résultat proche des millisecondes, mais c’est un peu trop rapide, il faudrait compter 986 cycles par quart de temps ou maintenir le chronomètre un cycle à la fois. Ceci est impossible, mais nous pouvons maintenir la minuterie pour 6 cycles avec la séquence DEC $DD0E, INC $DD0E: $DD0Eest le registre de commande de minuterie avec le bit 0 commutation sur et en dehors, et les deux instructions prennent 6 cycles, donc les écritures exactes que arrêter et démarrer le minuterie sont exactement 6 cycles d'intervalle. Nous devons donc exécuter cette séquence tous les 6 * 4 = 24ème ticks. Ce n'est toujours pas absolumentexact, le retardateur prendra 1 milliseconde de retard après 8 minutes et 12 secondes, mais c’est probablement assez bon - compenser cela prendrait beaucoup de code.

edit : La valeur de départ du minuteur doit être 984 et non 985, car ces minuteries se déclenchent "en aval", donc une valeur de 0 comptera un cycle supplémentaire avant le déclenchement. Code fixe, nombre d'octets inchangé.

Voici la liste de désassemblage commentée:

         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
la source
6
Eh bien, maintenant, j'ai une minuterie un peu décente milliseconde dans ma boîte à outils;) pourrait être utile un jour.
Felix Palmen
11
Faites attention, script kiddies. C'est du vrai golf.
J ...
1
@J ... Je pourrais jouer au golf plus loin en ajoutant .starttimer- je le ferai bientôt :) (et même plus loin en utilisant le système TIcomme cette réponse BASIC , mais je ne suis pas sûr que cela soit valide, car vous pouvez faire mieux en code machine )
Felix Palmen
Wow, j'ai tout d'abord manqué un facteur de 985 lors du calcul de l'erreur dans la mesure de mon temps - c'est en fait assez bon tel qu'il est (si je commets une autre erreur dans mes calculs, veuillez le préciser!) :)
Felix Palmen
Et voyez-vous ce que ce gars a dans le GITHUB ?: récupération de démarrage Android .... il est complètement fou! favorisé son profil.
Luciano Andress Martini le
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"

Doit être exécuté dans un terminal.

Essai

$ 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
la source
4
3479c'est assez rapide! bien fait :)
RobAu
Y at-il une version spécifique de bash requise ou quelque chose? Sur 4.4.12, taper aimmédiatement me donne line 1: ((: r=15094100773N: value too great for base (error token is "15094100773N")et quitte.
numbermaniac
@numbermaniac La version de Bash ne devrait pas avoir d'importance, mais celle de la dateforce. Le mien provient de GNU coreutils 8.23. Qu'est-ce que l' date +%s%3Nimpression sur votre système?
Dennis
@Dennis it output 15094104833N- voici l’ dateutilitaire intégré à macOS, si cela fait une différence.
Numbermaniac
1
@numbermaniac Les BSD datesemblent utiliser strftime, ce qui ne se reconnaît pas %N.
Dennis
9

Python 2 + getch , 116 octets

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

Merci à ovs et à ElPedro d’avoir corrigé le code et économisé 57 octets.

LyricLy
la source
7

SOGL V0.12 , 35 octets

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

Essayez-le ici! - Cliquez sur Exécuter et entrez l’alphabet dans la zone de saisie. Notez que cela peut être un peu lent, car SOGL ne met en pause que toutes les 100 jetons exécutés (et que SOGL est assez lent). Si cela vous dérange, lancez-vous sleepBI=truedans la console.

remarque: ne lancez pas ceci en mode de compatibilité - ça va juste boucler pour toujours.

Explication:

"ζ¦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
la source
@HyperNeutrino Je savais que cela serait utile: p
dzaima
Qui s'attendrait à ce que SOGL puisse le faire? Soit dit en passant, "Fail" n'est-il pas un mot dans le dictionnaire?
Erik l'Outgolfer
@EriktheOutgolfer eh bien, SOGL était supposé être un langage polyvalent, mais cela n'a pas fonctionné: p
dzaima
BTW, je ne sais pas si cela est tout à fait valable, mais encore une fois, je pense que cela pourrait être un problème avec l'interface et pas l'interprète derrière ...
Erik the Outgolfer
@EriktheOutgolfer ouais, je ne sais pas si c'est valable, je suppose que j'attends le PO. Au début, je pensais que cela ressemblait à la réponse HTML, mais c'est assez différent maintenant que je le regarde
dzaima
7

Pascal (FPC) , 176 octets

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.

Essayez-le en ligne!

Quelques astuces utilisées dans le code pour le golf:

  • Utiliser Realcomme alternative plus courte à TDateTime, parce que tel que défini ici , TDateTime= Double, qui est un type à virgule flottante.
  • Au lieu d'utiliser MilliSecondsBetweenpour calculer l'intervalle de temps, ce code multiplie la différence entre deux valeurs à virgule flottante par 864e5, ce qui fonctionne à cause de la manière dont Free Pascal code l'encodage TDateTimedécrit ici .

Remarque:

  • ReadKeyCette fonction n’imprime pas réellement la clé sur la console. Une écriture manuelle sur la console Write(c)est donc nécessaire.
  • TIO se rapproche d'une note 0pour avoir tapé l'alphabet pour une raison évidente.
  • Le programme imprime le temps en notation à virgule flottante, je suppose que cela est autorisé.
utilisateur75648
la source
Bienvenue sur le site!
Caird coinheringaahing
Vous pouvez enregistrer 1 octet en déplaçant le for c:='a'to'z'dosur la même ligne que a:=Time;.
Ismael Miguel
Peut-être devriez-vous essayer Nowau lieu de Timele raccourcir.
tsh
Pourquoi 86398338?? Je peux comprendre si vous multipliez 864e5 puisqu'il y a 864e5 millisecondes dans une journée. mais comment vient ce nombre magique?
tsh
@th je ne sais pas non plus. En testant manuel , j'arrive à constater que le numéro « magique », et je ne sais pas comment Pascal magasin TDateTimecomme Double. 864e5semble plus correct, je vais résoudre les problèmes.
user75648
5

Java, 404 388 354 348 320 318 octets

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

Et ici, je pensais que la console Java était déjà prolixe.
Comme Java n’a aucun moyen de faire une écoute brute des touches sur la console autant que je sache, j’utilise une interface graphique avec java.awt.

-78 octets grâce à @ OlivierGrégoire .

Explication:

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

Exemple de réussite: (Oui, je tape l’alphabet assez lentement ici ..)
Remarque: il s’agit d’un ancien gif. La version actuelle n’imprime plus les touches sur la console. Et il n’imprime plus l’heure avec les chiffres après le point décimal.

entrez la description de l'image ici
Exemple gif d'échec:
Remarque: Ceci est un ancien gif. La version actuelle n’imprime plus les touches sur la console.

entrez la description de l'image ici

Kevin Cruijssen
la source
2
réponse impressionnante compte tenu qu'il a un gui!
Pureferret
1
388 octets . J'ai pris la liberté de corriger votre code en plus du golf parce que vous utilisiez setVisible(false)au lieu de quitter.
Olivier Grégoire
@ OlivierGrégoire Merci. Oublié showet dispose, qui est encore plus court que setVisible. Je n'utilise presque jamais l'interface graphique de Java .. Et intelligent d'utiliser l'initialisation de classe au lieu de la mettre dans la méthode main. Je devrais m'en souvenir.
Kevin Cruijssen
1
@KevinCruijssen Merci et pas de problème ;-) Bien que quelques commentaires plus généraux: vous n'avez pas besoin de sortir les lettres deux fois. Les échos sont déjà fournis par TextField. En outre, vous pouvez utiliser TextAreaau lieu de TextFielddeux octets. Enfin, KeyEventa une getWhenméthode qui donne le temps entre l'époque et l'événement en millisecondes. Juste besoin d'utiliser ceux-ci au lieu de System.nanoTime()gagner encore plus d'octets.
Olivier Grégoire
1
Vous êtes les bienvenus! Mais je l'ai encore descendu à 320 octets . ;-)
Olivier Grégoire
4

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

+41 octets pour using System;using static System.Console.

Non testé car je suis sur mobile et cela ne fonctionne pas sur 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.
la source
1
+1 pour créer un programme qui fonctionne sans pouvoir le tester. Golf: 1) Un moyen plus rapide que j'ai trouvé pour produire l'exception: int x=0;et puis faire x=1/x;. Cela devrait économiser 14 octets. Malheureusement vous avez besoin x. Si vous essayez de faire cela, 1/0vous obtenez une erreur du compilateur Division par constante zéro . 2) -5 octets pour combiner la déclaration de cavec la première ReadKey. 3) Modifiez la condition à l'intérieur ifde ReadKey!=++cet supprimez-la c++;elsepour un autre -9 octets.
raznagul
@raznagul Merci! x=1/xpeut être réduit à x/=x. Et j'ai ajouté using static System.Console;pour économiser encore plus d'octets :)
Ian H.
Quelques octets supplémentaires peuvent être enregistrés en supprimant iet en utilisant cplutôt la condition de boucle.
Raznagul
3

MSX-BASIC, 126 caractères

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

TIME est une variable interne MSX-BASIC qui augmente d'une unité toutes les 20 millisecondes.

Konamiman
la source
3

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

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

Essayez-le en ligne!

Malheureusement, TIO ne peut pas l'exécuter, mais c'est pratique pour obtenir le nombre d'octets.

+13 pour using System;

-1 en changeant i==123pour i>122. J'ai été tenté de faire cela i>'z'.

Remerciements

-10 octets grâce à @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
la source
1
Vous pouvez enregistrer des octets en déplaçant la ReadKeycondition sur la boucle afin de pouvoir supprimer le premier ifet le break.
raznagul
3

Node.js, 240 213 octets

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: 27 octets sauvés grâce à Jordan

Version non-golfée:

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
la source
3

C (gcc) , 303 octets

Fonctionne sur les systèmes * nix. Code autonome supprimant le mode canonique du terminal actuel pour permettre la lecture de caractères sans attendre les nouvelles lignes:

/! \ L'exécution de ce programme rend le terminal presque inutilisable.

#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 et commenté:

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

Solution alternative (218 octets):

Si la configuration préalable du terminal est autorisée, nous pouvons supprimer la partie du code qui traite cette partie.

Voici le même code sans manipulation 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);}

Pour que cela fonctionne:

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

exemple d'exécution: entrez la description de l'image ici

scottinet
la source
3

Commodore BASIC v2 - 113 octets

Les lettres majuscules doivent être déplacées.
Merci à Felix Palmen pour avoir signalé quelques fautes de frappe, les spécifications l’
essaient

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
la source
Cliquez sur Modifier pour voir le code de démarquage corrigé.
NieDzejkob
Bienvenue sur le site! Pourriez-vous ajouter un lien vers un interprète (s'il en existe un), afin que d'autres puissent tester votre code?
Caird coinheringaahing
Eh bien, cela utilise le système IRQ ( TIest incrémenté dans celui-ci). J’ai jugé impropre à cause de son manque de précision, mais je suppose que c’est juste, car il n’ya aucun moyen de faire mieux en BASIC :). une erreur de syntaxe dans 1- toute aide?
Felix Palmen
Je l'ai compris moi-même, vous avez une faute de frappe dans la première ligne, devrait être 1on-(f=26)gO4:gEa$:ifa$=""tH1Nitpicks: 1.) la sortie est sur la même ligne, 2.) la sortie est en majuscule - Je pense que vous devriez les corriger, cela ne prendra pas beaucoup d'octets de toute façon :)
Felix Palmen
Adressé les problèmes, des fautes de frappe laissées?
Mondlos
2

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

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

$|=1n'est pas suffisant pour définir le terminal en mode brut, stty -icanondoit être exécuté avant ou

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

pour afficher des caractères dans le terminal après l'exécution de la commande: stty echooustty echo icanon

Nahuel Fouilleul
la source
Bon vieux ReadKey! Vous pouvez enregistrer quelques octets ici et là, 1e3pour 1000, $s||=timeet si vous définissez d' $sabord et ensuite appelez ReadKey, vous pouvez échanger le mapvers un suffixe for. J'aimerais dire dieau lieu de exit print, mais je pense que vous avez raison ... J'ai bricolé avec printf"\n%i"mais ça a fini par être plus gros, et j'ai pensé à utiliser $-au lieu de $s, mais c'était stupide! :)
Dom Hastings
@DomHastings, merci de votre aide. J'ai pu économiser 4 octets, mais j'ai ajouté 5 octets pour définir une entrée non tamponnée. De plus $|=1;, $ s || = le temps ne peut pas être échangé sur la carte car le minuteur doit démarrer après la première pression sur la touche, et dieecho Failsur stderr au lieu de stdout.
Nahuel Fouilleul
Heureux de vous aider, j'espère que cela ne vous dérange pas que j'offre des idées! Oui, c'est dommage, exit printc'est si long! Désolé, je ne pense pas avoir expliqué ma pensée pour le forbien: $s||=time,ReadKey eq$_||exit print" Fail"for a..zdevrait fonctionner, je pense ... Peut-être même $|=$s||=...ou $|=map...si vous préférez cette approche! Pensez-vous plutôt bien cloué!
Dom Hastings
$|=map..ne définit pas l'entrée non tamponnée dans le nouveau terminal (j'avais l'erreur lors de la suppression, ReadMode 3, car je testais au cours de la même session), et $s||=timeavant la première lecture, ReadKey démarrait trop tôt
Nahuel Fouilleul,
Ahh, j'ai mal compris, je l'ai compris maintenant, je n'ai pas attendu assez longtemps après avoir commencé à écrire le script pour vérifier cela ... :) C'est dommage $|, mais encore une fois, c'est stocker après la boucle, ce qui est trop tard! Vous avez une longueur d'avance!
Dom Hastings
2

Aceto , 70 octets

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

Je commence par définir un point d'accrochage et une mise en miroir horizontale ( @|), si la valeur de la pile est véracité. Ce n'est pas initialement, et le sera toujours plus tard. Nous reviendrons ici plus tard si une mauvaise clé est entrée. Ensuite, nous plaçons un a sur la pile ( 'a), puis nous le dupliquons et lisons un seul caractère de l'utilisateur ( d,). Si les deux caractères ne sont pas égaux ( =!), nous nous "plantons" ( $) et retournons à la cible. Sinon, on pousse un autre "a" et on l’imprime, puis on règle l’heure actuelle ( 'apT).

Ensuite, nous entrons dans notre "boucle principale": nous "incrémentons" le caractère actuel et "incrémentons" le caractère ( 'apToIc), puis nous le dupliquons, lisons un nouveau caractère, le comparons et "crashons" si les caractères ne sont pas identiques ( d,=!$) Si nous ne sommes pas bloqués, nous comparons le caractère actuel à "z" ( d'z=|). Si ce n'est pas égal, nous imprimons le caractère, puis nous poussons un 1 et sautons "conditionnellement" (dans ce cas: toujours) au seulement odans le code (le début de notre boucle principale). S'il était égal à z, nous avons inversé horizontalement un espace vide au-dessus. Nous imprimons "z", puis appuyons sur l'heure actuelle (moins l'heure de début; t) puis multiplions le nombre 1000 (obtenu en élevant 10 à la troisième puissance; 91+3F) par ce chiffre (car nous obtenons des secondes, millisecondes). Ensuite, nous imprimons une nouvelle ligne, l'heure, et quittons (pX).

En cas de plantage (mauvaise saisie de la part de l'utilisateur), nous sautons jusqu'au début. Puisque nous aurons maintenant une valeur de vérité sur la pile, nous refléterons horizontalement le u, ce qui inversera la direction dans laquelle nous nous déplaçons. nImprime un caractère de nouvelle ligne, puis nous poussons "Fail"sur la pile, l’imprimons et quittons ( pX).

L3viathan
la source
1

Mathematica (expression bloc-notes), 248 octets

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

Comment ça marche

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

Un DynamicModuleavec un EventHandlerqui répond aux lettres minuscules. Les variables x, set tmaintenez les lettres appuyées jusqu’à présent, l’heure de début et l’heure de fin, respectivement. Dès que nous remarquons xêtre égal à {"a"}, nous commençons le temps; nous affichons soit le temps total passé, soit la chaîne construite jusqu'à présent, ou en "Fail"fonction de la condition remplie.

Nous pourrions économiser un autre octet avec t<1plutôt que t==0si nous pouvons supposer que personne n’est assez rapide pour taper l’alphabet en moins d’une seconde :)

Si vous essayez ceci dans un cahier Mathematica, gardez à l'esprit que vous devez cliquer à l'intérieur du cadre avant d'enregistrer vos pressions de touche. (C’est la raison pour laquelle nous avons besoin du cadre pour commencer; s’il Framedn’y en a pas, alors l’ensemble de l’objet sélectionné est modifié lorsqu’une touche est enfoncée;

Misha Lavrov
la source
1

C #, 154 152 + 13 = 165 octets

2 octets sauvés grâce aux commentaires 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");
}

Le code ci-dessus a des espaces pour le faire rentrer dans SE sans barre de défilement. Les espaces ne font pas partie du nombre d'octets

et 13 octets pour using System;

C'est similaire à la version d'Ayb4btu mais avec les différences suivantes:

  • Stocker datetime comme un long permet de faire cun long aussi, et de raccourcir la déclaration

  • La boucle n'a pas besoin d'une pause séparée

  • Il n’est pas vraiment plus court d’utiliser $"interpreted strings"que d’ajouter un "\ n" nécessaire en millisecondes pour en faire une chaîne pour le inline si

  • L'utilisation d'une forboucle nous permet parfois de sauvegarder les caractères sur un certain temps, bien que celui-ci ne soit pas sauvegardé de manière équivalente.while

De Ayb4btu:

  • s=s==0peut devenir s=s<1et c==123peut devenirc>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
la source
Belle solution avec comment vous avez utilisé DateTime. Vous pouvez enregistrer un couple plus d' octets en changeant s=s==0de s=s<1(comptage sur le fait que s ne sera pas négatif) et la modification i==123de i>122.
Ayb4btu
Aussi, cela a-t-il été testé? Comme j'ai trouvé que cela i<123devait aller avant le ReadKey(), sinon il attend un autre caractère après z avant d'afficher l'heure.
Ayb4btu
Odd, car à la fin de l’alphabet zdevrait signifier readkey.keychar renvoie 122 lorsque l’utilisateur tape z, c vaut également 122, donc 'z' == 122réussit, c est alors incrémenté, puis c (contre 123) est testé c<123et échoue, arrêtant la boucle .. ?
Caius Jard
Vous avez raison, j'ai raté l' c++incrément lorsque je l'ai regardé. Cependant, je viens de l'essayer et quand je tape, abcdefghijklmnopqrstuvwxysça me donne un temps au lieu d'échouer. Je crois que c’est parce cque, même si la KeyCharvérification échoue, incrémente toujours c>122.
Ayb4btu
Bon point - peut-être que déplacer ++ vers la vérification c <123 maintiendra le décompte identique et empêchera le c de s’incrémenter si le dernier caractère est incorrect - pas le temps de déboguer pour le moment, mais je jetterai un coup d’œil à lui! acclamations :)
Caius Jard
0

Processing.org 133 142

le premier code n'est pas sorti

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
la source
0

GCC, Windows, 98 octets

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

Ne nécessite aucune saisie instantanée pour la première clé

l4m2
la source