Кто это сказал? Президентские выборы 2016


16

В этой задаче ваша задача состоит в том, чтобы написать программу длиной менее 300 символов, которая содержит короткий параграф или несколько предложений, которые сказал кандидат, и выдает их.

Ввод : может быть взят в качестве параметра для функции, для ввода в программу и т. Д. Это будет короткий абзац, отмеченный должным образом.

Вывод : кандидат, который, как вы думаете, есть. Это может быть одним из

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

Я исключил имена людей, которые выпали из 1 марта. Вы можете вывести само имя или, что более удобно, номер, соответствующий имени.

Подсчет баллов: ваш балл - это процент тестовых случаев, которые вы получили. Самый высокий балл выигрывает. Галстуки (или отличные результаты) разбиваются по длине кода, как в коде гольфа.

Контрольные примеры могут быть получены из:

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

Нажмите на каждую дискуссию, как демократов, так и республиканцев, которые произошли до сих пор (до 1 марта). Каждый абзац является тестовым примером, если только «абзац» не содержит менее 20 символов.

Вот код, который вытаскивает контрольные примеры с определенной страницы:

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

Затем вы categ.SANDERSможете получить список всех абзацев, которые сказал сенатор Сандерс.

Вы можете отказаться от всего, что не сказано кандидатами, перечисленными выше (например, categ.BUSHили categ.CHRISTIE).

Вот файл со всеми тестами: https://drive.google.com/file/d/0BxMn8--P71I-bDZBS2VZMDdmQ28/view?usp=sharing

Файл организован кандидатом

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.

Пример частичного представления будет:

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

или

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

Вот место, где вы можете протестировать решения javascript: https://jsfiddle.net/prankol57/abfuhxrh/

Код использует параметр pдля представления фразы для классификации. Пример кода, который набирает около 20% (угадывание получит около 11%):

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

Именно то, что я спрашиваю: напишите программу / функцию длиной менее 300 символов, которая принимает в качестве входных данных фразу, которую сказал кандидат, и возвращает в качестве выходной информации, какой кандидат сказал это. Ваша оценка - это процент тестовых случаев, которые вы получили правильно. Самый высокий балл выигрывает.

Да, я знаю, что много строк есть [laughter]или [cheering]в них. Они не будут удалены. В худшем случае это дополнительная информация, которую вы можете игнорировать; в лучшем случае это дополнительная информация, которую вы можете использовать (например, я придумал это, но, может быть, смех людей свидетельствует о том, что говорит Марко Рубио). Контрольные примеры, как они появляются в текстовом файле.


1
У меня есть предложение. Как насчет того, чтобы сделать код-гольф, но вы должны правильно составить все цитаты? Кроме того, вы можете захотеть сделать цитаты намного короче, так как это немного нелепо решать как есть.
Cyoce

2
@Cyoce, получая все цитаты правильно, было бы смешно (я думаю), учитывая огромное количество цитат.
soktinpk

1
Умная идея вызова, возможно, нуждается в некотором усовершенствовании все же. Вы рассматривали возможность размещения в Песочнице для получения обратной связи?
Эшвин Гупта

1
Какой критерий выигрыша? (И почему вы думаете, что никто не получит идеальный счет?)
Питер Тейлор

2
Предоставленные вами исходные данные немного запутаны (их сложно проанализировать автоматически), что, я думаю, лишает вас духа проблемы. Я сделал очищенную версию, которая использует одну строку в цитате, с пустой строкой, разделяющей следующее имя кандидата. Это гораздо проще разобрать на большинстве языков. Я загрузил его здесь: drive.google.com/file/d/0B3uyVnkMpqbVSnVrZkVwTUhDODg (кроме изменения перевода строки, я оставил данные нетронутыми. Это включает в себя то, что похоже на проблему с кодировкой для -)
Дейв

Ответы:


14

Полиглот, ~ 18,6%

Это работает в: Cjam, Pyth, TeaScript, Japt, Seriously, 05AB1E, GolfScript, Jelly и, возможно, многих других.

6

Это выводит Хиллари для всех входов. Это потому, что Хиллари сказала больше всего. Пока это не самый гениальный способ сделать это. Это работает ¯ \ _ (ツ) _ / ¯


Мне нравится, как это помечается как сообщение низкого качества. : P
Денкер

1
@DenkerAffe, вероятно, за то, что он короткий
Downgoat

1
Любая причина для использования JavaScript? Вы могли бы сыграть в гольф до одного символа на другом языке: P
ghosts_in_the_code

@ghosts_in_the_code исправлено
Downgoat

9

Pyth, 34,16% (297 байт)

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

(обратите внимание, что некоторые строки заканчиваются пробелами)

Я выбрал самый простой вариант: проверить список шаблонов и, как только вы найдете совпадение, вывести соответствующий кандидат. Если ничего не помогает, выведите наиболее вероятного кандидата из остатка. После этого все сводится к тому, чтобы собрать как можно больше данных в 300 байт.

FNc"<data>"bI}tNrzZhNB

Сломать:

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.

Так откуда эти данные? Ну структура просто:

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

(с записью в конце без фразы, которая будет действовать как последний запасной вариант)

Но почему именно эти предметы? Я написал программу на C ++ для анализа предоставленного набора данных (сначала с некоторой ручной очисткой строк, чтобы сделать структуру согласованной). Он просматривает все подстроки ("токены") в каждой кавычке (1-16 символов), затем многократно проверяет токен, который дает наибольшую выгоду, чтобы идти дальше в списке. Как только шаблон находится в списке, удалите все кавычки, которые ему соответствуют, и повторите (становится немного сложнее, чтобы сохранить его быстрым, но это основы). Код, вероятно, слишком длинный для включения в него, но я мог бы поместить его на github позже (когда я немного его почистил).

Я попробовал пару систем оценки. В конце концов я пошел с этим:

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

Более строгий подход, заключающийся в том, что допускаются только новые элементы, которые не содержат неправильных ответов, застрял примерно на 20-25%, и для этого нужно было много моделей. Этот нечеткий подход делает намного лучше, и все еще может достигать точности ~ 80% (с 550 пунктами). В представленном счете 38 пунктов, и это было самое большее, что я мог вместить в 300 символов.

34% -ный результат фактически получается из тестовой программы C ++, которая выполняет те же шаги. Он должен совпадать, но у меня нет тестовой оснастки Pyth для проверки.

Это первый раз, когда я использую Pyth, поэтому я предполагаю, что можно сжать еще несколько байтов, что позволит немного больше данных.


4
Также теперь я знаю, что Сандерс любит говорить о секретаре Клинтоне, Клинтон одержим сенатором Сандерсом, Касич любит Огайо, Круз всегда упоминает Дональда Трампа, Рубио одержим веками, у Карсона есть все «факты» этого вопроса, и Трамп полностью любит говорить "полностью". Это похоже на начало генератора политики-бинго. Я должен буду попробовать это на некоторых британских личностях ...
Дэйв

Я думаю, вы могли бы сэкономить здесь несколько байтов, упаковав строку в .".
lirtosiast

8

Javascript, 32,87%

299 символов:

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

Стратегия:

Я выполнил поиск по методу Брюса, какие сегменты слова должны быть включены в «хэш». Затем происходит поиск строки с этим хешем таким образом, чтобы выбрать наиболее вероятного кандидата для этого хеша.

Сам код:

// 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

Это моя первая подача кода в гольф, поэтому предложения приветствуются :)


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]]&

Он подсчитывает количество общих ключевых слов, уникальных для каждого кандидата, и выводит количество кандидатов с наибольшим количеством баллов.

В основном, я нашел наиболее распространенные слова всех кандидатов

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;

и выбрал общие ключевые слова, которые являются уникальными для каждого кандидата.

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

После удаления некоторых ключевых слов вручную получается финальная таблица:

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

С этими ключевыми словами общая длина функции составляет 211 символов. Я проверил функцию над всеми кавычками:

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

что дает точность 23,7775%.


3

Python, 25,677868%

Произвольно выбрал четыре разных персонажа, которые будут использоваться для идентификации кандидатов. Каждому кандидату присваивается коэффициент оценки на каждого персонажа на основе поиска по восхождению на холм, который я выполнял в течение нескольких минут, чтобы в итоге получить 25,68%.

Я предполагаю, что это, по крайней мере, доказывает, что концепция лучше, чем выбор кандидата с завязанными глазами или просто выбор Клинтона, но мне было бы интересно увидеть кого-то, кто применяет лучший алгоритм поиска, как по факторам, так и по используемым символам.

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)

Преобразует каждую строку в хеш-код, а затем использует вероятностные методы для определения говорящего. Было бы хорошо, если бы кто-то с хорошей настройкой мог проверить это для меня.


Я считаю около 16,1%, но я не совсем уверен, что он делает. Что делает a + = a? 0: 1000? (Я должен был заменить предупреждение на возврат, поэтому я не был уверен, что именно делать)
soktinpk

@soktinpk Извините, a+=должно быть, это опечатка.
LegionMammal978
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.