誰が言った?2016年大統領選挙


16

この課題では、あなたの仕事は、候補者が言った短い段落またはいくつかの文を取り、それを誰が言ったかを出力する300文字未満のプログラム作成することです。

入力:関数へのパラメーター、プログラムへの入力などとして使用できます。短い段落で、適切に区切られています。

出力:あなたがそうだと思う候補。これは

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

3月1日の時点で中退した人の名前は省略しました。名前自体を出力することも、より便利なことに、名前に対応する番号を出力することもできます。

スコアリング: あなたのスコアは、あなたが正しいテストケースの割合です。最高スコアが勝ちます。コードゴルフのように、タイ(またはパーフェクトスコア)はコードの長さによって分割されます。

テストケースは以下から取得できます。

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

これまでに起こった(3月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
提案があります。コードゴルフにするにはどうすればいいですか?ただし、すべての引用符を正しく取得する必要がありますか?また、現状のままで解決するのは少しばかげているので、引用をもっと短くしたいかもしれません。
チョイス

2
@Cyoceがすべての引用符を正しく取得するのは、引用符の数が多いことを考えるとばかげている(と思う)。
-soktinpk

1
巧妙な挑戦のアイデアは、しかし、いくつかの洗練を必要とするかもしれません。フィードバックのためにSandboxに投稿することを検討しましたか?
アシュウィングプタ

1
勝利基準は何ですか?(そして、なぜ誰も完璧なスコアを獲得できないと思いますか?)
ピーターテイラー

2
あなたが提供したソースデータは少し厄介で(自動的に解析するのが困難です)、チャレンジの精神の一部を取り除くと思います。次の候補名を空白行で区切って、引用ごとに1行を使用するクリーンアップバージョンを作成しました。これは、ほとんどの言語で解析するのがはるかに簡単です。私はここでそれをアップロードしました:drive.google.com/file/d/0B3uyVnkMpqbVSnVrZkVwTUhDODgは、(改行を変更する以外に、私はそのままデータを残してきたのエンコーディングの問題どのように見えるかを含んでいること- 。)
デイブ

回答:


14

ポリグロット、〜18.6%

これは、Cjam、Pyth、TeaScript、Japt、Seriously、05AB1E、GolfScript、Jelly、およびその他の多くで動作します。

6

これにより、すべての入力に対してヒラリーが出力されます。これは、ヒラリーが最も言ったからです。これを行うための最も巧妙な方法ではありませんが。動く¯\ _(ツ)_ /¯


これが低品質の投稿としてフラグ付けされる方法が気に入っています。:P
デンカー

1
@DenkerAffeはおそらく短いため
-Downgoat

1
JavaScriptを使用する理由は何ですか?他のいくつかの言語で1文字にゴルフすることができます。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
また、私は今、サンダースがクリントン秘書について話すのが大好きで、クリントンは上院議員サンダースに夢中になっている、カシッチはオハイオが大好き、クルーズは常にドナルド・トランプに言及している、ルビオは世紀に夢中、カーソンにはすべての「事実」があり、トランプは「完全に」と言うのが大好きです。これは、政治ビンゴジェネレーターの始まりのように感じます。英国のいくつかのパーソナリティで試してみる必要があります…
デイブ

で文字列をパックすることで、ここでいくつかのバイトを節約できると思います."
リルトシアスト

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%

候補者を識別するために使用される4つの異なる文字を任意に選択しました。各候補には、私が数分間実行して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
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.