พิมพ์ตัวอักษร - เร็วที่สุดเท่าที่จะทำได้!


44

งานของคุณคือการสร้างโปรแกรมที่วัดความเร็วที่คุณสามารถพิมพ์ตัวอักษรของตัวอักษรภาษาอังกฤษ

  • โปรแกรมที่จะยอมรับเฉพาะอักษรตัวพิมพ์เล็กaไปzตามลำดับตัวอักษร
  • ตัวอักษรแต่ละตัวถูก echoed ตามที่พิมพ์ในบรรทัดเดียวกัน (ไม่มีบรรทัดใหม่หรือตัวคั่นอื่นใดระหว่างตัวอักษร)
  • หากคุณพิมพ์อักขระที่ไม่ถูกต้องโปรแกรมจะแสดงผลFail บนบรรทัดใหม่และออก
  • หากคุณพิมพ์ตัวอักษรทั้งหมด 26 ตัวโปรแกรมจะขึ้นบรรทัดใหม่เอาท์พุทเวลาเป็นมิลลิวินาทีที่ใช้ตั้งแต่อักษรตัวแรกถึงตัวอักษรสุดท้ายและออก
  • aจับเวลาเริ่มต้นเมื่อคุณพิมพ์อักษรตัวแรก

ตัวอย่างผลลัพธ์:

b
Fail

abcdefgg
Fail

abcdefghijklmnopqrstuvwxyz
6440

นี่คือดังนั้นคำตอบที่สั้นที่สุดในจำนวนไบต์ชนะ


4
โครงการที่เกี่ยวข้องฉันทำในขณะที่กลับ (ระดับ 15 เป็นพื้นฐานนี้)
ETHproductions

4
เราสามารถส่งออกได้Failโดยไม่ต้องขึ้นบรรทัดใหม่ของหัวเรื่องหรือไม่ (เช่นabdFail\nหรือabd Fail\n))
scottinet

1
@scottinet ไม่ผลลัพธ์ ( Failหรือมิลลิวินาที) จะต้องอยู่ในบรรทัดใหม่เช่นในตัวอย่าง คำตอบส่วนใหญ่จะถือว่าสิ่งนี้อยู่แล้ว
Danko Durbić

2
-1 เนื่องจากกฎ "ใหม่" นี้ไม่ได้อยู่ในข้อกำหนดดั้งเดิมและทำให้คำแนะนำของฉันใน Python เป็นหนึ่งในคำตอบที่อยู่ภายในกฎเดิม
ElPedro

ฉันคาดหวังว่านี่จะเป็นความท้าทายที่เร็วที่สุดในการพิมพ์ตัวอักษร
ATaco

คำตอบ:


40

HTML (JavaScript (ES6)), 129 126 117 ไบต์

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

คลิกที่อินพุตและเริ่มพิมพ์! นอกจากนี้ฉันพิมพ์ sucks; ฉันใช้เวลาประมาณ 5 วินาทีแม้จะฝึกซ้อม แก้ไข: บันทึก 2 ไบต์ขอบคุณ @HermanLauenstein โดยการเปลี่ยนภาษา บันทึกแล้ว 3 ไบต์ด้วย @ qw3n บันทึกแล้ว 9 ไบต์ขอบคุณ @tsh


1
-2 bytes โดยใช้ html ที่มีแท็กสคริปต์: <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 bytes หากไม่จำเป็นต้องใช้ tag tag
Herman L

@HermanLauenstein แท็กปิดน่าจะเป็นสิ่งที่จำเป็นสำหรับข้อมูลโค้ดอย่างน้อยดังนั้นฉันจะทิ้งไว้ใน.
นีล

2
นี่มันโมโหและสนุกเกินไปในเวลาเดียวกัน
Zenon

1
สิ่งที่เกี่ยวกับการใส่เหตุการณ์ในการป้อนข้อมูล? <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
ไม่แสดงข้อความในบรรทัดใหม่
dkudriavtsev

33

รหัสเครื่อง 6502 (C64 PAL), 189 165 ไบต์

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 ไบต์โดยการขีดเส้นหน้าที่และไม่สนใจ CIA2 อินเตอร์รัปต์อื่น ๆ

สาธิตออนไลน์ (การใช้งาน:sys49152)

ภาพหน้าจอ


คำอธิบาย:

นี่จะเป็นโปรแกรมเล็ก ๆ หากไม่ได้มีปัญหาสำหรับการวัดค่าที่แน่นอนของมิลลิวินาทีใน C64 ระบบขัดจังหวะเกิดขึ้นประมาณ 60 ครั้งต่อวินาทีซึ่งไม่ได้ปิด ดังนั้นเราต้องใช้ตัวจับเวลาฮาร์ดแวร์ที่นี่เพื่อรับสัญญาณอินพุตจากนาฬิกาของระบบ

บนเครื่อง PAL นาฬิการะบบคือ 985248 Hz การเริ่มต้นตัวจับเวลาเป็น 985 จึงให้บางสิ่งบางอย่างใกล้เคียงกับติ๊กมิลลิวินาที แต่มันเร็วเกินไปเราจะต้องนับ 986 รอบสำหรับทุก ๆ รอบที่สี่หรือถือตัวจับเวลาสำหรับรอบเดียว นี้เป็นไปไม่ได้ แต่เราสามารถถือจับเวลาสำหรับ 6 รอบกับลำดับDEC $DD0E, INC $DD0E: $DD0Eคือการลงทะเบียนการควบคุมการจับเวลาด้วยบิต 0 เปลี่ยนมันในและนอกและคำแนะนำการใช้ทั้ง 6 รอบเพื่อให้การเขียนที่แน่นอนที่หยุดและเริ่มต้น ตัวจับเวลาอยู่ห่างกัน 6 รอบ ดังนั้นเราต้องดำเนินการตามลำดับทุก 6 * 4 = 24 ติ๊ก สิ่งนี้ยังไม่แน่นอนถูกต้องตัวจับเวลาจะล่าช้า 1 มิลลิวินาทีหลัง 8 นาทีและ 12 วินาที แต่มันอาจจะดีพอ - การชดเชยสำหรับรหัสนั้นจะใช้รหัสจำนวนมาก

แก้ไข : ค่าเริ่มต้นสำหรับตัวจับเวลาจะต้องเป็น 984 ไม่ใช่ 985 เนื่องจากตัวจับเวลาเหล่านี้ใช้งาน "on underflow" ดังนั้นค่า 0 จะนับหนึ่งรอบเพิ่มเติมก่อนการยิง รหัสคงที่นับไบต์ไม่เปลี่ยนแปลง

นี่คือรายการถอดแยกชิ้นส่วนที่แสดงความคิดเห็น:

         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
ตอนนี้ฉันมีตัวจับเวลามิลลิวินาทีที่ค่อนข้างดีในกล่องเครื่องมือของฉัน;) อาจมีประโยชน์ในบางวัน
Felix Palmen

11
ใส่ใจ kiddies สคริปต์ นี่คือสนามกอล์ฟจริง
เจ ...

1
@J ... ฉันสามารถเล่นกอล์ฟต่อไปได้โดยการทำอินไลน์.starttimer- จะทำในเร็ว ๆ นี้ :) (และยิ่งกว่านั้นโดยใช้ระบบTIเช่นคำตอบพื้นฐานนี้แต่ฉันไม่แน่ใจว่ามันถูกต้องเพราะคุณสามารถทำได้ดีกว่าในรหัสเครื่อง )
Felix Palmen

ว้าวฉันพลาดปัจจัยที่ 985 เมื่อคำนวณข้อผิดพลาดในการวัดเวลาของฉันก่อน - มันค่อนข้างดีในแบบที่มันเป็น (ถ้าฉันทำผิดพลาดอีกครั้งในการคำนวณของฉันโปรดชี้ให้เห็น!) :)
Felix Palmen

และคุณเห็นสิ่งที่ผู้ชายคนนี้มีใน GITHUB หรือไม่: การกู้คืนการบูต android .... เขาเป็นบ้าอย่างสมบูรณ์! ชื่นชอบโปรไฟล์ของเขา
Luciano Andress Martini

13

Bash + coreutils, 103 99 98 ไบต์

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"

ต้องทำงานในเทอร์มินัล

ทดสอบการทำงาน

$ bash type.sh
abcdefghijklmnopqrstuvwxyz
3479
$ bash type.sh
abcz
Fail
$ bash type.sh 2>&- # typing '@' would print to STDERR
ab@
Fail
$ bash type.sh
A
Fail

4
3479ค่อนข้างเร็ว! ทำได้ดีมาก :)
RobAu

มีรุ่นทุบตีที่ต้องการหรือบางอย่าง? ใน 4.4.12 การพิมพ์aจะให้ฉันทันทีline 1: ((: r=15094100773N: value too great for base (error token is "15094100773N")และออก
numbermaniac

@numbermaniac เวอร์ชันของ Bash ไม่ควรสำคัญ แต่อย่างใดอย่างหนึ่งdateอาจ ของฉันมาจาก GNU coreutils 8.23 สิ่งที่date +%s%3Nพิมพ์บนระบบของคุณ?
Dennis

@Dennis it เอาท์พุท15094104833N- นี่คือdateยูทิลิตี้ในตัวบน macOS ถ้ามันสร้างความแตกต่าง
numbermaniac

1
@numbermaniac ของ BSD dateดูเหมือนว่าจะใช้ strftime %Nซึ่งไม่รู้จัก
เดนนิส

9

Python 2 + getch , 116 ไบต์

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

ขอบคุณ ovs และ ElPedro สำหรับการแก้ไขรหัสและบันทึก 57 ไบต์


7

SOGL V0.12 , 35 ไบต์

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

ลองที่นี่! - คลิกเรียกใช้แล้วป้อนตัวอักษรในช่องป้อนข้อมูล โปรดทราบว่าอาจมีความล่าช้าเล็กน้อยเนื่องจาก SOGL จะหยุดชั่วคราวเฉพาะสำหรับโทเค็นที่ดำเนินการ 100 รายการเท่านั้น (และ SOGL ค่อนข้างช้า) หากสิ่งนั้นรบกวนจิตใจคุณให้รันsleepBI=trueในคอนโซล

หมายเหตุ:อย่ารันสิ่งนี้ในโหมดความเข้ากันได้มันจะวนซ้ำตลอดไป

คำอธิบาย:

"ζ¦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 ฉันรู้ว่ามันจะมีประโยชน์: p
dzaima

ใครจะคาดหวังว่า SOGL จะสามารถทำเช่นนั้น ... โดยวิธีการที่ "ไม่" คำในพจนานุกรม?
Erik the Outgolfer

@EriktheOutgolfer ได้ดี SOGL น่าจะเป็นภาษาเอนกประสงค์ แต่นั่นก็ไม่ได้ผล: p
dzaima

BTW ฉันไม่รู้ว่านี่ถูกต้องสมบูรณ์หรือไม่ แต่จากนั้นอีกครั้งฉันคิดว่านั่นอาจเป็นปัญหากับส่วนต่อประสานและไม่ใช่ล่ามที่อยู่เบื้องหลัง ...
Erik the Outgolfer

@EriktheOutgolfer ใช่ฉันไม่ทราบว่าถูกต้องหรือไม่ฉันเดาว่าฉันรอ OP ตอนแรกฉันคิดว่านี่เป็นคำตอบ HTML แต่ตอนนี้ฉันดูแตกต่างกันมาก
dzaima

7

Pascal (FPC) , 176 ไบต์

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.

ลองออนไลน์!

เทคนิคบางอย่างที่ใช้ในรหัสสำหรับการเล่นกอล์ฟ:

  • ใช้Realเป็นทางเลือกที่สั้นลงTDateTimeเพราะตามที่กำหนดไว้ที่นี่ , TDateTime= Doubleซึ่งเป็นชนิดจุดลอยตัว
  • แทนการใช้MilliSecondsBetweenสำหรับการคำนวณช่องว่างเวลารหัสนี้คูณความแตกต่างระหว่างสองค่าจุดลอยตัวจาก864e5ที่ทำงานเพราะวิธีที่ฟรี Pascal เข้ารหัสTDateTimeที่อธิบายไว้ที่นี่

บันทึก:

  • ReadKeyฟังก์ชั่นไม่ได้พิมพ์คีย์บนคอนโซลดังนั้นWrite(c)จำเป็นต้องเขียนด้วยตนเองลงบนคอนโซลด้วย
  • TIO ได้คะแนนใกล้เคียง0สำหรับการพิมพ์ตัวอักษรด้วยเหตุผลที่ชัดเจน
  • โปรแกรมพิมพ์เวลาในรูปแบบทศนิยมฉันคิดว่ามันใช้ได้

ยินดีต้อนรับสู่เว็บไซต์!
caird coinheringaahing

คุณสามารถบันทึก 1 ไบต์โดยการย้ายไปยังบรรทัดเดียวกับfor c:='a'to'z'do a:=Time;
Ismael Miguel

บางทีคุณควรลองNowแทนที่จะTimeเป็นแบบสั้น
tsh

ทำไม86398338?? ฉันสามารถเข้าใจได้ว่าคุณหลาย ๆ 864e5 เพราะมี 864e5 มิลลิวินาทีในหนึ่งวัน แต่จำนวนเวทมนตร์นี้มาได้อย่างไร
tsh

@tsh ฉันไม่รู้เหมือนกัน โดยการทดสอบด้วยตนเองฉันเกิดขึ้นจะพบว่าจำนวน "วิเศษ" และผมไม่ทราบว่าร้านวิธีปาสคาลเป็นTDateTime ฟังดูถูกต้องกว่านี้ฉันจะแก้ไขปัญหา Double864e5
user75648

5

Java, 404 388 354 348 320 318 ไบต์

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

และที่นี่ผมคิดว่า Java คอนโซลที่มีอยู่แล้วอย่างละเอียด ..
ตั้งแต่ Java มีวิธีที่จะดิบฟังคีย์กดในคอนโซล AFAIK ผมใช้ GUI java.awtด้วย

-78 ไบต์ขอบคุณที่@ OlivierGrégoire

คำอธิบาย:

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

ตัวอย่าง gif ของความสำเร็จ: (ใช่ฉันพิมพ์ตัวอักษรค่อนข้างช้าที่นี่ .. )
หมายเหตุ: นี่คือ gif เก่า เวอร์ชันปัจจุบันไม่พิมพ์กดปุ่มบนคอนโซลอีกต่อไป และมันจะไม่พิมพ์เวลาด้วยตัวเลขหลังจุดทศนิยม

ป้อนคำอธิบายรูปภาพที่นี่
ตัวอย่าง gif of fail:
หมายเหตุ: นี่คือ gif เก่า เวอร์ชันปัจจุบันไม่พิมพ์กดปุ่มบนคอนโซลอีกต่อไป

ป้อนคำอธิบายรูปภาพที่นี่


2
คำตอบที่น่าประทับใจพิจารณาว่ามีกุย!
Pureferret

1
388 ไบต์ ฉันเอาเสรีภาพในการแก้ไขรหัสของคุณนอกเหนือไปจากการเล่นกอล์ฟเพราะคุณใช้setVisible(false)แทนการออก
Olivier Grégoire

@ OlivierGrégoireขอบคุณ ลืมเกี่ยวกับshowและซึ่งแม้จะสั้นกว่าdispose setVisibleฉันแทบไม่เคยใช้ GUI ของ Java .. และฉลาดในการใช้การกำหนดคลาสแทนการใช้ในวิธีหลัก ฉันควรจำไว้ว่า
Kevin Cruijssen

1
@KevinCruijssen ขอบคุณและไม่มีปัญหา ;-) แม้ว่าจะมีความคิดเห็นทั่วไปเพิ่มเติม: คุณไม่จำเป็นต้องพิมพ์ตัวอักษรสองครั้ง TextFieldสะท้อนให้บริการแล้วโดย นอกจากนี้คุณสามารถใช้TextAreaแทนTextFieldรับสองไบต์ ในที่สุดก็KeyEventมีgetWhenวิธีที่ให้เวลาระหว่างยุคและเหตุการณ์เป็นมิลลิวินาที เพียงแค่ต้องใช้สิ่งเหล่านั้นแทนที่จะSystem.nanoTime()ได้จำนวนไบต์เพิ่มขึ้น
Olivier Grégoire

1
ยินดีต้อนรับคุณ! แต่เมื่อผมได้มันลงต่อไป320 ไบต์ ;-)
Olivier Grégoire

4

C # (.NET Core), 245 + 13 183 + 41 177 + 41 ไบต์

41 using System;using static System.Consoleไบต์

ยังไม่ทดลองตั้งแต่ฉันอยู่บนมือถือและนี่ไม่ได้ทำงานบน 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 สำหรับการสร้างโปรแกรมที่ใช้งานได้โดยไม่สามารถทดสอบได้ กอล์ฟ: 1) วิธีการหนึ่งที่สั้นกว่าที่ฉันได้พบในการผลิตยกเว้น: แล้วทำint x=0; x=1/x;สิ่งนี้ควรบันทึก 14 ไบต์ xแต่น่าเสียดายที่คุณต้องการ หากคุณพยายามที่จะทำให้1/0คุณได้รับข้อผิดพลาดหารด้วยศูนย์คงที่เรียบเรียง 2) -5 ไบต์สำหรับการรวมประกาศของกับครั้งแรกc ReadKey3) เปลี่ยนเงื่อนไขในส่วนภายในifเป็นReadKey!=++cและลบส่วนc++;elseอีก -9 ไบต์
raznagul

@raznagul ขอบคุณ! x=1/xสามารถลดลงx/=xได้ และฉันเพิ่มusing static System.Console;การบันทึกบางไบต์ :)
เอียนเอช

สามารถบันทึกไบต์จำนวนมากขึ้นได้โดยการลบiและใช้งานcในสภาพลูปแทน
raznagul

3

MSX-BASIC, 126 ตัวอักษร

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

TIME เป็นตัวแปร MSX-BASIC ภายในที่เพิ่มขึ้นทุก ๆ 20 มิลลิวินาที


3

C # (. NET Core) , 184 + 13 = 197 173 + 13 = 186 ไบต์

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

ลองออนไลน์!

น่าเสียดายที่ TIO ไม่สามารถเรียกใช้สิ่งนี้ได้ แต่มีประโยชน์ในการนับจำนวนไบต์

+13 สำหรับ using System;

-1 โดยการเปลี่ยนไปi==123 ฉันถูกล่อลวงเพื่อให้นี้i>122i>'z'

กิตติกรรมประกาศ

-10 ไบต์ขอบคุณ @raznagul

Ungolfed

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

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

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

1
คุณสามารถบันทึกไบต์บางส่วนโดยการย้ายReadKeyไปอยู่ในสภาพห่วงเพื่อให้คุณสามารถลบครั้งแรกและif break
raznagul

3

Node.js, 240 213 ไบต์

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)

แก้ไข: บันทึกแล้ว 27 ไบต์ขอบคุณจอร์แดน

เวอร์ชันที่ไม่ถูกปรับแต่ง:

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 ไบต์

ทำงานบนระบบ * nix รหัสแบบสแตนด์อโลนจะลบโหมดบัญญัติของเทอร์มินัลปัจจุบันเพื่ออนุญาตให้อ่านอักขระโดยไม่ต้องขึ้นบรรทัดใหม่:

/! \ การรันโปรแกรมนี้จะทำให้เทอร์มินัลใช้งานไม่ได้เกือบ

#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 และแสดงความคิดเห็น:

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

ทางเลือกอื่น ๆ (218 ไบต์):

หากการกำหนดค่าเครื่องล่วงหน้าได้รับอนุญาตเราสามารถกำจัดส่วนของการจัดการรหัสในส่วนนั้นได้

นี่คือรหัสเดียวกันโดยไม่มีการจัดการเทอร์มินัล:

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

เพื่อให้มันทำงาน:

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

ตัวอย่างรันไทม์: ป้อนคำอธิบายรูปภาพที่นี่


3

Commodore BASIC v2 - 113 bytes

ต้องเลื่อนตัวพิมพ์ใหญ่
ต้องขอบคุณเฟลิกซ์พาล์เมนที่ชี้ให้เห็นความผิดพลาดบางอย่างรายละเอียด
ลองใช้ดู

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"

คลิกแก้ไขเพื่อดูรหัสการแก้ไขที่ถูกต้อง
NieDzejkob

ยินดีต้อนรับสู่เว็บไซต์! คุณสามารถเพิ่มลิงค์ไปยังล่าม (ถ้ามี) เพื่อให้คนอื่นสามารถทดสอบรหัสของคุณได้หรือไม่
caird coinheringaahing

ทีนี้นี่ใช้ระบบ IRQ ( TIเพิ่มมากขึ้น) ฉันคิดว่ามันไม่เหมาะสมสำหรับการขาดความแม่นยำ แต่ฉันคิดว่ามันเป็นเกมที่ยุติธรรมเพราะที่นี่ไม่มีวิธีที่จะทำได้ดีกว่าใน BASIC :) ยังคงวางสิ่งนี้ไว้ในรอง ข้อผิดพลาดทางไวยากรณ์ใน1- ความช่วยเหลือใด ๆ
เฟลิกซ์ Palmen

คุณคิดว่าคุณพิมพ์ผิดในบรรทัดที่หนึ่งควรเป็น1on-(f=26)gO4:gEa$:ifa$=""tH1Nitpicks: 1. ) เอาท์พุทอยู่ในบรรทัดเดียวกัน 2. ) เอาท์พุทเป็นตัวพิมพ์ใหญ่ - ฉันคิดว่าคุณควรแก้ไขสิ่งเหล่านั้นไม่ต้องใช้ไบต์จำนวนมาก anyways :)
เฟลิกซ์ Palmen

ปัญหานี้ยังคงอยู่ใช่หรือไม่?
mondlos

2

Perl 5, 79 93 +31 (-MTerm :: ReadKey -MTime :: HiRes = เวลา) ไบต์

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

$|=1ไม่เพียงพอสำหรับการตั้งค่าเทอร์มินัลในโหมด raw stty -icanonควรรันก่อนหรือ

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

เพื่อดูอักขระในเทอร์มินัลหลังจากเรียกใช้คำสั่ง: stty echoหรือstty echo icanon


ดีมากReadKey! คุณสามารถบันทึกไม่กี่ไบต์ที่นี่และมี1e3สำหรับ1000, $s||=timeและถ้าคุณตั้งค่า$sแรกแล้วโทรReadKeyคุณสามารถสลับออกmapไป forpostfix ฉันอยากจะพูดdieแทนexit printแต่ฉันคิดว่าคุณอยู่ที่นั่น ... ฉันซ่อมด้วยprintf"\n%i"แต่มันก็ใหญ่ขึ้นและฉันคิดว่าจะใช้$-แทน$sแต่นั่นมันโง่! :)
Dom Hastings

@ DomHastings ขอขอบคุณสำหรับความช่วยเหลือของคุณฉันสามารถบันทึก 4 ไบต์ แต่ฉันได้เพิ่ม 5 ไบต์เพื่อตั้งค่าอินพุตที่ไม่มีบัฟเฟอร์$|=1;และ $ s || = เวลาไม่สามารถสลับแผนที่ได้เนื่องจากตัวจับเวลาต้องเริ่มต้นหลังจากกดปุ่มแรกและdieจะสะท้อนFailกับ stderr แทนที่จะเป็น stdout
Nahuel Fouilleul

มีความสุขที่ได้ช่วยหวังว่าคุณจะไม่รังเกียจที่จะเสนอแนวคิด! ใช่มันเป็นความอัปยศexit printนานมาก! ขออภัยฉันไม่คิดว่าฉันอธิบายความคิดของฉันforอย่างถูกต้อง: $s||=time,ReadKey eq$_||exit print" Fail"for a..zควรทำงานฉันคิดว่า ... อาจจะถึง$|=$s||=...หรือ$|=map...ถ้าคุณชอบวิธีการแบบนั้น! คิดว่าคุณน่ารักมาก ๆ เลย!
Dom Hastings

$|=map..ไม่ได้ตั้งค่าอินพุตที่ไม่มีบัฟเฟอร์ในเทอร์มินัลใหม่ (ฉันมีข้อผิดพลาดเมื่อลบออก ReadMode 3 เพราะฉันกำลังทดสอบในเซสชั่นเดียวกัน) และ$s||=timeก่อนที่ ReadKey แรกจะเริ่มจับเวลาเร็วเกินไป
Nahuel Fouilleul

อ่าฉันเข้าใจผิดฉันเข้าใจแล้วตอนนี้ไม่รอนานพอหลังจากเริ่มเขียนสคริปต์เพื่อตรวจสอบว่า ... :) อับอาย$|แต่อีกครั้งมันจัดเก็บหลังจากวนรอบซึ่งสายเกินไป! คุณกำลังก้าวไปหนึ่งก้าว!
Dom Hastings

2

Aceto , 70 ไบต์

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

ฉันเริ่มต้นด้วยการตั้งค่า catch catch และ mirroring ในแนวนอน ( @|) ถ้าค่าใน stack เป็นจริง มันไม่ได้เริ่มต้นและในภายหลังจะเป็น เราจะกระโดดกลับมาที่นี่ในภายหลังหากป้อนรหัสผิด ต่อไปเรากด a บนสแต็ก ( 'a) จากนั้นเราทำสำเนาและอ่านอักขระหนึ่งตัวจากผู้ใช้ ( d,) หากตัวละครทั้งสองไม่เท่ากัน ( =!) เรา "ผิดพลาด" ( $) และกระโดดกลับไปที่เครื่องหมายจับ มิฉะนั้นเราจะกด "a" อีกอันแล้วพิมพ์มันจากนั้นเราจะตั้งค่าเวลาปัจจุบัน ( 'apT)

จากนั้นเราป้อน "วงหลัก" ของเรา: เรา "เพิ่ม" ตัวละครปัจจุบันและ "เพิ่ม" ตัวละคร ( 'apToIc) จากนั้นเราทำซ้ำอ่านตัวอักษรใหม่เปรียบเทียบมันและ "ผิดพลาด" ถ้าตัวละครไม่เหมือนกัน ( d,=!$) หากเราไม่ผิดพลาดเราเปรียบเทียบอักขระปัจจุบันกับ "z" ( d'z=|) หากไม่เท่ากันเราพิมพ์อักขระจากนั้นเรากด 1 และกระโดด "ตามเงื่อนไข" (ในกรณีนี้: เสมอ) กับ เฉพาะoในรหัส (จุดเริ่มต้นของวงหลักของเรา) ถ้ามันเท่ากับ z เราจะสะท้อนในแนวนอนไปยังพื้นที่ว่างด้านบน เราพิมพ์ "z" จากนั้นกดเวลาปัจจุบัน (ลบด้วยเวลาเริ่มต้นt) และจากนั้นคูณจำนวน 1000 (รับโดยการเพิ่ม 10 เป็นกำลังสาม; 91+3F) โดยมัน (เพราะเราได้รับวินาที ไม่มิลลิวินาที) จากนั้นเราจะพิมพ์บรรทัดใหม่เวลาและทางออก (pX)

หากเรามีข้อผิดพลาด (อินพุตไม่ถูกต้องจากผู้ใช้) เราจะข้ามไปยังจุดเริ่มต้น เนื่องจากตอนนี้เราจะมีค่าความจริงบางอย่างบนสแต็กเราจะทำการสะท้อนในแนวนอนuซึ่งกลับทิศทางที่เราย้ายเข้าnพิมพ์อักขระบรรทัดใหม่จากนั้นเรากด"Fail"ลงบนสแต็กพิมพ์และออก ( pX)


1

Mathematica (การแสดงออกของโน้ตบุ๊ค), 248 ไบต์

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

มันทำงานอย่างไร

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 DynamicModuleพร้อมกับEventHandlerที่ตอบสนองต่อการกดอักษรตัวพิมพ์เล็ก ตัวแปรx, sและtถือตัวอักษรกดเพื่อให้ห่างไกลเวลาเริ่มต้นและสิ้นสุดเวลาตามลำดับ ทันทีที่เราสังเกตเห็นxว่าเท่ากับ{"a"}เราเริ่มเวลา เราแสดงทั้งเวลาที่ใช้ทั้งหมดหรือสตริงที่สร้างขึ้นจนถึงหรือ"Fail"ขึ้นอยู่กับเงื่อนไขที่พบ

เราสามารถบันทึกไบต์อื่นด้วยt<1แทนที่จะt==0คิดว่าไม่มีใครเร็วพอที่จะพิมพ์ตัวอักษรในเวลาไม่ถึงหนึ่งวินาที :)

หากคุณกำลังทดลองใช้งานในสมุดบันทึก Mathematica โปรดจำไว้ว่าคุณต้องคลิกภายในเฟรมก่อนที่การกดคีย์ของคุณจะถูกลงทะเบียน (นี่คือเหตุผลที่เราต้องการให้เฟรมเริ่มต้นด้วยหากFramedไม่มีอยู่วัตถุทั้งหมดจะถูกเลือกเมื่อมีการกดปุ่มดังนั้นมันจะหยุดเลือกและคุณจะต้องคลิกอีกครั้ง)


1

C #, 154 152 + 13 = 165 ไบต์

บันทึก 2 ไบต์ต้องขอบคุณความคิดเห็นของ 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");
}

รหัสด้านบนมีช่องว่างเพื่อให้พอดีกับ SE โดยไม่มีแถบเลื่อน ช่องว่างไม่ได้เป็นส่วนหนึ่งของจำนวนไบต์

และ 13 ไบต์สำหรับ using System;

มันคล้ายกับเวอร์ชั่นของ Ayb4btu แต่มีความแตกต่างดังต่อไปนี้:

  • การจัดเก็บข้อมูลอายุการใช้งานที่ยาวนานช่วยให้เราสามารถสร้างcความยาวได้และตัดการประกาศให้สั้นลง

  • การวนซ้ำไม่จำเป็นต้องมีการหยุดพักแยกต่างหาก

  • จริง ๆ แล้วมันไม่สั้นกว่าที่จะใช้$"interpreted strings"เมื่อเทียบกับการเพิ่ม "\ n" ที่จำเป็นลงในมิลลิวินาทีเพื่อให้เป็นสตริงสำหรับอินไลน์ถ้า

  • forบางครั้งการใช้การวนซ้ำช่วยให้เราประหยัด chars ได้สักพักหนึ่ง แต่ฉันคิดว่าอันนี้คงไม่ช่วยอะไรได้เทียบเท่าwhile

จาก Ayb4btu:

  • s=s==0สามารถเป็นs=s<1และc==123สามารถเป็นc>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");

DateTimeวิธีการแก้ปัญหาที่ดีกับวิธีการที่คุณใช้ คุณสามารถบันทึกคู่มากขึ้นไบต์โดยการเปลี่ยนs=s==0ไปs=s<1(นับความจริงที่ว่า s จะไม่ลบ) และการเปลี่ยนแปลงไปi==123 i>122
Ayb4btu

นอกจากนี้สิ่งนี้ได้รับการทดสอบแล้ว? ตามที่ฉันพบว่าi<123ต้องไปก่อนReadKey()มิฉะนั้นจะรออักขระอื่นหลังจากzก่อนแสดงเวลา
Ayb4btu

แปลกเพราะในตอนท้ายของตัวอักษรzควรหมายถึง readkey.keychar ส่งคืน 122 เมื่อผู้ใช้ประเภท z, c ยังเป็น 122 ดังนั้นจึง'z' == 122ประสบความสำเร็จ, c จะเพิ่มขึ้นแล้วจากนั้น c (ตอนนี้ 123) จะถูกทดสอบc<123และล้มเหลวหยุด ห่วง ..
Caius Jard

คุณพูดถูกฉันพลาดส่วนที่c++เพิ่มขึ้นเมื่อฉันมองมัน อย่างไรก็ตามฉันเพิ่งลองและเมื่อฉันพิมพ์abcdefghijklmnopqrstuvwxysมันจะให้เวลาฉันแทนที่จะล้มเหลว ฉันเชื่อว่าเป็นเพราะcยังคงเพิ่มขึ้นแม้ว่าการKeyCharตรวจสอบล้มเหลวดังนั้นผ่านการc>122ตรวจสอบ
Ayb4btu

จุดดี - บางทีการย้าย ++ ไปที่การตรวจสอบ c <123 จะทำให้ bytecount เหมือนเดิมและป้องกันการเพิ่มค่า c หากตัวอักษรตัวสุดท้ายผิด - ไม่มีเวลาที่จะดีบั๊กตอนนี้ แต่ฉันจะดูมัน! ไชโย :)
Caius Jard

0

Processing.org 133 142

รหัสแรกไม่ได้ออก

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 ไบต์

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

ไม่จำเป็นต้องใส่รหัสแรกทันที

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.