Chi ha detto questo? Elezioni presidenziali 2016


16

In questa sfida, il tuo compito è quello di far scrivere un programma con meno di 300 caratteri che richiede un breve paragrafo o alcune frasi che un candidato ha detto e genera chi lo ha detto.

Input : può essere preso come parametro per una funzione, input per un programma ecc. Sarà un breve paragrafo, opportunamente punteggiato.

Risultato : il candidato che ritieni sia. Questo potrebbe essere uno dei

Ben Carson (1)
Ted Cruz (2)
John Kasich (3)
Marco Rubio (4)
Donald Trump (5)
Hillary Clinton (6)
Bernie Sanders (7)

Ho lasciato fuori i nomi delle persone che hanno abbandonato il 1 ° marzo. È possibile generare il nome stesso o, più convenientemente, il numero corrispondente al nome.

Punteggio: il tuo punteggio è la percentuale di casi di test che ottieni correttamente. Il punteggio più alto vince. I pareggi (o i punteggi perfetti) sono interrotti dalla lunghezza del codice come in un codice golf.

I casi di test possono essere estratti da:

http://www.presidency.ucsb.edu/debates.php

Fai clic su ogni dibattito, sia democratico che repubblicano, che si è svolto finora (prima del 1 ° marzo). Ogni paragrafo è un caso di prova, a meno che il "paragrafo" non contenga più di 20 caratteri.

Ecco il codice che estrae i casi di test da una determinata pagina:

var t = $(".tools").parentNode.querySelectorAll("p");
var categ = {}, cur = 0;
for (var i = 0; i < t.length; ++i) {
  var p = t[i], str = p.innerText;
  if (p.querySelector("b")) {
    cur = p.querySelector("b").innerText.replace(':', '');
    str = str.replace(/^.*?:\s/, '');
  }
  str = str.replace(/\[applause\]/g, '')
  if (str.length < 20) continue;
  if (categ[cur] == null) categ[cur] = [];
  categ[cur].push(str);
}

È quindi possibile fare categ.SANDERSper ottenere un elenco di tutti i paragrafi che il senatore Sanders ha detto.

Puoi scartare tutto ciò che non è stato detto dai candidati sopra elencati (es. categ.BUSHO categ.CHRISTIE).

Ecco il file con tutti i casi di test: https://drive.google.com/file/d/0BxMn8--P71I-bDZBS2VZMDdmQ28/view?usp=sharing

Il file è organizzato per candidato

CANDIDATE CANDIDATE_LAST_NAME
(empty line)
Series of statements. Each paragraph is separated by (NEW PARAGRAPH)-
(empty line)
CANDIDATE NEXT_CANDIDATE_LAST_NAME
(empty line)
etc.

Un esempio di presentazione parziale sarebbe:

if (/ win | wall | great | beautiful/.test(p)) return 5;
if (/ percent | top one | rigged /.test(p)) return 7;
// etc. for all candidates

o

var words = p.split(' ');
// majority of words have less than 5 characters
if (words.length - words.filter(a => a.length < 5).length < 4) evidence[5]++;
// at the end
return /* index with the most evidence */ 

Ecco un luogo dove è possibile testare soluzioni javascript: https://jsfiddle.net/prankol57/abfuhxrh/

Il codice utilizza il parametro pper rappresentare la frase da classificare. Codice di esempio che segna circa il 20% (supponendo che si ottenga intorno all'11%):

if (/ rigged | top | percent | Wall Street /.test(p)) return 'Sanders';
return 'Trump';

Esattamente quello che sto chiedendo: scrivi un programma / funzione con meno di 300 caratteri che prende come input una frase che un candidato ha detto e restituisce come output il candidato che l'ha detto. Il tuo punteggio è la percentuale di casi di test che ottieni correttamente. Il punteggio più alto vince.

Sì, so che molte linee hanno [laughter]o [cheering]in esse. Questi non verranno rimossi. Nel peggiore dei casi, sono informazioni extra che puoi ignorare; nella migliore delle ipotesi, sono informazioni aggiuntive che è possibile utilizzare (ad esempio, l'ho inventato, ma forse le risate delle persone sono la prova che Marco Rubio sta parlando). I casi di test sono come appaiono nel file di testo.


1
Ho un suggerimento. Che ne dici di renderlo code-golf, ma devi ottenere tutte le virgolette giuste? Inoltre, potresti voler rendere le virgolette molto più brevi, poiché è un po 'ridicolo da risolvere così com'è.
Cyoce

2
@Cyoce ottenere tutte le virgolette giuste sarebbe ridicolo (penso) considerando il solo numero di citazioni.
soktinpk,

1
L'idea di una sfida intelligente potrebbe richiedere qualche raffinazione. Hai preso in considerazione l'idea di pubblicare su Sandbox per un feedback?
Ashwin Gupta,

1
Qual è il criterio vincente? (E perché pensi che nessuno otterrà un punteggio perfetto?)
Peter Taylor

2
I dati di origine che hai fornito sono un po 'disordinati (difficili da analizzare automaticamente), che penso tolga un po' dello spirito della sfida. Ho realizzato una versione pulita che utilizza una riga per citazione, con una riga vuota che separa il nome del candidato successivo. Questo è molto più facile da analizzare nella maggior parte delle lingue. L'ho caricato qui: drive.google.com/file/d/0B3uyVnkMpqbVSnVrZkVwTUhDODg (oltre alla modifica di nuove righe, ho lasciato i dati intatti. Ciò include quello che sembra un problema di codifica per -)
Dave

Risposte:


14

Poliglotta, ~ 18,6%

Funziona in: Cjam, Pyth, TeaScript, Japt, Seriamente, 05AB1E, GolfScript, Jelly e probabilmente molti altri.

6

Questo produce Hillary per tutti gli input. Questo perché Hillary ha detto di più. Anche se non è il modo più geniale per farlo. Funziona ¯ \ _ (ツ) _ / ¯


Mi piace come questo viene segnalato come post di bassa qualità. : P
Denker

1
@DenkerAffe probabilmente per essere basso
Downgoat

1
Qualche motivo per usare JavaScript? Avresti potuto giocarci fino a un personaggio in un'altra lingua: P
ghosts_in_the_code

@ghosts_in_the_code fixed
Downgoat

9

Pyth, 34,16% (297 byte)

FNc"7creta
6enato
3ohio
2donal
7 major 
6o try t
5tot
5se me
7nai
4m pres
2he ob
3 bala
5jeb
6e aff
5mendous 
2mnest
5. we'r
7ave got to
2c ter
4ntur
7 campaign 
2flat
5obo
4is pre
4-here'
2note
2m el
4 issue 
5, very
6o af
1fact o
6en's
5pany
6he republicans
7 -- 
4meon
5bea
4ory o
7"bI}tNrzZhNB

(nota che alcune linee finiscono negli spazi)

Sono andato con l'opzione più semplice che mi venisse in mente: controlla un elenco di schemi e, non appena trovi una corrispondenza, metti in uscita il candidato corrispondente. Se tutto il resto fallisce, genera il candidato più probabile dal resto. Dopodiché, si tratta di stipare quanti più dati possibile in 300 byte.

FNc"<data>"bI}tNrzZhNB

Abbattersi:

FN                      for N in ...
   "<data>"              the hard-coded data (newline separated)
  c                      split using...
           b             '\n' constant,
            I           if
              tN         tail (all but first char) of current item
             }           is contained within
                rzZ      the input (lowercased),
                        then:
                   hN    print the head (first char) of the current item
                     B   and break out of the loop.

Da dove provengono questi dati? Bene la struttura è semplicemente:

<candidate_number><phrase>
<candidate_number><phrase>
<etc.>

(con una voce alla fine senza alcuna frase che funga da fallback finale)

Ma perché quegli oggetti particolari? Ho scritto un programma C ++ per analizzare il set di dati fornito (con una prima pulizia manuale delle newline per rendere coerente la struttura). Esamina tutte le sottostringhe ("token") in ogni virgoletta (1-16 caratteri), quindi controlla ripetutamente il token che offre il massimo beneficio per passare all'elenco successivo. Una volta che un modello è nell'elenco, rimuovi tutte le virgolette che lo corrispondono e ripeti (diventa un po 'più complicato mantenerlo veloce, ma queste sono le basi). Il codice è probabilmente troppo lungo per essere incluso qui, ma potrei metterlo su Github più tardi (quando l'ho pulito un po ').

Ho provato un paio di sistemi di punteggio. Alla fine sono andato con questo:

score = (
    + matching_quote_count_for_most_likely_author * 10
    - matching_quote_count_for_other_authors * 7
    - token_length
)

Un approccio più rigoroso di consentire solo nuovi elementi che non introducono risposte errate sembrava rimanere bloccato a circa il 20-25%, necessitando di molti schemi per aumentare. Questo approccio fuzzier fa molto meglio e può ancora raggiungere un'accuratezza dell'80% (con 550 articoli). Il punteggio inviato ha 38 elementi, il massimo che potevo inserire nel limite di 300 caratteri.

Il risultato del 34% proviene effettivamente da un programma di test C ++ che esegue gli stessi passaggi. Dovrebbe corrispondere, ma non ho un cablaggio di test Pyth con cui verificarlo.

Questa è la prima volta che uso Pyth, quindi immagino che alcuni byte in più possano essere eliminati, consentendo un po 'più di dati.


4
Ora so anche che Sanders ama parlare del segretario Clinton, Clinton è ossessionato dal senatore Sanders, Kasich ama l'Ohio, Cruz menziona sempre Donald Trump, Rubio è ossessionato dai secoli, Carson ha tutti i "fatti" della questione, e Trump adora dire "totalmente". Sembra l'inizio di un generatore di bingo politico. Dovrò provarlo su alcune personalità del Regno Unito ...
Dave

Penso che potresti salvare alcuni byte qui comprimendo la stringa .".
lirtosiast

8

Javascript, 32,87%

299 personaggi:

function Q(a,b){return p.toLowerCase().split(' ').join('').includes(a)<<b}z=Q('ink',0)+Q('int',1)+Q('ona',2)+Q('rica',3)+Q('twe',4)+Q("we'",5)+Q('youkn',6);return '55472726464727446676664676767676563641233643334456364233336141745116222136477126111113361611262316263122216111673336225611363276'[z]*1

Strategia:

Ho fatto una ricerca della forza bruce su quali segmenti di parole includere in un "hash". Quindi avviene una ricerca di stringhe con quell'hash in modo tale da scegliere il candidato più probabile per quell'hash.

Il codice stesso:

// The Q function checks if a string is present.
// Then left-shifts the true/false result up to e.g. 64,32,16,8,4,2,1
// This way we can combine results into any number 0 to 127.
function Q(a,b){return p.toLowerCase().split(' ').join('').includes(a)<<b}

// Now we check for key string occurrences:
z=Q('ink',0)+Q('int',1)+Q('ona',2)+Q('rica',3)+Q('twe',4)+Q("we'",5)+Q('youkn',6)

// Finally, use this as an index into the lookup string. (Multiply by 1 to convert char to int.)
return '55472726464727446676664676767676563641233643334456364233336141745116222136477126111113361611262316263122216111673336225611363276'[z]*1

Questa è la mia prima presentazione di golf in codice, quindi i suggerimenti sono benvenuti :)


5

Mathematica, 23.7775%

(l=ToLowerCase@#;Ordering[-StringCount[l,#]&/@{"fact","donald"|"obama","done"|"ohio","issue"|"united"|"why"|"world","great"|"many","senator","american"|"believe"|"campaign"|"secretary"|"street"|"wall"},1])[[1]]&

Conta le occorrenze di parole chiave comuni uniche per ciascun candidato e genera il numero del candidato con il punteggio più alto.

Fondamentalmente, ho trovato le parole più comuni di tutti i candidati

t = Import["~/Documents/candidate quotes.txt"];
ts = DeleteCases[StringSplit[t, "\n\n"], ""];
tss = Split[ts, StringLength[#2] > 20 &][[{3, 4, 5, 6, 7, 1, 2}]];
names = StringSplit[#][[2]] & /@ tss[[All, 1]];
quotes = StringSplit[#, "(NEXT PARAGRAPH)"] & /@ StringJoin /@ tss[[All, 2 ;;]];
(* remove the 100 commonest english words *)
wd = WikipediaData["Most common words in English", "ArticleWikicode"];
Flatten[StringSplit[StringCases[wd, 
  Shortest["{| class=\"wikitable\"" ~~ w__ ~~ "}"] -> w], "\n"]];
common100 = 
Alternatives @@ ToLowerCase@DeleteDuplicates@Flatten[StringSplit /@ 
     StringCases[#, 
      "|| " ~~ ("[[" | "") ~~ w : ((WordCharacter | " ") ..) -> 
       w] & /@ %];
commonest = 
  Commonest[
Flatten[StringSplit[
    StringDelete[ToLowerCase[#], 
     PunctuationCharacter | (WordBoundary ~~ (common100) ~~ 
        WordBoundary)]] & /@ #], 20] & /@ quotes;

e ho scelto le parole chiave comuni che sono uniche per ciascun candidato.

keywords = 
 Alternatives @@@ 
  Table[Complement[commonest[[n]], 
    Union[Flatten[Delete[commonest, n]]]], {n, Length[names]}];

Dopo aver eliminato manualmente alcune delle parole chiave, questa è la tabella finale:

Carson    fact
Cruz      donald|obama
Kasich    done|ohio
Rubio     issue|united|why|world
Trump     great|many
Clinton   senator
Sanders   american|believe|campaign|secretary|street|wall

Con queste parole chiave la lunghezza totale della funzione è di 211 caratteri. Ho testato la funzione su tutte le citazioni:

pairs = Flatten[MapThread[Table[q -> #1, {q, #2}] &, {names, quotes}]];
test[q_ -> n_] := Boole[n === names[[p@q]]] (* here p is my function that outputs the predicted candidate's number *)
Total[ParallelMap[test, pairs]]/Length[pairs] // N

che fornisce una precisione del 23,7775%.


3

Python, 25.677868%

Scelto arbitrariamente quattro diversi personaggi che sarebbero stati utilizzati per identificare i candidati. A ciascun candidato viene assegnato un fattore di punteggio per personaggio basato su una ricerca in salita che ho corso per alcuni minuti per finire al 25,68%.

Suppongo che questo provi almeno che il concetto è meglio che scegliere un candidato con gli occhi bendati o semplicemente scegliere Clinton, ma sarei interessato a vedere qualcuno applicare un algoritmo di ricerca migliore, sia per i fattori che per i personaggi utilizzati.

w=dict(zip("hr?.",((.847,.491,.821,.54,.744,.765,.234),(.494,.777,.202,.587,.7,.852,.484),(.915,.187,.161,.559,.748,.244,.43),(.11,.013,.628,.974,1.037,.484,.302))))
def f(t,r=(0,0,0,0,0,0,0)):
 s=r
 for c in t:s=map(lambda a,b:a+b,s,w.get(c,r))
 return s.index(max(s))+1

1

Javascript, TBD

a=[...p].reduce((a,b)=>(a<<5)-a+b.charCodeAt(0)|0,0)%1000,alert(a>0?0:1000,a<79?1:a<226?2:a<333?3:a<497?4:a<697?5:a<849?6:7)

Converte ogni stringa in un codice hash, quindi utilizza metodi probabilistici per determinare l'altoparlante. Sarebbe bello se qualcuno con una buona configurazione potesse testarlo per me.


Conto circa il 16,1%, ma non sono sicuro di cosa faccia. Che cosa fa a + = a? 0: 1000? (Ho dovuto sostituire l'avviso con un ritorno, quindi non ero sicuro di cosa fare esattamente)
soktinpk,

@soktinpk Siamo spiacenti, a+=deve essere stato un refuso.
LegionMammal978,
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.