チャレンジ類似性検出器


11

チャレンジ

2つの質問IDが与えられたら、回答を見て、それらがどれほど似ているかを理解してください。

詳細

の2つの質問IDが与えられcodegolf.stackexchange.comます。削除されていないが、必ずしも開かれているわけではない両方のIDに関する質問が存在すると想定することができます。すべての回答を調べて、2つの質問に対する回答のコード間の最小レーベンシュタイン距離を決定する必要があります(削除された回答は含まれません)。つまり、質問1のすべての回答を質問2のすべての回答と比較し、最小レーベンシュタイン距離を決定する必要があります。回答内のコードを見つけるには、次の手順を想定します。

コードスニペットを見つける方法

テキストの本文は、上にテキストがない場合を除き、バックティック内にあり、独自の行にある場合、または4つのスペースでインデントされ、その上に空の行がある場合、回答の実際のコードです。

有効で無効なコードスニペットの例(.スペースとして)(等号のトンで区切られている)

This is `not a valid code snippet because it is not on its own line`
========================================
This is:
`A valid code snippet`
========================================
This is
....not a valid code snippet because there's no spacing line above
========================================
This is

....A valid code snippet because there's a spacing line above
========================================
....Valid code snippet because there's no other text
========================================

回答に有効なコードスニペットがない場合は、回答を完全に無視してください。最初のコードブロックのみを取得する必要があることに注意してください。

最終仕様

2つの整数には、2つの質問IDを適切な形式で入力できます。出力は、いずれかのチャレンジからの任意の2つの有効な回答間の最小レーベンシュタイン距離でなければなりません。課題の一方または両方に対して「有効な」回答がない場合は、output -1

テストケース

同志のSparklePonyによるチャレンジ115715(Embedded Hexagons)および116616(Embedded Triangles)の場合、2つのチャコールの回答(両方ともKritixiLithosによる)のレーベンシュタイン距離は23で、これは最小でした。したがって、の出力はに115715, 116616なります23

編集

APIページサイズの制限により、質問には最大100の回答があると想定できます。コードブロック内のバックティックを無視しないでください。コードブロック自体が、独自の行ではなくバックティックを使用して作成されている場合に限ります。

編集

賞金期間を早期に終了したのは、MODに1週間の停止をリクエストし、最高得点の回答(最長の場合)に賞金が自動的に与えられることを望まなかったためです。新たな提出物が入ってくるか、提出物が実際に報奨期間の終了(6月1日のUTC 00:00)の前に532バイトより短くなるように十分にゴルフされた場合、私はその約束に忠実であり続けるための報奨金を与えます停止の期限が切れます。正しく覚えていれば、次回は賞金期間を2倍にする必要があります。そのため、回答が得られた場合、+ 200が得られる可能性があります:)


1
有効なコードスニペットとしてカウントされるものに混乱しています。なぜHTMLの<code>タグにあるものだけではないのですか?
カルビンの趣味

@HelkaHomba改行の制限はどうですか?それらを組み込む別の方法を見つけることを試みることができます。
ハイパーニュートリノ

@HelkaHomba基本的に、回答の行内にバックティックで区切られたコードが含まれる場合、無視する必要があります。
ハイパーニュートリノ

これは、答えの1つであり、質問の主要部分を行う方が簡単です。ページをダウンロードしてコードブロックを抽出するのは、レーベンシュタイン距離を実行するよりも困難です。
バリント

1
涼しい。チェックしてるだけ。
マット

回答:


1

PowerShell、532バイト

$1,$2=$args
$a={irm "api.stackexchange.com/2.2/questions/$args/answers?pagesize=100&site=codegolf&filter=!9YdnSMKKT"|% i*}
$r={$args.body-replace"(?sm).*?^(<pre.*?>)?<code>(.*?)</code>.*",'$2'}
$1=&$a $1;$2=&$a $2
(0..($1.count-1)|%{
    $c=&$r $1[$_]
    0..($2.count-1)|%{
        &{$c,$d=$args;$e,$f=$c,$d|% le*;$m=[object[,]]::new($f+1,$e+1);0..$e|%{$m[0,$_]=$_};0..$f|%{$m[$_,0]=$_};1..$e|%{$i=$_;1..$f|%{$m[$_,$i]=(($m[($_-1),$i]+1),($m[$_,($i-1)]+1),($m[($_-1),($i-1)]+((1,0)[($c[($i-1)]-eq$d[($_-1)])]))|sort)[0]}};$m[$f,$e]} $c $d
    }
}|sort)[0]

読みやすくするために改行を入れました。それでも、バイトカウントに反映されます。

私はこれを理解しているはずです。PowerShellには私の知る限り組み込みの機能がないため、私にとって難しいのは実際にレーベンシュタインの距離を取得することでした。そのため、レーベンシュタインの距離に関する課題に答えることができました。私のコードがLDの匿名関数を参照している場合、その答えを参照して、それがどのように機能するかについての詳細な説明を参照できます。

コメントと進行状況インジケーター付きのコード

コードは(LDのせいで)本当に遅くなる可能性があるので、進行状況インジケーターが組み込まれているため、展開中のアクションを追跡でき、どこかにループが発生しているとは思いません。進行状況を監視するためのコードは、最上位ブロックにもバイトカウントにも含まれていません。

# Assign the two integers into two variables. 
$1,$2=$args

# Quick function to download up to 100 of the answer object to a given question using the SE API
$a={irm "api.stackexchange.com/2.2/questions/$args/answers?pagesize=100&site=codegolf&filter=!9YdnSMKKT"|% i*}

# Quick function that takes the body (as HTML) of an answer and parses out the likely codeblock from it. 
$r={$args.body-replace"(?sm).*?^(<pre.*?>)?<code>(.*?)</code>.*",'$2'}

# Get the array of answers from the two questions linked.
$1=&$a $1;$2=&$a $2

# Hash table of parameters used for Write-Progress
# LD calcuations can be really slow on larger strings so I used this for testing so I knew 
# how much longer I needed to wait.
$parentProgressParameters = @{
    ID = 1 
    Activity = "Get LD of all questions" 
    Status = "Counting poppy seeds on the bagel"
}

$childProgressParameters = @{
    ID = 2
    ParentID = 1
    Status = "Progress"
}


# Cycle each code block from each answer against each answer in the other question.
(0..($1.count-1)|%{
    # Get the code block from this answer
    $c=&$r $1[$_]

    # Next line just for displaying progress. Not part of code. 
    Write-Progress @parentProgressParameters -PercentComplete (($_+1) / $1.count * 100) -CurrentOperation "Answer $($_+1) from question 1"

    0..($2.count-1)|%{
        # Get the code block from this answer   
        $d=&$r $2[$_]

        # Next two lines are for progress display. Not part of code. 
        $childProgressParameters.Activity = "Comparing answer $($_+1) of $($2.count)"
        Write-Progress @childProgressParameters -PercentComplete (($_+1) / $2.count * 100) -CurrentOperation "Answer $($_+1) from question 2"

        # Anonymous function to calculate Levenstien Distance
        # Get a better look at that function here: /codegolf//a/123389/52023
        &{$c,$d=$args;$e,$f=$c,$d|% le*;$m=[object[,]]::new($f+1,$e+1);0..$e|%{$m[0,$_]=$_};0..$f|%{$m[$_,0]=$_};1..$e|%{$i=$_;1..$f|%{$m[$_,$i]=(($m[($_-1),$i]+1),($m[$_,($i-1)]+1),($m[($_-1),($i-1)]+((1,0)[($c[($i-1)]-eq$d[($_-1)])]))|sort)[0]}};$m[$f,$e]} $c $d
    }
# Collect results and sort leaving the smallest number on top.
}|sort)[0]

コードブロックを見つけるための私のロジックは、HTMLとして回答を取得し、オプションで独自の行で始まるpreタグセットに囲まれたcodeタグセットを探すことです。テストでは、6つの異なる質問セットのすべての正しいデータが見つかりました。

マークダウンコードから作業を試みましたが、適切なコードブロックを見つけるのは難しすぎました。

サンプル実行

Challenge-Similarity-Detector 97752 122740
57

Challenge-Similarity-Detector 115715 116616
23

私はこれを調べるのに3日間の大半を費やしました。この挑戦は、最も楽しい試みのための私のトップ5です。TFTC(チャレンジありがとう)
マット

良くやった!ありがとう、私はあなたがそれを楽しんでくれてうれしいです!:)
HyperNeutrino

注:一時停止をリクエストしているため、後ほど授与できないため、記載されているよりも早く賞金を授与しました。よくやった!:)
HyperNeutrino

停止をリクエストしますか?
マット

はい、デニスに1週間の休学をお願いして、学校の仕事に集中できるようにしました。それは以前に行われました(私はまだここにいますが...いつ消えるかわかりません)。
ハイパーニュートリノ

3

Java + Jsoup、1027バイト

最初の2つの引数は質問IDです。

ゴルフ済み:

import org.jsoup.*;import org.jsoup.nodes.*;class M{String a1[]=new String[100],a2[]=new String[100],c[];int i1=0,i2=0;public static void main(String a[])throws Exception{String r="/codegolf/";M m=new M();m.c=m.a1;m.r(Jsoup.connect(r+a[0]).get());m.c=m.a2;m.r(Jsoup.connect(r+a[1]).get());int s=m.ld(m.a1[1],m.a2[1]);for(int i=2;i<m.a1.length;i++)for(int j=2;j<m.a2.length;i++){if(m.a1[i]==null)break;int d=m.ld(m.a1[i],m.a2[j]);if(d<s)s=d;}System.out.print(s);}void r(Document d){a:for(Element e:d.select("td")){for(Element p:e.select("pre")){ a(p.select("code").get(0).html());continue a;}}}void a(String d){c[c==a1?i1++:i2++]=d;}int ld(String a,String b){a=a.toLowerCase();b=b.toLowerCase();int[]costs=new int[b.length()+1];for(int j=0;j<costs.length;j++)costs[j]=j;for(int i=1;i<=a.length();i++){costs[0]=i;int nw=i-1;for(int j=1;j<=b.length();j++){int cj=Math.min(1+Math.min(costs[j],costs[j-1]),a.charAt(i-1)==b.charAt(j-1)?nw:nw+1);nw=costs[j];costs[j]=cj;}}return costs[b.length()];}}

読みやすい:

import org.jsoup.*;import org.jsoup.nodes.*;

class M {
    String a1[]=new String[100],a2[]=new String[100],c[];
    int i1=0,i2=0;
    public static void main(String a[])throws Exception{
    String r="/codegolf/";
    M m=new M();

    m.c=m.a1;
    m.r(Jsoup.connect(r+a[0]).get());
    m.c=m.a2;
    m.r(Jsoup.connect(r+a[1]).get());

    int s=m.ld(m.a1[1],m.a2[1]);
    for(int i=2;i<m.a1.length;i++)for(int j=2;j<m.a2.length;i++){if(m.a1[i]==null)break;int d=m.ld(m.a1[i],m.a2[j]);if(d<s)s=d;}
    System.out.print(s);
}

void r(Document d) {
    a:for(Element e:d.select("td")) {for(Element p:e.select("pre")) { 
        a(p.select("code").get(0).html());
        continue a;
    }}
}

void a(String d){c[c==a1?i1++:i2++]=d;}

int ld(String a, String b) {
    a = a.toLowerCase();
    b = b.toLowerCase();
    int [] costs = new int [b.length() + 1];
    for (int j = 0; j < costs.length; j++)costs[j] = j;
    for (int i = 1; i <= a.length(); i++) {
        costs[0] = i;
        int nw = i - 1;
        for (int j = 1; j <= b.length(); j++) {
            int cj = Math.min(1 + Math.min(costs[j], costs[j - 1]), a.charAt(i - 1) == b.charAt(j - 1) ? nw : nw + 1);
            nw = costs[j];
            costs[j] = cj;
        }
    }
    return costs[b.length()];
}

}


それに私を打つ!!!! いいね!
-tuskiomi

1
PPCGへようこそ!サードパーティのライブラリを使用することは規則に反しませんが、ライブラリの使用を言語で明記する必要があります(したがって、JavaHTMLというライブラリを使用するJavaの回答には「Java + JavaHTML」というラベルが付けられます)。
メゴ

わかった、ありがとう!次回もそのことを心に留めておきます!
トマホーク

必要に応じて、このチャレンジでライブラリを使用するのを妨げるものは何もありません。
マット

誰かが私の答えを突破した今、私はしなければならないかもしれません!
トマホーク

0

Mathematica、540バイト

f=Flatten;l=Length;P=StringPosition;(H[r_]:=Block[{s,a,t,k},t={};d=1;k="/codegolf/"<>r;s=First/@P[Import[k,"Text"],"<pre><code>"];a=f[First/@P[Import[k,"Text"],"answerCount"]][[1]];While[d<l@s,If[s[[d]]>a,AppendTo[t,s[[d]]]];d++];Table[StringDelete[StringCases[StringTake[Import[k,"Text"],{t[[i]],t[[i]]+200}],"<pre><code>"~~__~~"</code></pre>"],{"<pre><code>","</code></pre>"}],{i, l@t}]];Min@DeleteCases[f@Table[EditDistance[ToString@Row@H[#1][[i]],ToString@Row@H[#2][[j]]],{i,l@H[#1]},{j,l@H[#1]}],0])&


入力

["115715"、 "116616"]

出力

23

組み込みのEditDistanceを使用して、「文字列またはベクトルuとvの間に編集距離またはレーベンシュタイン距離を与えます」。

テストケースは数学

EditDistance["FN«AX²ιβ×__β↓↘β←↙β↑←×__β↖β→↗β","NαWα«X²ι↙AX²⁻ι¹β↙β↑↖β→A⁻α¹α"]

23を返します

もう少しゴルフができると思う
走るのに数分かかる

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.