Wpisz alfabet - najszybciej jak potrafisz!


44

Twoim zadaniem jest stworzenie programu, który mierzy szybkość wpisywania liter alfabetu angielskiego.

  • Program przyjmuje tylko małe litery ato zw kolejności alfabetycznej.
  • Każda litera jest powtarzana jak w tym samym wierszu (bez nowej linii lub innych separatorów między literami).
  • Jeśli wpiszesz nieprawidłowy znak, program wyświetli Fail nowy wiersz i zakończy działanie.
  • Jeśli wpiszesz wszystkie 26 liter, program w nowym wierszu wyświetli czas w milisekundach od pierwszej do ostatniej litery i wyjdzie.
  • Timer rozpoczyna się po wpisaniu pierwszej litery a.

Przykładowe wyniki:

b
Fail

abcdefgg
Fail

abcdefghijklmnopqrstuvwxyz
6440

To jest , więc wygrywa najkrótsza odpowiedź w bajtach.


4
Odpowiedni projekt zrobiłem jakiś czas temu. (15. poziom jest w zasadzie taki)
ETHproductions

4
Czy możemy produkować Failbez nagłówka nowej linii? (np. abdFail\nlub abd Fail\n))
scottinet 30.10.17

1
@ scottinet, nie, wynik ( Faillub milisekundy) musi znajdować się w nowym wierszu, jak w przykładzie. Większość odpowiedzi już to zakłada.
Danko Durbić

2
-1, ponieważ ta „nowa” reguła nie była w oryginalnej specyfikacji i unieważnia moje sugestie dotyczące jednej z odpowiedzi w języku Python, która mieściła się w oryginalnych regułach.
ElPedro

Spodziewałem się, że będzie to najszybsze wyzwanie drukowania alfabetu.
ATaco,

Odpowiedzi:


40

HTML (JavaScript (ES6)), 129 126 117 bajtów

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

Kliknij wejście i zacznij pisać! Poza tym moje pisanie jest do bani; Zajmuję około 5 sekund nawet podczas ćwiczeń. Edycja: Zapisano 2 bajty dzięki @HermanLauenstein poprzez zmianę języka. Zaoszczędzono 3 bajty dzięki @ qw3n. Zaoszczędź 9 bajtów dzięki @tsh.


1
-2 bajty przy użyciu html ze znacznikiem skryptu:, <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 bajtów, jeśli znacznik zamykający nie jest potrzebny
Herman L

@HermanLauenstein Tag zamykający wydaje się być niezbędny przynajmniej dla fragmentu, więc zostawię go.
Neil,

2
Jest to jednocześnie irytujące i zabawne.
Zenon

1
Co z wprowadzeniem zdarzenia na wejściu? <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
Nie odzwierciedla tekstu w nowym wierszu
dkudriavtsev

33

Kod maszynowy 6502 (C64 PAL), 189 165 bajtów

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 bajty przez wstawianie funkcji i nie dbanie o inne przerwania CIA2

Demo online (Zastosowanie:sys49152)

Zrzut ekranu


Wyjaśnienie:

Byłby to mały program, gdyby nie problem dokładnego pomiaru milisekund na C64. Przerwanie systemu występuje z grubsza 60 razy na sekundę, co nie jest nawet blisko. Musimy więc użyć tutaj timera sprzętowego, który odbiera tiki wejściowe z zegara systemowego.

Na maszynie PAL zegar systemowy ma dokładnie 985248 Hz. Zainicjowanie licznika czasu na 985 daje więc coś zbliżonego do milisekundowych tyknięć, ale jest to trochę za szybko, musielibyśmy liczyć 986 cykli na co czwarty tyknięcie lub przytrzymać licznik dla jednego cyklu. Nie jest to możliwe, ale możemy trzymać timera przez 6 cykli z sekwencji DEC $DD0E, INC $DD0E: $DD0Ejest rejestr kontrolny zegar z bit 0 przełączania go i wyłączać, a obie instrukcje przyjąć 6 cykli, więc dokładnie pisze, że zatrzymanie i rozpoczęcie Timer dzieli dokładnie 6 cykli. Dlatego musimy wykonywać tę sekwencję co 6 * 4 = 24 tyknięcie. To wciąż nie jest absolutniedokładnie, zegar opóźni się o 1 milisekundę do tyłu po 8 minutach i 12 sekundach, ale prawdopodobnie jest wystarczająco dobry - zrekompensowanie tego zajmie dużo kodu.

edycja : Wartość początkowa dla timera musi wynosić 984, a nie 985, ponieważ te timery odpalają „przy niedopełnieniu”, więc wartość 0 będzie liczyć jeszcze jeden cykl przed odpaleniem. Naprawiono kod, niezmieniono liczbę bajtów.

Oto skomentowana lista dezasemblacji:

         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
Cóż, teraz mam w swoim przyborniku nieco przyzwoity licznik milisekund;) może kiedyś się przydać.
Felix Palmen

11
Uważaj, dzieciaki ze scenariusza. To jest prawdziwy golf.
J ...

1
@J ... Mógłbym jeszcze zagrać w golfa poprzez wprowadzenie .starttimer- zrobię to wkrótce :) (a nawet dalej, używając systemu TItakiego jak ta odpowiedź BASIC , ale nie jestem pewien, czy jest to poprawne, ponieważ można lepiej zrobić w kodzie maszynowym )
Felix Palmen

Wow, pominąłem współczynnik 985 przy pierwszym obliczaniu błędu w moim pomiarze czasu - tak naprawdę jest całkiem niezły (jeśli popełniłem kolejny błąd w moich obliczeniach, proszę zauważyć!) :)
Felix Palmen

A widzisz, co ten facet ma w GITHUBIE ?: odzyskiwanie rozruchu Androida ... jest całkowicie szalony! faworyzował jego profil.
Luciano Andress Martini

13

Bash + coreutils, 103 99 98 bajtów

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"

Musi być uruchamiany w terminalu.

Testowe uruchomienie

$ 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
3479jest dość szybki! dobra robota :)
RobAu,

Czy jest wymagana konkretna wersja bash czy coś takiego? W dniu 4.4.12 pisanie aod razu daje mi line 1: ((: r=15094100773N: value too great for base (error token is "15094100773N")i kończy działanie.
numbermaniac

@numbermaniac Wersja Bash nie powinna mieć znaczenia, ale ta z datepotęgą. Mój pochodzi z GNU coreutils 8.23. Co date +%s%3Ndrukuje w twoim systemie?
Dennis

@Dennis wyprowadza 15094104833N- to wbudowane datenarzędzie w systemie macOS, jeśli to robi różnicę.
numbermaniac

1
@numbermaniac BSD datewydaje się używać strftime, który nie rozpoznaje %N.
Dennis

9

Python 2 + getch , 116 bajtów

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

Dzięki ovs i ElPedro za poprawienie kodu i oszczędność 57 bajtów.


7

SOGL V0.12 , 35 bajtów

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

Wypróbuj tutaj! - kliknij Uruchom i wprowadź alfabet w polu wprowadzania. Zauważ, że może to być nieco opóźnione, ponieważ SOGL zatrzymuje się tylko na dane wejściowe co 100 wykonanych tokenów (a SOGL jest dość wolny). Jeśli Ci to przeszkadza, uruchom sleepBI=truekonsolę.

Uwaga: nie uruchamiaj tego w trybie zgodności - zapętli się na zawsze.

Wyjaśnienie:

"ζ¦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 Wiedziałem, że przyda się: p
dzaima

Kto by się spodziewał, że SOGL będzie w stanie to zrobić ... nawiasem mówiąc, słowo „Fail” nie jest słowem w słowniku?
Erik the Outgolfer

@EriktheOutgolfer dobrze, SOGL miał być językiem uniwersalnym, ale to nie wyszło: p
dzaima

BTW Nie wiem, czy to jest w pełni poprawne, ale znowu myślę, że może to być problem z interfejsem, a nie tłumaczem stojącym za ...
Erik Outgolfer

@EriktheOutgolfer tak, nie wiem, jak ważne to jest, chyba czekam na OP. Na początku myślałem, że jest to coś w rodzaju odpowiedzi HTML, ale teraz jest zupełnie inaczej, kiedy na nią
patrzę

7

Pascal (FPC) , 176 bajtów

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.

Wypróbuj online!

Niektóre sztuczki używane w kodzie do gry w golfa:

  • Użyj Realjako krótszej alternatywy TDateTime, ponieważ, jak zdefiniowano tutaj , TDateTime= Double, która jest typu zmiennoprzecinkowego.
  • Zamiast używać MilliSecondsBetweendo obliczania przerwy czasowej, ten kod zwielokrotnia różnicę między dwiema wartościami zmiennoprzecinkowymi przez 864e5, co działa z powodu sposobu TDateTimeopisanego tutaj kodowania Free Pascal .

Uwaga:

  • ReadKeyfunkcja faktycznie nie drukuje klucza na konsoli, więc Write(c)konieczne jest ręczne pisanie na konsoli za pomocą .
  • TIO otrzymuje wynik 0za pisanie alfabetu z oczywistego powodu.
  • Program drukuje czas w notacji zmiennoprzecinkowej, myślę, że jest to dozwolone.

Witamy na stronie!
caird coinheringaahing 30.10.17

Możesz zapisać 1 bajt, przesuwając for c:='a'to'z'doten sam wiersz co a:=Time;.
Ismael Miguel

Może powinieneś spróbować Nowzamiast tego, Timeponieważ jest krótszy.
tsh

Dlaczego 86398338?? Rozumiem, jeśli pomnożysz 864e5, ponieważ dziennie jest 8 milisekund. ale skąd ta magiczna liczba?
tsh

@tsh Ja też nie wiem. Poprzez badanie ręcznym zdarza mi się znaleźć ten numer „Magic”, a ja nie wiem jak sklep Pascal TDateTimejako Double. 864e5brzmi bardziej poprawnie, naprawię problemy.
user75648,

5

Java, 404 388 354 348 320 318 bajtów

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

I tutaj myślałem, że Java Console jest już gadatliwa.
Ponieważ Java nie ma sposobu na surowe nasłuchiwanie naciśnięć klawiszy w konsoli, używam GUI z java.awt.

-78 bajtów dzięki @ OlivierGrégoire .

Wyjaśnienie:

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

Przykład gif sukcesu: (Tak, dość powoli wpisuję alfabet tutaj.)
Uwaga: To jest stary gif. Obecna wersja nie drukuje już naciśnięć klawiszy w konsoli. I nie drukuje już czasu cyframi po przecinku.

wprowadź opis zdjęcia tutaj
Przykład gif fail:
Uwaga: To jest stary gif. Obecna wersja nie drukuje już naciśnięć klawiszy w konsoli.

wprowadź opis zdjęcia tutaj


2
imponująca odpowiedź, biorąc pod uwagę, że ma GUI!
Pureferret,

1
388 bajtów . Pozwoliłem sobie na poprawienie kodu oprócz gry w golfa, ponieważ używałeś go setVisible(false)zamiast wychodzić.
Olivier Grégoire

@ OlivierGrégoire Thanks. Zapomniałem o showi dispose, co jest nawet krótsze niż setVisible. Prawie nigdy nie używam GUI Javy. I sprytnie korzystam z inicjalizacji klas zamiast umieszczania jej w metodzie głównej. Powinienem to pamiętać.
Kevin Cruijssen

1
@KevinCruijssen Dzięki, i nie ma problemu ;-) Chociaż kilka bardziej ogólnych komentarzy: nie musisz wysyłać listów dwa razy. Echoing jest już zapewniony przez TextField. Można również użyć TextAreazamiast, TextFieldaby uzyskać dwa bajty. Wreszcie KeyEventma getWhenmetodę, która podaje czas między epoką a zdarzeniem w milisekundach. Wystarczy użyć ich zamiast System.nanoTime()zyskać jeszcze więcej bajtów.
Olivier Grégoire

1
Nie ma za co! Ale zmniejszyłem to do 320 bajtów . ;-)
Olivier Grégoire

4

C # (.NET Core), 245 + 13 183 + 41 177 + 41 bajtów

+41 bajtów dla using System;using static System.Console.

Nie sprawdzono, ponieważ jestem na telefonie komórkowym i nie działa na 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 za stworzenie działającego programu bez możliwości jego przetestowania. Gra w golfa: 1) Znalazłem jeden krótszy sposób, aby stworzyć wyjątek: int x=0;a potem zrobić x=1/x;. Powinno to zaoszczędzić 14 bajtów. Niestety potrzebujesz x. Jeśli spróbujesz to zrobić 1/0, otrzymasz błąd dzielenia przez stały błąd kompilatora zero . 2) -5 bajtów do łączenia deklaracji cz pierwszym ReadKey. 3) Zmień warunek wewnętrzny ifna ReadKey!=++ci usuń c++;elsedla kolejnych -9 bajtów.
raznagul

@raznagul Thanks! x=1/xmożna zredukować do x/=x. I dodałem, using static System.Console;aby zaoszczędzić trochę więcej bajtów :)
Ian H.

Więcej bajtów można zapisać, usuwając je ii używając cw pętli.
raznagul

3

MSX-BASIC, 126 znaków

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

TIME jest wewnętrzną zmienną MSX-BASIC, która zwiększa się o jedną co 20 milisekund.


3

C # (.NET Core) , 184 + 13 = 197 173 + 13 = 186 bajtów

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

Wypróbuj online!

Niestety TIO nie może tego uruchomić, ale przydaje się do liczenia bajtów.

+13 dla using System;

-1, zmieniając i==123na i>122. Kusiło mnie, aby to zrobić i>'z'.

Podziękowanie

-10 bajtów dzięki @raznagul

Nie golfił

()=>{
    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
Możesz zapisać niektóre bajty, przesuwając ReadKeywarunek do pętli, aby usunąć pierwszy ifi break.
raznagul

3

Node.js, 240 213 bajtów

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)

EDYCJA: Oszczędność 27 bajtów dzięki Jordanowi

Wersja bez golfa:

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 bajty

Działa na systemach * nix. Samodzielny kod usuwający tryb kanoniczny bieżącego terminala, aby umożliwić czytanie znaków bez czekania na znaki nowej linii:

/! \ Uruchomienie tego programu sprawi, że terminal będzie prawie bezużyteczny.

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

Nie golfił i skomentował:

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

Alternatywne rozwiązanie (218 bajtów):

Jeśli dozwolone jest wcześniejsze skonfigurowanie terminala, możemy pozbyć się części kodu obsługującej tę część.

Oto ten sam kod bez manipulacji terminalem:

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

Aby to działało:

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

przykład środowiska wykonawczego: wprowadź opis zdjęcia tutaj


3

Commodore BASIC v2 - 113 bajtów

Wielkie litery muszą być przesunięte.
Dzięki Felixowi Palmenowi za wskazanie literówek, specyfikacje
próbują

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"

Kliknij edytuj, aby zobaczyć poprawiony kod przeceny.
NieDzejkob

Witamy na stronie! Czy możesz dodać link do tłumacza (jeśli taki istnieje), aby inni mogli przetestować Twój kod?
caird coinheringaahing

Cóż, to korzysta z systemu IRQ ( TIjest w nim zwiększane) Uznałem, że nie nadaje się ze względu na brak precyzji, ale myślę, że jest to uczciwa gra, ponieważ po prostu nie ma lepszego sposobu na BASIC :) Mimo to, wklejając to na odwrót, otrzymuję błąd składniowy w 1- jakaś pomoc?
Felix Palmen

Zrozumiałem to sam, masz literówkę w pierwszej linii, powinno być 1on-(f=26)gO4:gEa$:ifa$=""tH1Nitpicks: 1.) wyjście jest w tej samej linii, 2.) wyjście jest wielkimi literami - Myślę, że powinieneś to naprawić, nie zajmie wielu bajtów tak czy inaczej :)
Felix Palmen

Rozwiązano problemy, zostały jakieś literówki?
mondlos

2

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

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

$|=1nie jest wystarczające, aby ustawić terminal w trybie surowym, stty -icanonnależy uruchomić przed lub

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

aby zobaczyć znaki w terminalu po uruchomieniu polecenia: stty echolubstty echo icanon


Dobry stary ReadKey! Można zaoszczędzić kilka bajtów tu i tam, 1e3o 1000, $s||=timea jeśli ustawiony $s, a następnie zadzwonić ReadKey, możesz zamienić się z mapdo Postfix for. Chciałbym powiedzieć diezamiast exit print, ale myślę, że tam jesteś ... Majstrowałem przy, printf"\n%i"ale skończyło się to na większym, i pomyślałem o użyciu $-zamiast $s, ale to było głupie! :)
Dom Hastings

@DomHastings, dziękuję za pomoc, mogłem zaoszczędzić 4 bajty, ale dodałem 5 bajtów, aby ustawić niebuforowane dane wejściowe $|=1;, również $ s || = czas nie może zostać zamieniony na mapę, ponieważ zegar musi się uruchomić po pierwszym naciśnięciu klawisza, i dieodbija Failsię echem na stderr zamiast na stdout.
Nahuel Fouilleul

Chętnie Ci pomożemy, mam nadzieję, że nie masz nic przeciwko oferowaniu pomysłów! Tak, szkoda, exit printjest tak długo! Przepraszam, nie sądzę, że wytłumaczyłem swoją myśl forpoprawnie: $s||=time,ReadKey eq$_||exit print" Fail"for a..zpowinien działać, myślę ... Może nawet $|=$s||=...lub $|=map...jeśli wolisz takie podejście! Myślisz, że prawie to przybiłeś!
Dom Hastings,

$|=map..nie ustawia niebuforowanego wejścia w nowym terminalu (miałem błąd podczas usuwania, ReadMode 3, ponieważ testowałem w tej samej sesji), a $s||=timeprzed pierwszym ReadKey zbyt wcześnie uruchomiłby licznik czasu
Nahuel Fouilleul

Ahh, źle zrozumiałem, rozumiem teraz, nie zaczekałem wystarczająco długo po uruchomieniu skryptu, aby to sprawdzić ... :) Szkoda $|, ale znowu, przechowuje się po pętli, która jest za późno! Jesteś krok do przodu!
Dom Hastings

2

Aceto , 70 bajtów

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

Zaczynam od ustawienia znacznika i dublowania w poziomie ( @|), jeśli wartość na stosie jest prawdziwa. Początkowo tak nie jest, a później zawsze tak będzie. Wrócimy tutaj później, jeśli zostanie wprowadzony zły klucz. Następnie wciskamy a na stosie ( 'a), a następnie kopiujemy go i odczytujemy pojedynczy znak od użytkownika ( d,). Jeśli dwa znaki nie są równe ( =!), „upaść” ( $) i przeskoczyć z powrotem do znaku catch. W przeciwnym razie wciskamy kolejne „a” i drukujemy je, a następnie ustawiamy bieżącą godzinę ( 'apT).

Następnie wchodzimy do naszej „głównej pętli”: „Zwiększamy” bieżący znak i „zwiększamy” znak ( 'apToIc), następnie kopiujemy go, czytamy nowy znak, porównujemy go i „zawieszamy”, jeśli znaki nie są identyczne ( d,=!$). Jeśli się nie zawiesiliśmy, porównujemy bieżący znak do „z” ( d'z=|), jeśli nie jest równy, drukujemy znak, a następnie wciskamy 1 i przeskakujemy „warunkowo” (w tym przypadku: zawsze) do tylko ow kodzie (początek naszej głównej pętli). Jeśli był równy z, to odbijaliśmy poziomo do jakiegoś pustego miejsca na górze. Drukujemy „z”, a następnie przesuwamy aktualny czas (minus czas początkowy; t), a następnie mnożymy liczbę 1000 (uzyskaną przez podniesienie 10 do trzeciej potęgi; 91+3F) przez to (ponieważ otrzymujemy sekundy, nie milisekundy). Następnie wypisujemy nowy wiersz, godzinę i kończymy (pX).

Jeśli kiedykolwiek się zawiesimy (złe dane wprowadzone przez użytkownika), przeskoczymy do samego początku. Ponieważ będziemy mieli teraz pewną prawdziwą wartość na stosie, będziemy wykonywać odbicie lustrzane w poziomie w kierunku u, który odwraca kierunek, w którym się poruszamy. nDrukuje znak nowej linii, następnie wciskamy "Fail"stos, drukujemy go i kończymy ( pX).


1

Mathematica (wyrażenie w notesie), 248 bajtów

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

Jak to działa

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 DynamicModulez EventHandlerreagującym na naciśnięcia małych liter. Zmienne x, si tprzytrzymaj naciśnięty litery tak daleko, czas rozpoczęcia i czas zakończenia, odpowiednio. Gdy tylko zauważymy, xże jesteśmy równi {"a"}, zaczynamy czas; wyświetlamy całkowity czas spędzony lub ciąg zbudowany do tej pory lub w "Fail"zależności od tego, który warunek jest spełniony.

Możemy zapisać kolejny bajt, t<1zamiast t==0zakładać, że nikt nie jest wystarczająco szybki, aby wpisać alfabet w mniej niż sekundę :)

Jeśli wypróbowujesz to w notatniku Mathematica, pamiętaj, że musisz kliknąć wewnątrz ramki przed zarejestrowaniem naciśnięć klawiszy. (To jest powód, dla którego potrzebujemy ramki od samego początku; jeśli jej Framednie ma, wówczas cały wybrany obiekt zmienia się po naciśnięciu klawisza, więc przestaje być wybierany i trzeba będzie kliknąć ponownie).


1

C #, 154 152 + 13 = 165 bajtów

Zaoszczędzono 2 bajty dzięki komentarzom 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");
}

Powyższy kod ma spacje, aby zmieścił się w SE bez paska przewijania. Białe znaki nie są częścią liczby bajtów

i 13 bajtów dla using System;

Jest podobny do wersji Ayb4btu, ale z następującymi różnicami:

  • Przechowywanie daty i godziny jako długiej pozwala nam również zrobić cdługą i skrócić deklarację

  • Pętla nie potrzebuje oddzielnej przerwy

  • W rzeczywistości nie jest krótszy w $"interpreted strings"porównaniu do dodania potrzebnego „\ n” do milisekund, aby uczynić go ciągiem wstawianym, jeśli

  • Korzystanie z forpętli czasami pozwala nam zapisywać znaki przez jakiś czas, chociaż myślę, że ten nie zapisałby więcej niż równowartośćwhile

Od Ayb4btu:

  • s=s==0może się stać s=s<1i c==123może się staćc>122

Nie golfił

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

Dobre rozwiązanie dzięki temu, jak korzystałeś DateTime. Możesz zaoszczędzić kilka bajtów, zmieniając s=s==0na s=s<1(licząc, że s nie będzie ujemne) i zmieniając i==123na i>122.
Ayb4btu

Czy to również zostało przetestowane? Jak się przekonałem, i<123musiało to nastąpić przed ReadKey(), inaczej czeka na inną postać po z, zanim wyświetli czas.
Ayb4btu

Dziwne, ponieważ na końcu alfabetu zpowinno oznaczać readkey. Keychar zwraca 122, gdy użytkownik wpisze z, c jest również 122, a zatem 'z' == 122powiedzie się, c jest następnie zwiększany, a następnie c (teraz 123) jest testowany c<123i kończy się niepowodzeniem, zatrzymując pętla ..?
Caius Jard

Masz rację, przegapiłem c++przyrost, gdy na niego patrzyłem. Jednak właśnie go wypróbowałem, a kiedy abcdefghijklmnopqrstuvwxysgo wpisuję, daje mi to czas zamiast się nie udać. Uważam, że dzieje się tak, ponieważ cwciąż wzrasta, nawet jeśli KeyCharczek się nie powiedzie, dlatego też przekazanie c>122czeku.
Ayb4btu

Dobra uwaga - być może przeniesienie ++ na czek c <123 sprawi, że liczba bajtów pozostanie taka sama i zapobiegnie zwiększeniu c, jeśli ostatni znak jest nieprawidłowy - nie ma czasu na debugowanie w tej chwili, ale przyjrzę się temu! na zdrowie :)
Caius Jard

0

Processing.org 133 142

pierwszy kod nie wyszedł

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 bajtów

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

Nie wymaga natychmiastowego wprowadzania pierwszego klucza

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.