Que idioma é essa palavra?

16

Você deve escrever um programa ou função que determine o idioma de uma determinada palavra.

A tarefa é reconhecer algumas das 5000 palavras mais comuns em 4 idiomas:

  • Inglês
  • alemão
  • italiano
  • húngaro

As listas de palavras podem ser encontradas neste repositório GitHub.

Você pode cometer erros em 40% dos casos de teste fornecidos . Ou seja, você pode categorizar erroneamente 8000 das 20.000 entradas.

Detalhes

  • As listas contêm apenas palavras com letras minúsculas, a-zpor exemplo, won'te möchtenão estão incluídas.
  • Algumas palavras aparecem em vários idiomas, o que significa que seu código nem sempre pode adivinhar a saída esperada corretamente.
  • Por conveniência, você pode baixar todos os casos de teste como uma lista . Em cada linha, um número indica o idioma da palavra. ( 1para inglês, 2alemão, 3italiano e 4húngaro).
  • As brechas padrão não são permitidas.
  • Usando listas de palavras, nossos dados semelhantes fornecidos pela sua linguagem de programação são proibidos.

Entrada

  • Uma sequência contendo apenas letras minúsculas em inglês (az).
  • A nova linha à direita é opcional.

Resultado

  • Você pode categorizar as palavras fornecendo uma saída distinta e consistente (sempre a mesma) para cada idioma. (Por exemplo, 1para inglês, 2alemão, 3italiano e 4húngaro.)

Este é um código de golfe, para que o programa ou função mais curto ganhe.

Código relacionado à questão do golfe: isso é mesmo uma palavra?

As listas de palavras foram retiradas de wiktionary.org e 101languages.net.

randomra
fonte
você tem certeza de que as listas estão corretas? Tenho certeza de que nunca ouvi falar em alemão. A saída de uma matriz com todos os idiomas possíveis conta? por exemplo, o aparentemente está em todas as línguas para que ele woul colocar {1,2,3,4}
Eumel
@Eumel As duas primeiras palavras em inglês podem estar presentes em algum lugar das outras listas, pois pode haver frases em inglês nos textos dos idiomas que foram usadas para gerar as listas de palavras. Você pode categorizar uma entrada em apenas um idioma. (Meios whihch como mencionado na pergunta que "seu código nem sempre pode adivinhar o resultado esperado corretamente".)
randomra
As listas contêm apenas palavras com letras minúsculas ... Isso não é totalmente verdade. O all_languagesarquivo inclui dezenas de palavras em maiúsculas ( Mr, Gutenbergetc.) e as não palavras "" (sequência vazia) e "]] | -". Presumo que não há problema em minúsculas o anterior e excluir o último?
Ossifrage melindroso
@squeamishossifrage Obrigado pela captura. Atualizadas as listas em inglês. (Não foram ~ 60 maiúscula palavras e 2 não-palavras.)
randomra
Por que remover diacríticos? Se o objetivo é distinguir idiomas sem diacríticos, por que não usar idiomas sem diacríticos?
Pat

Respostas:

9

Retina , 51 bytes

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

Eu vim com as regexes e @ MartinBüttner fez a conversão para / golfe na Retina, então ... viva para o trabalho em equipe?

O mapeamento é 1 -> Italian, 2 -> German, (empty) -> Hungarian, 4 -> English, com a quantidade classificada em cada categoria 4506 + 1852 + 2092 + 3560 = 12010.

Experimente online! | Versão multilinha modificada

Explicação

Primeiro, o Python equivalente é mais ou menos assim:

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

Permitam-me apenas dizer que o$é um excelente indicador do italiano.

A versão Retina é semelhante, com pares de linhas formando estágios de substituição. Por exemplo, as duas primeiras linhas

.*[aeio]$
1

substitui correspondências da primeira linha pelo conteúdo da segunda.

As próximas três linhas fazem o mesmo, mas o uso do modo anti-grep da Retina - anti-grep (especificado com A`) remove a linha se corresponder ao regex especificado, e as duas linhas a seguir substituem uma linha vazia pela saída desejada.

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

A linha a seguir usa o anti-grep novamente, mas não substitui a linha vazia, fornecendo a saída fixa para o húngaro.

A`[jkz]|gy|m$

Finalmente, as duas últimas linhas

\D+
4

substitui uma linha sem dígito não vazia por 4. Todas as substituições só podem ocorrer se nenhuma substituição anterior for ativada, simulando uma if/else ifcadeia.

Sp3000
fonte
1

LabVIEW, 29 primitivas do LabVIEW e 148.950 bytes

alterna entre os idiomas e coloca o iterador em uma matriz, se a palavra estiver lá. Isso é verificado pelo loop interno, escolhendo a i-ésima linha e fazendo =. No LabVIEW, isso só é verdadeiro se as Strings forem exatamente iguais.

Agora pegue o primeiro elemento da matriz de saída para que o inglês passe pelo resto.

A saída agora é 0para inglês, 1alemão, 2italiano e 3húngaro.

Eumel
fonte
Não conheço o LabView, mas como você armazena os valores (listas de palavras) e como eles são refletidos nas Primitivas do LabView? A meta entrada diz: " Constants: strings são 1 primitivas do LabVIEW por caractere ". Isso não aumentaria muito a contagem primitiva?
insertusernamehere
Eu carrego o de um arquivo que é o caminho do diretório + o caminho da construção com a string + o arquivo de carregamento. O armazenamento é feito internamente e é passado pelos fios.
Eumel
5
Posso estar errado, mas acho que o principal desafio é como compactar / armazenar as listas de palavras. Portanto, o carregamento de um arquivo externo pode não ser permitido. Irá perguntar ao OP sobre isso. :)
insertusernamehere
2
Se você usar um arquivo externo, seu tamanho deverá ser adicionado ao tamanho do código, pois isso faz parte da sua solução.
randomra
Fiquei com a impressão de que aqueles que deveriam ser dadas, mas mal adicioná-los np
Eumel
1

Java, 3416 bytes, 62%

esta é a minha solução, analiso a lista de palavras fornecidas e encontro 60 bigramas e trigramas comuns para cada idioma. Agora, estou verificando meus n gramas contra a palavra e escolhendo o idioma com a maioria dos n gramas na palavra.

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

e esta é minha caixa de teste

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
fonte