Wykryj duplikaty pytań

20

Wykryj duplikaty pytań

Dawno, dawno temu istniało pole golfowe. Miał problem: ludzie wielokrotnie zadawali podobne lub identyczne pytania. Ty byłeśwybrani wybrani przymusowo pobrani do szantażu zażądano zautomatyzowania procesu decydowania, czy pytanie jest duplikatem istniejącego, za pomocą wszelkich niezbędnych środków (patrz Reguły).

Wejście

Twój program musi zaakceptować pojedynczy adres URL jako dane wejściowe. Można założyć, że prowadzi to do pytania na codegolf.stackexchange.com .

Wynik

Wyszukaj w witrynie podobne pytania. Jeśli uważasz, że pytanie wejściowe jest duplikatem istniejącego pytania (lub odwrotnie), wypisz adres URL drugiego pytania. Możesz generować wiele adresów URL oddzielonych nowymi wierszami. Na końcu danych wyjściowych dane wyjściowe end(w osobnym wierszu).

Punktacja

  • Jeśli zadane przez Ciebie pytanie rzeczywiście zostało oznaczone jako duplikat pytania wejściowego (lub odwrotnie), zdobywasz 4 punkty. To jest „prawidłowe odgadnięcie”.
  • Za każde fałszywie pozytywne (inaczej „niepoprawne zgadywanie”) tracisz 2 punkty.
  • Za każde pytanie, które faktycznie było duplikatem, ale nie pojawia się w twoich wynikach (inaczej „brak zgadywania”), strac 1 punkt.

Najwyższy wynik po rozpatrzeniu 32 pytań wejściowych wygrywa. Te 32 pytania są „okrągłe”. Na początku każdej rundy wyniki zostaną zresetowane do 0. Jedna runda będzie przeprowadzana co kilka dni, a tabela liderów będzie aktualizowana po każdej rundzie.

Zasady

  • Jeśli pytania A i C zostaną zamknięte jako duplikaty B, A będzie się liczyć jako duplikat C i odwrotnie.
  • Na początku każdej rundy twój program może nie posiadać żadnych danych na temat jakichkolwiek pytań (tj. Bez kodowania na stałe ), z wyjątkiem tego, jak parsować witrynę.
  • Możesz jednak przechowywać dane w plikach zewnętrznych podczas rundy.
  • Żadne dane nie mogą być przechowywane między rundami.
  • Twój wynik musi mieć końcowy nowy wiersz.
  • Nie możesz używać żadnych danych ze strony internetowej, z wyjątkiem wyników wyszukiwania oraz adresu URL, tytułu, tagów i tekstu pytania , z formatowaniem lub bez. Na przykład nie możesz używać tekstu „oznaczonego jako duplikat przez foo, bar ...”, który pojawia się na zduplikowanych pytaniach.
  • Możesz pobrać te dane bezpośrednio z witryny, za pośrednictwem data.SE lub interfejsu API.
  • Każde zgłoszenie musi mieć nazwę.
  • Każde zgłoszenie musi mieć czytelną numerację wersji.
  • Jeśli zgłoszenie nie przyniesie rezultatu po upływie określonego czasu (do ustalenia; proszę określić, jak długo trwa zgłoszenie), zostanie zabite i straci 8 punktów.

źródło
2
Czy minuta nie jest subiektywna? Połączenia sieciowe i indeksowanie doprowadzą do ogromnej liczby żądań internetowych. Może to zająć każdemu więcej niż 1 minutę :)
Optymalizator
4
Myślę, że nie możemy dojść bezpośrednio do tego numeru, być może będziesz musiał napisać przykładowy program samodzielnie (lub skorzystać z pierwszej odpowiedzi), aby ustalić właściwy czas progowy.
Optymalizator
7
Zamiast skrobać witrynę, powinieneś przejść przez interfejs API i określić, które pola mogą być używane.
Gilles „SO- przestań być zły”
5
Byłoby tak zabawnie, gdyby to pytanie było duplikatem .. o ironia xD
Teun Pronk
3
@professorfish Możesz naprawdę skorzystać z niektórych przypadków testowych, proszę bardzo. Wszystkie te dane pochodzą z Data.SE, więc powinny być wiarygodne. Spraw, żebym wyglądała głupio i udowodniła, że ​​się mylę. To pytanie ma kodegolf.stackexchange.com/q/37737 nie ma duplikatów. To pytanie codegolf.stackexchange.com/q/12348 ma to codegolf.stackexchange.com/q/10465 To pytanie codegolf.stackexchange.com/q/12498 ma te codegolf.stackexchange.com/q/20006 codegolf.stackexchange.com/ q / 242
PenutReaper,

Odpowiedzi:

3

Python 3

Nadaję temu wpisowi nazwę The Differ.

Kod:

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")

Filtr "!-*f(6rc.cI8O"zawierał totalparametr globalnego obiektu opakowania i bodyparametr na pytania.

Ten wpis powoduje, że dwa żądania API plus jeden na tag w pytaniu plus jeden na sto pytań w jego najmniej używanym tagu. Jeśli uderzy w przepustnicę API (której nie sprawdza), podniesieurllib.error.HTTPError: HTTP Error 400: Bad Request

pppery
źródło