Crea un selezionatore di concorsi di matematica


17

Mi piace partecipare alle competizioni di matematica tenute da Mu Alpha Theta, una società di onore matematico negli Stati Uniti. Alle competizioni faccio un test a scelta multipla di 30 domande. Sono disponibili cinque opzioni per domanda, etichettate da A a E.

Il mio punteggio in un test è di quattro punti per ogni risposta corretta, zero punti per una domanda lasciata vuota e uno negativo per ogni risposta sbagliata.

Scrivi un programma che classifica un test in base al sistema di punteggio sopra. Dovrebbero esserci due componenti nell'input: un tasto di risposta seguito da risposte. Le domande lasciate vuote devono essere inserite come spazi vuoti. Il primo input deve contenere solo le lettere AE (o ae, a scelta) e si può presumere che non vi sia spazio bianco nell'input. Il secondo input deve contenere solo spazi vuoti e le lettere AE (o ae). Gli input che non implementano test con 30 domande devono essere stampati Invalid testcome output.

L'output dovrebbe essere il grado o Invalid test.

indennità

Se il programma stampa il numero a destra, il numero lasciato in bianco e il numero errato dopo il punteggio finale come (aR bB cW), togliere 20 byte.

Input di esempio

CABBDCABECDBACDBEAACADDBBBEDDA    //answer key
CABEDDABDC BACDBBAADE  CBBEDDA    //responses

Uscita campione

Nessun bonus

73

indennità

73 (20R 3B 7W)

Si applicano le regole standard. Vince il codice più breve in byte.


Cosa dovremmo fare con gli spazi nella prima riga?
lirtosiast

@ThomasKwa Non dovrebbero esserci spazi nella prima riga. Invalid test.
Arturo

2
Sembra che tu abbia modificato le regole dopo che le risposte sono state pubblicate, il che ha invalidato almeno 2 di esse. Non apportare modifiche che potrebbero invalidare le risposte dopo la pubblicazione di una richiesta. È consigliabile utilizzare Sandbox per ottenere feedback prima della pubblicazione.
Alex A.

Penso che questo sarebbe stato più interessante come subdolo
gatto

che ne dici di maiuscole e minuscole? Inoltre, cosa succede se la mia lingua è ... un piacere per gli spazi bianchi? posso specificare spazi vuoti nell'input dovrebbe essere sottolineato?
gatto,

Risposte:


7

Pyth, 53 51

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

Provalo online

I controlli vengono eseguiti verificando se l'intero input contiene caratteri quando tutti gli spazi e a-evengono rimossi e controllando se entrambe le stringhe hanno lunghezza 30.

Il calcolo del punteggio è fatto da zippare le due linee insieme, poi mappando ogni coppia a: (letters are equal) ? 4 : -1. Quindi semplicemente sommando i valori e aggiungendo il numero di spazi nella seconda riga al punteggio.


1
Nessun errore (Attualmente meno byte della risposta di Dennis ...)
Arcturus,

7

Scherzi a parte , 86 byte

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

Accetta input come "CABBDCABECDBACDBEAACADDBBBEDDA", "CABEDDABDC BACDBBAADE CBBEDDA"

Provalo online (dovrai inserire manualmente l'input perché ai permalink non piacciono le virgolette)

Ora sto lavorando al bonus. No, l'aggiunta del bonus costerebbe più di 20 byte.

Sapevo che stavo dimenticando qualcosa ... Invalid Testnon veniva stampato in caso di errore. Ecco le mie speranze di giocare a golf a Dennis.


Vero? Sul serio? Quindi devo
votarlo

4

JavaScript (ES6), 134 byte

Modifica: i requisiti della domanda sono cambiati. Questa risposta proviene da quando il programma doveva assicurarsi che ogni carattere di risposta fosse AE, ogni carattere di risposta è AE o spazio ed entrambi avevano una lunghezza di 30, altrimenti ritorno 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

Spiegazione

(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

Test

<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

CJam, 60 byte

2{l_,30=\N?}*_2$|S'F,65>+-!@2$.{=4W?}@' f=+:+"Invalid test"?

Provalo online nell'interprete CJam .


3

JavaScript (Firefox 31+), 86 byte

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

Utilizza la comprensione dell'array proposta per ES7. Pertanto il supporto è limitato a Firefox per il momento.

Con bonus, 106 byte (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]

Modifica: in precedenza la mia soluzione controllava solo la risposta o la lunghezza della domanda, ora controlla entrambi.


Puoi omettere f=all'inizio e dire che questo genera una funzione lambda.
Conor O'Brien,

1
@ CᴏɴᴏʀO'Bʀɪᴇɴ Grazie dimentico sempre che proviene dai loro test -_-
George Reith,

Questo sarebbe significativamente più breve senza il bonus. 86 byte:(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

@ user81655 Vero, grazie ... Ci sono rimasto un po 'preso ... la stringa del modello da sola è di 34 byte
George Reith,

Ho una risposta molto simile, ma non l'ho copiata (il mio primo tentativo è precedente, ma l'ho cancellato perché non controllavo le lunghezze). Detto questo: questo non è valido nonostante 3 voti, in quanto non controlla l'intervallo A ... E
edc65,

2

Japt , 71 byte

Japt è una versione abbreviata di Ja vaScri pt . Interprete

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

I due .s alla fine dovrebbero essere i caratteri Unicode non stampabili U + 0017 e U + 0099, rispettivamente.

Come funziona

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

Spero che ci sia un modo più breve per assicurarsi che entrambe le lunghezze siano uguali a 30. Suggerimenti benvenuti!


2

Haskell, 144 138 byte

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

Sarebbe circa 50 senza la convalida. annusare .

Uso: "ABCDEABCDEABCDEABCDEABCDEABCDE" % "AAAAABBBBBCCCCCDDDDDEEEEEAAAAA"


1
!può essere definito come all(`elem`l)s, salvando 6 byte.
Zgarb,

1
... o pointfree Go: g=all.flip elem.
nimi,

2

C #, 162 154 148 134 byte

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)+"";

uso

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

Test

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


È possibile modificarlo in int s=0,i=0;for(;...per salvare 3 byte.
LegionMammal978,

Questo non funzionerà se inserisco 29 caratteri per il primo input e 31 per il secondo .. dovrebbe stampare "test non valido" ma proverò effettivamente a valutare.
Johan

@ noisyass2: stringa x (stringa k, stringa a) => k.Length! = 30 || a.Length! = 30? "Test non valido!": Enumerable.Range (0,30) .Sum (e => a [e] == ''? 0: k [e] == a [e]? 4: -1) + ""; (134 caratteri) e considera l'input di Johans.
Stephan Schinkel,

+1 per la soluzione, ma questo si qualifica? OP ha detto programma completo.
Yytsi,

Johan bella cattura! @StephanSchinkel grazie per l'idea di usare il delegato e il bit Enum.range. Sono stato in grado di radere altri 3 caratteri cambiando la condizione in 30 == (k.Length & a.Length)
noisyass2

2

Rubino, 81 caratteri

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

Esecuzione di esempio:

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

Giava, 183 169 byte

Questo è stato un bel po 'di pratica con 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";}

Non sono un giocatore di golf Java, ma penso che puoi salvare il String.valueOfsemplicemente aggiungendo int a una stringa vuota ( ""+IntStream....) - Credo anche che Java consenta il non-corto circuito e, quindi, puoi rimuovere uno dei &e salvare un byte .
VisualMelon,

@VisualMelon Ottimi consigli, grazie. Mi dava fastidio quanti byte String.valueOf occupava!
RCB,

2

Brainfuck, 354 byte

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

Richiede un interprete che consente di andare a sinistra dalla cella 0. L'output è un byte con segno. Ad esempio, il byte 0x49viene stampato per l'input di esempio e 0xFFviene stampato per l'input con la stessa prima riga ma la seconda riga sostituita con "C" e 29 spazi.

Il punteggio inizia da 0 e quando viene letta la seconda riga di input, vengono apportate queste modifiche:

  • L'immissione è corretta: non fare nulla
  • L'immissione non è corretta: Sottrai 5
  • L'input è uno spazio: Sottrai 4

Infine, viene aggiunto 120. Funzionalmente è come assumere un punteggio perfetto e applicare penalità, anziché iniziare da 0.

Con commenti:

+[--[>]<<+>-]                          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

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

Come al solito, il bonus non vale la pena.

(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

Controllo di spazi non validi nel primo input (poiché questo ha senso per me) 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

Uff, la convalida ha assorbito metà del mio codice quando ho provato: (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 byte.
Neil,

1

Python 2.7, 131, 116, 109 , 139

Ho provato a fare una soluzione "breve" in pitone ... Bene, ecco i suggerimenti sono più che benvenuti

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'

L'aggiunta di alcuni caratteri in più lo rende molto più leggibile ...

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

Prolog, 165 byte

Più della metà dei byte sono destinati al controllo dei test non validi.

Codice:

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').

Ha spiegato:

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

Esempio:

`CABBDCABECDBACDBEAACADDBBBEDDA`*`CABEDDABDC BACDBBAADE  CBBEDDA`.
73

Provalo online qui


1

MATLAB, 92 90 byte

Grazie a Tom Carpenter per avermi aiutato a ridurre la mia risposta di 2 byte!

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)

La funzione può essere chiamata assegnando il foglio delle risposte a q e le risposte inviate a a . per esempio:

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

La risposta è semplicemente stampata sullo schermo. 8 byte potrebbero essere salvati se è consentito stampare ans = 73


È possibile salvare 2 byte sostituendoli numel(q)con nnz(q).
Tom Carpenter,

1

C # 6.0 -> (270-20 = 250) 246 - 20 = 226 byte

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");}

Versione leggibile e non modificata:

    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");
    }

Volevo davvero ottenere il bonus: D


Bel lavoro! Alcuni trucchi generali che si applicano qui, è possibile dichiarare iinsieme al di sfuori del ciclo for. Puoi usare varper dichiarare a, salvando 1 byte (evviva!). Non hai bisogno di molte parentesi graffe {}nel tuo codice, che è sempre un buon modo per tagliare i byte, e vale sempre la pena guardare una tabella ASCII quando si confrontano i caratteri (puoi in c[i]==' 'qualche modo cancellare un byte usando una disuguaglianza). Dovresti anche considerare di contare le stringhe all'indietro: in questo caso puoi salvare almeno 1 byte rigonfiando leggermente il ciclo for.
VisualMelon,

Purtroppo, l'invio non è attualmente complice dei criteri, in quanto non è in grado di riconoscere input non validi.
VisualMelon,

@VisualMelon Ahh, mi sento così stupido. Ho scritto questa presentazione a scuola, quindi ho dimenticato di aggiungere le cose "test non valide" ecc. Le aggiungerò :)
Yytsi,

@VisualMelon Sì, questo è stato inviato e scritto a scuola alla fine della lezione, lo modificherò. Grazie per i trucchi :)
Yytsi il

0

Groovy 2.4.5, 107 byte

Solo una semplice traduzione della precedente risposta 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 byte

#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]);}}

Ho preso il bonus, anche se mi è costato 23 byte solo per stamparlo. :-(

Spiegazione

#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 */
    }
}

C'è il doppio del codice per verificare l'input non valido rispetto al conteggio delle risposte - la vera carne della sfida è nel forciclo verso la fine. In effetti ecco una versione che presuppone che l'input sia sempre valido, in 163-20 = 143 byte:

#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]);}

E uno che fa la stessa ipotesi e stampa solo il punteggio, in 133 byte:

#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 byte (con bonus) o 231 byte (senza bonus)

Con bonus:

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;

Senza bonus:

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 non ha davvero un input / output, quindi dovresti sostituire k = '..' con la chiave e r = '..' con la risposta. L'output viene stampato nel registro.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.