중복 질문 감지


20

중복 질문 감지

옛날 옛적에 골프장이있었습니다. 문제가있었습니다. 사람들은 유사하거나 동일한 질문을 반복해서 게시 할 것입니다. 당신은선택된 강제 강제 협박 질문은 필요한 방법으로 질문이 기존 질문과 중복되는지 여부를 결정하는 프로세스를 자동화하도록 요청했습니다 (규칙 참조).

입력

프로그램은 단일 URL을 입력으로 승인해야합니다. 이것이 codegolf.stackexchange.com 에 대한 질문으로 이어진다 고 가정 할 수 있습니다 .

산출

비슷한 질문이 있는지 사이트를 검색하십시오. 입력 질문이 기존 질문의 복제본이라고 생각하거나 다른 질문의 URL을 출력하십시오. 새 줄로 구분하여 여러 개의 URL을 출력 할 수 있습니다. 출력이 끝나면 출력 end(별도의 줄로).

채점

  • 출력 한 질문이 실제로 입력 질문의 복제본으로 표시되거나 그 반대의 경우 4 점을 얻습니다. 이것은 "올바른 추측"입니다.
  • 각 오 탐지 (일명 "잘못된 추측")에 대해 2 점을 잃습니다.
  • 실제로 중복되었지만 출력에 나타나지 않는 각 질문 (일명 "미스 추측")에 대해 1 점을 잃습니다.

32 개의 입력 질문을 처리 한 후 가장 높은 점수가 이깁니다. 이 32 개의 질문은 "라운드"입니다. 각 라운드가 시작될 때 점수는 0으로 재설정됩니다. 며칠에 한 번 라운드가 진행되고 각 라운드 후에 순위표가 업데이트됩니다.

규칙

  • 질문 A와 C가 둘 다 B의 복제본으로 닫히면 A는 C의 복제본으로 계산되며 그 반대도 마찬가지입니다.
  • 각 라운드가 시작될 때 프로그램은 웹 사이트를 파싱하는 방법을 제외하고는 질문에 대한 데이터를 가지고 있지 않을 수 있습니다 ( 하드 코딩 없음 ).
  • 그러나 라운드 중에 외부 파일에 데이터를 보관할 수 있습니다.
  • 라운드 사이에 데이터를 유지할 수 없습니다.
  • 출력에는 새로운 줄이 있어야합니다.
  • 검색 결과 및 질문의 URL, 제목, 태그 및 텍스트를 제외하고 서식이 있거나없는 웹 사이트의 데이터를 사용할 수 없습니다 . 예를 들어, 중복 질문에 나타나는 "foo, bar ...로 중복 표시됨"이라는 텍스트를 사용할 수 없습니다.
  • 이 데이터는 사이트, data.SE 또는 API를 통해 직접 검색 할 수 있습니다.
  • 각 제출물에는 이름이 있어야합니다.
  • 각 제출에는 명확한 버전 번호가 있어야합니다.
  • 시간 제한 이후에 제출물이 출력물을 생성하지 않으면 (결정, 제출 시간이 얼마인지 명시) 제출물은 종료되고 8 점을 잃게됩니다.

2
1 분이 주관적이지 않습니까? 네트워크 연결 및 크롤링으로 수많은 웹 요청이 발생합니다. 모두에게 1 분 이상이 걸릴 수 있습니다. :)
Optimizer

4
나는 우리가 그 숫자에 직접 도달 할 수 없다고 생각합니다. 올바른 임계 시간을 결정하기 위해 예제 프로그램을 직접 작성해야하거나 첫 번째 대답을 사용해야 할 수도 있습니다.
Optimizer

7
사이트를 스크랩하는 대신 API를 통해 사용 가능한 필드를 지정해야합니다.
Gilles 'SO- 악의를 멈춰라'

5
이 질문이 중복된다면 너무 재미있을 것입니다 .. oh irony xD
Teun Pronk

3
@professorfish 당신은 실제로 몇 가지 테스트 사례를 사용할 수 있습니다. 이 데이터는 모두 Data.SE에서 가져온 것이므로 신뢰할 수 있어야합니다. 내가 바보처럼 보이고 나를 잘못 증명하게 자유롭게 느끼십시오. 이 질문에는 codegolf.stackexchange.com/q/37737 에 중복이 없습니다. 이 질문 codegolf.stackexchange.com/q/12348 에는이 codegolf.stackexchange.com/q/10465가 있습니다. 이 질문 codegolf.stackexchange.com/q/12498 에는 다음 codegolf.stackexchange.com/q/20006이 있습니다 q / 242
PenutReaper

답변:


3

파이썬 3

이 항목에 이름을 부여하고 The Differ있습니다.

암호:

import urllib.request, gzip, re, json, difflib, sys
API_URL = "https://api.stackexchange.com/"
qurl = input()
qid = int(re.search("\d+",qurl).group(0))
def request(url,wrapper=False,**params):
    params.setdefault("filter","withbody")
    params.setdefault("site","codegolf")
    url = API_URL + url + "?"+"&".join([str(k)+"="+str(v) for k,v in params.items()])
    compressed_response = urllib.request.urlopen(url)
    response = gzip.decompress(compressed_response.read()).decode("utf8")
    response_object = json.loads(response)
    if wrapper:
        return response_object
    else:
        return response_object["items"]
question = request("questions/%s"%qurl)[0]
tags = ";".join(question["tags"])
title = question["title"]
escaped = title.replace(" ","%20")
related = request("similar",title=escaped,pagesize=100)
hasmore = False
length = sys.maxsize
for tag in question["tags"]:
    result = request("search",tagged=tag,
                     wrapper=True,
                     filter="!-*f(6rc.cI8O",
                     pagesize=100)
    if result["total"] < length:
        length = result["total"]
        related.extend(result["items"])
        hasmore = result["has_more"]
        besttag = tag
related.extend(best)
if length < 1500:
    for page in itertools.count(2):
        if not hasmore:
            break
        response = request("search",
                           tagged=besttag,
                           page=page,
                           pagesize=100,
                           filter="!-*f(6rc.cI8O",
                           wrapper=True)
        hasmore = response["has_more"]
        related.extend(result["items"])
matcher = difflib.SequenceMatcher(None, question["body"], None)
titlematcher = difflib.SequenceMatcher(None, question["title"], None)
seen = set()
seen.add(question["question_id"])
for possible in related:
    matcher.set_seq2(possible["body"])
    titlematcher.set_seq2(possible["title"])
    score = matcher.ratio()+titlematcher.ratio()
    qid = possible["question_id"]
    if score > .85 and qid not in seen:
        print(qid)
        seen.add(qid)
print("end")

필터 "!-*f(6rc.cI8O"에는 total전역 랩퍼 오브젝트의 body매개 변수와 질문 의 매개 변수가 포함되었습니다.

이 항목은 두 개의 API 요청과 질문에 대한 태그 당 하나, 가장 적게 사용 된 태그에 대한 질문 당 100 개를 만듭니다. 확인하지 않은 api throttle에 도달하면urllib.error.HTTPError: HTTP Error 400: Bad Request

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.