На каком языке это слово?

16

Вы должны написать программу или функцию, которая определяет язык данного слова.

Задача состоит в том, чтобы распознать некоторые из 5000 наиболее распространенных слов на 4 языках:

  • английский
  • Немецкий
  • итальянский
  • Венгерский

Списки слов можно найти в этом репозитории GitHub.

Вам разрешено делать ошибки в 40% предоставленных тестовых случаев . Т.е. вы можете неправильно классифицировать 8000 из 20000 входов.

Детали

  • Списки содержат только слова с строчными буквами, a-zнапример, won'tи möchteне включены.
  • Несколько слов появляются на нескольких языках, что означает, что ваш код не всегда может правильно угадать ожидаемый результат.
  • Для удобства вы можете скачать все контрольные примеры одним списком . В каждой строке число указывает на язык слова. ( 1для английского, 2для немецкого, 3для итальянского и 4для венгерского.)
  • Стандартные лазейки запрещены.
  • Использование списков слов аналогичных данных, предоставленных вашим языком программирования, запрещено.

вход

  • Строка, содержащая только строчные английские буквы (az).
  • Трейлинг новой строки не является обязательным.

Выход

  • Вы можете классифицировать слова, предоставляя различный и непротиворечивый (всегда одинаковый) вывод для каждого языка. (Например, 1для английского, 2для немецкого, 3для итальянского и 4для венгерского.)

Это код гольф, поэтому выигрывает самая короткая программа или функция.

Связанный код гольф вопрос: это даже слово?

Списки слов были взяты с wiktionary.org и 101languages.net.

randomra
источник
Вы уверены, что списки верны? Я уверен, что никогда не слышал по-немецки. Имеет ли значение выходной массив со всеми возможными языками? например, по-видимому, на всех языках, поэтому он будет положить {1,2,3,4}
Eumel
@Eumel Первая пара английских слов может присутствовать где-то в других списках, так как могут быть английские фразы в текстах языков, которые использовались для создания списков слов. Вы можете классифицировать вход только на одном языке. (Как указано в вопросе, «ваш код не всегда может правильно угадать ожидаемый результат».)
randomra
Списки содержат только слова с строчными буквами ... Это не совсем так. all_languagesФайл включает в себя десятки капитализированных слов ( Mr, Gutenbergи т.д.) и не-слова «» (пустая строка) и «]] | -». Я предполагаю, что это нормально, чтобы нижний регистр первого и удалить второе?
брезгливое оссифраж
@squeamishossifrage Спасибо за улов. Обновлены английские списки. (Было ~ 60 заглавных слов и 2
неслова
Зачем удалять диакритические знаки? Если цель состоит в том, чтобы различать языки без диакритики, то почему бы не использовать языки без диакритики?
Пэт

Ответы:

9

Сетчатка , 51 байт

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

Я придумал регулярные выражения, и @ MartinBüttner сделал преобразование в / гольф в Retina, так что ... ура для командной работы?

Отображение 1 -> Italian, 2 -> German, (empty) -> Hungarian, 4 -> English, с количеством, классифицированным в каждой категории, является 4506 + 1852 + 2092 + 3560 = 12010.

Попробуйте онлайн! | Модифицированная многострочная версия

объяснение

Во-первых, эквивалентный Python выглядит примерно так:

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

Позвольте мне просто сказать, что o$это отличный показатель итальянского языка.

Версия Retina схожа с парами линий, образующими стадии замены. Например, первые две строки

.*[aeio]$
1

заменяет совпадения первой строки содержимым второй.

Следующие три строки делают то же самое, но используя режим Retina Anti-Grep - anti-grep (задается с A`) удаляет строку, если она соответствует заданному регулярному выражению, и следующие две строки заменяют пустую строку на желаемый вывод.

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

Следующая строка снова использует anti-grep, но не заменяет пустую строку, давая фиксированный вывод для венгерского.

A`[jkz]|gy|m$

Наконец, последние две строки

\D+
4

заменяет непустую нецифровую строку на 4. Все замены могут произойти только в том случае, если не было активировано предыдущее замещение, имитирующее if/else ifцепочку.

Sp3000
источник
1

LabVIEW, 29 примитивов LabVIEW и 148,950 байт

циклически переключает языки и помещает итератор в массив, если слово есть. Это проверяется внутренним циклом, выбирает i-ю строку и выполняет =. В LabVIEW он дает истину только в том случае, если строки совпадают.

Теперь возьмите первый элемент выходного массива, чтобы английский перебрал остальные.

На данный момент вывод для 0английского, 1немецкого, 2итальянского и 3венгерского языков .

Eumel
источник
Я не знаком с LabView, но как вы храните значения (списки слов) и как они отражаются в примитивах LabView? Мета-запись гласит: « Константы: строки - 1 примитив LabVIEW на символ ». Не сильно ли это увеличит количество примитивов?
insertusername здесь
Я загружаю из файла, который является путь к каталогу + путь сборки со строкой + файл загрузки. Хранение осуществляется внутри и передается по проводам.
Eumel
5
Я могу ошибаться, но я думаю, что основная проблема заключается в том, как сжать / сохранить списки слов. Поэтому загрузка из внешнего файла может быть запрещена. Спросите у ОП об этом. :)
insertusername здесь
2
Если вы используете внешний файл, его размер должен быть добавлен к размеру вашего кода, так как это является частью вашего решения.
рандома
у меня сложилось впечатление, что это должно было быть дано, но я плохо добавлю их, нп
Eumel
1

Ява, 3416 байт, 62%

это мое решение, я анализирую список заданных слов и нахожу 60 наиболее распространенных биграмм и триграмм для каждого языка. Теперь я проверяю свои n-граммы против слова и выбираю язык с большинством n-граммов в слове.

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;
    }
}

и это мой тест

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()));

    }

}
user902383
источник