Memetakan antara integer dan kata yang dapat diucapkan

10

Tujuan

Idenya adalah untuk menyediakan kode yang diperlukan untuk memetakan integer 32-bit ke / dari kata yang dapat diucapkan maksimum 9 karakter. Itu bisa berguna, misalnya, untuk membuat nomor seri lebih mudah diingat, atau mengetikkan formulir.

Diperlukan metode untuk menerjemahkan bilangan bulat ke kata yang sesuai dan untuk menerjemahkan kembali kata ke bilangan bulat yang sesuai.

Aturan

Harus ada pemetaan satu-ke-satu antara bilangan bulat dan kata-kata, dan seluruh rangkaian bilangan bulat 32-bit (atau, dengan kata lain, bilangan bulat dari 0 hingga 4294967295) harus dapat dipetakan. Meskipun, jelas, tidak semua kata akan bermakna, dan memasukkan kata-kata yang tidak dipetakan ke bilangan bulat mungkin memiliki perilaku yang tidak ditentukan.

Anda bebas memutuskan set kata-kata "yang dapat diucapkan" mana yang bermakna, dan bagaimana pemetaan dilakukan, tetapi kata-kata setidaknya harus mengikuti aturan ini:

  • Hanya 26 huruf dasar (A ... Z) yang dapat digunakan sebagai karakter. Aksen, casing, dll ... tidak boleh digunakan untuk memperpanjang kemungkinan kombinasi.
  • Maksimum 9 karakter per kata.
  • dua konsonan (BCDFGHJKLMNPQRSTVWXZ - 20 possiblities) tidak boleh diletakkan berdampingan satu sama lain (mereka harus dikelilingi oleh vokal).
  • dua vokal (AEIOUY - 6 kemungkinan) tidak boleh diletakkan berdampingan (mereka harus dikelilingi oleh konsonan).

Catatan: skema paling sederhana di mana Anda memiliki semua kata dibangun sebagai CVCVCVCVC( Cmenjadi konsonan dan Vvokal) memberikan 4147200000 kombinasi, dan integer 32 bit memiliki 4294967296 nilai yang mungkin, jadi itu tidak cukup. Anda perlu memperluas jumlah kombinasi, baik dengan memungkinkan kata-kata pendek, atau dengan memungkinkan VCVCVCVCVkombinasi, juga.

Aturan standar lain berlaku, dan celah standar dilarang.

Input / Output

Untuk setiap pengiriman, dua potong kode harus disediakan:

  • Yang mengambil integer sebagai argumen / input dan mengembalikan / mencetak kata yang sesuai
  • Salah satu yang mengambil kata sebagai argumen / input dan mengembalikan / mencetak integer yang sesuai

Atau, Anda dapat memilih untuk mengirimkan satu kode yang menangani kedua operasi:

  • Ketika diberi bilangan bulat sebagai input, itu menghasilkan kata yang sesuai
  • Ketika diberi string sebagai input, itu menghasilkan integer yang sesuai

Kondisi menang

Ini adalah , jawabannya yang memiliki byte paling sedikit (ketika menjumlahkan kedua bagian kode, untuk solusi memilih potongan kode yang terpisah) menang.

redup
sumber
Apakah ada batasan ruang atau waktu? Apakah kita harus muat dalam memori 32GB?
John Dvorak
@ JanDvorak Yah, kita harus dapat menguji program Anda pada komputer "standar". Tetapi algoritme harus sederhana, apa yang ada dalam pikiran Anda yang membutuhkan memori sebesar itu?
redup
Saya hanya bisa menghasilkan semua kata sembilan huruf yang mungkin cocok dengan rumus Anda dan kemudian mengindeks ke set atau melakukan pencarian biner.
John Dvorak
@ JanDvorak saya harus mengakui bahwa saya tidak memikirkan itu. Saya lebih memikirkan solusi yang pada dasarnya melakukan konversi basis-26, dengan beberapa penyesuaian untuk memenuhi kendala vokal / konsonan. Tapi saya entah bagaimana meragukan cara "brutal" yang ada dalam pikiran Anda bisa menjadi kode-golf yang efisien. Bagaimanapun, jika saya harus benar-benar menjelaskan ini, katakanlah Anda tidak diizinkan mengalokasikan lebih dari 4GB memori.
redup
Anda dapat meminta penjawab untuk menjalankan kode mereka untuk beberapa nilai yang telah ditentukan (0,1,10,2 ** 32-1 dan semacamnya) dan kemudian kembali dan untuk memasukkan hasil dalam jawaban.
John Dvorak

Jawaban:

1

JavaScript (ES6), 205 byte

p=>(a='bcdfghjklmnpqrstvwxzaeiouy',1/p)?[...Array(9)].map(_=>r=a[p%(n=26-n)+(p=p/n|0,n<7)*20]+r,n=p>(p%=4e9)?20:6,r='')&&r:[...p].map(c=>r=r*(n=26-n)+a.search(c)%20,n=a.search(p[r=0])<20?6:20)&&r+(n<7)*4e9

Titik potong antara CVCVCVCVC dan VCVCVCVCV adalah 4e9, jadi mulai salah di 5244160000 (input numerik) atau zesuwurib(input string).

Neil
sumber
Enam bulan kemudian ... Saya memberi Anda poin terima, karena Anda yang terpendek (dan saya tidak bisa menerima jawaban rturnbull, yang tidak memenuhi klarifikasi yang saya buat di komentar).
redup
2

PHP, 353 Bytes

Encoding + Decoding

is_numeric($argn)berisi boolean. Memang benar jika inputnya adalah integer.

$c=array_diff(range(A,Z),$v=[A,E,I,O,U,Y]);sort($c);if(is_numeric($a=$argn)){$r=($a)%26<6?$v[$a%26]:$c[$a%26-6];$a=$a/26^0;while($a){$z=count($t=in_array($r[0],$v)?$c:$v);$r=$t[$n=$a%$z].$r;$a=$a/$z^0;}echo$r;}else{for($p=1;$i++<strlen($a);){$u=($b=in_array($a[-$i],$c))?$c:$v;$s+=array_flip($u)[$a[-$i]]*$p+($b&$i<2?6:0);$p*=$i>1?count($u):26;}echo$s;}

PHP, 190 Bytes (Encode) + 195 Byte (Decode) = 385 Bytes

Pengkodean

$c=array_diff(range(A,Z),$v=[A,E,I,O,U,Y]);sort($c);$r=($a=$argn)%26<6?$v[$a%26]:$c[$a%26-6];$a=$a/26^0;while($a){$z=count($t=in_array($r[0],$v)?$c:$v);$r=$t[$n=$a%$z].$r;$a=$a/$z^0;}echo$r;

5391360000 = 26 * 120 ** 4 kombinasi tersedia

Pengkodean Versi Online tanpa E_NOTICE

Diperluas

$c=array_diff(range(A,Z),$v=[A,E,I,O,U,Y]);
sort($c); # End of Prepare the two array
$r=($a=$argn)%26<6?$v[$a%26]:$c[$a%26-6]; #base 26 decision input mod 26 <6 end with vowel
$a=$a/26^0; #integer division input with 26
while($a){
    $z=count($t=in_array($r[0],$v)?$c:$v); # use vowel if last entry is consonant and viceversa
    $r=$t[$n=$a%$z].$r; # base 6 or base 20 decision
    $a=$a/$z^0; # divide through base
}echo$r; # Output result

Input => Output

4294967296 => TYPYQACOV 
333 => DAT 
1 => E 
7 => C 
4294967276 => UTOPOQAMI

Jika Anda selalu membutuhkan hasil 9 Byte, harap ganti while($a)dengan while(strlen($r)<9)+ 10 Bytes

Decoding

$c=array_diff(range(A,Z),$v=[A,E,I,O,U,Y]);sort($c);for($p=1;$i++<strlen($a=$argn);){$u=($b=in_array($a[-$i],$c))?$c:$v;$s+=array_flip($u)[$a[-$i]]*$p+($b&$i<2?6:0);$p*=$i>1?count($u):26;}echo$s;

Diperluas

$c=array_diff(range("A","Z"),$v=["A","E","I","O","U","Y"]);
sort($c); # End of Prepare the two array
for($p=1;$i++<strlen($a=$argn);){ 
    $u=($b=in_array($a[-$i],$c))?$c:$v; # find use array for $a[-$i]
    $s+=array_flip($u)[$a[-$i]]*$p+($b&$i<2?6:0); # sum value
    $p*=$i>1?count($u):26; # raise multiple for next item
}echo$s;

Input => Output

ABABABABE => 1
E => 1
UTOPOQAMI => 4294967276
BABABADAT => 333
DAT => 333
TYPYQACOV => 4294967296

Decoding Versi Online tanpa E_NOTICE

Pemeriksaan Tambahan

Jika kita perlu memeriksa apakah sebuah string valid.

Tambahkan $x.=$b?:0;di akhir loop decoding + 10 Bytes

Ganti echo$s;dengan echo!preg_match('#([01])\1$#',$x)?$s:_;+ 32 Bytes

Jörg Hülsermann
sumber
1

R, 165 byte

Pengkodean dan penguraian dalam satu fungsi.

Fungsi ini menggunakan metode brute-force untuk menciptakan semua nilai yang mungkin dan kemudian hanya mengembalikan indeks ketika diberi input string dan mengembalikan string ketika diberi input integer. Akibatnya, sangat lambat dan menggunakan memori 16GB +!

function(x){i=c(1,5,9,15,21,25)
d=apply(expand.grid(c<-letters[-i],v<-letters[i],c,v,c,v,c,v,c(c,"")),1,paste,collapse="")
`if`(mode(x)=="numeric",d[x],which(d==x))}

4.354.560.000 nilai dimungkinkan. Ini mencakup semua string dari formulir CVCVCVCV (C), dengan C terakhir opsional.

rturnbull
sumber
@ mbomb007 Gigabytes, maaf atas kesalahan ketiknya. Fungsi melakukan encoding dan decoding tergantung pada apakah argumennya adalah string atau integer. Saya telah memperbarui pos untuk mengklarifikasi itu.
rturnbull
Bisakah pemberi downvoter memberikan komentar untuk menyarankan peningkatan? Terima kasih.
rturnbull
1
Dalam komentar pertanyaan itu, redup menjelaskan bahwa Anda tidak dapat menggunakan lebih dari 4gb memori ....
Socratic Phoenix