Зробіть першокласник з математики


17

Мені подобається брати участь у математичних змаганнях, які проводить Муфа Альфа Тета, товариство з математики в США. На змаганнях я беру тест з множинним вибором 30 питань. Існує п’ять варіантів на запитання, позначені від A до E.

Мій бал за тест - чотири бали за кожну правильну відповідь, нуль балів за запитання, залишене порожнім, і мінус один бал за кожну неправильну відповідь.

Напишіть програму, яка оцінює тест відповідно до вищезазначеної системи балів. На вхід повинні бути два компоненти: клавіша відповіді з подальшими відповідями. Питання, залишені порожніми, вводяться як порожні пробіли. Перший вхід повинен містити лише букви AE (або ae, ваш вибір), і можна вважати, що у введенні немає пробілу. Другий вхід повинен містити лише порожні пробіли та літери AE (або ae). Вхідні дані, які не реалізують тести на 30 питань, повинні друкувати Invalid testяк вихідні дані.

Вихід повинен бути оцінкою або Invalid test.

Бонус

Якщо ваша програма роздруковує число праворуч, число залишається порожнім, а число неправильним після остаточної оцінки як (aR bB cW) , зніміть 20 байт.

Зразок введення

CABBDCABECDBACDBEAACADDBBBEDDA    //answer key
CABEDDABDC BACDBBAADE  CBBEDDA    //responses

Вибірка зразка

Без бонусу

73

Бонус

73 (20R 3B 7W)

Діють стандартні правила. Виграє найкоротший код у байтах.


Що нам робити з пробілами в першому рядку?
lirtosiast

@ThomasKwa У першому рядку не повинно бути пробілів. Invalid test.
Арктур

2
Здається, ви змінили правила після опублікування відповідей, які визнали недійсними принаймні 2 з них. Будь ласка, не вносьте змін, які можуть визнати недійсними відповіді після публікації виклику. Корисно використовувати пісочницю, щоб отримати зворотний зв'язок перед публікацією.
Олексій А.

Думаю, це було б цікавіше, ніж підкреслено
кіт

як щодо чутливості до справ? також, що робити, якщо моя мова ... не заповнена пробілом? Чи можу я вказати пробіл у вводі, замість цього слід мати підкреслення?
кіт

Відповіді:


7

Піта, 53 51

?&!-sJ.z+d<G5&FqR30lMJ+sm?qFd4_1CJ/eJd"Invalid test

Спробуйте в Інтернеті

Перевірки проводяться, бачачи, чи весь вхід містить будь-які символи, коли всі пробіли та a-eвилучені, та перевіряючи, чи мають обидва рядки довжину 30.

Розрахунок балів проводиться пролітаючи два рядки разом, а потім шляхом відображення кожній парі: (letters are equal) ? 4 : -1. Потім просто підсумовуючи значення та додаючи кількість пробілів у другому рядку назад до балу.


1
Немає помилок. (В даний час менше байтів, ніж відповідь Деніса ...)
Арктур

7

Серйозно , 86 байт

,`;l5╙¬=);' UΣS" ABCDE"=(**;l`Mi@)=YWé"Invalid test"0WX@Z```i@;(=5*(' =D+`(;l@)5╙¬=IMΣ

Приймає вхід як "CABBDCABECDBACDBEAACADDBBBEDDA", "CABEDDABDC BACDBBAADE CBBEDDA"

Спробуйте в режимі он-лайн (вам доведеться ввести вручну, оскільки постійні посилання не люблять лапок)

Робота над бонусом зараз. Ні, додавання бонусу коштувало б більше 20 байт.

Я знав, що щось забуваю ... Invalid Testне надруковано у випадку помилки. Туди я сподіваюсь, що Деніс позаграє в гольф.


Робить це? Серйозно? Тоді я маю підтвердити це
edc65

4

JavaScript (ES6), 134 байти

Редагувати: вимоги до запитання змінені. Ця відповідь відбувається з того часу, коли програмі потрібно переконатися, що кожен символ відповіді є AE, кожен символ відповіді - AE або пробіл, і обидва вони мають довжину 30, а інше повертається Invalid test.

(a,r)=>[...a].map((q,i)=>q>"E"|q<"A"?x=1:(c=r[l=i])==" "?0:c>"E"|c<"A"?x=1:c==q?s+=4:s--,s=x=0)&&x|l!=29|r.length!=30?"Invalid test":s

Пояснення

(a,r)=>                   // a = answer string, r = responses string
  [...a].map((q,i)=>      // iterate over answers, q = answer, i = question number
    q>"E"|q<"A"?x=1:      // x = 1 if answer is invalid
    (c=r[l=i])==" "?0:    // c = question response, l = answer length, add 0 for space
    c>"E"|c<"A"?x=1:      // x = 1 if response is invalid
    c==q?s+=4:s--,        // add 4 if correct, subtract 1 if incorrect
    s=x=0                 // s = total score, x = is invalid
  )&&
    x|l!=29|r.length!=30? // check input lengths for validity
      "Invalid test":
      s                   // return the score

Тест

<input type="text" id="answers" value="CABBDCABECDBACDBEAACADDBBBEDDA" /><br />
<input type="text" id="responses" value="CABEDDABDC BACDBBAADE  CBBEDDA" /><br />
<button onclick='result.innerHTML=(

(a,r)=>[...a].map((q,i)=>q>"E"|q<"A"?x=1:(c=r[l=i])==" "?0:c>"E"|c<"A"?x=1:c==q?s+=4:s--,s=x=0)&&x|l!=29|r.length!=30?"Invalid test":s

)(answers.value,responses.value)'>Go</button><pre id="result"></pre>



3

JavaScript (Firefox 31+), 86 байт

(x,y)=>(r=i=0,[for(l of y)x[i++]==l?r+=4:r-=l!=' '],i!=30|i-x.length?'Invalid test':r)

Використовує розуміння масиву, який пропонується для ES7. Таким чином, підтримка на даний момент обмежена Firefox.

З бонусом 106 байт (126 - 20)

(x,y)=>[r=w=i=0,[for(l of y)x[i++]==l?r++:w+=l!=' '],`${r*4-w} (${r}R ${i-r-w}B ${w}W)`,'Invalid test'][i!=30||i-x.length?3:2]

Редагувати: Раніше моє рішення перевіряло лише довжину відповіді чи запитання, тепер перевіряє обидва.


Ви можете опустити f=на початку і сказати, що це породжує лямбда-функцію.
Conor O'Brien

1
@ CᴏɴᴏʀO'Bʀɪᴇɴ Дякую, я завжди забуваю, що це на їх тестуванні -_-
Джордж Рейт

Це було б значно коротше без премії. 86 байт:(x,y)=>(r=i=0,[for(l of y)x[i++]==l?r+=4:r-=l!=' '],i!=30|i-x.length?'Invalid test':r)
користувач81655

@ user81655 Щоправда, дякую ... Я трохи натрапив на це ... один рядок шаблону становить 34 байти
Джордж Рейт

У мене дуже схожа відповідь, але я не скопіював цю (моя перша спроба є прецедентною, але я видалив її, оскільки не перевіряв довжини). Це сказало: це не вірно, не дивлячись на 3 оновлення, оскільки не перевіряється діапазон A ... E
edc65

2

Japt , 71 байт

Japt - скорочена версія Ja vaScri pt . Перекладач

Ul ¥30©Vl ¥30«(U+V k"[A-E ]+" ?U¬r@VgZ ¥Y?X+4:VgZ ¥S?X:X-1,0 :`InvÃ. È.

Два .s в кінці повинні бути недрукованими символами Unicode U + 0017 та U + 0099 відповідно.

Як це працює

Ul ==30&&Vl ==30&&!(U+V k"[A-E ]+" ?Uq r@VgZ ==Y?X+4:VgZ ==S?X:X-1,0 :"Invalid test
                    // Implicit: U = first input, V = second input
Ul ==30&&Vl ==30&&  // If both input lengths are 30, and
!(U+V k"[A-E ]+"?   // removing all ABCDE and spaces from (U+V) results in an empty string:
Uq r@            ,0 //  Reduce U with this function, starting with a value of 0:
VgZ ==Y?            //   If the matching char in V is equal to this char, 
X+4                 //    return previous value + 4.
:VgZ ==S?X          //   Else if the matching char in V is a space, return previous value.
:X-1                //   Else (if it's wrong), return previous value - 1.
:"Invalid test      // Else, return "Invalid test".
                    // Implicit: output last expression

Сподіваюся, існує коротший спосіб переконатися, що обидві довжини дорівнюють 30. Пропозиції вітаються!


2

Haskell, 144 138 байт

a%b|map length[a,b]==[30,30]&&"ABCDE"!a&&"ABCDE "!b=show$sum$zipWith(?)a b|0<1="Invalid test"
l!s=all(`elem`l)
_?' '=0
x?y|x==y=4|0<1=0-1

Без валідації було б близько 50. нюхати .

Використання: "ABCDEABCDEABCDEABCDEABCDEABCDE" % "AAAAABBBBBCCCCCDDDDDEEEEEAAAAA"


1
!можна визначити як all(`elem`l)s, економлячи 6 байт.
Згарб

1
... або йти pointfree: g=all.flip elem.
німі

2

C #, 162 154 148 134 байт

string g(string k,string a)=>k.Length!=30||a.Length!=30?"Invalid Test!":Enumerable.Range(0,30).Sum(e=>a[e]==' '?0:k[e]==a[e]?4:-1)+"";

Використання

g("CABBDCABECDBACDBEAACADDBBBEDDA", "CABEDDABDC BACDBBAADE  CBBEDDA")

Тест

http://csharppad.com/gist/15f7c9c3c8cfce471ff2


Ви можете змінити його, int s=0,i=0;for(;...щоб зберегти 3 байти.
LegionMammal978

Це не працює, якщо я ввожу 29 символів для першого вводу та 31 для другого .. він повинен надрукувати "недійсний тест", але насправді спробує оцінити.
Йоган

@ noisyass2: string x (рядок k, рядок a) => k.Length! = 30 || a.Length! = 30? "Недійсний тест!": безліч.Ранг (0,30) .Sum (e => a [e] == ''? 0: k [e] == a [e]? 4: -1) + ""; (134 символів) і враховує вклад Йоханса.
Стефан Шінкель

+1 для рішення, але чи відповідає це? ОП сказала повну програму.
Yytsi

Йохан приємний улов! @StephanSchinkel дякую за ідею використання делегата та біта Enum.range. Мені вдалося поголити ще 3 символи, змінивши стан на 30 == (k.Length & a.Length)
noisyass2

2

Рубі, 81 персонаж

->t,s{r=0;30.times{|i|r+=t[i]==s[i]?4:s[i]>' '?-1:0};t.size==30?r:'Invalid test'}

Проба зразка:

2.1.5 :001 > ->t,s{r=0;30.times{|i|r+=t[i]==s[i]?4:s[i]>' '?-1:0};t.size==30?r:'Invalid test'}['CABBDCABECDBACDBEAACADDBBBEDDA','CABEDDABDC BACDBBAADE  CBBEDDA']
 => 73 

2.1.5 :002 > ->t,s{r=0;30.times{|i|r+=t[i]==s[i]?4:s[i]>' '?-1:0};t.size==30?r:'Invalid test'}['CCCATCH','CABEDDABDC BACDBBAADE  CBBEDDA']
 => "Invalid test" 

2

Java, 183 169 байт

Це було приємною практикою Java 8:

String f(String a,String r){return a.length()==30&r.length()==30?""+IntStream.range(0,30).map(i->a.charAt(i)==r.charAt(i)?4:r.charAt(i)!=' '?-1:0).sum():"Invalid test";}

Я не Java-гольфер, але я думаю, що ви можете зберегти String.valueOf, просто додавши int до порожнього рядка ( ""+IntStream....) - Я також вважаю, що Java дозволяє не коротко замикатись, і тому ви можете видалити один із &байтів і зберегти його .
VisualMelon

@VisualMelon Чудові поради, дякую. Мене дратувало, скільки байтів займає String.valueOf!
RCB

2

мозковий ебать, 354 байти

+[--[>]<<+>-],----------[[<<<]>>->[>>>],----------]<<<[<<<]>>+[<-[-------<+>]<.+[---<+>]<.++++++++.[-<+++>]<-.+++++++++++.---.-----.-[---<+>]<-.---[-<++++>]<.+++[-<+++>]<.[---<+>]<----.+.>]>[[>,----------->+++++++[<---<<+++>>>-]<[<<+[>>+<<-]]>[>]<<<[>[>+>+<<-]>>[<<+>>-]>[>>>]>----<<<<[<<<]>>[-]]>[>-<-]>[>>[>>>]>-----<<<<[<<<]>[-]]>>]----[>+++<--]>--.<]

Потрібен перекладач, який дозволяє перейти ліворуч від комірки 0. Вихід - це підписаний байт. Наприклад, байт 0x49друкується для прикладу введення та 0xFFдрукується для введення тим самим першим рядком, але другий рядок замінено на "C" та 29 пробілами.

Оцінка починається з 0, і коли читається другий рядок введення, до неї вносяться такі зміни:

  • Введення правильне: нічого не робіть
  • Введення неправильне: Віднімайте 5
  • Введення - пробіл: Віднімайте 4

Нарешті, додається 120. Це функціонально так само, як припускати ідеальний рахунок та застосовувати пенальті, а не починати з 0.

З коментарями:

+[--[>]<<+>-]                          Get 29

,----------[[<<<]>>->[>>>],----------] Get first line of input; for each char sub one
                                       from the 29

<<<[<<<]>>+                            Add one to the cell that originally held 29

[                                      If the cell that originally held 29 is nonzero:

  Write "Invalid test"
  <-[-------<+>]<.+[---<+>]<.++++++++.[-<+++>]<-.+++++++++++.---.-----.-[---<+>]<-.---[-<++++>]<.+++[-<+++>]<.[---<+>]<----.+.

>]

>[                                     If the cell to the right is nonzero:

  This block is only ever entered if "Invalid test" isn't written!

  [                                      For all 30 characters of the first input:

    >,                                     Get char from second input to the right

    ----------                             Subtract 10 for consistency

    -                                      Subtract one more

    >+++++++[<---<<+++>>>-]                Subtract 21 (plus above lines = 32)

    <[                                     If it's nonzero:

      <<+[>>+<<-]                            Add 22 to the character

    ]

    >[>]<<<[                                 If the above block wasn't entered:

      >[>+>+<<-]>>[<<+>>-]                   Make a copy of the character from input 1

      >[>>>]>----                            Subtract 4 from the score

      <<<<[<<<]>>[-]                         Go to the cell just before first character

    ]

    >[>-<-]                                Subtract input 1 char from input 2 char

    >[                                     If the result is nonzero:

      >>[>>>]>-----                          Subtract 5 from the score

      <<<<[<<<]>[-]                          Go back to the result and set it to 0

    ]

    >>                                     Move on to next character

  ]

  ----[>+++<--]>--                       Add 120 to score (perfect score)

  .                                      Print score

  <                                      Go to an empty cell to kill loop

]

1

Пітон 3, 187 179 175 165 155 151

lambda a,b:(['Invalid test',sum([-1,4][i==j]for i,j in zip(a,b))+b.count(' ')][len(a)==len(b)==30and set(a)^set('ABCDE')==set(b)^set('ABCDE ')==set()])

1

JavaScript ES7, 102

Як завжди, бонус не вартий зусиль.

(k,h,t=i=0)=>[for(x of h)t+=k[i++]==x?4:1-x?0:-1]|/[^ A-E]/.test(k+h)|i-30|k.length-i?"Invalid test":t

Перевірка недійсних пробілів на першому вході (оскільки це має сенс для мене) 112

(k,h,t=i=0)=>[for(x of h)(y=k[i++])>' '?t+=y==x?4:1-x?0:-1:k=h+h]|/[^ A-E]/.test(k+h)|i-30|k[i]?"Invalid test":t

Тьфу, перевірка зайняла половину мого коду, коли я спробував: (k,r,s=0)=>/^[A-E]{30}$/.test(k)&&/^[ A-E]{30}$/.test(r)?Object.keys(k).map(i=>k[i]==r[i]?s+=4:s-=r[i]!=' ').pop():'Invalid Test'це 129 байт.
Ніл

1

Python 2.7, 131, 116, 109 , 139

Я спробував зробити "коротке" рішення пітона ... Ну ось воно, пропозиції більш ніж вітаються

lambda c,d:d.count(' ')+sum([-1,4][a==b]for a,b in zip(c,d)if b!=' ')if not set('ABCDE ')^set(c+d)and len(c)==len(d)==30 else'Test Invalid'

Додавання ще кількох символів робить його набагато легше читати ...

def m(c, d):
    if len(c)==len(d)==30:return d.count(' ')+sum((a==b)*4+(a!=b)*-1 for a,b in zip(c,d)if b!=' ')
    return'Test Invalid'

1

Пролог, 165 байт

Більше половини байтів призначені для перевірки недійсних тестів.

Код:

p(X,X,4).
p(_,32,0).
p(_,_,-1).
A*B:-length(A,30),length(B,30),subset(A,`ABCDE`),subset(B,`ABCDE `),maplist(p,A,B,L),sum_list(L,S),write(S);write('Invalid Test').

Пояснили:

p(X,X,4).                                       % If corresponding elements are equal, 4p
p(_,32,0).                                      % If answer is 'space', 0p
p(_,_,-1).                                      % Else, -1p
A*B:-length(A,30),length(B,30),                 % Check that input is of correct length
     subset(A,`ABCDE`),subset(B,`ABCDE `),      % Check that input has correct characters
     maplist(p,A,B,L),sum_list(L,S),write(S);   % Create a list of scores (L) and print sum
     write('Invalid Test').                     % If anything failed, write Invalid Test

Приклад:

`CABBDCABECDBACDBEAACADDBBBEDDA`*`CABEDDABDC BACDBBAADE  CBBEDDA`.
73

Спробуйте його онлайн тут


1

MATLAB, 92 90 байт

Дякую Тому Карпентеру за те, що він міг зменшити мою відповідь на 2 байти!

function c(q,a),if nnz(q)~=30,t='Invalid test';else s=q-a;t=5*nnz(~s)-sum(s<9);end,disp(t)

Функцію можна викликати, призначивши аркуш відповідей q і подані відповіді на a . наприклад:

c('CABBDCABECDBACDBEAACADDBBBEDDA','CABEDDABDC BACDBBAADE  CBBEDDA')

Відповідь проставляється на екрані. 8 байтів можна зберегти, якщо дозволено друкувати ans = 73


Ви можете зберегти 2 байти, замінивши numel(q)на nnz(q).
Том Карпентер

1

C # 6.0 -> (270 - 20 = 250) 246 - 20 = 226 байт

void m(string b,string c){if((b+c).Length==60){var a=new int[3];int s=0;for(int i=0;i<30;i++){if(b[i]==c[i]){a[0]++;s+=4;}else if(c[i]==' ')a[2]++;else{a[1]++;s--;}}Console.Write(s+$" ({a[0]} {a[2]} {a[1]})");}else Console.Write("Invalid test");}

Читана та неперевершена версія:

    void m(string b, string c)
    {
        if ((b+c).Length==60)
        {
            var a = new int[3];
            int s = 0;
            for (int i = 0; i < 30; i++)
            {
                if (b[i]==c[i])
                {
                    a[0]++;
                    s+=4;
                }
                else if (c[i] == ' ')a[2]++;
                else
                {
                    a[1]++;
                    s--;
                }
            }
            Console.Write(s+$" ({a[0]} {a[2]} {a[1]})");
        }
        else Console.Write("Invalid test");
    }

Дуже хотів отримати бонус: D


Nice work! A few of general tricks that apply here, you can declare i along with s outside the for loop. You can use var to declare a, saving 1 byte (hurrah!). You don't need many of the curly braces {} in your code, which is always a good way to trim bytes, and it's always worth looking at an ASCII table when comparing chars (you can knock a byte off c[i]==' ' somewhat by using an inequality). You should also consider counting through the strings backwards - in this case you can save at least 1 byte by rejigging the for loop somewhat.
VisualMelon

Unfortunately, your submission is currently not complicit with the criteria, as it is unable to recognise invalid inputs.
VisualMelon

@VisualMelon Ahh, I feel so dumb. I wrote this submission at school so I forgot to add the 'invalid test' things etc. I'll add them :)
Yytsi

@VisualMelon Yeah, this was submitted and written in school at the end of the class, I'll edit it. Thanks for the tricks :)
Yytsi

0

Groovy 2.4.5, 107 bytes

Just a simple translation of the earlier Java answer.

f={a,b->a.length()==30&b.length()==30?(0..29).collect{a[it]==b[it]?4:b[it]!=' '?-1:0}.sum():'Invalid test'}

0

C, 273 - 20 = 253 байт

#include<stdio.h>
#include<string.h>
int main(int c,char**v){char*p=v[1],*q=v[2],*s=" ABCDE",r[]={0,0,0};if(strspn(p,s+1)!=30||p[30]||strspn(q,s)!=30||q[30])puts("Invalid test");else{for(;*p;++q)++r[(*p++!=*q)+(*q==' ')];printf("%d (%dR %dB %dW)",4**r-r[1],*r,r[2],r[1]);}}

Я взяв бонус, навіть якщо він коштував мені 23 байти просто для його друку. :-(

Пояснення

#include <stdio.h>
#include <string.h>
int main(int c,char**v)
{
    char *p=v[1], *q=v[2],      /* arguments */
        *s=" ABCDE",            /* valid chars */
        r[]={0,0,0};            /* results - right, wrong, blank */

    if (strspn(p,s+1) != 30     /* validity check - answer key begins with [A-E]{30} */
        || p[30]                /* and ends there */
        || strspn(q,s) != 30    /* same for answers, but allow space, too */
        || q[30])
    {
        puts("Invalid test");
    } else {
        for ( ;  *p;  ++q)      /* for each answer */
            ++r[(*p++!=*q)+(*q==' ')]; /* increment the appropriate counter */
        printf("%d (%dR %dB %dW)",4**r-r[1],*r,r[2],r[1]); /* print result */
    }
}

Існує вдвічі більше коду, щоб перевірити наявність недійсного введення, ніж потрібно для підрахунку відповідей - справжнє м'ясо завдання полягає в forциклі, що знаходиться в кінці. Насправді ось версія, яка передбачає, що введення завжди дійсне, у 163-20 = 143 байтах:

#include<stdio.h>
int main(int c,char**v){char*p=v[1],*q=v[2],r[]={0,0,0};for(;*p;++q)++r[(*p++!=*q)+(*q==' ')];printf("%d (%dR %dB %dW)",4**r-r[1],*r,r[2],r[1]);}

І той, хто робить те саме припущення, і друкує лише бал у 133 байтах:

#include<stdio.h>
int main(int c,char**v){char*p=v[1],*q=v[2],r[]={4,-1,0};for(c=0;*p;++q)c+=r[(*p++!=*q)+(*q==' ')];printf("%d",c);}

0

SAS 9.4, 291-20 = 271 байт (з бонусом) або 231 байт (без бонусу)

З бонусом:

data a;k='CABBDCABECDBACDBEAACADDBBBEDDA';r='CABEDDABDC BACDBBAADE  CBBEDDA';c=0;b=0;w=0;if length(k) ne 30 then put "Invalid test";do i=1 to 30;if substr(k,i,1)=substr(r,i,1) then c=c+1;else if substr(r,i,1) =' ' then b=b+1;else w=w+1;end;a=cat(c*4-w,' (',c,'R ',b,'B ',w,'W)');put a;run;

Без бонусу:

data a;k='CABBDCABECDBACDBEAACADDBBBEDDA';r='CABEDDABDC BACDBBAADE  CBBEDDA';c=0;if length(k) ne 30 then put "Invalid test";do i=1 to 30;if substr(k,i,1)=substr(r,i,1) then c=c+4;else if substr(r,i,1)ne' ' then c=c-1;end;put c;run;

Сас насправді не має вводу / виводу, тому вам потрібно буде замінити k = '..' на ключ, а r = '..' у відповідь. Вихід друкується до журналу.

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