Karakter Lintas-Alfabet

17

Latar Belakang

Saya melihat Diagram Venn yang sangat menarik ini di wikipedia: https://simple.wikipedia.org/wiki/Alphabet#/media/File:Venn_diagram_gr_la_ru.svg

Ini menunjukkan huruf (bentuk fisik) dalam huruf yang berbeda yang umum antara huruf Rusia, Yunani dan Latin.

Tantangan

Diberikan string input karakter dari salah satu dari tiga skrip yang ditampilkan (yaitu huruf kapital huruf Yunani, Sirilik atau Latin), mengeluarkan persentase string yang cocok dengan setiap bahasa. Surat yang berulang dihitung setiap waktu.

Misalnya, FFLURSsemua karakter hanya-latin, jadi outputnya adalah FFLURS is 100% Latin, 0% Cyrillic and 0% Greek.

Sebaliknya, TOX BEAM PHPdibentuk sepenuhnya karakter yang muncul dalam ketiga bahasa, sehingga hasilnya adalah TOX BEAM PHP is 100% Cyrillic, 100% Greek and 100% Latin.

Tabel Pencarian

Diagram Venn adalah sumber surat-surat di bawah ini:

Hanya Latin:

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

Latin dan Sirilik:

C, С

Latin dan Yunani:

I,Ι, N,Ν, Z,Ζ

Yunani dan Sirilik

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

Ketiganya:

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

Sisanya ... hanya Yunani atau Cyrillic saja.

CATATAN PENTING

Unicode mendefinisikan (misalnya) "A" dalam (setidaknya) tiga cara terpisah - satu untuk setiap bahasa. Apapun yang digunakan dalam input (& # 0391, & # 0410 atau & # 0041), program harus memahaminya sebagai pencocokan ketiga bahasa. Jadi, A(Latin), Α(Greek Alpha) dan А(Cyrillic) semua harus memberikan 100% Cyrillic, 100% Greek and 100% Latinjawabannya.

Masukkan format

String yang berisi eksklusif А-Я, Α-Ω, A-Zdan (ruang). Karakter-karakter ini dapat diulang beberapa kali dalam string.

Format output

Output dapat dalam format apa pun, asalkan fungsi tersebut menghasilkan hasil yang konsisten. Saya ingin melihat output dalam format yang saya tunjukkan dalam contoh saya ( FFLURS is 100% Latin, 0% Cyrillic and 0% Greek), tetapi untuk membuat tantangan lebih terbuka bagi siapa pun, saya senang menerima array / string persentase / rasio:

[100,0,0],

100 0 0

[1.0 0.0 0.0]

selama itu selalu jelas nomor mana bahasa mana - jadi output harus konsisten.

Beberapa lagi kasus uji

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

Kriteria Menang

Aturan dan pengecualian biasa berlaku; jawaban terpendek (byte) menang.

(tautan kotak pasir: https://codegolf.meta.stackexchange.com/a/14984/62289 )

Untuk menghindari keraguan, satu-satunya karakter Unicode yang valid dalam input adalah:

  • 0020, 0041-005A (Alfabet Latin)
  • 0020, 0391-03A9 (Alfabet Yunani)
  • 0020, 0401, 0410-042F (Alfabet Sirilik)

Tetapi seperti yang ditunjukkan dalam tabel pencarian, karakter mungkin alfabet silang.

Menambahkan tabel Jonathan Allan dari komentar:

                                                 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
sumber
1
Selamat datang di PPCG! Ini adalah tantangan pertama yang bagus. :) Sebuah catatan pada catatan UTF-8 Anda: itu bukan UTF-8 yang mendefinisikan beberapa versi dari karakter-karakter ini tetapi Unicode (dan UTF-8 hanyalah satu cara spesifik untuk menyandikan poin kode Unicode). Juga, karena bagian ini agak penting untuk mendapatkan jawaban yang benar, Anda mungkin ingin memasukkan daftar eksplisit semua karakter Unicode yang perlu ditangani dengan benar.
Martin Ender
@ ngn ya, terima kasih.
simonalexander2005
@ JonathanAllan, ngn: Saya setuju, saya hanya bermaksud huruf-huruf yang ada di diagram Venn - tetapi semua representasi dari surat-surat itu valid - seperti saya coba katakan dalam pertanyaan, ada beberapa representasi unicode "A", misalnya
simonalexander2005
Sirilik "El" sebenarnya adalah bahasa Yunani "Lambda". Cyrillic "Pe" adalah bahasa Yunani "Pi".
simonalexander2005
@JonathanAllan Bergantung pada font, Cyrillic Л dapat persis seperti bahasa Yunani Λ. Bentuk seperti Π hanyalah variasi gaya dari huruf yang sama.
ngn

Jawaban:

4

Jelly , 56 byte

Hash mungkin lebih pendek.

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

Tautan monadik mengembalikan daftar jumlah rasio dalam urutan bahasa Inggris, Yunani, Rusia.

Cobalah online!
... atau lihat output yang diformat sepenuhnya (termasuk pembulatan tersirat ke satu tempat desimal)

Bagaimana?

Kami ingin memiliki kode yang diterjemahkan masing-masing karakter mungkin untuk triple satu dan nol mewakili apakah mereka milik masing-masing dari abjad (seperti tabel di pertanyaan di mana Cadalah 1 0 1). Setelah selesai, kita dapat menjumlahkannya dan membaginya dengan panjang untuk menghasilkan rasio (antara nol dan satu inklusif) - ini adil S÷L(terlihat di sebelah kanan kode).

Untuk setiap karakter tertentu, kita tahu bahwa jika ordinal kurang dari 256, itu dianggap sebagai bahasa Inggris, jika lebih besar dari 1024 ia dianggap sebagai Rusia, dan bahwa jika di antara 256 dan 1024 itu dianggap sebagai bahasa Yunani. Dengan demikian mengambil pembagian ordinal dan integer dengan 256 dan kemudian integer membagi hasilnya dengan dua hasil 0untuk spasi dan karakter Latin (dihitung sebagai bahasa Inggris), 1untuk Hellenic (hitungan sebagai bahasa Yunani), dan 2untuk Cyrillic (hitungan sebagai bahasa Rusia). Ini hanya O:⁹:2di Jelly (terlihat di sebelah kiri kode).

Jika kita memutar tiga kali lipat bit sehingga bit alfabet alami * adalah yang paling signifikan maka kita dapat menyandikan dua bit yang lebih rendah (sebagai nilai antara nol dan tiga inklusif) dalam tabel pencarian dengan tiga baris dan kemudian memutar ke kanan oleh nomor ditemukan di atas.

Ketika kita melakukan ini ada dua hal yang patut dicatat - 1. Jelly memiliki atom rotate-left-by, bukan rotate-right-by one; 2. baris Hellenic dari tabel pencarian akan mulai dengan nol (karena Ξhanya bahasa Yunani), menggagalkan pengkodean basis-4 yang sederhana (karena nol di depannya tidak dapat dikodekan). Untuk mengurangi (1) kita dapat memutar-kiri dengan nilai yang dinegasikan dan untuk mengurangi (2) kita dapat menyandikan baris kita secara terbalik dan mengindeksnya dengan jumlah negatif. Dengan cara ini kita dapat meniadakan indeks baris dan kolom dengan byte tunggal ( N) sehingga indeks baris dan kolom kita dapat dihitung dengan O:⁹:2;ON.

Perhatikan bahwa Jelly sekarang memiliki atom pengindeks multi-dimensi œị,.

Tabel ini dibentuk dari tiga angka besar yang, setelah dikonversi menjadi basis empat, memberikan bit yang lebih rendah yang diperlukan untuk Cyrillic, Yunani dan Latin (+ Spasi) masing-masing. Mereka memiliki panjang minimal sedemikian sehingga pengindeksan modular dengan nilai ordinal dinegasikan adalah mungkin - 47, 25, dan 30 masing-masing ( .s berada pada indeks yang tidak digunakan):

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

Sebagai contoh, perhatikan karakter Φ pada titik Unicode U + 03A6 (yang akan menghasilkan [0,1,1]) ia memiliki nilai urut (3 × 16² + 10 × 16 + 6 =) 934. ( O:⁹:2artinya 934 // 256 // 2 =) 1 mengidentifikasinya sebagai bagian dari blok Hellenic. The ;Omerangkai ordinal memberikan kita [1,934]dan Nkemudian meniadakan kedua nilai memberikan kita [-1,-934]. Karena pengindeksan Jelly baik berbasis 1 dan modular dan ada tiga baris -1referensi yang kedua dari tiga baris (baris 2 dalam blok kode di atas), karena baris tengah memiliki panjang 25 -934referensi (-934% 25 =) entri ke 16 di baris itu, yaitu 2. Kode kemudian menambahkan empat (bit paling signifikan) memberi kita 6yang dikonversi ke biner[1,1,0]. Kode kemudian memutar kiri ini dengan masing-masing [-1,-934]dan mengambil kepala (yaitu rotasi kiri oleh -1, kanan rotasi oleh 1) menghasilkan [0,1,1]sesuai kebutuhan.

* Bahasa Inggris untuk ruang karena dikelompokkan dengan karakter Latin


Kode yang dikomentari

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
sumber
Sepertinya Anda memiliki beberapa terminologi di sana ... apakah "hash" berarti konstruksi seperti (keys)iị(values)Ʋ?
Erik the Outgolfer
Maksud saya membentuk satu set kunci yang berbeda dari beberapa manipulasi matematika sehingga orang dapat mengindeks ke dalam daftar nilai, ya. Jadi suka ...ị“...atau mungkin ...ṃ“...(sebenarnya rantai monadik yang saya bentuk adalah fungsi hash )
Jonathan Allan
@ngn M kebard isning
Jonathan Allan
Oh, saya tahu cara memperbaikinya! Konfigurasikan ulang keyboard Anda dan ketikkan Cyrillic "у" dan "о" sebagai ganti "y" dan "o": D
ngn
Saya belum pernah melihat jawaban Jelly yang panjang ... pekerjaan bagus!
simonalexander2005
5

JavaScript (ES6), 197 179 byte

Mengembalikan susunan 3 rasio dalam [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]

Cobalah online!

Bagaimana?

Kami menggunakan fungsi hash (agak tidak efisien) % 202 % 116 % 89untuk mengubah setiap kode karakter menjadi indeks di [0..88]. Tabel pencarian yang sesuai terdiri dari entri 3-bit di mana bit # 2 = Latin, bit # 1 = Yunani dan bit # 0 = Cyrillic. Menggunakan digit desimal, ini memberi:

76273722773722017732767267300071731711117377737577371111111111000775474476474767744474447

Kami menambahkan ekstra 1untuk mendapatkan jumlah entri genap dan menyandikan bit stream ini dengan karakter ASCII yang dapat dicetak dalam kisaran [37..99] ( %hingga c), dengan 6 bit data payload per karakter.

Ini mengarah ke string berikut:

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

Offset dipilih untuk menghindari karakter seperti \yang akan diperlukan melarikan diri.

Arnauld
sumber
3

Ruby , 165 byte

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

Cobalah online!

Sunting: Memodifikasi kode secara signifikan, dan yang paling penting, meringkas 3 urutan terjemahan menjadi satu string UTF-8. Kode asli yang lebih panjang disimpan di bawah ini agar lebih mudah dibaca dan penjelasan logikanya.

Ruby, 211 byte

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

Cobalah online!

Mungkin bukan pendekatan yang paling efisien, tetapi melakukan pekerjaan. Menggunakan tabel terjemahan untuk setiap alfabet dengan kemunculan karakter dalam skrip yang berbeda yang dikodekan oleh bit angka (dalam urutan: Latin, Yunani, Rusia). Outputnya adalah array persentase dalam urutan yang sama.

Untuk memperbaiki Ёkasus outlier , saya memperpanjang blok hanya-Rusia dari 4-s dari 10 posisi di akhir alfabet ke 15. Dengan cara ini, Ёakan diambil dengan benar dengan indeks negatif (dan kami tidak diharuskan untuk menangani huruf kecil daripada sesuai dengan indeks tambahan ini).

Kirill L.
sumber
1

Retina 0.8.2 , 230 byte

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

Cobalah online! Tautan termasuk kasus uji. Catatan: Output dalam% terpotong ke integer, karena meningkatkan presisi membuat skrip terlalu lambat dan batas waktunya habis pada TIO.

Neil
sumber