Quelle langue est ce mot?

16

Vous devez écrire un programme ou une fonction qui détermine la langue d'un mot donné.

La tâche consiste à reconnaître certains des 5000 mots les plus courants en 4 langues:

  • Anglais
  • allemand
  • italien
  • hongrois

Les listes de mots peuvent être trouvées dans ce référentiel GitHub.

Vous êtes autorisé à faire des erreurs dans 40% des cas de test fournis . C'est-à-dire que vous pouvez mal catégoriser 8000 des 20000 entrées.

Détails

  • Les listes ne contiennent que des mots avec des lettres minuscules a-z, par exemple won'tet möchtene sont pas incluses.
  • Quelques mots apparaissent dans plusieurs langues, ce qui signifie que votre code ne peut pas toujours deviner correctement la sortie attendue.
  • Pour plus de commodité, vous pouvez télécharger tous les cas de test en une seule liste . Dans chaque ligne, un nombre indique la langue du mot. ( 1pour l'anglais, l' 2allemand, l' 3italien et le4 hongrois.)
  • Failles standard ne sont pas autorisées.
  • L'utilisation de listes de mots nos données similaires fournies par votre langage de programmation est interdite.

Contribution

  • Chaîne contenant uniquement des lettres anglaises minuscules (az).
  • Le retour à la ligne est facultatif.

Production

  • Vous pouvez classer les mots en fournissant une sortie distincte et cohérente (toujours la même) pour chaque langue. (Par exemple 1pour l'anglais, l' 2allemand, l' 3italien et le 4hongrois.)

C'est le golf de code, donc le programme ou la fonction la plus courte l'emporte.

Code de golf associé: est-ce même un mot?

Les listes de mots proviennent de wiktionary.org et 101languages.net.

randomra
la source
êtes-vous sûr que les listes sont correctes? Im assez sûr que je n'ai jamais entendu le en allemand. La sortie d'un tableau avec toutes les langues possibles compte-t-elle? par exemple, il est apparemment dans toutes les langues, donc il mettra {1,2,3,4}
Eumel
@Eumel Les deux premiers mots anglais peuvent être présents quelque part dans les autres listes car il peut y avoir des phrases anglaises dans les textes des langues qui ont été utilisées pour générer les listes de mots. Vous pouvez classer une entrée dans une seule langue. (Whihch signifie comme mentionné dans la question que "votre code ne peut pas toujours deviner correctement la sortie attendue".)
randomra
Les listes ne contiennent que des mots avec des lettres minuscules ... Ce n'est pas tout à fait vrai. Le all_languagesfichier comprend des dizaines de mots en majuscules ( Mr, Gutenberg, etc.) et les non-mots "" (chaîne vide) et "]] | -". Je suppose que c'est OK de mettre en minuscule le premier et de supprimer le dernier?
squeamish ossifrage
@squeamishossifrage Merci pour la capture. Mise à jour des listes anglaises. (Il y avait ~ 60 mots majuscules et 2 non-mots.)
randomra
Pourquoi supprimer les diacritiques? Si le but est de distinguer les langues qui n'ont pas de signes diacritiques, alors pourquoi ne pas utiliser des langues qui n'ont pas de signes diacritiques?
pat

Réponses:

9

Rétine , 51 octets

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

Je suis venu avec les regexes et @ MartinBüttner a fait la conversion à / golf à Retina alors ... hourra pour l'effort d'équipe?

La cartographie est 1 -> Italian, 2 -> German, (empty) -> Hungarian, 4 -> English, avec le montant classé dans chaque catégorie étant 4506 + 1852 + 2092 + 3560 = 12010.

Essayez-le en ligne! | Version multiligne modifiée

Explication

Tout d'abord, l'équivalent Python ressemble à ceci:

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

Permettez-moi de dire que o$c'est un excellent indicateur de l'italien.

La version Retina est similaire, avec des paires de lignes formant des étapes de remplacement. Par exemple, les deux premières lignes

.*[aeio]$
1

remplace les correspondances de la première ligne par le contenu de la seconde.

Les trois lignes suivantes font de même, mais en utilisant le mode anti-grep de Retina - anti-grep (spécifié avec A`) supprime la ligne si elle correspond à l'expression régulière donnée, et les deux lignes suivantes sont un remplacement d'une ligne vide vers la sortie souhaitée.

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

La ligne suivante utilise à nouveau l'anti-grep, mais ne remplace pas la ligne vide, donnant la sortie fixe pour le hongrois.

A`[jkz]|gy|m$

Enfin, les deux dernières lignes

\D+
4

remplace une ligne non vide non numérique par 4. Toutes les substitutions ne peuvent se produire que si aucune substitution précédente n'est activée, simulant une if/else ifchaîne.

Sp3000
la source
1

LabVIEW, 29 primitives LabVIEW et 148,950 octets

fait défiler les langues et place l'itérateur dans un tableau si le mot est là. Ceci est vérifié par la boucle intérieure, en choisissant la ième ligne et en faisant =. Dans LabVIEW, cela ne donne un vrai que si les chaînes sont exactement les mêmes.

Maintenant, prenez le premier élément du tableau de sortie pour que english passe le reste.

La sortie pour l'instant est 0pour l'anglais, l' 1allemand, l' 2italien et le 3hongrois.

Eumel
la source
Je ne connais pas LabView, mais comment stockez-vous les valeurs (listes de mots) et comment sont-elles reflétées dans les primitives LabView? L'entrée meta dit: " Constantes: les chaînes sont 1 primitive LabVIEW par caractère ". Cela n'augmenterait-il pas considérablement le nombre de primitifs?
insertusernamehere
Je charge le depuis un fichier qui est chemin de répertoire + chemin de construction avec chaîne + fichier de chargement. Le stockage se fait en interne et se fait passer par les fils.
Eumel
5
Je peux me tromper, mais je pense que le cœur du défi est de savoir comment compresser / stocker les listes de mots. Le chargement à partir d'un fichier externe peut donc être interdit. Va demander au PO à ce sujet. :)
insertusernamehere
2
Si vous utilisez un fichier externe, sa taille doit être ajoutée à la taille de votre code car cela fait partie de votre solution.
randomra
Eumel
1

Java, 3416 octets, 62%

c'est ma solution, j'analyse la liste des mots donnés et trouve 60 la plupart des bigrammes et trigrammes communs pour chaque langue. Maintenant, je vérifie mes n-grammes par rapport à word, et je choisis la langue avec la plupart des n-grammes en word.

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

et c'est ma vitrine

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
la source