Побудуйте тест швидкості набору тексту / вимірювання CPM


11

Правила

Настав час скласти тест на швидкість набору тексту вашою мовою!

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

а
здатний
о
вище
відсутність
...

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!

Переможець

Це коефіцієнт коду, найкоротший запис (кількість символів вихідного коду) виграє, весело!


4
Я думаю, що переможець повинен частково набрати особу з найвищим показником CPM;)
mellamokb

Наскільки точно нам потрібно виміряти час? Чи добре одна секунда роздільна здатність?
Ільмарі Каронен

@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!";}

Дуже приємно і коротко, перший запис, який 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

Реалізовано пропозицію з маневрених робіт


1
Не збираюсь перемагати, але це було весело - я вважаю те саме, коли публікую свої рішення C # :)
Крістіан Лупаску

1
Ви можете використовувати $SECONDSзмінну оболонки для спрощення обчислення минулого часу.
маніпуляція

Ви можете видалити ще 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-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першими і заощаджуйте простір.
ugoren

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

Пітон ( 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
Я думаю , що ви можете змінити z=lambda x:в def z(x):.
Джої Адамс

@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!")
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.