Twoim zadaniem jest stworzenie programu, który mierzy szybkość wpisywania liter alfabetu angielskiego.
- Program przyjmuje tylko małe litery
a
toz
w kolejności alfabetycznej. - Każda litera jest powtarzana jak w tym samym wierszu (bez nowej linii lub innych separatorów między literami).
- Jeśli wpiszesz nieprawidłowy znak, program wyświetli
Fail
nowy wiersz i zakończy działanie. - Jeśli wpiszesz wszystkie 26 liter, program w nowym wierszu wyświetli czas w milisekundach od pierwszej do ostatniej litery i wyjdzie.
- Timer rozpoczyna się po wpisaniu pierwszej litery
a
.
Przykładowe wyniki:
b
Fail
abcdefgg
Fail
abcdefghijklmnopqrstuvwxyz
6440
To jest golf golfowy , więc wygrywa najkrótsza odpowiedź w bajtach.
code-golf
date
alphabet
interactive
Danko Durbić
źródło
źródło
Fail
bez nagłówka nowej linii? (np.abdFail\n
lubabd Fail\n
))Fail
lub milisekundy) musi znajdować się w nowym wierszu, jak w przykładzie. Większość odpowiedzi już to zakłada.Odpowiedzi:
HTML (JavaScript (ES6)),
129126117 bajtówKliknij wejście i zacznij pisać! Poza tym moje pisanie jest do bani; Zajmuję około 5 sekund nawet podczas ćwiczeń. Edycja: Zapisano 2 bajty dzięki @HermanLauenstein poprzez zmianę języka. Zaoszczędzono 3 bajty dzięki @ qw3n. Zaoszczędź 9 bajtów dzięki @tsh.
źródło
<input id=i><script>l=0;n=Date.now;i.onkeypress=e=>e.charCode-97-l?i.outerHTML='Fail':l>24?i.outerHTML=n()-t:t=l++?t:n()</script>
-11 bajtów, jeśli znacznik zamykający nie jest potrzebny<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>
Kod maszynowy 6502 (C64 PAL),
189165 bajtówDemo online (Zastosowanie:
sys49152
)Wyjaśnienie:
Byłby to mały program, gdyby nie problem dokładnego pomiaru milisekund na C64. Przerwanie systemu występuje z grubsza 60 razy na sekundę, co nie jest nawet blisko. Musimy więc użyć tutaj timera sprzętowego, który odbiera tiki wejściowe z zegara systemowego.
Na maszynie PAL zegar systemowy ma dokładnie 985248 Hz. Zainicjowanie licznika czasu na 985 daje więc coś zbliżonego do milisekundowych tyknięć, ale jest to trochę za szybko, musielibyśmy liczyć 986 cykli na co czwarty tyknięcie lub przytrzymać licznik dla jednego cyklu. Nie jest to możliwe, ale możemy trzymać timera przez 6 cykli z sekwencji
DEC $DD0E
,INC $DD0E
:$DD0E
jest rejestr kontrolny zegar z bit 0 przełączania go i wyłączać, a obie instrukcje przyjąć 6 cykli, więc dokładnie pisze, że zatrzymanie i rozpoczęcie Timer dzieli dokładnie 6 cykli. Dlatego musimy wykonywać tę sekwencję co 6 * 4 = 24 tyknięcie. To wciąż nie jest absolutniedokładnie, zegar opóźni się o 1 milisekundę do tyłu po 8 minutach i 12 sekundach, ale prawdopodobnie jest wystarczająco dobry - zrekompensowanie tego zajmie dużo kodu.edycja : Wartość początkowa dla timera musi wynosić 984, a nie 985, ponieważ te timery odpalają „przy niedopełnieniu”, więc wartość 0 będzie liczyć jeszcze jeden cykl przed odpaleniem. Naprawiono kod, niezmieniono liczbę bajtów.
Oto skomentowana lista dezasemblacji:
źródło
.starttimer
- zrobię to wkrótce :) (a nawet dalej, używając systemuTI
takiego jak ta odpowiedź BASIC , ale nie jestem pewien, czy jest to poprawne, ponieważ można lepiej zrobić w kodzie maszynowym )Bash + coreutils,
1039998 bajtówMusi być uruchamiany w terminalu.
Testowe uruchomienie
źródło
3479
jest dość szybki! dobra robota :)a
od razu daje miline 1: ((: r=15094100773N: value too great for base (error token is "15094100773N")
i kończy działanie.date
potęgą. Mój pochodzi z GNU coreutils 8.23. Codate +%s%3N
drukuje w twoim systemie?15094104833N
- to wbudowanedate
narzędzie w systemie macOS, jeśli to robi różnicę.date
wydaje się używać strftime, który nie rozpoznaje%N
.Python 2 + getch , 116 bajtów
Dzięki ovs i ElPedro za poprawienie kodu i oszczędność 57 bajtów.
źródło
SOGL V0.12 , 35 bajtów
Wypróbuj tutaj! - kliknij Uruchom i wprowadź alfabet w polu wprowadzania. Zauważ, że może to być nieco opóźnione, ponieważ SOGL zatrzymuje się tylko na dane wejściowe co 100 wykonanych tokenów (a SOGL jest dość wolny). Jeśli Ci to przeszkadza, uruchom
sleepBI=true
konsolę.Uwaga: nie uruchamiaj tego w trybie zgodności - zapętli się na zawsze.
Wyjaśnienie:
źródło
Pascal (FPC) , 176 bajtów
Wypróbuj online!
Niektóre sztuczki używane w kodzie do gry w golfa:
Real
jako krótszej alternatywyTDateTime
, ponieważ, jak zdefiniowano tutaj ,TDateTime
=Double
, która jest typu zmiennoprzecinkowego.MilliSecondsBetween
do obliczania przerwy czasowej, ten kod zwielokrotnia różnicę między dwiema wartościami zmiennoprzecinkowymi przez864e5
, co działa z powodu sposobuTDateTime
opisanego tutaj kodowania Free Pascal .Uwaga:
ReadKey
funkcja faktycznie nie drukuje klucza na konsoli, więcWrite(c)
konieczne jest ręczne pisanie na konsoli za pomocą .0
za pisanie alfabetu z oczywistego powodu.źródło
for c:='a'to'z'do
ten sam wiersz coa:=Time;
.Now
zamiast tego,Time
ponieważ jest krótszy.86398338
?? Rozumiem, jeśli pomnożysz 864e5, ponieważ dziennie jest 8 milisekund. ale skąd ta magiczna liczba?TDateTime
jakoDouble
.864e5
brzmi bardziej poprawnie, naprawię problemy.Java,
404388354348320318 bajtówI tutaj myślałem, że Java Console jest już gadatliwa.
Ponieważ Java nie ma sposobu na surowe nasłuchiwanie naciśnięć klawiszy w konsoli, używam GUI z
java.awt
.-78 bajtów dzięki @ OlivierGrégoire .
Wyjaśnienie:
Przykład gif sukcesu: (Tak, dość powoli wpisuję alfabet tutaj.)
Uwaga: To jest stary gif. Obecna wersja nie drukuje już naciśnięć klawiszy w konsoli. I nie drukuje już czasu cyframi po przecinku.
Przykład gif fail:
Uwaga: To jest stary gif. Obecna wersja nie drukuje już naciśnięć klawiszy w konsoli.
źródło
setVisible(false)
zamiast wychodzić.show
idispose
, co jest nawet krótsze niżsetVisible
. Prawie nigdy nie używam GUI Javy. I sprytnie korzystam z inicjalizacji klas zamiast umieszczania jej w metodzie głównej. Powinienem to pamiętać.TextField
. Można również użyćTextArea
zamiast,TextField
aby uzyskać dwa bajty. WreszcieKeyEvent
magetWhen
metodę, która podaje czas między epoką a zdarzeniem w milisekundach. Wystarczy użyć ich zamiastSystem.nanoTime()
zyskać jeszcze więcej bajtów.C # (.NET Core),
245 + 13183 + 41177 + 41 bajtów+41 bajtów dla
using System;using static System.Console
.Nie sprawdzono, ponieważ jestem na telefonie komórkowym i nie działa na TIO.
źródło
int x=0;
a potem zrobićx=1/x;
. Powinno to zaoszczędzić 14 bajtów. Niestety potrzebujeszx
. Jeśli spróbujesz to zrobić1/0
, otrzymasz błąd dzielenia przez stały błąd kompilatora zero . 2) -5 bajtów do łączenia deklaracjic
z pierwszymReadKey
. 3) Zmień warunek wewnętrznyif
naReadKey!=++c
i usuńc++;else
dla kolejnych -9 bajtów.x=1/x
można zredukować dox/=x
. I dodałem,using static System.Console;
aby zaoszczędzić trochę więcej bajtów :)i
i używającc
w pętli.MSX-BASIC, 126 znaków
TIME
jest wewnętrzną zmienną MSX-BASIC, która zwiększa się o jedną co 20 milisekund.źródło
C # (.NET Core) ,
184 + 13 = 197173 + 13 = 186 bajtówWypróbuj online!
Niestety TIO nie może tego uruchomić, ale przydaje się do liczenia bajtów.
+13 dla
using System;
-1, zmieniając
i==123
nai>122
. Kusiło mnie, aby to zrobići>'z'
.Podziękowanie
-10 bajtów dzięki @raznagul
Nie golfił
źródło
ReadKey
warunek do pętli, aby usunąć pierwszyif
ibreak
.Node.js,
240213 bajtówEDYCJA: Oszczędność 27 bajtów dzięki Jordanowi
Wersja bez golfa:
źródło
C (gcc) , 303 bajty
Działa na systemach * nix. Samodzielny kod usuwający tryb kanoniczny bieżącego terminala, aby umożliwić czytanie znaków bez czekania na znaki nowej linii:
/! \ Uruchomienie tego programu sprawi, że terminal będzie prawie bezużyteczny.
Nie golfił i skomentował:
Alternatywne rozwiązanie (218 bajtów):
Jeśli dozwolone jest wcześniejsze skonfigurowanie terminala, możemy pozbyć się części kodu obsługującej tę część.
Oto ten sam kod bez manipulacji terminalem:
Aby to działało:
przykład środowiska wykonawczego:
źródło
Commodore BASIC v2 - 113 bajtów
Wielkie litery muszą być przesunięte.
Dzięki Felixowi Palmenowi za wskazanie literówek, specyfikacje
próbują
źródło
TI
jest w nim zwiększane) Uznałem, że nie nadaje się ze względu na brak precyzji, ale myślę, że jest to uczciwa gra, ponieważ po prostu nie ma lepszego sposobu na BASIC :) Mimo to, wklejając to na odwrót, otrzymuję błąd składniowy w1
- jakaś pomoc?1on-(f=26)gO4:gEa$:ifa$=""tH1
Nitpicks: 1.) wyjście jest w tej samej linii, 2.) wyjście jest wielkimi literami - Myślę, że powinieneś to naprawić, nie zajmie wielu bajtów tak czy inaczej :)Perl 5,
7993 +31 (-MTerm :: ReadKey -MTime :: HiRes = czas) bajty$|=1
nie jest wystarczające, aby ustawić terminal w trybie surowym,stty -icanon
należy uruchomić przed lubaby zobaczyć znaki w terminalu po uruchomieniu polecenia:
stty echo
lubstty echo icanon
źródło
ReadKey
! Można zaoszczędzić kilka bajtów tu i tam,1e3
o1000
,$s||=time
a jeśli ustawiony$s
, a następnie zadzwonićReadKey
, możesz zamienić się zmap
do Postfixfor
. Chciałbym powiedziećdie
zamiastexit print
, ale myślę, że tam jesteś ... Majstrowałem przy,printf"\n%i"
ale skończyło się to na większym, i pomyślałem o użyciu$-
zamiast$s
, ale to było głupie! :)$|=1;
, również $ s || = czas nie może zostać zamieniony na mapę, ponieważ zegar musi się uruchomić po pierwszym naciśnięciu klawisza, idie
odbijaFail
się echem na stderr zamiast na stdout.exit print
jest tak długo! Przepraszam, nie sądzę, że wytłumaczyłem swoją myślfor
poprawnie:$s||=time,ReadKey eq$_||exit print" Fail"for a..z
powinien działać, myślę ... Może nawet$|=$s||=...
lub$|=map...
jeśli wolisz takie podejście! Myślisz, że prawie to przybiłeś!$|=map..
nie ustawia niebuforowanego wejścia w nowym terminalu (miałem błąd podczas usuwania, ReadMode 3, ponieważ testowałem w tej samej sesji), a$s||=time
przed pierwszym ReadKey zbyt wcześnie uruchomiłby licznik czasu$|
, ale znowu, przechowuje się po pętli, która jest za późno! Jesteś krok do przodu!Aceto , 70 bajtów
Zaczynam od ustawienia znacznika i dublowania w poziomie (
@|
), jeśli wartość na stosie jest prawdziwa. Początkowo tak nie jest, a później zawsze tak będzie. Wrócimy tutaj później, jeśli zostanie wprowadzony zły klucz. Następnie wciskamy a na stosie ('a
), a następnie kopiujemy go i odczytujemy pojedynczy znak od użytkownika (d,
). Jeśli dwa znaki nie są równe (=!
), „upaść” ($
) i przeskoczyć z powrotem do znaku catch. W przeciwnym razie wciskamy kolejne „a” i drukujemy je, a następnie ustawiamy bieżącą godzinę ('apT
).Następnie wchodzimy do naszej „głównej pętli”: „Zwiększamy” bieżący znak i „zwiększamy” znak (
'apToIc
), następnie kopiujemy go, czytamy nowy znak, porównujemy go i „zawieszamy”, jeśli znaki nie są identyczne (d,=!$
). Jeśli się nie zawiesiliśmy, porównujemy bieżący znak do „z” (d'z=|
), jeśli nie jest równy, drukujemy znak, a następnie wciskamy 1 i przeskakujemy „warunkowo” (w tym przypadku: zawsze) do tylkoo
w kodzie (początek naszej głównej pętli). Jeśli był równy z, to odbijaliśmy poziomo do jakiegoś pustego miejsca na górze. Drukujemy „z”, a następnie przesuwamy aktualny czas (minus czas początkowy;t
), a następnie mnożymy liczbę 1000 (uzyskaną przez podniesienie 10 do trzeciej potęgi;91+3F
) przez to (ponieważ otrzymujemy sekundy, nie milisekundy). Następnie wypisujemy nowy wiersz, godzinę i kończymy (pX
).Jeśli kiedykolwiek się zawiesimy (złe dane wprowadzone przez użytkownika), przeskoczymy do samego początku. Ponieważ będziemy mieli teraz pewną prawdziwą wartość na stosie, będziemy wykonywać odbicie lustrzane w poziomie w kierunku
u
, który odwraca kierunek, w którym się poruszamy.n
Drukuje znak nowej linii, następnie wciskamy"Fail"
stos, drukujemy go i kończymy (pX
).źródło
Mathematica (wyrażenie w notesie), 248 bajtów
Jak to działa
A
DynamicModule
zEventHandler
reagującym na naciśnięcia małych liter. Zmiennex
,s
it
przytrzymaj naciśnięty litery tak daleko, czas rozpoczęcia i czas zakończenia, odpowiednio. Gdy tylko zauważymy,x
że jesteśmy równi{"a"}
, zaczynamy czas; wyświetlamy całkowity czas spędzony lub ciąg zbudowany do tej pory lub w"Fail"
zależności od tego, który warunek jest spełniony.Możemy zapisać kolejny bajt,
t<1
zamiastt==0
zakładać, że nikt nie jest wystarczająco szybki, aby wpisać alfabet w mniej niż sekundę :)Jeśli wypróbowujesz to w notatniku Mathematica, pamiętaj, że musisz kliknąć wewnątrz ramki przed zarejestrowaniem naciśnięć klawiszy. (To jest powód, dla którego potrzebujemy ramki od samego początku; jeśli jej
Framed
nie ma, wówczas cały wybrany obiekt zmienia się po naciśnięciu klawisza, więc przestaje być wybierany i trzeba będzie kliknąć ponownie).źródło
C #,
154152 + 13 = 165 bajtówZaoszczędzono 2 bajty dzięki komentarzom Ayb4btu
Powyższy kod ma spacje, aby zmieścił się w SE bez paska przewijania. Białe znaki nie są częścią liczby bajtów
i 13 bajtów dla
using System;
Jest podobny do wersji Ayb4btu, ale z następującymi różnicami:
Przechowywanie daty i godziny jako długiej pozwala nam również zrobić
c
długą i skrócić deklaracjęPętla nie potrzebuje oddzielnej przerwy
W rzeczywistości nie jest krótszy w
$"interpreted strings"
porównaniu do dodania potrzebnego „\ n” do milisekund, aby uczynić go ciągiem wstawianym, jeśliKorzystanie z
for
pętli czasami pozwala nam zapisywać znaki przez jakiś czas, chociaż myślę, że ten nie zapisałby więcej niż równowartośćwhile
Od Ayb4btu:
s=s==0
może się staćs=s<1
ic==123
może się staćc>122
Nie golfił
źródło
DateTime
. Możesz zaoszczędzić kilka bajtów, zmieniającs=s==0
nas=s<1
(licząc, że s nie będzie ujemne) i zmieniająci==123
nai>122
.i<123
musiało to nastąpić przedReadKey()
, inaczej czeka na inną postać po z, zanim wyświetli czas.z
powinno oznaczać readkey. Keychar zwraca 122, gdy użytkownik wpisze z, c jest również 122, a zatem'z' == 122
powiedzie się, c jest następnie zwiększany, a następnie c (teraz 123) jest testowanyc<123
i kończy się niepowodzeniem, zatrzymując pętla ..?c++
przyrost, gdy na niego patrzyłem. Jednak właśnie go wypróbowałem, a kiedyabcdefghijklmnopqrstuvwxys
go wpisuję, daje mi to czas zamiast się nie udać. Uważam, że dzieje się tak, ponieważc
wciąż wzrasta, nawet jeśliKeyChar
czek się nie powiedzie, dlatego też przekazaniec>122
czeku.Processing.org
133142pierwszy kod nie wyszedł
źródło
GCC, Windows, 98 bajtów
Nie wymaga natychmiastowego wprowadzania pierwszego klucza
źródło