Jakim językiem jest to słowo?

16

Powinieneś napisać program lub funkcję, która określa język danego słowa.

Zadanie polega na rozpoznaniu 5000 najczęściej używanych słów w 4 językach:

  • język angielski
  • Niemiecki
  • Włoski
  • język węgierski

Listy słów można znaleźć w tym repozytorium GitHub.

Możesz popełniać błędy w 40% podanych przypadków testowych . Oznacza to, że można błędnie sklasyfikować 8000 z 20000 wejść.

Detale

  • Listy zawierają tylko słowa z małymi literami, a-zwięc np. won'tI möchtenie są uwzględniane.
  • Kilka słów pojawia się w wielu językach, co oznacza, że ​​Twój kod nie zawsze może poprawnie odgadnąć oczekiwane wyjście.
  • Dla wygody możesz pobrać wszystkie przypadki testowe jako jedną listę . W każdym wierszu liczba wskazuje język słowa. ( 1w języku angielskim, 2niemieckim, 3włoskim i 4węgierskim).
  • Standardowe luki są niedozwolone.
  • Korzystanie z list słów jest zabronione dla naszych podobnych danych dostarczanych przez Twój język programowania.

Wejście

  • Ciąg zawierający tylko małe litery angielskie (az).
  • Końcowy znak nowej linii jest opcjonalny.

Wynik

  • Możesz kategoryzować słowa, zapewniając odrębne i spójne (zawsze takie same) wyniki dla każdego języka. (Np. W 1języku angielskim, 2niemieckim, 3włoskim i 4węgierskim).

To jest golf golfowy, więc wygrywa najkrótszy program lub funkcja.

Powiązany kod golfowy: czy to w ogóle słowo?

Listy słów zostały zaczerpnięte z wiktionary.org i 101languages.net.

randomra
źródło
czy jesteś pewien, że listy są prawidłowe? Jestem prawie pewien, że nigdy nie słyszałem po niemiecku. Czy liczenie na tablicę ze wszystkimi możliwymi językami się liczy? np. najwyraźniej jest we wszystkich językach, więc woul put {1,2,3,4}
Eumel
@Eumel Pierwsze kilka angielskich słów może znajdować się gdzieś na innych listach, ponieważ w tekstach języków, które zostały użyte do wygenerowania list słów, mogą znajdować się angielskie zwroty. Możesz podzielić dane wejściowe na tylko jeden język. (Whihch oznacza, jak wspomniano w pytaniu, że „Twój kod nie zawsze może poprawnie odgadnąć oczekiwany wynik”)
randomra
Listy zawierają tylko słowa z małymi literami ... To nie do końca prawda. all_languagesPlik zawiera dziesiątki aktywowanych słów ( Mr, Gutenbergetc.) oraz brak słów „” (pusty ciąg znaków) i „]] | -”. Zakładam, że jest w porządku, aby małe i pierwsze skasować małymi literami?
skrzypliwy ossifrage
@squeamishossifrage Dzięki za połów. Zaktualizowano listy angielskie. (Było ~ 60 wielkich liter i 2 nie-słowa.)
randomra
Po co usuwać znaki diakrytyczne? Jeśli celem jest rozróżnienie języków, które nie mają znaków diakrytycznych, to dlaczego nie skorzystać z języków, które nie mają znaków diakrytycznych?
pat

Odpowiedzi:

9

Siatkówka , 51 bajtów

.*[aeio]$
1
A`en$|ch|ei|au
^$
2
A`[jkz]|gy|m$
\D+
4

Wymyśliłem wyrażenia regularne i @ MartinBüttner przeprowadził konwersję do / gry w golfa w Retina, więc ... hurra za wysiłek zespołu?

Mapowanie jest 1 -> Italian, 2 -> German, (empty) -> Hungarian, 4 -> English, z kwotą sklasyfikowaną w każdej kategorii 4506 + 1852 + 2092 + 3560 = 12010.

Wypróbuj online! | Zmodyfikowana wersja multilinii

Wyjaśnienie

Po pierwsze, równoważny Python jest mniej więcej taki:

import re
def f(s):
  if re.search("[aeio]$", s):
    return 1
  if re.search("en$|ch|ei|au", s):
    return 2
  if re.search("[jkz]|gy|m$", s):
    return ""
  return 4

Powiem tylko, że o$jest to doskonały wskaźnik języka włoskiego.

Wersja Retina jest podobna, z parami linii tworzących etapy wymiany. Na przykład pierwsze dwie linie

.*[aeio]$
1

zastępuje dopasowania pierwszego wiersza zawartością drugiego wiersza.

Następne trzy linie robią to samo, ale używając trybu anty-grep Retiny - anti-grep (określony za pomocą A`) usuwa linię, jeśli pasuje do podanego wyrażenia regularnego, a kolejne dwie linie zastępują pustą linię do pożądanego wyniku.

A`en$|ch|ei|au
^$
2

Poniższy wiersz ponownie używa anti-grep, ale nie zastępuje pustego wiersza, dając stałe wyjście dla języka węgierskiego.

A`[jkz]|gy|m$

Wreszcie dwie ostatnie linie

\D+
4

zastępuje niepustą niecyfrową linię na 4. Wszystkie substytucje mogą się zdarzyć tylko wtedy, gdy nie aktywowano wcześniejszej substytucji, symulując if/else ifłańcuch.

Sp3000
źródło
1

LabVIEW, 29 operacji pierwotnych LabVIEW i 148,950 bajtów

przełącza między językami i umieszcza iterator w tablicy, jeśli słowo tam jest. Jest to sprawdzane przez wewnętrzną pętlę, wybieranie i-tej linii i wykonywanie =. W LabVIEW daje prawdę tylko wtedy, gdy ciągi są dokładnie takie same.

Teraz weź pierwszy element tablicy wyjściowej, aby angielski przeszedł resztę.

Dane wyjściowe są na razie 0w języku angielskim, 1niemieckim, 2włoskim i 3węgierskim.

Eumel
źródło
Nie znam LabView, ale jak przechowujesz wartości (listy słów) i jak są one odzwierciedlone w Prymitywach LabView? Wpis w meta mówi: „ Stałe: łańcuchy mają 1 element pierwotny LabVIEW na znak ”. Czy nie zwiększyłoby to znacznie liczby Prymitywów?
inserttusernamehere
Ładuję z pliku, który jest ścieżką do katalogu + ścieżka kompilacji z łańcuchem + plik ładowania. Przechowywanie odbywa się wewnętrznie i przechodzi przez przewody.
Eumel
5
Mogę się mylić, ale myślę, że sedno tego wyzwania polega na tym, jak skompresować / przechowywać listy słów. Dlatego ładowanie z pliku zewnętrznego może być niedozwolone. Zapyta o to OP. :)
inserttusernamehere
2
Jeśli używasz pliku zewnętrznego, jego rozmiar należy dodać do rozmiaru kodu, ponieważ jest to część twojego rozwiązania.
randomra
Byłem pod wrażeniem, że te miały być wydane, ale źle je dodać NP
Eumel
1

Java, 3416 bajtów, 62%

to jest moje rozwiązanie, analizuję listę podanych słów i znajduję 60 najczęściej używanych bigramów i trygramów dla każdego języka. Teraz sprawdzam moje n-gramy względem słowa i wybieram język z większością n-gramów w słowie.

public class Classificator {

    String[][] triGr = {
            {"ing","ion","ent","tio","ted","nce","ter","res","ati","con","ess","ate","pro","ain","est","ons","men","ect","red","rea","com","ere","ers","nte","ine","her","ble","ist","tin","for","per","der","ear","str","ght","pre","ver","int","nde","the","igh","ive","sta","ure","end","enc","ned","ste","dis","ous","all","and","anc","ant","oun","ten","tra","are","sed","cti"},
            {"sch","che","ver","gen","ten","cht","ich","ein","ste","ter","hen","nde","nge","ach","ere","ung","den","sse","ers","and","eit","ier","ren","sen","ges","ang","ben","rei","est","nen","nte","men","aus","der","ent","hei","her","lle","ern","ert","uch","ine","ehe","auf","lie","tte","ige","ing","hte","mme","end","wei","len","hre","rau","ite","bes","ken","cha","ebe"},
            {"ent","are","ato","nte","ett","ere","ion","chi","con","one","men","nti","gli","pre","ess","att","tto","par","per","sta","tra","zio","and","iam","end","ter","res","est","nto","tta","acc","sci","cia","ver","ndo","amo","ant","str","tro","ssi","pro","era","eri","nta","der","ate","ort","com","man","tor","rat","ell","ale","gio","ont","col","tti","ano","ore","ist"},
            {"sze","ere","meg","ett","gye","ele","ond","egy","enn","ott","tte","ete","unk","ban","tem","agy","zer","esz","tet","ara","nek","hal","dol","mon","art","ala","ato","szt","len","men","ben","kap","ent","min","ndo","eze","sza","isz","fog","kez","ind","ten","tam","nak","fel","ene","all","asz","gon","mar","zem","szo","tek","zet","elm","het","eve","ssz","hat","ell"}

                    };
    static String[][] biGr = {
        {"in","ed","re","er","es","en","on","te","ng","st","nt","ti","ar","le","an","se","de","at","ea","co","ri","ce","or","io","al","is","it","ne","ra","ro","ou","ve","me","nd","el","li","he","ly","si","pr","ur","th","di","pe","la","ta","ss","ns","nc","ll","ec","tr","as","ai","ic","il","us","ch","un","ct"},
        {"en","er","ch","te","ge","ei","st","an","re","in","he","ie","be","sc","de","es","le","au","se","ne","el","ng","nd","un","ra","ar","nt","ve","ic","et","me","ri","li","ss","it","ht","ha","la","is","al","eh","ll","we","or","ke","fe","us","rt","ig","on","ma","ti","nn","ac","rs","at","eg","ta","ck","ol"},
        {"re","er","to","ar","en","te","ta","at","an","nt","ra","ri","co","on","ti","ia","or","io","in","st","tt","ca","es","ro","ci","di","li","no","ma","al","am","ne","me","le","sc","ve","sa","si","tr","nd","se","pa","ss","et","ic","na","pe","de","pr","ol","mo","do","so","it","la","ce","ie","is","mi","cc"},
        {"el","en","sz","te","et","er","an","me","ta","on","al","ar","ha","le","gy","eg","re","ze","em","ol","at","ek","es","tt","ke","ni","la","ra","ne","ve","nd","ak","ka","in","am","ad","ye","is","ok","ba","na","ma","ed","to","mi","do","om","be","se","ag","as","ez","ot","ko","or","cs","he","ll","nn","ny"}

                    };

    public int guess(String word) {

        if (word.length() < 3) {
            return 4; // most words below 2 characters on list are hungarians
        }
        int score[] = { 0, 0, 0, 0 };
        for (int i = 0; i < 4; i++) {
            for (String s : triGr[i]) {
                if (word.contains(s)) {
                    score[i] = score[i] + 2;
                }
            }
            for (String s : biGr[i]) {
                if (word.contains(s)) {
                    score[i] = score[i] + 1;
                }
            }
        }
        int v = -1;
        int max = 0;
        for (int i = 0; i < 4; i++) {
            if (score[i] > max) {
                max = score[i];
                v = i;
            }
        }
        v++;
        return v==0?Math.round(4)+1:v;
    }
}

i to jest mój testcase

public class Test {

    Map<String, List<Integer>> words = new HashMap<String, List<Integer>>();

    boolean validate(String word, Integer lang) {
        List<Integer> langs = words.get(word);
        return langs.contains(lang);
    }

    public static void main(String[] args) throws FileNotFoundException {

        FileReader reader = new FileReader("list.txt");
        BufferedReader buf = new BufferedReader(reader);
        Classificator cl = new Classificator();
        Test test = new Test();
        buf.lines().forEach(x -> test.process(x));
        int guess = 0, words = 0;
        for (String word : test.words.keySet()) {
            int lang = cl.guess(word);
            if (lang==0){
                continue;
            }
            boolean result = test.validate(word, lang);
            words++;
            if (result) {
                guess++;
            }
        }
        System.out.println(guess+ " "+words+ "    "+(guess*100f/words));
    }

    private void process(String x) {
        String arr[] = x.split("\\s+");
        String word = arr[0].trim();
        List<Integer> langs = words.get(word);
        if (langs == null) {
            langs = new ArrayList<Integer>();
            words.put(word, langs);
        }
        langs.add(Integer.parseInt(arr[1].trim()));

    }

}
użytkownik902383
źródło