Введіть алфавіт - якнайшвидше!


44

Ваше завдання - скласти програму, яка вимірює, наскільки швидко ви можете набрати літери англійського алфавіту.

  • Програма повинна приймати тільки малі літери aв zв алфавітному порядку.
  • Кожна літера повторюється як введена в одному рядку (без нового рядка або будь-якого іншого роздільника між літерами).
  • Якщо ви введете недійсний символ, програма виведе Fail на новий рядок і вийде.
  • Якщо ви введете всі 26 літер, програма повинна в новому рядку вивести час у мілісекундах, який пройшов від першої до останньої літери, та вийти.
  • Таймер запускається під час введення першої літери a,.

Приклади виходів:

b
Fail

abcdefgg
Fail

abcdefghijklmnopqrstuvwxyz
6440

Це , тому найкоротша відповідь у байтах виграє.


4
Відповідний проект я задовго зробив. (15-й рівень в основному це)
ETHproductions

4
Чи можемо ми вивести Failбез заголовка новий рядок? (наприклад, abdFail\nабо abd Fail\n))
scottinet

1
@scottinet, ні, результат ( Failабо мілісекунди) повинен бути на новому рядку, як у прикладі. Більшість відповідей вже припускають це.
Данько Дурбич

2
-1, оскільки це "нове" правило не було в оригінальній специфікації і визнає недійсними мої пропозиції щодо однієї з відповідей Python, яка була в межах початкових правил.
ElPedro

Я очікував, що це буде найшвидшим завданням друку алфавіту.
Атако

Відповіді:


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

Клацніть на вводі та почніть вводити! Також мій типінг смокче; Я займаю близько 5 секунд навіть на практиці. Редагувати: Збережено 2 байти завдяки @HermanLauenstein шляхом переключення мови. Збережено 3 байти завдяки @ qw3n. Збережено 9 байт завдяки @tsh.


1
-2 байти, використовуючи 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 байт, якщо закриваючий тег не потрібен
Herman L

@HermanLauenstein Замикаючий тег, здається, необхідний для фрагмента, принаймні, тому я залишу його.
Ніл

2
Це занадто гнівно і весело водночас.
Зенон

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

Інтернет демо (Usage:sys49152)

Знімок екрана


Пояснення:

Це була б крихітна програма, якби не проблема точного вимірювання мілісекунд на C64. Переривання системи відбувається приблизно 60 разів за секунду, що навіть не близько. Таким чином, ми повинні використовувати апаратний таймер, який отримує свої вхідні клітинки від системних годин.

На машині PAL системний такт рівно 985248 Гц. Отже, ініціалізація таймера до 985 дає щось близьке до мілісекундних тиків, але це занадто швидко, нам доведеться рахувати 986 циклів за кожну четверту галочку або утримувати таймер протягом одного циклу. Це неможливо, але ми можемо провести таймер на 6 циклів з послідовністю DEC $DD0E, INC $DD0E: $DD0Eце регістр управління таймером з бітом 0 перемикання його включенням і вимиканням, і обидві інструкції приймають 6 циклів, тому точні пише , що зупинка і почати таймер знаходиться рівно на 6 циклів один від одного. Тому ми повинні виконувати цю послідовність кожні 6 * 4 = 24-й галочки. Це все ще не зовсімТочно, таймер відставатиме на 1 мілісекунд через 8 хвилин і 12 секунд, але це, мабуть, досить добре - компенсація за це потребує багато коду.

редагувати : Стартове значення для таймера повинно бути 984, а не 985, оскільки ці таймери спрацьовують "під потоком", тому значення 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
Ну, а тепер у мене в інструментальній панелі є дещо пристойний таймер мілісекунд;) може бути корисним якогось дня.
Фелікс Палмен

11
Зверніть увагу, сценарії дітлахів. Це справжній гольф.
J ...

1
@J ... Я міг би розіграти його далі за допомогою вбудовування .starttimer- зробимо незабаром :) (і навіть далі, використовуючи систему на TIзразок цієї ОСНОВНОЇ відповіді , але я не впевнений, що це дійсно, тому що ви можете зробити краще в машинному коді )
Фелікс Палмен

Нічого собі, я пропустив коефіцієнт 985 під час обчислення помилки в моєму вимірюванні часу спочатку - це насправді дуже добре, як є (якщо я зробив ще одну помилку в своїх розрахунках, будь ласка, вкажіть!) :)
Фелікс Палмен

І чи бачите ви, що цей хлопець має у GITHUB ?: відновлення завантаження андроїд .... він абсолютно божевільний! вибрали його профіль.
Лучано Андресс Мартіні

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

Чи потрібна певна версія bash чи щось таке? 4.4.12 введення тексту aнегайно дає мені line 1: ((: r=15094100773N: value too great for base (error token is "15094100773N")і виходить.
numbermaniac

@numbermaniac Версія Bash не повинна мати значення, але версія могутньої date. Шахта виробляється з основних ядер GNU 8.23. Що date +%s%3Nдрукує у вашій системі?
Денніс

@Dennis він виводить 15094104833N- це вбудована dateутиліта на macOS, якщо це має значення.
numbermaniac

1
@numbermaniac BSD, dateмабуть, використовує стрімкінг, який не розпізнає %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 зможе це зробити ... до речі, це не "Fail" слово у словнику?
Ерік Аутгольфер

@EriktheOutgolfer добре, SOGL повинен був бути універсальною мовою, але це не вийшло: p
dzaima

До речі, я не знаю, чи це цілком справедливо, але я знову думаю, що це може бути проблемою з інтерфейсом, а не інтерпретатором ззаду ...
Erik the Outgolfer

@EriktheOutgolfer Так, я не знаю, наскільки це дійсно, я думаю, чекаю на ОП. Спочатку я думав, що це щось на зразок відповіді HTML, але зараз я зовсім інше, як я дивлюся на це
dzaima

7

Паскаль (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, що працює через TDateTimeописаний тут спосіб кодування Free Pascal .

Примітка:

  • ReadKeyФункція насправді не друкує ключ на консолі, тому потрібно вручну писати на консоль Write(c).
  • TIO отримайте бальну оцінку 0за введення алфавіту з очевидних причин.
  • Програма друкує час у позначеннях з плаваючою комою, я думаю, це дозволено.

Ласкаво просимо на сайт!
caird coinheringaahing

Ви можете зберегти 1 байт, перемістивши в for c:='a'to'z'doтой самий рядок, що і a:=Time;.
Ісмаїл Мігель

Можливо, вам слід спробувати Nowзамість того Time, що це коротше.
tsh

Чому 86398338?? Я можу зрозуміти, чи багато у вас 864e5, оскільки в день є 864e5 мілісекунд. але як приходить це магічне число?
tsh

@tsh я теж не знаю. При ручному тестуванні я буваю знайти , що «магічний» номер, і я не знаю , як Паскаль магазину TDateTimeяк Double. 864e5звучить правильніше, я вирішу проблеми.
користувач75648

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 помилки:
Примітка. Це старий gif. Поточна версія більше не друкує натискання клавіш на консолі.

введіть тут опис зображення


2
вражаюча відповідь, враховуючи, що вона має гуї!
Pureferret

1
388 байт . Я взяв на себе можливість виправити ваш код на додаток до гольфу, тому що ви використовували setVisible(false)замість того, щоб виходити.
Олів’є Грегоар

@ OlivierGrégoire Дякую Забули про showі dispose, що навіть коротше, ніж setVisible. Я майже ніколи не використовую графічний інтерфейс Java .. І розумно використовувати ініціалізацію класів, а не ставити її в основний метод. Я повинен це пам’ятати.
Кевін Кройсейсен

1
@KevinCruijssen Дякую, і немає проблем ;-) Хоча деякі загальні зауваження: листи не потрібно виводити двічі. Відлуння вже надає компанія TextField. Також ви можете використовувати TextAreaзамість того, TextFieldщоб набрати два байти. Нарешті, KeyEventє getWhenметод, який дає час між епохою та подією в мілісекундах. Просто потрібно використовувати ці замість, System.nanoTime()щоб набрати ще більше байтів.
Олів’є Грегоар

1
Ласкаво просимо! Але я знизив її ще до 320 байт . ;-)
Олів’є Грегоар

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з першим ReadKey. 3) Зміна стану у внутрішній , 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>122. Мені спокусилося це зробити i>'z'.

Подяка

-10 байт завдяки @raznagul

Безумовно

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

EDIT: Збережено 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);}

Негольфірованний і прокоментував:

// 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 байт

Великі літери повинні бути зміщені.
Завдяки Феліксу Палмену за вказівку на деякі помилки, спекуляції
спробуйте

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- будь-яка допомога?
Фелікс Палмен

Я розібрався сам, у вас є помилка1on-(f=26)gO4:gEa$:ifa$=""tH1 друку в першому рядку, має бути Nitpicks: 1.) висновок знаходиться в одному рядку, 2.) висновок - це все великі літери - я думаю, ви повинні виправити це, не займе багато байтів так чи інакше :)
Фелікс Палмен

Вирішували питання, залишалися помилки?
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недостатньо для встановлення терміналу в режимі "необроблений", його 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його на постфікс for. Я хотів би сказати dieзамість цього exit print, але я думаю, що ти там ... Я розібрався, printf"\n%i"але це в кінцевому рахунку більше, і я думав про використання $-замість $s, але це було дурним! :)
Дом Гастінгс

@DomHastings, дякую за допомогу, я міг зберегти 4 байти, але я додав 5 байт, щоб встановити незаблокований ввід $|=1;, також $ s || = час не можна замінити карту, оскільки таймер повинен запускатися після першого натискання клавіші, і dieбуде відлунювати Failна stderr замість stdout.
Нахуель Фуле

Раді допомогти, сподіваюся, ви не заперечуєте, пропонуючи ідеї! Так, це соромно, exit printтак довго! До жаль, я не думаю , що я пояснив свою думку для forправильно: $s||=time,ReadKey eq$_||exit print" Fail"for a..zповинні працювати , я думаю , що ... Можливо , навіть , $|=$s||=...чи $|=map...якщо ви віддаєте перевагу такий підхід! Думаю, ти досить сильно прибив це!
Дом Гастінгс

$|=map..не встановлює розблоковане введення в новий термінал (у мене виникла помилка під час видалення ReadMode 3, тому що я тестував на тому ж сеансі), і $s||=timeдо першого ReadKey запустив таймер занадто рано
Nahuel Fouilleul

Ах, я неправильно зрозумів, я розумію, що не чекав досить довго після того, як почав сценарій, щоб перевірити це ... :) Сором $|, але знову ж, він зберігається після циклу, який занадто пізно! Ти на крок попереду!
Дом Гастінгс

2

Ацето , 70 байт

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

Почніть із встановлення позначки лову та дзеркального відображення по горизонталі ( @|), якщо значення на стеку є правдоподібним. Спочатку це не буде, а пізніше завжди буде. Ми підемо сюди пізніше, якщо введено неправильний ключ. Далі ми натискаємо на стек ( 'a), потім копіюємо його і читаємо з користувача ( d,) один символ . Якщо два символи не рівні ( =!), ми "збоїмо" ( $) і відскакуємо назад до позначки лову. В іншому випадку ми натискаємо інше «а» і друкуємо його, після чого встановлюємо поточний час ( 'apT).

Потім ми входимо в наш "основний цикл": ми "збільшуємо" поточний символ і "збільшуємо" персонаж ( 'apToIc), потім копіюємо його, читаємо новий символ, порівнюємо його і "руйнуємося", якщо символи не однакові ( d,=!$). Якщо ми не вийшли з ладу, ми порівнюємо поточний символ із "z" ( d'z=|), якщо він не дорівнює, друкуємо символ, потім натискаємо 1 і стрибаємо "умовно" (у цьому випадку: завжди) на лише oв коді (початок нашого основного циклу). Якщо вона дорівнювала z, ми відбивались горизонтально до порожнього простору вгорі. Ми друкуємо "z", потім натискаємо на поточний час (мінус початковий час; t), а потім множимо число 1000 (отримане, піднімаючи 10 на третю потужність; 91+3F) на нього (бо ми отримуємо секунди, не мілісекунд). Потім друкуємо новий рядок, час та вихід (pX).

Якщо ми колись вийдемо з ладу (поганий вклад користувача), ми перестрибуємо все до початку. Оскільки тепер у нас буде мати деяке значення truthy на стеку, ми будемо відображати горизонтально на те u, що повертає напрямок, у якому ми рухаємося. nДрукує символ нового рядка, потім натискаємо "Fail"на стек, друкуємо його та виходимо ( pX).


1

Математика (вираз із зошита), 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[]}]]]

А 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циклу іноді дозволяє нам зберігати символи протягом певного часу, хоча, я думаю, цей не економив би більше, ніж еквівалентwhile

Від Ayb4btu:

  • s=s==0може стати s=s<1, і c==123може статиc>122

Безумовно

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.
Айб4бту

Також це перевірено? Як я виявив, що i<123треба було пройти перед ReadKey()символом, інакше він чекає іншого символу після z, перш ніж відобразити час.
Айб4бту

Як не дивно, тому що в кінці алфавіту zслід означати readkey.keychar, що повертає 122, коли користувач вводить z, c також 122, отже, це 'z' == 122досягає успіху, c потім збільшується, тоді c (зараз 123) перевіряється c<123і не працює, зупиняючи петля ..?
Caius Jard

Ти маєш рацію, я пропустив c++приріст, коли дивився на це. Однак я просто спробував це, і коли я набираю, abcdefghijklmnopqrstuvwxysце дає мені час, а не збій. Я вважаю, що це cвсе-таки збільшується, навіть якщо KeyCharчек не працює, тому передаючи c>122чек.
Айб4бту

Хороший момент - можливо, переміщення ++ на с <123 перевірятиме збереження обліку рахунків однаковим і запобігає збільшенню 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);}

Не потрібно миттєвого введення для першого ключа

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.