Alfabeyi yaz - olabildiğince hızlı!


44

Görevin İngilizce alfabenin harflerini ne kadar hızlı yazabileceğini ölçen bir program yapmak.

  • Program sadece küçük harfleri kabul eder aiçin zalfabetik sırayla.
  • Her harf aynı satırda yazıldığı gibi yankılanır (yeni satır olmadan veya harfler arasında başka bir ayırıcı olmadan).
  • Geçersiz bir karakter yazarsanız, program Fail yeni bir satıra çıkar ve çıkar.
  • 26 harfin tümünü yazarsanız, program yeni bir satırda , süreyi ilk harften son harfe kadar geçen süreyi milisaniye cinsinden belirtir ve çıkar.
  • İlk harfi yazdığınızda zamanlayıcı başlar a,.

Örnek çıktılar:

b
Fail

abcdefgg
Fail

abcdefghijklmnopqrstuvwxyz
6440

Bu , bayt cinsinden en kısa cevap kazanır.


4
İlgili proje bir süre önce yaptım. (15. seviye temelde şudur)
ETHproductions

4
Yeni Failbir satır olmadan çıktı alabilir miyiz ? (örneğin abdFail\nveya abd Fail\n))
scottinet

1
@scottinet, hayır, sonuç ( Failveya milisaniye) örnekte olduğu gibi yeni bir satırda olmalıdır. Çoğu cevap bunu zaten varsayıyor.
Danko Durbić

2
-1 Bu "yeni" kural orjinal şartnamede değildi ve orjinal kurallar içinde yer alan Python cevaplarından biri hakkındaki önerilerimi geçersiz kılıyor.
ElPedro

Bunu alfabenin basılmasının en hızlı kod mücadelesi olmasını bekliyordum .
ATaco

Yanıtlar:


40

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

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

Girdiyi tıklayın ve yazmaya başlayın! Ayrıca yazmam berbat; Uygulamada bile 5 saniye sürüyor. Düzenleme: Dil değiştirme yoluyla @HermanLauenstein sayesinde 2 bayt kaydedildi. @ Qw3n sayesinde 3 bayt kaydedildi. @Tsh sayesinde 9 bayt kaydedildi.


1
Bir betik etiketi ile html kullanarak -2 bayt:, <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>kapanış etiketi gerekmiyorsa -11 bayt
Herman L

@HermanLauenstein Kapanış etiketi, en azından bir pasaj için gerekli gibi görünüyor, bu yüzden içeride bırakacağım.
Neil

2
Bu aynı zamanda çok çıldırtan ve eğlenceli.
Zenon

1
Girişte put olayı ne olacak? <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
Metni yeni bir satıra
eklemez

33

6502 makine kodu (C64 PAL), 189 165 bayt

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
  • Diğer CIA2 kesmelerine dikkat etmeyip işlev göstermeyerek -24 bayt

Çevrimiçi demo (Kullanımı:sys49152)

Ekran görüntüsü


Açıklama:

C64'te tam bir milisaniye ölçümü sorunu olmasaydı bu küçük bir program olurdu. Sistemin kesilmesi saniyede yaklaşık 60 kez gerçekleşir ve bu da yakın değildir. Bu yüzden burada sistem saatinden girişini tıkayan bir donanım zamanlayıcı kullanmalıyız.

Bir PAL makinesinde, sistem saati tam olarak 985248 Hz'dir. Zamanlayıcıyı 985'e başlatmak bu nedenle milisaniye kenelerine yakın bir şey verir , ancak biraz fazla hızlı, her dördüncü kene için 986 döngü saymamız veya zamanlayıcıyı tek bir döngü için tutmamız gerekir. Bu mümkün değil, ama biz dizisi ile 6 döngüleri için zamanlayıcı tutabilir DEC $DD0E, INC $DD0E: $DD0EBit 0 etkinleştirmek veya devre dışı geçiş ile zamanlayıcı kontrolü kayıt olduğunu ve her iki talimatlar, bu yüzden kesin yazıyor 6 döngüleri aldığını stop ve start Zamanlayıcı tam olarak 6 döngüdür. Bu nedenle, bu sırayı her 6 * 4 = 24 tıklatmada çalıştırmalıyız. Bu hala değil kesinliklekesin olarak, zamanlayıcı 8 dakika ve 12 saniye sonra 1 milisaniyeyi geride bırakacaktır, ancak muhtemelen yeterince iyidir - bunu telafi etmek çok fazla kod alacaktır .

düzenleme : Zamanlayıcı için başlangıç ​​değeri 984 değil, 985 olmalıdır, çünkü bu zamanlayıcılar "akış altında" yanar, bu nedenle 0 değeri, ateşlemeden önce bir döngü daha sayar. Kod düzeltildi, bayt sayısı değişmedi.

İşte yorum sökme listesi:

         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
Eh, şimdi benim araç kutusunda biraz iyi bir milisaniye zamanlayıcı var;) bir gün yararlı olabilir.
Felix Palmen

11
Dikkat et, senaryo çocukları. Bu gerçek golf.
J ...

1
İnlining daha da @J ... I could golf it .starttimer- sistemini kullanarak daha da :) yakında yapmayı (ve olacak TIgibi bu TEMEL cevap nedeniyle, ama değilim emin bu geçerlidir, olabilir makine kodunda iyisini )
Felix Palmen

Vay, önce zaman ölçümümdeki hatayı hesaplarken 985 faktörünü kaçırdım - bu aslında oldukça iyi (eğer hesaplamalarımda başka bir hata yaptıysam, lütfen işaret et!) :) :)
Felix Palmen

Ve bu adamın GITHUB'da neler olduğunu görüyor musunuz ?: android boot recovery .... o tamamen delirmiş! profilini favorilerine ekledi.
Luciano Andress Martini,

13

Bash + coreutils, 103 99 98 bayt

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"

Bir terminalde çalıştırılmalıdır.

Test sürüşü

$ 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
3479oldukça hızlı! aferin :)
RobAu

Gerekli bir bash sürümü var mı? 4.4.12, yazarak ahemen bana verir line 1: ((: r=15094100773N: value too great for base (error token is "15094100773N")ve çıkar.
numbermaniac

@ sayı_maniac Bash sürümü önemli olmamalıdır, ancak güçlü biri date. Maden GNU coreutils 8.23'ten geliyor. date +%s%3NSisteminizde ne yazdırıyor?
Dennis,

Çıktıları @Dennis 15094104833N- Bu fark yaratırsa, macOS'ta yerleşik bir dateyardımcı programdır.
numbermaniac

1
@ sayı_maniac BSD'ler datetanımadığı strftime kullanıyor gibi görünüyor %N.
Dennis,

9

Python 2 + getch , 116 bayt

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

Kodu düzeltmek ve 57 bayt kaydetmek için ovs ve ElPedro'ya teşekkürler.


7

SOGL V0.12 , 35 bayt

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

Burada dene! - Çalıştır'ı tıklatın ve giriş kutusuna alfabeyi girin. SOGL yalnızca her 100 çalıştırılan jetonun girişini duraklattığından (ve SOGL oldukça yavaştır) biraz gecikmeli olabileceğini unutmayın. Bu sizi rahatsız ediyorsa, sleepBI=truekonsolu çalıştırın .

not: Bunu uyumluluk modunda çalıştırmayın - bu sonsuza dek tekrar eder.

Açıklama:

"ζ¦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 İşe yarayacağını biliyordum: p
dzaima

SOGL'un bunu yapmasını kim beklerdi ... bu arada sözlükte "başarısız" olmaz mı?
Outgolfer Erik,

@EriktheOutgolfer iyi, SOGL çok amaçlı bir dil olması gerekiyordu , ama işe yaramadı: p
dzaima

Bu tamamen geçerli olup olmadığını BTW bilmiyorum, ama sonra tekrar sanırım o arayüzü ile bir sorun değil, tercüman arkasında ... olabilir
Erik Outgolfer

@EriktheOutgolfer evet, bunun ne kadar geçerli olduğunu bilmiyorum, sanırım OP'yi bekliyorum. İlk başta bunun HTML cevabı gibi bir şey olduğunu düşünmüştüm, fakat şimdi baktığımda oldukça farklı
dzaima

7

Pascal (FPC) , 176 bayt

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.

Çevrimiçi deneyin!

Golf oynamak için kodda kullanılan bazı hileler:

  • Kullanım Realiçin daha kısa bir alternatif olarak TDateTime, tarif edildiği gibi, çünkü burada , TDateTime= Double, bir kayan noktalı türü.
  • MilliSecondsBetweenZaman boşluğunu hesaplamak yerine , bu kod 864e5, Free Pascal kodunun buradaTDateTime açıklanan şekilde çalışması nedeniyle çalışan iki kayan nokta değeri arasındaki farkı çarpar .

Not:

  • ReadKeyBu işlev aslında konsoldaki anahtarı yazdırmaz, bu yüzden konsola el ile yazmak Write(c)gerekir.
  • TIO 0, bariz bir nedenden dolayı alfabeyi yazmak için yakın bir puan olsun .
  • Program kayan nokta gösteriminde zaman basar, sanırım buna izin var.

Siteye Hoşgeldiniz!
Caird coinheringaahing

İle for c:='a'to'z'doaynı satıra taşıyarak 1 byte tasarruf edebilirsiniz a:=Time;.
Ismael Miguel,

Belki denemelisiniz Nowyerine Timedaha kısa olduğu gibi.
tsh

Neden 86398338?? Günde 864e5 milisaniye olduğundan 864e5'i birden çarptığınızı anlayabiliyorum. ama bu sihirli sayı nasıl geliyor?
tsh

@ tsh Ben de bilmiyorum. Manuel test derken o "sihirli" sayısını bulmak için olur ve nasıl Pascal mağaza bilmiyoruz TDateTimeolarak Double. 864e5daha doğru geliyorsa, sorunları çözeceğim.
user75648

5

Java, 404 388 354 348 320 318 bayt

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

Ve burada ben .. Java Konsolu ayrıntılı zaten düşünce
Java ham afaik Konsolu anahtar presleri dinlemek için bir yol olduğundan, ben bir GUI kullanmak java.awt.

@ OlivierGrégoire sayesinde -78 bayt .

Açıklama:

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

Başarı için örnek gif: (Evet, alfabeyi buraya oldukça yavaş yazarım ..)
Not: Bu eski bir gif. Şu anki sürüm artık basılan tuşları Konsol'a basmıyor. Ve artık ondalık basamağından sonra basamağa rakamlarla basmaz.

görüntü tanımını buraya girin
Başarısız örnek gif:
Not: Bu eski bir gif. Şu anki sürüm artık basılan tuşları Konsol'a basmıyor.

görüntü tanımını buraya girin


2
bir GUI olduğu göz önüne alındığında etkileyici cevap!
Pureferret

1
388 bayt . Golfe ek olarak kodunuzu düzeltme özgürlüğünü de kullandım çünkü setVisible(false)çıkmak yerine kullandınız .
Olivier Grégoire

@ OlivierGrégoire Teşekkürler. showVe disposedaha da kısa olanı unuttum setVisible. Java'nın GUI'sini neredeyse hiç kullanmam .. Ana yöntemde kullanmak yerine, sınıf başlatma işlemini kullanmak akıllıca. Bunu hatırlamalıyım.
Kevin Cruijssen

1
@KevinCruijssen Teşekkürler, sorun değil ;-) Bazı genel yorumlar olsa da; harfleri iki kere basmanıza gerek yok. Echoing zaten tarafından sağlandı TextField. Ayrıca, iki bayt kazanmak TextAreayerine kullanabilirsiniz TextField. Son olarak, çağ ile olay arasındaki süreyi milisaniye cinsinden veren KeyEventbir getWhenmetoda sahiptir . Sadece System.nanoTime()daha fazla bayt kazanmak için bunları kullanmanız gerekir .
Olivier Grégoire

1
Rica ederim! Ama 320 bayta daha da indirdim . ;-)
Olivier Grégoire

4

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

İçin +41 bayt using System;using static System.Console.

Mobil olduğum ve bu TIO üzerinde çalışmadığından beri denenmemiş.

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
Test edebilmek için çalışan bir program oluşturmak için +1. Golf oynamak: 1) İstisnayı ortaya çıkardığım kısa bir yol: int x=0;ve sonra yapın x=1/x;. Bu 14 byte tasarruf etmelidir. Maalesef ihtiyacın var x. Yapmaya çalışırsanız sürekli sıfır derleyici hatası ile 1/0bir Division olsun . 2) -5 bayt cilki ile bildirimi birleştirir ReadKey. 3) Değişim iç koşul ifiçin ReadKey!=++cve kaldırma c++;elseiçin başka -9 bayt.
raznagul

@raznagul Teşekkürler! x=1/xazaltılabilir x/=x. using static System.Console;Biraz daha bayt kurtarmayı da ekledim :)
Ian H.

Döngü koşulundaki yerine kaldırarak ive kullanarak cbiraz daha bayt kaydedilebilir .
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 her 20 milisaniyede bir artan bir dahili MSX-BASIC değişkenidir.


3

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

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

Çevrimiçi deneyin!

Maalesef TIO bunu çalıştıramaz, ancak bayt sayısını almak için kullanışlıdır.

İçin +13 using System;

-1 değiştirerek i==123için i>122. Bunu yapmak için cazip oldum i>'z'.

Teşekkür

@Raznagul sayesinde -10 bayt

Ungolfed

()=>{
    var s=DateTime.Now;
    var i=97;

    while(i<123&&Console.ReadKey().KeyChar==i)
        if(i++<98)
            s=DateTime.Now;

    Console.Write(i>122?
        $"\n{(DateTime.Now-s).TotalMilliseconds}":
        "\nFail"
    );
} 

1
Bazı baytları ReadKeydöngü koşuluna getirerek kaydedebilirsiniz , böylece birinci ifve break.
raznagul

3

Node.js, 240 213 bayt

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: Ürdün sayesinde 27 bayt kaydedildi

Ungolfed versiyonu:

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 bayt

* Nix sistemlerinde çalışır. Yeni satırları beklemeden karakterleri okumak için geçerli terminalin kurallı modunu kaldıran bağımsız kod:

/! \ Bu programın çalıştırılması terminali neredeyse kullanılamaz hale getirecek.

#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 ve yorumladı:

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

Alternatif çözüm (218 bayt):

Önceden terminal yapılandırmasına izin verilirse, o zaman kod işleme bölümünden kurtulabiliriz.

İşte terminal manipülasyon olmadan aynı kod:

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

Çalışmasını sağlamak için:

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

çalışma zamanı örneği: görüntü tanımını buraya girin


3

Commodore BASIC v2 - 113 bayt

Büyük harfler değiştirilmelidir.
Bazı yazımcıları işaret ettiği için Felix Palmen'e teşekkürler, özellikler
bunu deniyor

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"

Düzeltilmiş etiketleme kodunu görmek için düzenle'yi tıklayın.
NieDzejkob

Siteye Hoşgeldiniz! Başkalarının kodunuzu test edebilmesi için (varsa) tercümana bir link ekleyebilir misiniz?
caird coinheringaahing

Peki, bu IRQ sistemini kullanıyor ( TIiçinde artış var) Hassas olmamasından dolayı uygun değildi , ancak burada adil bir oyun çünkü sanırım BASIC'te daha iyisini yapmanın bir yolu yok :) Yine de bunu yardımcılığa yapıştırarak alıyorum. bir sözdizimi hatası 1- herhangi bir yardım?
Felix Palmen

Kendim anladım, bir satırda bir yazım hatası var , 1on-(f=26)gO4:gEa$:ifa$=""tH1Nitpicks olmalı : 1.) çıktı aynı satırda, 2.) çıktı her şeyde - sanırım bunları düzeltmelisin, çok bayt almayacaksın Neyse :)
Felix Palmen

Sorunları dile getirdi, yazım hatası kaldı mı?
mondlos

2

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

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

$|=1terminali ham moda ayarlamak yeterli değildir, stty -icanonönce veya önce çalıştırılmalıdır.

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

Komutu çalıştırdıktan sonra terminaldeki karakterleri görmek için: stty echoveyastty echo icanon


İyi yaşlı ReadKey! Burada ve orada birkaç bayt kaydedebilirsiniz, 1e3için 1000, $s||=timeve $sönce ayarlayıp sonra aramayı ReadKeyyaparsanız, mapbir postfix ile değiştirebilirsiniz for. Onun dieyerine söylemek isterim exit print, ama sanırım tam oradasın ... Tinkledim printf"\n%i"ama daha büyük bitti ve $-yerine kullanmayı düşündüm $sama aptalcaydı! :)
Dom Hastings

@DomHastings, yardımınız için teşekkür ederim, 4 bayt kurtarabilirim, ancak arabelleksiz girdi ayarlamak için 5 bayt ekledim $|=1;, ayrıca $ s || = zaman haritayı değiştiremez çünkü zamanlayıcı ilk tuşa basıldıktan sonra başlamalıdır ve stdout yerine stderr üzerinde dieyankısı olur Fail.
Nahuel Fouilleul

Yardımcı olmaktan mutlu, umarım bana fikirler sunarken sakıncası yoktur! Evet, ayıp, exit printçok uzun! Üzgünüm, düşüncelerimi fordoğru şekilde açıkladığımı sanmıyorum : $s||=time,ReadKey eq$_||exit print" Fail"for a..zçalışmalıyım diye düşünüyorum ... Belki de $|=$s||=...ya $|=map...da bu yaklaşımı tercih edersen! Yine de çivilenmiş olduğunu düşünüyorum!
Dom Hastings

$|=map..yeni terminalde arabelleksiz girdi ayarlamıyor (aynı oturumda test ettiğim için ReadMode 3'ü çıkarırken hatam vardı) ve $s||=timeilk önce ReadKey daha önce zamanlayıcıyı çok erken başlatacaktı
Nahuel Fouilleul

Ahh, yanlış anladım, şimdi anlıyorum, bunu kontrol etmek için senaryo yazmaya başladıktan sonra yeterince beklemedim ... :) Utanç $|ver, ama yine de, çok geç olan döngüden sonra saklıyor! Bir adım öndesin!
Dom Hastings

2

Aseto , 70 bayt

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

@|Yığın işaretini ayarlayarak ve yataydaki yansımayı ( ), eğer yığındaki değer gerçeğe uygunsa başlıyorum. Başlangıçta değil ve daha sonra her zaman olacaktır. Yanlış bir tuş girilirse daha sonra buraya geri döneceğiz. Sonra, a ( 'a) yığına a basarız , sonra kopyalarız ve kullanıcıdan ( d,) tek bir karakter okuruz . İki karakter eşit değilse ( =!), "crash" ( $) yaparız ve catch işaretine geri döneriz. Aksi takdirde, bir "a" basar ve basarız, sonra şimdiki zamanı ( 'apT) belirleriz.

Sonra "ana döngü" ye giriyoruz: Geçerli karakteri "artırıyoruz" ve "(") karakterini artırıyoruz " 'apToIc, sonra karakterleri özdeşleştirmiyorsak onu kopyalarız, yeni bir karakter okuruz, karşılaştırırız ve" kilitlenir " ( d,=!$). Eğer çarpışmadıysak, şu anki karakteri "z" ( d'z=|) ile karşılaştırırız, eğer eşit değilse, karakteri basarız, sonra 1'e basarız ve "koşullu" olarak atlarız (bu durumda: her zaman). sadece okodda (ana döngümüzün başlangıcı). Z'ye eşit olsaydı, yatay olarak üstte bir miktar boş alana yansıtırdık. "Z" i basarız, daha sonra şimdiki zamanı (eksi başlangıç ​​zamanı; t) bastırır ve sonra 1000 sayısını (10'u üçüncü güce yükselterek aldığınla) çarparak 91+3Falırız (çünkü saniyeler, milisaniye değil). Sonra yeni bir satır yazdırırız, zaman ve çıkış (pX).

Hiç çarpışmazsak (kullanıcı tarafından hatalı girdi), sonuna kadar atlıyoruz. Yığın üzerinde bir miktar truthy değeri olacağından, üzerine yatay olarak yansıtacağız ki u, içinde hareket ettiğimiz yönü tersine çeviririz . Yeni nbir satır basar, sonra "Fail"yığını bastırır , yazdırır ve çıkar ( pX).


1

Mathematica (not defteri ifadesi), 248 bayt

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

Nasıl çalışır

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

Küçük harfli tuşlara basıldığında cevap veren DynamicModulebir A. EventHandlerDeğişkenler x, sve tsırasıyla, mektuplar, şimdiye kadar başlangıç zamanını preslenmiş tutun ve bitiş zamanı. xEşit olduğumuzu fark {"a"}ettiğimiz anda, zamanı başlatırız; harcanan toplam süreyi veya şu ana kadar oluşturulan dizgiyi veya "Fail"hangi koşulun sağlandığına bağlı olarak görüntüleriz.

Biz başka byte kurtarabilecek t<1ziyade t==0biz kimsenin az bir saniye içinde alfabe yazmak için yeterince hızlı olduğunu varsayabiliriz eğer :)

Bunu bir Mathematica not defterinde deniyorsanız, tuşlara basılmadan önce çerçevenin içine tıklamanız gerektiğini unutmayın. (Bu çerçeveye başlamak için ihtiyacımızın nedeni budur; Framedorada değilse , bir tuşa basıldığında seçilen nesnenin tamamı değişir, bu yüzden seçili durur ve tekrar tıklamanız gerekir.)


1

C #, 154 152 + 13 = 165 bayt

Ayb4btu'nun yorumları sayesinde 2 bayt kaydedildi

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

Yukarıdaki kod SE'ye kaydırma çubuğu olmadan sığdırmak için boşluk bırakıyor. Boşluk, bayt sayımının bir parçası değil

ve 13 bayt using System;

Ayb4btu'nun versiyonuna benziyor ancak aşağıdaki farklılıklar var:

  • Datetime'ı uzun süre saklamak, cuzun sürmemizi ve bildirimi kısaltmamızı sağlar

  • Döngü ayrı bir mola gerektirmez

  • $"interpreted strings"Satır içi için bir dize yapmak için milisaniye üzerine gerekli bir "\ n" eklenmesine karşı kullanmak aslında kısa değil.

  • Bir fordöngü kullanmak bazen karakterleri bir süre saklamamızı sağlar, ancak bunun eşdeğerden tasarruf etmeyeceğini düşünüyorum.while

Ayb4btu'dan:

  • s=s==0olabilir s=s<1ve c==123olabilirc>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");

Nasıl kullandığınızla ilgili güzel bir çözüm DateTime. Daha birkaç kaydetmek değiştirerek bayt olabilir s=s==0için s=s<1(ler negatif olmayacak gerçeğine sayma) ve değişen i==123için i>122.
Ayb4btu

Ayrıca, bu test edildi mi? Bunu buldum gibi i<123önce gitmek zorunda kaldı ReadKey(), aksi takdirde sonra başka karakter için bekler z zaman görüntülemeden önce.
Ayb4btu

Tuhaf, çünkü alfabenin sonunda zreadkey.keychar, z, c aynı zamanda 122 olan kullanıcı tipleri olduğunda 122 döndürür, dolayısıyla 'z' == 122başarılı olur, c artar, sonra c (şimdi 123) test edilir c<123ve durur, durdurulur. döngü ..?
Caius Jard

Haklısın c++, baktığımda artışı kaçırdım . Ancak, sadece denedim ve yazarken abcdefghijklmnopqrstuvwxysbaşarısızlık yerine bana zaman veriyor. Bunun sebebi c, KeyCharkontrolün başarısız olmasına rağmen hala yapılan artışların , dolayısıyla c>122kontrolün geçilmesinden kaynaklandığını düşünüyorum .
Ayb4btu

İyi nokta - belki ++ 'ı c <123 çekine taşımak bayt sayısını aynı tutar ve son karakter yanlışsa c'nin artmasını önler - şu anda hata ayıklamak için zaman yok, ama ben bir göz atacağım! Şerefe :)
Caius Jard

0

Processing.org 133 142

ilk kod çıkmadı

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, pencereler, 98 bayt

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

İlk anahtar için anında giriş yapılmasını gerektirmez

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.