Caracteres alfabéticos cruzados


17

fundo

Eu vi esse diagrama de Venn muito interessante na wikipedia: https://simple.wikipedia.org/wiki/Alphabet#/media/File:Venn_diagram_gr_la_ru.svg

Ele mostra as letras (formas físicas) em diferentes alfabetos comuns entre os alfabetos russo, grego e latino.

O desafio

Dada uma sequência de caracteres de entrada de qualquer um dos três scripts mostrados (por exemplo, letras maiúsculas em grego, cirílico ou latino), imprima uma porcentagem da sequência que corresponde a cada idioma. Letras repetidas contam todas as vezes.

Por exemplo, FFLURSsão todos os caracteres somente em latim, portanto, a saída é FFLURS is 100% Latin, 0% Cyrillic and 0% Greek.

Por outro lado, TOX BEAM PHPé formado completamente de caracteres que aparecem nos três idiomas, então a saída é TOX BEAM PHP is 100% Cyrillic, 100% Greek and 100% Latin.

Tabelas de pesquisa

O diagrama de Venn é a fonte das letras abaixo:

Somente em latim:

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

Latim e cirílico:

C, С

Latim e grego:

I,Ι, N,Ν, Z,Ζ

Grego e cirílico

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

Todos três:

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

O resto ... é apenas grego ou cirílico.

NOTA IMPORTANTE

O Unicode define (por exemplo) "A" de (pelo menos) três maneiras separadas - uma para cada idioma. Qualquer que seja usado na entrada (& # 0391, & # 0410 ou & # 0041), o programa deve entendê-lo como sendo compatível com os três idiomas. Portanto, A(latim), Α(grego alfa) e А(cirílico) devem todos dar 100% Cyrillic, 100% Greek and 100% Latincomo resposta.

Formato de entrada

Qualquer string contendo exclusivamente А-Я, Α-Ω, A-Ze (espaço). Esses caracteres podem ser repetidos várias vezes na cadeia.

Formato de saída

A saída pode estar em qualquer formato, desde que a função produza resultados consistentes. Eu gostaria de ver a saída no formato mostro em meus exemplos ( FFLURS is 100% Latin, 0% Cyrillic and 0% Greek), mas, a fim de tornar o desafio mais aberto a qualquer um que eu sou feliz em aceitar matrizes / cordas de percentagens / proporções:

[100,0,0],

100 0 0

[1.0 0.0 0.0]

desde que esteja sempre claro qual número é qual idioma - a saída deve ser consistente.

Mais alguns casos de teste

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érios Vencedores

Aplicam-se regras e exclusões usuais; a resposta mais curta (bytes) vence.

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

Para evitar dúvidas, os únicos caracteres Unicode válidos na entrada são:

  • 0020, 0041-005A (alfabeto latino)
  • 0020, 0391-03A9 (alfabeto grego)
  • 0020, 0401, 0410-042F (alfabeto cirílico)

Mas, como mostrado nas tabelas de pesquisa, os caracteres podem ser alfabéticos cruzados.

Adicionando a tabela de Jonathan Allan a partir dos comentários:

                                                 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

1
Bem-vindo ao PPCG! Este é um bom primeiro desafio. :) Uma observação na sua nota UTF-8: não é UTF-8 que define várias versões desses caracteres, mas Unicode (e UTF-8 é apenas uma maneira específica de codificar pontos de código Unicode). Além disso, como essa parte é muito importante para que as respostas sejam acertadas, convém incluir a lista explícita de todos os caracteres Unicode que precisam ser manipulados corretamente.
Martin Ender

@ngn sim, obrigado.
simonalexander2005

@ JonathanAllan, ngn: Eu concordo, pretendia apenas as letras que estão no diagrama de Venn - mas todas as representações dessas letras são válidas - como tento dizer na pergunta, existem várias representações unicode de "A", por exemplo
simonalexander2005

"El" cirílico é na verdade "Lambda" grego. "Pe" cirílico é o grego "Pi".
simonalexander2005

@ JonathanAllan Dependendo da fonte, o cirílico look pode se parecer exatamente com o grego Λ. A forma Π é apenas mais uma variação estilística da mesma letra.
NGN

Respostas:


4

Geléia , 56 bytes

Um hash pode muito bem ser mais curto.

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

Um link monádico que retorna uma lista de valores de proporção na ordem em inglês, grego e russo.

Experimente online!
... ou veja uma saída totalmente formatada (incluindo o arredondamento implícito até uma casa decimal)

Quão?

Desejamos ter um código que traduza cada caractere possível para um triplo de um e zeros, representando se eles pertencem a cada um dos alfabetos (bem como a tabela na pergunta onde Cestá 1 0 1). Feito isso, podemos somar entre eles e dividir pelo comprimento para produzir as proporções (entre zero e uma inclusiva) - isso é apenas S÷L(visto à direita do código).

Para qualquer caractere específico, sabemos que se o ordinal é menor que 256, conta como inglês, se é maior que 1024, conta como russo e que, se estiver entre 256 e 1024, conta como grego. Como tal, pegue o ordinal e o número inteiro dividindo por 256 e depois o número inteiro dividindo o resultado por dois rendimentos 0para o espaço e caracteres latinos (conte como inglês), 1para helênico (conte como grego) e 2cirílico (conte como russo). Isso é apenas O:⁹:2no Jelly (visto à esquerda do código).

Se girarmos os triplos bits para que o alfabeto natural * seja o mais significativo, podemos codificar os dois bits inferiores (como valores entre zero e três inclusive) em uma tabela de pesquisa com três linhas e depois girar para a direita pela números encontrados acima.

Quando fazemos isso, há duas coisas dignas de nota: 1. A geléia tem um átomo de rotação à esquerda e não um de rotação à direita; 2. a linha helênica da tabela de pesquisa começaria com um zero (já que Ξé apenas grego), impedindo uma codificação simples de base 4 (já que os zeros à esquerda não são codificáveis). Para aliviar (1), podemos girar para a esquerda pelo valor negado e para aliviar (2), podemos codificar nossas linhas no sentido inverso e indexá-las com a quantidade negativa. Dessa forma, podemos negar o índice de linha e coluna com um único byte ( N), pois assim nossos índices de linha e coluna podem ser calculados O:⁹:2;ON.

Note que o Jelly agora possui um átomo de indexação multidimensional œị,.

A tabela é formada por três números grandes que, uma vez convertidos na base quatro, fornecem os bits mais baixos necessários para cirílico, grego e latim (+ espaço), respectivamente. Eles são de tamanho mínimo, de modo que a indexação modular pelos valores ordinais negados é possível - 47, 25 e 30 respectivamente (os .s estão em índices não utilizados):

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

Como exemplo, considere o caractere Φ no ponto Unicode U + 03A6 (que deve render [0,1,1]), que possui um valor ordinal de (3 × 16² + 10 × 16 + 6 =) 934. ( O:⁹:2significa 934 // 256 // 2 =) 1 identificando-o como parte do bloco helênico. O ;Oconcatena o ordinal nos dando [1,934]e Ndepois nega os dois valores nos dando [-1,-934]. Como a indexação do Jelly é baseada em 1 e modular e existem três linhas nas -1referências, a segunda das três linhas (linha 2 no bloco de código acima), uma vez que a linha do meio tem um comprimento de 25 as -934referências (-934% 25 =) 16 th entrada na linha, o qual é 2. O código então adiciona quatro (o bit mais significativo), dando-nos o 6que convertido em binário é[1,1,0]. O código então gira esta esquerda para cada um [-1,-934]e pega a cabeça (ou seja, a rotação deixada por -1, uma rotação direita por 1), produzindo [0,1,1]conforme necessário.

* Inglês para o espaço, pois está agrupado com os caracteres latinos


Código comentado

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

Parece que você tem alguma terminologia aí ... "hash" significa uma construção como (keys)iị(values)Ʋ?
Erik the Outgolfer

Quero dizer, formar um conjunto distinto de chaves a partir de alguma manipulação matemática, para que se possa indexar em uma lista de valores, sim. Assim como ...ị“...ou possivelmente ...ṃ“...(estritamente falando a cadeia monádico formei é uma função hash )
Jonathan Allan

@ngn M kebard isning
Jonathan Allan

Ah, eu sei como consertar isso! Reconfigure o teclado e digite cirílico "у" e "о" em vez de "y" e "o": D
ngn

Eu nunca vi uma resposta tão longa da Jelly ... ótimo trabalho!
simonalexander2005

5

JavaScript (ES6), 197 179 bytes

Retorna uma matriz de 3 proporções em [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]

Experimente online!

Quão?

Usamos a função hash (bastante ineficiente) % 202 % 116 % 89para transformar cada código de caractere em um índice em [0..88]. A tabela de pesquisa correspondente consiste em entradas de 3 bits em que bit # 2 = latino, bit # 1 = grego e bit # 0 = cirílico. Usando dígitos decimais, isso fornece:

76273722773722017732767267300071731711117377737577371111111111000775474476474767744474447

Anexamos um extra 1para obter um número par de entradas e codificamos esse fluxo de bits com caracteres ASCII imprimíveis no intervalo [37..99] ( %a c), com 6 bits de dados de carga útil por caractere.

Isso leva à seguinte string:

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

O deslocamento foi escolhido para evitar caracteres como o \que seria necessário escapar.


3

Ruby , 165 bytes

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

Experimente online!

Edit: Golfed o código significativamente, e mais importante, espremeu 3 seqüências de tradução em uma seqüência UTF-8. O código mais longo original é mantido abaixo para melhor legibilidade e explicação da lógica.

Ruby, 211 bytes

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

Experimente online!

Pode não ser a abordagem mais eficiente, mas faz o trabalho. Usa uma tabela de conversão para cada alfabeto com ocorrência de caracteres em diferentes scripts codificados pelos bits do número (na ordem: latim, grego, russo). A saída é uma matriz de porcentagens na mesma ordem.

Para corrigir o Ёcaso externo , estendi o bloco de 4 s apenas em russo de 10 posições no final do alfabeto para 15. Dessa forma, Ёé escolhido corretamente com índice negativo (e não somos obrigados a lidar com letras minúsculas que correspondam a esses índices extras).


1

Retina 0.8.2 , 230 bytes

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

Experimente online! O link inclui casos de teste. Nota: A saída está em% truncada para um número inteiro, porque aumentar a precisão tornou o script muito lento e atingiu o tempo limite no TIO.

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.