¿Qué idioma es esta palabra?

16

Debe escribir un programa o función que determine el idioma de una palabra determinada.

La tarea es reconocer algunas de las 5000 palabras más comunes en 4 idiomas:

  • Inglés
  • alemán
  • italiano
  • húngaro

Las listas de palabras se pueden encontrar en este repositorio de GitHub.

Se le permite cometer errores en el 40% de los casos de prueba proporcionados . Es decir, puede clasificar erróneamente 8000 de las 20000 entradas.

Detalles

  • Las listas solo contienen palabras con letras minúsculas, a-zpor ejemplo, won'ty möchteno están incluidas.
  • Aparecen algunas palabras en varios idiomas, lo que significa que su código no siempre puede adivinar la salida esperada correctamente.
  • Para mayor comodidad, puede descargar todos los casos de prueba en una sola lista . En cada línea, un número indica el idioma de la palabra. ( 1para inglés, 2alemán, 3italiano y 4húngaro).
  • Las lagunas estándar no están permitidas.
  • El uso de listas de palabras de nuestros datos similares proporcionados por su lenguaje de programación está prohibido.

Entrada

  • Una cadena que contiene solo letras minúsculas en inglés (az).
  • La nueva línea final es opcional.

Salida

  • Puede clasificar las palabras proporcionando una salida distinta y coherente (siempre la misma) para cada idioma. (Por ejemplo, 1para inglés, 2para alemán, 3para italiano y 4para húngaro).

Este es el código de golf, por lo que gana el programa o la función más corta.

Pregunta relacionada con el código de golf: ¿Es esta una palabra?

Las listas de palabras fueron tomadas de wiktionary.org y 101languages.net.

randomra
fuente
¿Estás seguro de que las listas son correctas? Estoy bastante seguro de que nunca escuché el en alemán. ¿Cuenta la salida de una matriz con todos los idiomas posibles? por ejemplo, aparentemente está en todos los idiomas, por lo que se pondría {1,2,3,4}
Eumel
@Eumel Las primeras dos palabras en inglés pueden estar presentes en algún lugar de las otras listas, ya que puede haber frases en inglés en los textos de idiomas que se usaron para generar las listas de palabras. Puede clasificar una entrada en un solo idioma. (Whihch significa, como se menciona en la pregunta, que "su código no siempre puede adivinar la salida esperada correctamente".)
randomra
Las listas solo contienen palabras con letras minúsculas ... Eso no es del todo cierto. El all_languagesarchivo incluye docenas de palabras en mayúsculas ( Mr, Gutenberg, etc.) y los que no son palabras "" (cadena vacía) y "]] | -". ¿Supongo que está bien poner en minúscula la primera y eliminar la segunda?
ossifrage aprensivo
@squeamishossifrage Gracias por la captura. Se actualizaron las listas en inglés. (Había ~ 60 palabras en mayúscula y 2 no palabras.)
randomra
¿Por qué eliminar los diacríticos? Si el objetivo es distinguir idiomas que no tienen diacríticos, ¿por qué no usar idiomas que no tienen diacríticos?
Pat

Respuestas:

9

Retina , 51 bytes

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

Se me ocurrieron las expresiones regulares y @ MartinBüttner hizo la conversión a / golf en Retina, así que ... ¿hurra por el esfuerzo del equipo?

El mapeo es 1 -> Italian, 2 -> German, (empty) -> Hungarian, 4 -> English, con la cantidad clasificada en cada categoría 4506 + 1852 + 2092 + 3560 = 12010.

Pruébalo en línea! El | Versión multilínea modificada

Explicación

En primer lugar, el Python equivalente es algo como esto:

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

Déjame decir eso o$ es un excelente indicador del italiano.

La versión Retina es similar, con pares de líneas que forman etapas de reemplazo. Por ejemplo, las dos primeras líneas.

.*[aeio]$
1

reemplaza las coincidencias de la primera línea con el contenido de la segunda.

Las siguientes tres líneas hacen lo mismo, pero usando el modo anti-grep de Retina - anti-grep (especificado con A` ) elimina la línea si coincide con la expresión regular dada, y las siguientes dos líneas son un reemplazo de una línea vacía a la salida deseada.

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

La siguiente línea usa anti-grep nuevamente, pero no reemplaza la línea vacía, dando la salida fija para húngaro.

A`[jkz]|gy|m$

Finalmente, las dos últimas líneas.

\D+
4

reemplaza una línea no vacía sin dígitos con 4. Todas las sustituciones solo pueden suceder si no se activó ninguna sustitución previa, simulando una if/else ifcadena.

Sp3000
fuente
1

LabVIEW, 29 primitivas de LabVIEW y 148.950 bytes

recorre los idiomas y coloca el iterador en una matriz si la palabra está allí. Esto se verifica mediante el bucle interno, seleccionando la línea i-ésima y haciendo =. En LabVIEW solo da un verdadero si las cadenas son exactamente iguales.

Ahora tome el primer elemento de la matriz de salida para que el inglés pase al resto.

La salida por ahora es 0para inglés, 1alemán, 2italiano y 3húngaro.

Eumel
fuente
No estoy familiarizado con LabView, pero ¿cómo almacena los valores (listas de palabras) y cómo se reflejan en las primitivas de LabView? La meta entrada dice: " Constantes: las cadenas son 1 LabVIEW Primitivo por personaje ". ¿No aumentaría mucho el recuento primitivo?
insertusernamehere
Cargo desde un archivo que es ruta de directorio + ruta de compilación con cadena + archivo de carga. El almacenamiento se realiza internamente y lo pasan los cables.
Eumel
55
Podría estar equivocado, pero creo que el núcleo del desafío es cómo comprimir / almacenar las listas de palabras. Por lo tanto, no se puede cargar desde un archivo externo. Le preguntará al OP sobre eso. :)
insertusernamehere
2
Si usa un archivo externo, su tamaño debe agregarse al tamaño de su código, ya que es parte de su solución.
randomra
Tenía
1

Java, 3416 bytes, 62%

esta es mi solución, analizo la lista de palabras dadas y encuentro 60 bigrams y trigrams más comunes para cada idioma. Ahora estoy comprobando mis n-gramas con la palabra, y elijo el idioma con la mayoría de los n-gramas en la palabra.

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

y este es mi caso de prueba

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

    }

}
usuario902383
fuente