Odgadnij język

23

Wprowadzenie

Ta strona szybko buduje ogromny zbiór danych fragmentów kodu, więc zróbmy coś z tym!

Oto plik danych . Zawiera 9 066 unikalnych par język + fragment kodu dla 113 języków, wszystkie pobrane z tej witryny. Format jest rozdzielony tabulatorami (język-TAB-urywek), wszystkie znaki nowego wiersza we urywkach są zastąpione <LF>, a wszystkie tabulacje zastąpione 4 spacjami. Istnieje co najmniej 5 fragmentów dla każdego języka.

[aktualizacja: Wprowadziłem niewielką zmianę w pliku danych, aby scalić niektóre wersje Pythona i RegExp, które wcześniej mi brakowały - powyższy link został zaktualizowany]

Wyzwanie

Napisz program lub funkcję, która pobiera fragment kodu i wyświetla język, w którym jest napisany (szczegóły poniżej). Całkowity rozmiar źródła + wszelkie wymagane dane muszą wynosić 300 bajtów lub mniej, a program musi wyświetlać poprawny język, jeśli otrzyma własny kod źródłowy. Wygrywa najwyższa dokładność (najbardziej poprawne odpowiedzi w powyższym zestawie danych).

Zasady

  • Całkowity rozmiar kodu źródłowego, zasobów i wymaganych flag kompilacji / środowiska wykonawczego nie może przekraczać 300 bajtów.
  • Twoja odpowiedź zostanie przetestowana w oparciu o powyższy zestaw danych; otrzyma jedną z wartości „Snippet” jako dane wejściowe, a jego wyniki zostaną porównane z „poprawnymi” danymi wyjściowymi zgodnie z zestawem danych. Zostanie to powtórzone dla wszystkich wpisów w zbiorze danych, a ostateczna liczba poprawnych odpowiedzi to Twój wynik.
  • Możesz wybrać kodowanie wejściowe - zakładam UTF-8, więc jeśli potrzebujesz innego kodowania, podaj je w swojej odpowiedzi.
  • Nie musisz używać <LF>zamiennika dla nowych linii; jeśli twój wpis spodziewa się otrzymywać nowe wiersze jako dosłowne nowe znaki (znak 10), określ to w swojej odpowiedzi.
  • Wpis musi zawierać język, w którym według niego jest wpisany fragment kodu. Aby uniknąć konieczności kompresji wielu ciągów językowych, pozwolę na odwzorowania (jeśli chcesz wypisać 3 dla „Java”, to w porządku); zwróć uwagę na mapowania w swojej odpowiedzi.
  • Możesz mieć tylko 1 mapowanie wyjściowe dla każdego języka (tzn. Jeśli 3 oznacza „Java”, nie możesz również mieć 4 oznaczenia „Java”).
  • Po otrzymaniu własnego kodu źródłowego twój program musi uzyskać poprawną odpowiedź (musi wypisać język, w którym jest napisany).
  • Nie musisz obsługiwać wszystkich języków w zbiorze danych i możesz wesprzeć dodatkowe języki, jeśli chcesz (np. Jeśli twój wpis nie jest w jednym z języków w zbiorze danych).
  • Twój program musi być deterministyczny (dwukrotne podanie tego samego sygnału wejściowego musi dać ten sam wynik).

Łamanie krawatów

  • Decyzje dotyczące remisów będą redukowane przez zestaw danych do momentu wygrania jednego wpisu. Zestaw danych zostanie zmniejszony przez usunięcie wszystkich fragmentów dla najpopularniejszego języka (tzn. Powiązania są przerywane przez dokładność w rzadszych językach). Na przykład, jeśli A i B uzyskają 70% wyniku w pełnym zbiorze danych, wszystkie fragmenty Pythona zostaną usunięte. Jeśli oba A i B zdobędą teraz 60%, CJam zostanie usunięty. Jeśli A uzyska teraz 50%, a B 55%, B jest zwycięzcą.
  • Jeśli zostanie osiągnięta 100% dokładność, decyzje o powiązaniach zostaną ustalone na podstawie drugiego (ślepego) zestawu danych zawierającego więcej próbek dla tych samych języków.

Przykład 1

Skrypt Pythona:

print("python")

Skrypt z powodzeniem tworzy „python”, gdy otrzymuje swój własny kod źródłowy, więc jest poprawny. W zbiorze danych wynik wynosi 1008/9066 = 11,1%

Przykład 2

Funkcja JavaScript:

function f(s){return /function/.test(s)?1:2}

Z mapowaniami 1 → javascript, 2 → python. Ponownie z powodzeniem produkuje 1 („javascript”) dla własnego źródła, a w zestawie danych osiąga wynik 1092/9066 = 12,0%


Skąd pochodzą dane?

Utworzyłem zapytanie SEDE, aby pobrać próbki z [golf-golfa] wyzwań na tej stronie. Z uzyskanych 10 000 odpowiedzi użyłem zhakowanego skryptu python, aby znaleźć kod i nazwę języka dla każdego z nich, a następnie odfiltrowałem dowolny język z mniej niż 5 przykładami. Dane nie są w 100% czyste (wiem, że zostały wyciągnięte niektóre fragmenty kodu), ale powinny być wystarczająco dobre.


Zainspirowany tym wyzwaniem z początku roku: kto to powiedział? Wybory prezydenckie w 2016 r

Również częściowo związany z tym, co to jest język?

Dave
źródło
3
Niesamowicie trudne w 300 bajtach. Być może przeznaczasz więcej bajtów?
Rohan Jhunjhunwala
1
@RohanJhunjhunwala tak Wyobrażam sobie, że będzie to nie lada wyzwanie! Nie oczekuję jednak, że ktoś uzyska 100% dokładności; wyzwanie polega na zdobyciu jak największej wysokości. W „kto to powiedział?” wyzwanie, z którym się połączyłem, wszyscy osiągnęliśmy szczyt z dokładnością ~ 30%. Próbowałem ustawić limit bajtów, aby tutaj było 50–70%. Mam nadzieję, że mam równowagę. Oczywiście, jeśli znajdziesz świetne rozwiązanie, które wykorzystuje więcej bajtów, opublikuj je! To po prostu nie będzie konkurować (możesz to wyciąć dla konkurencyjnej wersji).
Dave
Czy usunąłeś poligloty z zestawu danych, czy będą to tylko „gotchas”?
Geobits,
9
Tak trudno będzie odróżnić golfa ...
busukxuan,
2
Interesujące fakty: 20 najczęściej używanych (przynajmniej w twoim zbiorze danych) języków stanowi 81% twojego zbioru danych, a 10 najczęściej używanych stanowi 61%. Nawet samo wykrycie różnic między JavaScript, Pyth, CJam i Python wystarcza, aby uzyskać około 35%.
helloworld922

Odpowiedzi:

17

C, 297 bajtów, dopasowanie 43.194351% (v2)

To pierwsze wyzwanie, w którym nie brałem udziału w golfie. Zaskakujące jest to, że języki gry w golfa są dość łatwe do rozdzielenia, z dokładnością około 60% dla każdego języka.

Kod wymaga wprowadzenia jako ciągu UTF-8, wyniki oparte na wersji 2 dostarczonego zestawu danych. Ten kod nie wymaga <LF>zastąpienia rzeczywistymi znakami nowej linii.

#define S(x)!!strstr(p,#x)
f(char*p){return S(#d)?:S(voi)?0:S(mai)|S(utc)?:S(mbd)|S(impor)|S(input)|S(def)|S(rang)?2:S(log)|S(fun)|S(=>)|S(lert)?3:S(<?)?4:S(echo)|S(sed)?5:S(+++)?6:S(<-)?7:S($_)|S(say)?8:S(\342)|S(\303)?9:S(->)|S(map)?10:S(@#)|S(]])|S([#)?11:S(V)|S(Q)?12:S(Z)|S(Y)?13:S(.)?14:15;}

Tabela mapowania:

 0. java
 1. c
 2. python
 3. javascript
 4. php
 5. bash
 6. brainf*
 7. haskell
 8. perl
 9. apl
10. ruby
11. wolfram
12. pyth
13. matl
14. golfscript
15. cjam

Procent oparty jest na moich trafieniach / obliczeniach ogółem: 3916 trafień / 9066 łącznie.

owacoder
źródło
Dobry początek; to było szybkie! Jeśli chodzi o „Mój kod testowy i edytor tekstu z jakiegoś powodu widzę wpisy 9068 zamiast 9065” - czy na końcu pominąłeś nagłówki i pusty wiersz? To stanowi 2 dodatkowe linie.
Dave
Przepraszam; to nie jest zgodna z regułą nr 7 (musi wypisać poprawną odpowiedź dla własnego kodu źródłowego): w tej chwili mówi 0, która jest Pythonem (domyślam się, że nie byłoby zbyt wiele pracy, aby zmienić kolejność kontroli, aby to naprawić)
Dave
Możesz stracić miejsce po define S(x)i 1, gdziekolwiek masz ?1.
feersum
Dzięki! Nie wiedziałem o tej ?1sztuczce i zapomniałem o drugiej. ;-)
owacoder
Wow, to cicho się poprawia! Zweryfikowano najnowsze 43,19% :)
Dave
2

Python 3, 271 278 bajtów, dopasowane 25,049636% (wersja 2, niezweryfikowana)

def f(c):
 try:compile(c,'','exec');return 5
 except:
  for j in range(9):
   if any(l in c for l in [['echo'],['require'],['Main','string'],['document','alert','var ','function'],['String'],['def ','lambda','print '],['main','int','char'],['+++','<<<'],[]][j]):break
 return j

mapa:

0 = bash
1 = ruby
2 = c#
3 = javascript
4 = java
5 = python
6 = c
7 = brainf*
8 = cjam

znacznie lepiej grał w golfa (prawdopodobnie nadal nie jest świetny), w końcu przekroczył barierę 25%! Dane wejściowe zostały <LF>zastąpione przez newline ( \n)

helloworld922
źródło
Podoba mi się ta execpróba. Nawiasem mówiąc, możesz poprosić o dane wejściowe, które zostały <LF>wcześniej zastąpione \n, więc możesz zapisać tam kilka bajtów, aby potencjalnie dodać trochę więcej dostrajania.
Dave
W końcu udało mi się to zweryfikować. Widzę tylko 2103 (23,19%) z jakiegoś powodu - jakiś pomysł, dlaczego różnica?
Dave
hmmm ... nie jestem pewien. Być może ma to związek z tym, jak dajesz wkład? Używam decode('utf-8')do przekonwertowania surowej wejściowej tablicy bajtów na natywny ciąg Unicode (utf-16?) W Pythonie przed przekazaniem jej do mojej funkcji.
helloworld922,
Ach OK. Może to być problem z kodowaniem; Po prostu polegam na tym, co fileinput.input () robi pod maską. Zbadam.
Dave