Сделать математика Конкурс Грейдер

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

Pyth, 53 51

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

Попробуйте онлайн

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

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

FryAmTheEggman
источник
1
Нет ошибок (В настоящее время меньше байтов, чем в ответе Дениса ...)
Arcturus
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не печатался в случае ошибки. Мои надежды на то, чтобы выйти за пределы Денниса.

Mego
источник
Является ли? Шутки в сторону? Тогда я должен объявить это
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>

user81655
источник
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=в начале и сказать, что это генерирует лямбда-функцию.
Конор О'Брайен
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)
user81655 25.11.15
@ 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. Предложения приветствуются!

ETHproductions
источник
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
... или идти бессмысленно 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

noisyass2
источник
Вы можете изменить его, int s=0,i=0;for(;...чтобы сохранить 3 байта.
LegionMammal978
Это не сработает, если я введу 29 символов для первого ввода и 31 для второго ... это должно вывести «недопустимый тест», но на самом деле будет пытаться оценить.
Йохан
@ noisyass2: строка x (строка k, строка a) => k.Length! = 30 || a.Length! = 30? "Invalid Test!": Enumerable.Range (0,30) .Sum (e => a [e] == ''? 0: k [e] == a [e]? 4: -1) + ""; (134 знака) и учитывает вклад Johans.
Стефан Шинкель
+1 за решение, но соответствует ли это критериям? ОП сказала полную программу.
Yytsi 25.11.15
Йохан, хороший улов! @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" 
manatwork
источник
2

Джава, 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";}
RCB
источник
Я не Java Golfer, но я думаю, что вы можете сохранить 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

]
undergroundmonorail
источник
1

Python 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
edc65
источник
Тьфу, проверка заняла половину моего кода, когда я пытался: (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

Я попытался сделать "короткое" решение Python ... Ну вот, предложения более чем приветствуются

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'
N3buchadnezzar
источник
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

Попробуйте это онлайн здесь

Emigna
источник
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

slvrbld
источник
Вы можете сохранить 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

Yytsi
источник
Хорошо сделано! Несколько общих приемов, которые применимы здесь, вы можете объявить iвместе с sциклом for. Вы можете использовать varдля объявления a, сохраняя 1 байт (ура!). Вам не нужно много фигурных скобок {}в вашем коде, что всегда является хорошим способом обрезать байты, и всегда стоит взглянуть на таблицу ASCII при сравнении символов (вы можете c[i]==' 'немного сбить байт , используя неравенство). Вам также следует рассмотреть возможность подсчета строк в обратном направлении - в этом случае вы можете сэкономить не менее 1 байта, перенастроив цикл for.
VisualMelon
К сожалению, ваша заявка в настоящее время не связана с критериями, поскольку она не может распознать неверные данные.
VisualMelon
@VisualMelon Ааа, я чувствую себя так глупо. Я написал это представление в школе, так что я забыл добавить вещи «недействительный тест» и т. Д. Я добавлю их :)
Yytsi
@VisualMelon Да, это было отправлено и написано в школе в конце урока, я его отредактирую. Спасибо за трюки :)
Yytsi
0

Groovy 2.4.5, 107 байт

Просто простой перевод более раннего ответа Java .

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;

Sas на самом деле не имеет ввода / вывода, поэтому вам нужно заменить k = '..' ключом, а r = '..' ответом. Вывод распечатывается в журнал.

TMP4
источник