Ketik Alfabet - secepat mungkin!


44

Tugas Anda adalah membuat program yang mengukur seberapa cepat Anda bisa mengetik huruf-huruf alfabet bahasa Inggris.

  • Program ini hanya akan menerima huruf kecil ake zdalam urutan abjad.
  • Setiap huruf digaungkan sebagai diketik pada baris yang sama (tanpa baris baru atau pemisah lainnya antara huruf)
  • Jika Anda mengetik karakter yang tidak valid, program akan menampilkan Fail pada baris baru dan keluar.
  • Jika Anda mengetikkan semua 26 huruf, program akan, pada baris baru , menampilkan waktu dalam milidetik yang diperlukan dari yang pertama hingga yang terakhir dan keluar.
  • Timer dimulai ketika Anda mengetik huruf pertama, a.

Output contoh:

b
Fail

abcdefgg
Fail

abcdefghijklmnopqrstuvwxyz
6440

Ini adalah , jadi jawaban tersingkat dalam byte menang.


4
Proyek yang relevan saya buat beberapa waktu lalu. (level 15 pada dasarnya adalah ini)
ETHproduksi

4
Bisakah kita menampilkan Failtanpa judul baris baru? (mis. abdFail\natau abd Fail\n))
scottinet

1
@ skottinet, tidak, hasilnya ( Failatau milidetik) harus di baris baru, seperti pada contoh. Sebagian besar jawaban sudah mengasumsikan ini.
Danko Durbić

2
-1 karena aturan "baru" ini tidak ada dalam spesifikasi asli dan membatalkan saran saya pada salah satu jawaban Python yang ada dalam aturan asli.
ElPedro

Saya mengharapkan ini menjadi tantangan kode tercepat untuk mencetak alfabet.
ATaco

Jawaban:


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

Klik pada input dan mulai mengetik! Juga, mengetik saya menyebalkan; Saya membutuhkan waktu sekitar 5 detik bahkan dengan latihan. Sunting: Disimpan 2 byte berkat @HermanLauenstein dengan beralih bahasa. Disimpan 3 byte berkat @ qw3n. Disimpan 9 byte berkat @tsh.


1
-2 byte dengan menggunakan html dengan tag skrip <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 jika tag penutup tidak diperlukan
Herman L

@HermanLauenstein Tag penutup tampaknya diperlukan untuk cuplikan, setidaknya, jadi saya akan meninggalkannya.
Neil

2
Ini terlalu menyebalkan dan menyenangkan sekaligus.
Zenon

1
Bagaimana dengan memasukkan event pada 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
Tidak menggemakan teks pada baris baru
dkudriavtsev

33

6502 kode mesin (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 dengan fungsi inlining dan tidak mempedulikan interupsi CIA2 lainnya

Demo online (Penggunaan:sys49152)

Tangkapan layar


Penjelasan:

Ini akan menjadi program kecil jika bukan karena masalah pengukuran milidetik pada C64. Gangguan sistem terjadi kira-kira 60 kali per detik, yang bahkan tidak mendekati. Jadi kita harus menggunakan pengatur waktu perangkat keras di sini yang mendapatkan kutu input dari jam sistem.

Pada mesin PAL, jam sistem tepat 985248 Hz. Oleh karena itu, menginisialisasi timer ke 985 memberikan sesuatu yang dekat dengan kutu milidetik, tetapi itu agak terlalu cepat, kita harus menghitung 986 siklus untuk setiap centang keempat, atau menahan timer untuk satu siklus tunggal. Ini tidak mungkin, tapi kita bisa menahan timer selama 6 siklus dengan urutan DEC $DD0E, INC $DD0E: $DD0Eadalah kontrol timer mendaftar dengan bit 0 beralih dan mematikan, dan kedua petunjuk mengambil 6 siklus, sehingga menulis yang tepat yang berhenti dan memulai Timer persis 6 siklus terpisah. Oleh karena itu kita harus menjalankan urutan ini setiap 6 * 4 = 24 centang. Ini masih belum mutlaktepatnya, timer akan tertinggal 1 milidetik setelah 8 menit dan 12 detik, tetapi mungkin cukup baik - mengimbanginya akan membutuhkan banyak kode.

sunting : Nilai awal untuk pengatur waktu harus 984, bukan 985, karena pengatur waktu ini menyala "saat underflow", jadi nilai 0 akan menghitung satu siklus lagi sebelum menembak. Kode diperbaiki, jumlah byte tidak berubah.

Berikut daftar pembongkaran yang dikomentari:

         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
Nah, sekarang saya punya timer milidetik yang lumayan di toolbox saya;) mungkin berguna suatu hari nanti.
Felix Palmen

11
Perhatikan, skrip kiddies. Ini golf asli.
J ...

1
@ J ... Saya bisa bermain golf lebih jauh dengan inlining .starttimer- akan segera dilakukan :) (dan lebih jauh lagi dengan menggunakan sistem TIseperti jawaban BASIC ini , tapi saya tidak yakin ini valid, karena Anda dapat melakukan yang lebih baik dalam kode mesin )
Felix Palmen

Wow, saya melewatkan faktor 985 ketika menghitung kesalahan dalam pengukuran waktu saya yang pertama - sebenarnya cukup bagus seperti itu (jika saya membuat kesalahan lain dalam perhitungan saya, tolong tunjukkan!) :)
Felix Palmen

Dan apakah Anda melihat apa yang dimiliki orang ini di GITHUB ?: pemulihan booting android .... ia benar-benar gila! disukai profilnya.
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"

Harus dijalankan di terminal.

Uji coba

$ 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
3479cukup cepat! dilakukan dengan baik :)
RobAu

Apakah ada versi spesifik dari bash yang diperlukan atau sesuatu? Pada 4.4.12, mengetik asegera memberi saya line 1: ((: r=15094100773N: value too great for base (error token is "15094100773N")dan keluar.
numbermaniac

@numbermaniac Versi Bash seharusnya tidak masalah, tapi salah satu datekekuatan. Milik saya berasal dari GNU coreutils 8.23. Apa yang date +%s%3Ntercetak pada sistem Anda?
Dennis

@Dennis it outputs 15094104833N- ini adalah dateutilitas bawaan pada macOS, jika itu membuat perbedaan.
numbermaniac

1
@numbermaniac BSD datetampaknya menggunakan strftime, yang tidak dikenali %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

Terima kasih kepada Ovs dan ElPedro untuk memperbaiki kode dan menghemat 57 byte.


7

SOGL V0.12 , 35 byte

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

Coba Di Sini! - klik jalankan, dan masukkan alfabet di kotak input. Perhatikan bahwa ini mungkin sedikit lamban karena SOGL hanya berhenti sebentar untuk input setiap 100 token yang dieksekusi (dan SOGL cukup lambat). Jika itu mengganggu Anda, jalankan sleepBI=truedi konsol.

Catatan: jangan jalankan ini dalam mode kompatibilitas - itu hanya akan berulang selamanya.

Penjelasan:

"ζ¦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 Saya tahu ini akan berguna: p
dzaima

Siapa yang mengharapkan SOGL dapat melakukan itu ... omong-omong bukan "Gagal" kata dalam kamus?
Erik the Outgolfer

@EriktheOutgolfer dengan baik, SOGL seharusnya menjadi bahasa serba guna, tapi itu tidak berhasil: p
dzaima

BTW Saya tidak tahu apakah ini benar-benar valid, tapi sekali lagi saya pikir itu mungkin masalah dengan antarmuka dan bukan penerjemah di belakang ...
Erik the Outgolfer

@EriktheOutgolfer ya, saya tidak tahu seberapa valid itu, saya kira saya sedang menunggu OP. Pada awalnya saya berpikir bahwa ini adalah sesuatu seperti jawaban HTML, tetapi sangat berbeda sekarang karena saya melihatnya
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.

Cobalah online!

Beberapa trik yang digunakan dalam kode untuk bermain golf:

  • Gunakan Realsebagai alternatif yang lebih pendek TDateTime, karena seperti yang didefinisikan di sini , TDateTime= Double, yang merupakan tipe titik-mengambang.
  • Alih-alih menggunakan MilliSecondsBetweenuntuk menghitung kesenjangan waktu, kode ini mengalikan perbedaan antara dua nilai floating-point dengan 864e5, yang bekerja karena cara pengkodean Free Pascal TDateTimedijelaskan di sini .

catatan:

  • ReadKeyfungsi sebenarnya tidak mencetak kunci pada konsol, jadi penulisan manual untuk konsol Write(c)diperlukan.
  • TIO mendapatkan skor dekat 0untuk mengetik alfabet karena alasan yang jelas.
  • Program mencetak waktu dalam notasi floating-point, saya kira itu diperbolehkan.

Selamat datang di situs ini!
caird coinheringaahing

Anda dapat menyimpan 1 byte dengan memindahkannya for c:='a'to'z'doke baris yang sama dengan a:=Time;.
Ismael Miguel

Mungkin Anda harus mencoba Nowdaripada Timelebih pendek.
tsh

Mengapa 86398338?? Saya bisa mengerti jika Anda menggandakan 864e5 karena ada 864e5 milidetik dalam sehari. tetapi bagaimana angka ajaib ini datang?
tsh

@ tsh saya juga tidak tahu. Dengan pengujian manual saya kebetulan menemukan bahwa "ajaib" nomor, dan saya tidak tahu toko bagaimana Pascal TDateTimesebagai Double. 864e5Kedengarannya lebih benar, saya akan memperbaiki masalah.
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();}};}}

Dan di sini saya pikir Java Console sudah verbose ..
Karena Java tidak punya cara mentah untuk mendengarkan penekanan tombol di Konsol afaik, saya menggunakan GUI dengan java.awt.

-78 byte terima kasih kepada @ OlivierGrégoire .

Penjelasan:

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

Contoh gif sukses: (Ya, saya mengetik alfabet dengan sangat lambat di sini ..)
Catatan: Ini adalah gif lama. Versi saat ini tidak lagi mencetak penekanan tombol ke Konsol. Dan itu tidak lagi mencetak waktu dengan angka setelah titik desimal.

masukkan deskripsi gambar di sini
Contoh gif gagal:
Catatan: Ini adalah gif lama. Versi saat ini tidak lagi mencetak penekanan tombol ke Konsol.

masukkan deskripsi gambar di sini


2
jawaban yang mengesankan mengingat ia memiliki gui!
Pureferret

1
388 byte . Saya mengambil kebebasan untuk memperbaiki kode Anda selain bermain golf karena Anda menggunakan setVisible(false)bukannya keluar.
Olivier Grégoire

@ OlivierGrégoire Terima kasih. Lupa tentang showdan dispose, yang bahkan lebih pendek dari setVisible. Saya hampir tidak pernah menggunakan GUI Java .. Dan pintar menggunakan inisialisasi kelas daripada memasukkannya ke dalam metode utama. Saya harus ingat itu.
Kevin Cruijssen

1
@KevinCruijssen Terima kasih, dan tidak ada masalah ;-) Meskipun ada beberapa komentar yang lebih umum: Anda tidak perlu menampilkan surat dua kali. Echoing sudah disediakan oleh TextField. Juga, Anda bisa menggunakan TextAreaalih-alih TextFieldmendapatkan dua byte. Akhirnya, KeyEventmemiliki getWhenmetode yang memberikan waktu antara zaman dan peristiwa dalam milidetik. Hanya perlu menggunakan itu daripada System.nanoTime()mendapatkan lebih banyak byte.
Olivier Grégoire

1
Sama-sama! Tapi saya mendapatkannya lebih jauh hingga 320 byte . ;-)
Olivier Grégoire

4

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

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

Belum diuji karena saya menggunakan ponsel dan ini tidak berjalan di 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 untuk membuat program yang berfungsi tanpa bisa mengujinya. Golf: 1) Satu cara yang lebih pendek yang saya temukan untuk menghasilkan pengecualian: int x=0;dan kemudian lakukan x=1/x;. Ini harus menghemat 14 byte. Sayangnya kamu butuh x. Jika Anda mencoba melakukannya, 1/0Anda mendapatkan Divisi dengan kesalahan kompiler nol konstan . 2) -5 byte untuk menggabungkan deklarasi cdengan yang pertama ReadKey. 3) Ubah kondisi di bagian dalam ifke ReadKey!=++cdan hapus c++;elseuntuk -9 byte lainnya.
raznagul

@raznagul Terima kasih! x=1/xdapat dikurangi menjadi x/=x. Dan saya menambahkan using static System.Console;untuk menghemat lebih banyak byte :)
Ian H.

Beberapa byte lagi dapat disimpan dengan menghapus idan menggunakan cdalam kondisi loop sebagai gantinya.
raznagul

3

MSX-BASIC, 126 karakter

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

TIME adalah variabel internal MSX-BASIC yang meningkat satu setiap 20 milidetik.


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

Cobalah online!

Sayangnya TIO tidak dapat menjalankan ini, tetapi berguna untuk mendapatkan jumlah byte.

+13 untuk using System;

-1 dengan mengubah i==123ke i>122. Saya tergoda untuk membuat ini i>'z'.

Ucapan Terima Kasih

-10 byte terima kasih kepada @raznagul

Tidak disatukan

()=>{
    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
Anda dapat menyimpan beberapa byte dengan memindahkan ReadKeyke kondisi loop sehingga Anda dapat menghapus yang pertama ifdan 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: Disimpan 27 byte berkat Jordan

Versi tidak disatukan:

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

Bekerja pada sistem * nix. Kode mandiri menghapus mode kanonik terminal saat ini untuk memungkinkan membaca karakter tanpa menunggu baris baru:

/! \ Menjalankan program ini akan membuat terminal hampir tidak dapat digunakan.

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

Tidak dikumpulkan dan berkomentar:

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

Solusi alternatif (218 byte):

Jika mengkonfigurasi terminal sebelumnya diizinkan, maka kita dapat menyingkirkan bagian dari penanganan kode bagian itu.

Berikut adalah kode yang sama tanpa manipulasi 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);}

Untuk membuatnya bekerja:

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

contoh runtime: masukkan deskripsi gambar di sini


3

Commodore BASIC v2 - 113 byte

Huruf kapital harus digeser.
Terima kasih kepada Felix Palmen karena menunjukkan beberapa kesalahan ketik, spesifikasinya
cobalah

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"

Klik edit untuk melihat kode penurunan harga yang diperbaiki.
NieDzejkob

Selamat datang di situs ini! Bisakah Anda menambahkan tautan ke juru bahasa (jika ada), sehingga orang lain dapat menguji kode Anda?
caird coinheringaahing

Yah, ini menggunakan sistem IRQ ( TIbertambah di dalamnya) Saya dianggap tidak cocok untuk ketepatannya, tapi saya kira itu permainan yang adil di sini karena tidak ada cara untuk berbuat lebih baik di BASIC :) Tetap, menempelkan ini di wakil, saya dapatkan kesalahan sintaksis dalam 1- bantuan apa pun?
Felix Palmen

Mencari tahu sendiri, Anda memiliki salah ketik di baris satu, harus 1on-(f=26)gO4:gEa$:ifa$=""tH1Nitpicks: 1.) output berada di baris yang sama, 2.) output all-caps - Saya pikir Anda harus memperbaikinya, saya tidak akan mengambil banyak byte lagian :)
Felix Palmen

Mengatasi masalah, masih ada kesalahan ketik?
mondlos

2

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

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

$|=1tidak cukup untuk mengatur terminal dalam mode mentah, stty -icanonharus dijalankan sebelum atau

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

untuk melihat karakter di terminal setelah menjalankan perintah: stty echoataustty echo icanon


Bagus tua ReadKey! Anda dapat menyimpan beberapa byte di sana-sini, 1e3untuk 1000, $s||=timedan jika Anda atur $sterlebih dahulu lalu panggil ReadKey, Anda dapat menukar keluar mapke postfix for. Saya ingin mengatakan diealih-alih exit print, tapi saya pikir Anda ada di sana ... Saya bermain-main printf"\n%i"tapi itu berakhir lebih besar, dan saya berpikir untuk menggunakan, $-bukan $s, tapi itu bodoh! :)
Dom Hastings

@HomHastings, terima kasih atas bantuan Anda, saya bisa menyimpan 4 byte, tetapi saya menambahkan 5 byte untuk mengatur input yang tidak ditambahkan $|=1;, juga $ s || = waktu tidak dapat menukar peta karena timer harus dimulai setelah tombol pertama ditekan, dan dieakan bergema Faildi stderr bukannya stdout.
Nahuel Fouilleul

Senang membantu, harap Anda tidak keberatan saya menawarkan ide! Ya, ini memalukan, exit printsangat lama! Maaf, saya tidak berpikir saya menjelaskan pemikiran saya dengan forbenar: $s||=time,ReadKey eq$_||exit print" Fail"for a..zharus bekerja saya pikir ... Mungkin bahkan $|=$s||=...atau $|=map...jika Anda lebih suka pendekatan itu! Pikir Anda cukup banyak berhasil!
Dom Hastings

$|=map..tidak menyetel input yang tidak dibangun pada terminal baru (saya mengalami kesalahan saat menghapus, ReadMode 3, karena saya sedang menguji di sesi yang sama), dan $s||=timesebelum ReadKey pertama akan memulai timer terlalu dini
Nahuel Fouilleul

Ahh, saya salah paham, saya mengerti sekarang, tidak menunggu cukup lama setelah mulai skrip untuk memeriksa itu ... :) Malu $|, tapi sekali lagi, ini menyimpan setelah loop yang sudah terlambat! Anda selangkah lebih maju!
Dom Hastings

2

Aceto , 70 byte

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

Saya mulai dengan menetapkan tanda tangkap dan mirroring secara horizontal ( @|), jika nilai pada stack benar. Ini bukan awalnya, dan nanti akan selalu begitu. Kami akan melompat kembali ke sini nanti jika kunci yang salah dimasukkan. Selanjutnya, kita mendorong a pada stack ( 'a), lalu kita menduplikasinya dan membaca satu karakter dari pengguna ( d,). Jika kedua karakter tidak sama ( =!), kita "crash" ( $) dan melompat kembali ke tanda tangkap. Kalau tidak, kita dorong "a" yang lain dan cetak, lalu kita atur waktu saat ini ( 'apT).

Lalu kita masukkan "loop utama" kami: Kami "menambah" karakter saat ini dan "menambah" karakter ( 'apToIc), lalu kami menduplikatnya, membaca karakter baru, membandingkannya, dan "crash" jika karakternya tidak sama ( d,=!$). Jika kita tidak crash, kita membandingkan karakter saat ini dengan "z" ( d'z=|), jika tidak sama, kita mencetak karakter, maka kita mendorong 1 dan melompat "kondisional" (dalam hal ini: selalu) ke hanya odalam kode (awal dari loop utama kami). Jika sama dengan z, kami melakukan mirroring secara horizontal ke beberapa ruang kosong di atasnya. Kami mencetak "z", lalu mendorong waktu saat ini (dikurangi waktu mulai; t) dan kemudian mengalikan angka 1000 (didapat dengan menaikkan 10 ke kekuatan ketiga; 91+3F) dengan itu (karena kami mendapatkan detik, bukan milidetik). Kemudian kami mencetak baris baru, waktu, dan keluar (pX).

Jika kita pernah crash (input buruk oleh pengguna), kita melompat ke awal. Karena kita sekarang akan memiliki beberapa nilai kebenaran pada stack, kita akan mirror secara horizontal ke u, yang membalikkan arah kita bergerak masuk. nMencetak karakter baris baru, kemudian kita mendorong "Fail"stack, mencetaknya, dan keluar ( pX).


1

Mathematica (ekspresi 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[]}]]]

Bagaimana itu bekerja

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 DynamicModuledengan EventHandleryang merespons penekanan tombol huruf kecil. Variabel x,, sdan ttahan huruf ditekan sejauh ini, waktu mulai, dan waktu akhir, masing-masing. Begitu kami menyadari xkesetaraan {"a"}, kami memulai waktunya; kami menampilkan total waktu yang dihabiskan, atau string yang dibangun sejauh ini, atau "Fail"tergantung pada kondisi mana yang dipenuhi.

Kita dapat menyimpan byte lain dengan t<1daripada t==0jika kita dapat berasumsi bahwa tidak ada yang cukup cepat untuk mengetik alfabet dalam waktu kurang dari satu detik :)

Jika Anda mencoba ini di buku catatan Mathematica, perlu diingat bahwa Anda harus mengklik di dalam bingkai sebelum penekanan tombol Anda akan didaftarkan. (Ini adalah alasan bahwa kita membutuhkan bingkai untuk memulai; jika Framedtidak ada, maka seluruh objek yang dipilih berubah ketika tombol ditekan, sehingga berhenti dipilih dan Anda harus mengklik lagi.)


1

C #, 154 152 + 13 = 165 byte

Disimpan 2 byte berkat komentar 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");
}

Kode di atas memiliki spasi untuk membuatnya pas di SE tanpa bilah gulir. Spasi bukan bagian dari jumlah byte

dan 13 byte untuk using System;

Ini mirip dengan versi Ayb4btu tetapi dengan perbedaan berikut:

  • Menyimpan datetime sebagai panjang, memungkinkan kita untuk membuat cpanjang juga, dan memotong pendek deklarasi

  • Loop tidak perlu istirahat terpisah

  • Sebenarnya tidak lebih pendek untuk digunakan $"interpreted strings"dibandingkan dengan menambahkan "\ n" yang diperlukan ke dalam milidetik untuk menjadikannya string untuk inline jika

  • Menggunakan forloop kadang-kadang memungkinkan kita untuk menyimpan karakter lebih dari beberapa saat, meskipun saya pikir ini tidak akan menghemat lebih dari yang setarawhile

Dari Ayb4btu:

  • s=s==0bisa menjadi s=s<1, dan c==123bisa menjadic>122

Tidak disatukan

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

Solusi yang bagus dengan cara Anda menggunakannya DateTime. Anda dapat menyimpan beberapa byte lagi dengan mengubah s=s==0ke s=s<1(mengandalkan fakta bahwa s tidak akan negatif), dan mengubah i==123ke i>122.
Ayb4btu

Juga, sudahkah ini diuji? Ketika saya menemukan bahwa i<123harus pergi sebelum ReadKey(), jika tidak menunggu karakter lain setelah z sebelum menampilkan waktu.
Ayb4btu

Aneh, karena pada akhir alfabet, zharus berarti readkey.keychar mengembalikan 122 ketika pengguna mengetikkan z, c juga 122, maka 'z' == 122berhasil, c kemudian bertambah, kemudian c (sekarang 123) diuji terhadap c<123dan gagal, menghentikan lingkaran ..?
Caius Jard

Kau benar, aku melewatkan c++kenaikan ketika aku melihatnya. Namun, saya hanya mencobanya dan ketika saya mengetiknya abcdefghijklmnopqrstuvwxysmemberi saya waktu bukannya gagal. Saya percaya itu karena cmasih bertambah meskipun KeyCharcek gagal, oleh karena itu melewati c>122cek.
Ayb4btu

Poin bagus - mungkin memindahkan ++ ke pemeriksaan c <123 akan membuat bytecount tetap sama dan mencegah kenaikan c jika karakter terakhir salah - tidak ada waktu untuk men-debug sekarang, tapi saya akan melihatnya! Cheers :)
Caius Jard

0

Processing.org 133 142

kode pertama tidak keluar

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

Tidak memerlukan input langsung untuk kunci pertama

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.