Caractères alphabétiques croisés

17

Contexte

J'ai vu ce diagramme de Venn très intéressant sur wikipedia: https://simple.wikipedia.org/wiki/Alphabet#/media/File:Venn_diagram_gr_la_ru.svg

Il montre les lettres (formes physiques) dans différents alphabets communs aux alphabets russe, grec et latin.

Le défi

Étant donné une chaîne d'entrée de caractères provenant de l'un des trois scripts présentés (c.-à-d. Lettres grecques, cyrilliques ou latines en majuscules), affichez un pourcentage de la chaîne correspondant à chaque langue. Les lettres répétées comptent à chaque fois.

Par exemple, FFLURStous les caractères sont uniquement latins, donc la sortie est FFLURS is 100% Latin, 0% Cyrillic and 0% Greek.

En revanche, TOX BEAM PHPest complètement formé de caractères qui apparaissent dans les trois langues, donc la sortie est TOX BEAM PHP is 100% Cyrillic, 100% Greek and 100% Latin.

Tables de recherche

Le diagramme de Venn est à l'origine des lettres ci-dessous:

Latin uniquement:

J,G,S,D,Q,U,V,W,F,L,R

Latin et cyrillique:

C, С

Latin et grec:

I,Ι, N,Ν, Z,Ζ

Grec et cyrillique

Φ,Ф, Π,П, Γ,Г, Λ,Л

Tous les trois:

A,B,E,O,M,K,T,X,Y,H,P (and equivalents in greek and cyrillic), (space)

Le reste ... est uniquement grec ou cyrillique.

NOTE IMPORTANTE

Unicode définit (par exemple) "A" de (au moins) trois façons distinctes - une pour chaque langue. Quel que soit celui utilisé dans l'entrée (& # 0391, & # 0410 ou & # 0041), le programme doit le comprendre comme correspondant aux trois langues. Donc, A(latin), Α(grec alpha) et А(cyrillique) devraient tous donner 100% Cyrillic, 100% Greek and 100% Latincomme réponse.

Format d'entrée

Toute chaîne contenant exclusivement А-Я, Α-Ω, A-Zet (espace). Ces caractères peuvent être répétés plusieurs fois dans la chaîne.

Format de sortie

La sortie peut être dans n'importe quel format, à condition que la fonction produise des résultats cohérents. Je tiens à voir la sortie au format que je montre dans mes exemples ( FFLURS is 100% Latin, 0% Cyrillic and 0% Greek), mais pour rendre le défi plus ouvert à tous ceux que je suis heureux d'accepter que des tableaux / chaînes de pourcentages / rapports:

[100,0,0],

100 0 0

[1.0 0.0 0.0]

tant qu'il est toujours clair quel numéro est quelle langue - donc la sortie doit être cohérente.

Quelques cas de test supplémentaires

CINEMATICS -> CINEMATICS is 100% Latin, 70% Greek and 60% Cyrillic

ЩJЩFЩLΞRΞVΞW -> ЩJЩFЩLΞRΞVΞW is 50% Latin, 25% Cyrillic and 25% Greek

-> is 100% Cyrillic, 100% Greek and 100% Latin

ΨΩTESTINGЯЮ -> ΨΩTESTINGЯЮ is 63.6% Greek, 63.6% Latin and 45.5% Cyrillic

Critères gagnants

Les règles et exclusions habituelles s'appliquent; la réponse la plus courte (octets) l'emporte.

(lien sandbox: https://codegolf.meta.stackexchange.com/a/14984/62289 )

Pour éviter tout doute, les seuls caractères Unicode valides dans l'entrée sont:

  • 0020, 0041-005A (alphabet latin)
  • 0020, 0391-03A9 (alphabet grec)
  • 0020, 0401, 0410-042F (alphabet cyrillique)

Mais comme indiqué dans les tableaux de recherche, les caractères peuvent être inter-alphabétiques.

Ajout du tableau de Jonathan Allan à partir des commentaires:

                                                 Latin  Greek  Cyrillic
U+0020     Space                                 1      1      1
U+0041  A  Latin capital letter A                1      1      1
U+0042  B  Latin capital letter B                1      1      1
U+0043  C  Latin capital letter C                1      0      1
U+0044  D  Latin capital letter D                1      0      0
U+0045  E  Latin capital letter E                1      1      1
U+0046  F  Latin capital letter F                1      0      0
U+0047  G  Latin capital letter G                1      0      0
U+0048  H  Latin capital letter H                1      1      1
U+0049  I  Latin capital letter I                1      1      0
U+004A  J  Latin capital letter J                1      0      0
U+004B  K  Latin capital letter K                1      1      1
U+004C  L  Latin capital letter L                1      0      0
U+004D  M  Latin capital letter M                1      1      1
U+004E  N  Latin capital letter N                1      1      0
U+004F  O  Latin capital letter O                1      1      1
U+0050  P  Latin capital letter P                1      1      1
U+0051  Q  Latin capital letter Q                1      0      0
U+0052  R  Latin capital letter R                1      0      0
U+0053  S  Latin capital letter S                1      0      0
U+0054  T  Latin capital letter T                1      1      1
U+0055  U  Latin capital letter U                1      0      0
U+0056  V  Latin capital letter V                1      0      0
U+0057  W  Latin capital letter W                1      0      0
U+0058  X  Latin capital letter X                1      1      1
U+0059  Y  Latin capital letter Y                1      1      1
U+005A  Z  Latin capital letter Z                1      1      0

U+0391  Α  Greek capital letter Alpha            1      1      1
U+0392  Β  Greek capital letter Beta             1      1      1
U+0393  Γ  Greek capital letter Gamma            0      1      1
U+0394  Δ  Greek capital letter Delta            0      1      0
U+0395  Ε  Greek capital letter Epsilon          1      1      1
U+0396  Ζ  Greek capital letter Zeta             1      1      0
U+0397  Η  Greek capital letter Eta              1      1      1
U+0398  Θ  Greek capital letter Theta            0      1      0
U+0399  Ι  Greek capital letter Iota             1      1      0
U+039A  Κ  Greek capital letter Kappa            1      1      1
U+039B  Λ  Greek capital letter Lambda           0      1      1
U+039C  Μ  Greek capital letter Mu               1      1      1
U+039D  Ν  Greek capital letter Nu               1      1      0
U+039E  Ξ  Greek capital letter Xi               0      1      0
U+039F  Ο  Greek capital letter Omicron          1      1      1
U+03A0  Π  Greek capital letter Pi               0      1      1
U+03A1  Ρ  Greek capital letter Rho              1      1      1

U+03A3  Σ  Greek capital letter Sigma            0      1      0
U+03A4  Τ  Greek capital letter Tau              1      1      1
U+03A5  Υ  Greek capital letter Upsilon          1      1      1
U+03A6  Φ  Greek capital letter Phi              0      1      1
U+03A7  Χ  Greek capital letter Chi              1      1      1
U+03A8  Ψ  Greek capital letter Psi              0      1      0
U+03A9  Ω  Greek capital letter Omega            0      1      0

U+0401  Ё  Cyrillic capital letter Io            0      0      1

U+0410  А  Cyrillic capital letter A             1      1      1
U+0411  Б  Cyrillic capital letter Be            0      0      1
U+0412  В  Cyrillic capital letter Ve            1      1      1
U+0413  Г  Cyrillic capital letter Ghe           0      1      1
U+0414  Д  Cyrillic capital letter De            0      0      1
U+0415  Е  Cyrillic capital letter Ie            1      1      1
U+0416  Ж  Cyrillic capital letter Zhe           0      0      1
U+0417  З  Cyrillic capital letter Ze            0      0      1
U+0418  И  Cyrillic capital letter I             0      0      1
U+0419  Й  Cyrillic capital letter Short I       0      0      1
U+041A  К  Cyrillic capital letter Ka            1      1      1
U+041B  Л  Cyrillic capital letter El            0      1      1
U+041C  М  Cyrillic capital letter Em            1      1      1
U+041D  Н  Cyrillic capital letter En            1      1      1
U+041E  О  Cyrillic capital letter O             1      1      1
U+041F  П  Cyrillic capital letter Pe            0      1      1
U+0420  Р  Cyrillic capital letter Er            1      1      1
U+0421  С  Cyrillic capital letter Es            1      0      1
U+0422  Т  Cyrillic capital letter Te            1      1      1
U+0423  У  Cyrillic capital letter U             1      1      1
U+0424  Ф  Cyrillic capital letter Ef            0      1      1
U+0425  Х  Cyrillic capital letter Ha            1      1      1
U+0426  Ц  Cyrillic capital letter Tse           0      0      1
U+0427  Ч  Cyrillic capital letter Che           0      0      1
U+0428  Ш  Cyrillic capital letter Sha           0      0      1
U+0429  Щ  Cyrillic capital letter Shcha         0      0      1
U+042A  Ъ  Cyrillic capital letter hard sign     0      0      1
U+042B  Ы  Cyrillic capital letter Yeru          0      0      1
U+042C  Ь  Cyrillic capital letter soft sign     0      0      1
U+042D  Э  Cyrillic capital letter E             0      0      1
U+042E  Ю  Cyrillic capital letter Yu            0      0      1
U+042F  Я  Cyrillic capital letter Ya            0      0      1
simonalexander2005
la source
1
Bienvenue chez PPCG! C'est un joli premier défi. :) Une note sur votre note UTF-8: ce n'est pas UTF-8 qui définit plusieurs versions de ces caractères mais Unicode (et UTF-8 n'est qu'une façon spécifique d'encoder des points de code Unicode). De plus, comme cette partie est assez importante pour que les réponses soient correctes, vous souhaiterez peut-être inclure la liste explicite de tous les caractères Unicode qui doivent être traités correctement.
Martin Ender
@ngn oui, merci.
simonalexander2005
@JonathanAllan, ngn: Je suis d'accord, je voulais juste les lettres qui sont dans le diagramme de Venn - mais toutes les représentations de ces lettres sont valides - comme j'essaye de dire dans la question, il y a plusieurs représentations unicodes de "A", par exemple
simonalexander2005
Le cyrillique "El" est en fait le grec "Lambda". Le «pe» cyrillique est le «pi» grec.
simonalexander2005
@JonathanAllan Selon la police, le cyrillique Л peut ressembler exactement au grec Λ. La forme en Π n'est qu'une autre variante stylistique de la même lettre.
2018

Réponses:

4

Gelée , 56 octets

Un hachage peut très bien être plus court.

O:⁹:2;ON©œị“ŒḂI4ƥƒⱮıtɱN¦“¤COṙṚ¹`“ÑṂḄẈɼ]ġÐ’b4¤+4Bṙ®Ḣµ€S÷L

Un lien monadique renvoyant une liste de montants de ratio dans l'ordre anglais, grec, russe.

Essayez-le en ligne!
... ou voir une sortie entièrement formatée (y compris l'arrondissement implicite à une décimale)

Comment?

Nous souhaitons avoir un code qui traduit chaque caractère possible en un triple de uns et de zéros représentant s'ils appartiennent à chacun des alphabets (un peu comme le tableau de la question où se Ctrouve 1 0 1). Une fois cela fait, nous pouvons additionner à travers ceux-ci et diviser par la longueur pour donner les ratios (entre zéro et un inclus) - c'est juste S÷L(vu à droite du code).

Pour tout caractère donné Nous savons que si l'ordinal est inférieur à 256, il compte comme anglais, s'il est supérieur à 1024, il compte comme russe, et que s'il est entre 256 et 1024, il compte comme grec. En tant que tel, la division de l'ordinal et de l'entier par 256, puis l'entier divisant le résultat par deux rendements 0pour l'espace et les caractères latins (comptez comme anglais), 1pour l'hellénique (comptez pour le grec) et 2pour le cyrillique (comptez pour le russe). C'est juste O:⁹:2dans Jelly (vu à gauche du code).

Si nous faisons pivoter les triplets de bits de sorte que le bit d'alphabet naturel * soit le plus significatif, nous pouvons coder les deux bits inférieurs (sous forme de valeurs comprises entre zéro et trois inclus) dans une table de recherche à trois lignes, puis faire pivoter vers la droite de nombres trouvés ci-dessus.

Lorsque nous faisons cela, il y a deux choses qui méritent d'être notées - 1. La gelée a un atome tournant à gauche et non un tournant à droite; 2. la ligne hellénique de la table de recherche commencerait par un zéro (car elle Ξn'est que grecque), contrecarrant un simple codage en base 4 (puisque les zéros de tête ne sont pas codables). Pour alléger (1), nous pouvons faire pivoter vers la gauche de la valeur négative et pour alléger (2), nous pouvons coder nos lignes en sens inverse et les indexer avec le montant négatif. De cette façon, nous pouvons annuler à la fois l'index de ligne et de colonne avec un seul octet ( N), de sorte que nos indices de ligne et de colonne peuvent être calculés avec O:⁹:2;ON.

Notez que Jelly a maintenant un atome d'indexation multi-dimensionnelle, œị.

Le tableau est formé de trois grands nombres qui, une fois convertis en base quatre, donnent respectivement les bits inférieurs requis pour le cyrillique, le grec et le latin (+ espace). Ils sont de longueur minimale telle qu'une indexation modulaire par les valeurs ordinales négatives est possible - 47, 25 et 30 respectivement (les .s sont à des index inutilisés):

1: 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 3 1 3 3 2 3 1 3 3 3 1 3 0 0 0 0 3 0 1 3 0 3 0 0 0 0 0 0
   . . . . . . . . . Я Ю Э Ь Ы Ъ Щ Ш Ч Ц Х Ф У Т С Р П О Н М Л К Й И З Ж Е Д Г В Б А Ё . . . . .

2: 3 2 3 1 0 3 1 3 0 2 3 3 0 0 3 2 3 3 0 0 3 2 3 0 1
   Μ Λ Κ Ι Θ Η Ζ Ε Δ Γ Β Α Ω Ψ Χ Φ Υ Τ Σ . Ρ Π Ο Ξ Ν

3: 3 3 0 0 0 3 0 0 0 3 3 2 3 0 3 0 2 3 0 0 3 0 1 3 3 0 0 3 0 2
   Y X W V U T S R Q P O N M L K J I H G F E D C B A . .   . Z

À titre d'exemple, considérons le caractère Φ au point Unicode U + 03A6 (qui devrait donner [0,1,1]), il a une valeur ordinale de (3 × 16² + 10 × 16 + 6 =) 934. ( O:⁹:2signifie 934 // 256 // 2 =) 1 l'identifiant comme faisant partie du bloc hellénique. Le ;Oconcatène l'ordinal nous donnant [1,934]et le Nnie ensuite les deux valeurs nous donnant [-1,-934]. Étant donné que l'indexation Jelly est à la fois basée sur 1 et modulaire et qu'il y a trois lignes, les -1références la deuxième des trois lignes (ligne 2 dans le bloc de code ci-dessus), car la ligne du milieu a une longueur de 25 les -934références les (-934% 25 =) 16 e entrée de cette ligne, ce qui est 2. Le code ajoute ensuite quatre (le bit le plus significatif) nous donnant 6qui converti en binaire est[1,1,0]. Le code fait ensuite tourner celui-ci à gauche de chacun [-1,-934]et prend la tête (c'est-à-dire la rotation à gauche par -1, une rotation à droite par 1) donnant [0,1,1]comme requis.

* Anglais pour l'espace car il est groupé avec les caractères latins


Code commenté

O:⁹:2;ON©œị“...“...“...’b4¤+4Bṙ®Ḣµ€S÷L - Link: list of characters        e.g.: "СЯ"
                                 µ€    - for €ach character:                С       Я
O                                      -   cast to ordinal               1057    1071
  ⁹                                    -   literal 256
 :                                     -   integer division                 4       4
   :2                                  -   integer divide by 2              2       2
      O                                -   cast to ordinal               1057    1071
     ;                                 -   concatenate                  [2,1057] [2,1071]
       N                               -   negate                     [-2,-1057] [-2,-1071]
        ©                              -   copy to register for later
                          ¤            -   nilad followed by link(s) as a nilad:
           “...“...“...’               -     list of integers encoded in base 250 = [4951760157204492290900832256, 1043285073970097, 1081712651052809266]
                        b4             -     convert to base 4                    = [[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,3,1,3,3,2,3,1,3,3,3,1,3,0,0,0,0,3,0,1,3,0,3,0,0,0,0,0,0],[3,2,3,1,0,3,1,3,0,2,3,3,0,0,3,2,3,3,0,0,3,2,3,0,1],[3,3,0,0,0,3,0,0,0,3,3,2,3,0,3,0,2,3,0,0,3,0,1,3,3,0,0,3,0,2]]
         œị                            -   index into                       2       0                   ^--[-2,-1071]   [-2,-1057]--^
                           +4          -   add four                         6       4
                             B         -   convert to binary             [1,1,0] [1,0,0]
                               ®       -   recall from register       [-2,-1057] [-2,-1071]
                              ṙ        -   rotate left         [[1,0,1],[0,1,1]] [[0,0,1],[1,0,0]]
                                Ḣ      -   head                          [1,0,1] [0,0,1]
                                   S   - sum                                 [1,0,2]
                                     L - length                                 2
                                    ÷  - divide                            [0.5,0,1]
                                       -   i.e.: 50.0% Latin, 0% Greek, 100% Russian
Jonathan Allan
la source
On dirait que vous avez une terminologie là-bas ... "hachage" signifie une construction comme (keys)iị(values)Ʋ?
Erik the Outgolfer
Je veux dire former un ensemble distinct de clés à partir d'une manipulation mathématique afin que l'on puisse indexer dans une liste de valeurs, oui. Donc, comme ...ị“...ou peut-être ...ṃ“...(à proprement parler, la chaîne monadique que j'ai formée est une fonction de hachage )
Jonathan Allan
@ngn M kebard est anning
Jonathan Allan
Oh, je sais comment résoudre ce problème! Reconfigurez votre clavier et tapez cyrillique "у" et "о" au lieu de "y" et "o": D
ngn
Je n'ai jamais vu une réponse aussi longue de Jelly ... excellent travail!
simonalexander2005
5

JavaScript (ES6), 197 179 octets

Renvoie un tableau de 3 ratios dans [0..1].

s=>[...s].map(_=>(x='b;C6cC6%c>b^[<$]_3--_c_acC-----$+aKHbKK[`H`H]'[(p=s[a='charCodeAt'](l++)%202%116%89)>>1][a]()-36,x/=p&1||8,L+=x/4&1,G+=x/2&1,C+=x&1),l=L=G=C=0)&&[L/l,G/l,C/l]

Essayez-le en ligne!

Comment?

Nous utilisons la fonction de hachage (plutôt inefficace) % 202 % 116 % 89pour transformer chaque code de caractère en un index dans [0..88]. La table de recherche correspondante se compose d'entrées de 3 bits où le bit # 2 = latin, le bit # 1 = grec et le bit # 0 = cyrillique. En utilisant des chiffres décimaux, cela donne:

76273722773722017732767267300071731711117377737577371111111111000775474476474767744474447

Nous ajoutons un supplément 1pour obtenir un nombre pair d'entrées et codons ce flux binaire avec des caractères ASCII imprimables dans la plage [37..99] ( %à c), avec 6 bits de données utiles par caractère.

Cela conduit à la chaîne suivante:

b;C6cC6%c>b^[<$]_3--_c_acC-----$+aKHbKK[`H`H]

Le décalage a été choisi pour éviter les caractères tels que \ cela aurait nécessité un échappement.

Arnauld
la source
3

Rubis , 165 octets

->s{(0..2).map{|x|s.chars.map{|c|o=c.ord;(o<33?7:"ĝ]ē¯]÷W59WUė½ñĝĕ×ßoĝėÏė55#{?!*15}"[o-[913,1040,65][y=o>>7<=>7]].ord+226>>3*-~y)[x]*1.0}.sum/s.size}}

Essayez-le en ligne!

Edit: joué de manière significative le code, et surtout, compressé 3 séquences de traduction en une seule chaîne UTF-8. Le code original plus long est conservé ci-dessous pour une meilleure lisibilité et explication de la logique.

Rubis, 211 octets

->s{(0..2).map{|x|s.chars.map{|x|o=x.ord;o<33?7:o<91?"77517117317173771117111773"[o-65]:o<938?"7762737237673276702776722"[o-913]:"74764744444767776757767#{?4*15}"[o-1040]}.inject(0.0){|y,z|y+=z.to_i[x]}/s.size}}

Essayez-le en ligne!

Ce n'est peut-être pas l'approche la plus efficace, mais cela fait l'affaire. Utilise une table de traduction pour chaque alphabet avec occurrence de caractère dans différents scripts encodés par les bits du nombre (dans l'ordre: latin, grec, russe). La sortie est un tableau de pourcentages dans le même ordre.

Pour corriger le Ёcas aberrant , j'ai étendu le bloc de 4 s uniquement en russe de 10 positions à la fin de l'alphabet à 15. De cette façon, Ёest correctement sélectionné avec un index négatif (et nous ne sommes pas tenus de gérer les lettres minuscules qui correspondent à ces indices supplémentaires).

Kirill L.
la source
1

Retina 0.8.2 , 230 octets

.+
$&¶$&¶$&¶$&
T`ΓΔΘΛΞΠΣΦΨΩЁБГДЖ-ЙЛПФЦ-Я`_`.+(?=¶.+¶.+$)
T`CDFGJ\LQRSUVWЁБДЖ-ЙС-Я`_`.+(?=¶.+$)
T`DFGIJ\LNQRSUVWZΔΖΘΙΝΞΣΨΩ`_`.+$
¶(.*)
¶$.1$*
1
100$*
.
1
(1+)¶(\1)*1*¶(\1)*1*¶(\1)*1*
$#2 $#3 $#4

Essayez-le en ligne! Le lien inclut des cas de test. Remarque: La sortie est en% tronquée jusqu'à un entier, car l'augmentation de la précision a rendu le script trop lent et a expiré sur TIO.

Neil
la source