Постройте тест скорости набора / измерения CPM

11

Правила

Пришло время создать тест скорости набора текста на выбранном вами языке!

1 . Вы предоставляете файл со словарем выбора (каждое слово в нем должно быть разделено новой строкой). Передайте его через stdinили укажите его имя в качестве аргумента командной строки.

a
в состоянии
около
над
отсутствие
...

2 . Выберите 10 случайных слов из файла (дубликаты не должны быть разрешены) и распечатайте их следующим образом:

-> прямой
-> земля
-> следующий
-> пять
...

3 . Начните измерять время, проведенное с этого момента!

4 . Позвольте пользователю набрать все десять слов как можно быстрее (заканчивается переводом каретки). Печатайте, OKкогда у вас есть совпадение, печатайте, WRONGкогда у нас есть ошибка ввода (или слово уже было успешно набрано в этом цикле).

5 . Останови часы! Теперь распечатайте CPM (Caracters в минуту) тесте, который рассчитывается следующим образом : (sum of the characters of the chosen words / time spent typing (seconds)) * 60. Округлите до ближайшего целого числа и воспроизведите следующий (пример) вывод:

-> Вы набрали 344 CPM!

Пробный прогон

-> урегулировать
-> сторона
-> открыть
-> министр
-> риск
-> цвет
-> корабль
-> то же самое
-> размер
-> меч
селиться
хорошо
сторона
хорошо
открыть
хорошо
# ...................... некоторые строки обрезаны ......................
слово
НЕПРАВИЛЬНО
меч
хорошо
-> Вы набрали 298 CPM!

Победитель

Это код colf, выигрывает самая короткая запись (в количестве символов исходного кода), получайте удовольствие!

ChristopheD
источник
4
Я думаю, что победитель должен быть частично забит человеком с самой высокой
ценой
Насколько точно нам нужно измерять время? Одна секунда разрешения в порядке?
Ильмари Каронен
@Ilmari Karonen: одна секунда резолюции будет хорошо для этого конкретного конкурса.
ChristopheD

Ответы:

5

К, 146

Предполагается файл словаря с именем 'd' в текущем рабочем каталоге.

{b:+/#:'a:10?_0:`:d;-1"-> ",/:a;s:.z.t;while[#a;$[(,/0:0)~*a;[a:1_a;-1"OK"];-1"WRONG"]];-1"--> You have scored ",($(60000*b)%"i"$.z.t-s)," CPM!";}
tmartin
источник
Очень хорошая и короткая, первая запись, Kкоторую я видел (здесь, на codegolf.se) ...
ChristopheD
Спасибо, все мои ответы здесь в Q или (все чаще) в K.
tmartin
Я не совсем понимаю, почему это только один голос (мой)!
ChristopheD
11

Баш - 217 212 199 196 символов

Не выиграю, но было весело

declare -A W
for w in `shuf -n10`;do C+=$w;echo -\> $w;W[$w]=OK;done
SECONDS=0
for((;${#W[*]};));do read r;echo ${W[$r]-WRONG};unset W[$r];done
echo --\> You have scored $((60*${#C}/SECONDS)) CPM!

До 200 символов сейчас!

Принимает файл списка слов в качестве аргумента. Теперь принимает список слов при стандартном вводе. Вставьте его в терминал и нажмите ^ D

Реализовано предложение от manatwork

Джефф Риди
источник
1
Не собираюсь побеждать, но это было весело - я думаю, то же самое, когда я
публикую
1
Вы можете использовать $SECONDSпеременную оболочки, чтобы упростить подсчет истекшего времени.
manatwork
Вы можете удалить еще 2 символа: 1) :расширение значения параметра по умолчанию; 2) $перед SECONDSарифметической оценкой. На самом деле есть еще один дополнительный символ, символ новой строки в и из файла.
Манатворк
4

Рубин (189 178 171 168)

$><<t=['',d=[*$<.lines].sample(10)]*'-> '
s=Time.now
puts d.delete($stdin.gets)?:OK:'WRONG'while d[0]
puts'--> You have scored %i CPM!'%((t.size-40)/(Time.now-s)*60)

Довольно простой, я уверен, что есть улучшения, которые нужно сделать. Принимает имя файла словаря в качестве аргумента командной строки.

РЕДАКТИРОВАТЬ : несколько мелких изменений, в основном, вокруг сохранения перевода строки из словаря. В результате для корректной работы файла потребуется завершающий символ новой строки.

Пол Престиж
источник
4

C 305 309 347 символов

char*stdin,w[11][99];long i,t;main(int n,char**v){v=fopen(v[1],"r");
for(srand(time(&t));fgets(w[i++>9?(n=rand()%i)>10?0:n:i],99,v););
for(i=n=0;i<10;n+=printf("-> %s",w[++i])-4);
for(;i;puts(!strcmp(*w,w[11-i])?--i,"OK":"WRONG"))fgets(*w,99,stdin);
printf("--> You have scored %ld CPM!\n",n*60/(time(0)-t));}

Спасибо @ugoren за советы по улучшению. Использование «11-го слова» для отбрасывания входящих словарных статей было большой победой над моим предыдущим подходом strcpy-if-selected.

Вот неопрятный источник:

#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

static char words[11][99];
static long i, t;

int main(int argc, char *argv[])
{
    FILE *fp;
    int n;

    fp = fopen(argv[1], "r");
    srand(time(0));
    for (i = 0 ; fgets(words[0], sizeof words[0], fp) ; ++i) {
        n = i < 10 ? i : rand() % i;
        if (n < 10)
            strcpy(words[n + 1], words[0]);
    }
    fclose(fp);

    n = 0;
    for (i = 1 ; i <= 10 ; ++i)
        n += printf("-> %s", words[i]) - 4;
    t = time(0);
    i = 1;
    while (i <= 10 && fgets(words[0], sizeof words[0], stdin)) {
        if (strcmp(words[0], words[i])) {
            puts("WRONG");
        } else {
            puts("OK");
            ++i;
        }
    }
    if (i > 9)
        printf("-> You have scored %ld CPM!\n", n * 60 / (time(0) - t));

    return argc - argc;
}
Хлебница
источник
Некоторые улучшения: 1. K & R декларация: main(n,v)char**v;{.... 2. stdinможет быть char *. fgets(buf,len,stdin)= gets(buf)(не говоря уже о переполнении буфера). 3. Что не так с rand()%i? RAND_MAXне нужен 4. Почему long?
Угорен
1
Также: 1) t=time(0)-> time(&t). 2) n*60/(time(0)-t)круглые скобки , которые должны идти - *60может быть перемещен n+=60*printf, то n/=time(0)-t. 3) Заменить bна дополнительный элемент w, заменить strcpyна чтение непосредственно в w.
Угорен
Замена fgets()с gets()потребностями дополнительного кода сделки с новой строкой в словаре; это оказалось короче. rand()%iне достаточно; фактический расчет есть (double)i*rand()/RAND_MAX. Перемещение *60к Printf также означает изменение -4к -240так это в конечном счете завершаться потери. Ваши другие пункты являются действительными, хотя (я верю). О, и longэто потому, что time_t традиционно долго. То, что мы играем в гольф, не означает, что мы не можем быть портативными.
хлебница
Я скучал 4-> 240... Переносимость и гольф не сочетаются друг с другом. Но определение i,t;(неявно int) в порядке вплоть до MAX_INTсекунд (если вы не используете time(&t)). С rand(), все, что вам нужно, это 10/iшанс, и rand()%i<10делает это.
Угорен
Ваш случайный выбор несколько ошибочен (не то, чтобы абсолютная справедливость требовалась). У 11-й линии должен быть шанс 10/11 быть выбранным, но вы делаете rand()%10>10, что дает 100%. rand()%(i+1)>9лучше (но вместо этого, если %(i+1)сделать i++>9?. Также двигаться, *stdinчтобы быть первым и сохранить место.
Угорен
2

C # 401

void T(){
Action<string>C=Console.WriteLine;Func<string>R=Console.ReadLine;
var w=new List<string>();
for(var l=R();l!="";l=R())w.Add(l);
var s=w.OrderBy(_=>Guid.NewGuid()).Take(10).ToList();
s.ForEach(x=>C("=> "+x));
var t=s.Select(x=>x.Length).Sum();
var c=Stopwatch.StartNew();
while(s.Any()){C(s.Remove(R())?"OK":"WRONG");}
c.Stop();
C("--> You have scored "+c.Elapsed.TotalSeconds*60/t+" CPM!");}

Работающая версия здесь: http://ideone.com/Nt6Id

Кристиан Лупаску
источник
2

Python ( 256 235)

import time as t,random as r
def p(x):print x
c=r.sample(input().split("\n"),10)
z=lambda x:p(("WRONG","OK")[raw_input()==x])or len(x)
p("--> "+"\n--> ".join(c))
_=t.time()
p("--> You have scored %d CPM!"%(sum(map(z,c))/(t.time()-_)*60))

Это в Python 2.x, в 3.x я могу сбрить еще 4 символа с помощью функции печати.

Новые строки включены

Джоэл Корнетт
источник
2
"Вопрос: новые переводы считаются?" Мы обычно ходим по «необходимым персонажам». В случае с Python да, переводы строк должны быть подсчитаны, так как их удаление не даст программе работать.
Джои Адамс
1
I think you can change z=lambda x: to def z(x):.
Joey Adams
@JoeyAdams: Я мог бы, если нужно, только вернуть ни одного, но мне нужно вернуться, len(x)и def z(x):returnэто еще 5 символов: /
Джоэл Корнетт
Я думаю, что вы можете выиграть некоторых персонажей, набрав в строке (разрешено в вопросе) и используя input()вместоsys.argv[1].read()
ChristopheD
@JoelCornett: Ой, ты прав.
Джои Адамс
2

PHP 187 байт

Новые строки были добавлены для ясности:

<?$s=file($argv[1]);
for(shuffle($s);$i++<10;$l+=strlen($$i))echo~ÒÁß,$$i=$s[$i];
for($t=time();$j++<10;)echo$$j==fgets(STDIN)?OK:WRONG,~õ?>
--> You have scored <?=0|$l/(time()-$t)*60?> CPM!

Принимает имя файла словаря в качестве аргумента командной строки. Файл словаря должен заканчиваться символом новой строки.

Примо
источник
2

Скала ( 319 306 304 302)

var s=util.Random.shuffle(io.Source.fromFile(args(0)).getLines.toSet)take 10
def?(a:Any)=println(a)
var l=(0/:s){_+_.size}
s map{"-> "+_}map?
def n=System.nanoTime
val t=n
while(s.size!=0){val m=readLine
if(s contains m)?("OK")else?("WRONG");s-=m}
?("--> You have scored "+l*60000000000L/(n-t)+" CPM!")
Принц Джон Уэсли
источник