การทำแผนที่ระหว่างจำนวนเต็มและคำที่ออกเสียง


10

วัตถุประสงค์

ความคิดคือการให้รหัสที่จำเป็นในการแมปจำนวนเต็ม 32 บิตไปยัง / จากคำที่ออกเสียงได้สูงสุด 9 ตัวอักษร นั่นอาจเป็นประโยชน์ตัวอย่างเช่นเพื่อให้จำหมายเลขได้ง่ายขึ้นหรือพิมพ์ในแบบฟอร์ม

ทั้งวิธีการแปลจำนวนเต็มเป็นคำที่สอดคล้องกันและสำหรับการแปลกลับคำเป็นจำนวนเต็มที่สอดคล้องกันจะต้อง

กฎระเบียบ

จะต้องมีการแมปแบบหนึ่งต่อหนึ่งระหว่างจำนวนเต็มกับคำและทั้งชุดของจำนวนเต็ม 32 บิต (หรือใส่อีกวิธีหนึ่งคือจำนวนเต็มใด ๆ จาก 0 ถึง 4294967295) ต้องสามารถแมปได้ แม้ว่าแน่นอนว่าไม่ใช่ทุกคำที่จะมีความหมายและการป้อนคำที่ไม่ได้แมปไปยังจำนวนเต็มอาจมีพฤติกรรมที่ไม่ระบุ

คุณมีอิสระในการตัดสินใจว่าชุดคำใดที่มีความหมายและสามารถทำแผนที่ได้ แต่อย่างน้อยคำต่างๆต้องเป็นไปตามกฎเหล่านี้:

  • ควรใช้เฉพาะตัวอักษร 26 ตัว (A ... Z) เป็นอักขระ ไม่ควรใช้สำเนียงตัวเรือน ฯลฯ ... เพื่อขยายชุดค่าผสมที่เป็นไปได้
  • สูงสุด 9 ตัวอักษรต่อคำ
  • ไม่ควรวางพยัญชนะสองตัว (BCDFGHJKLMNPQRSTVWXZ - 20 possiblities) ไว้ข้างๆกัน (จะต้องล้อมรอบด้วยสระ)
  • ไม่ควรวางสระสองตัว (AEIOUY - 6 ความเป็นไปได้) ไว้ข้างๆกัน (จะต้องล้อมรอบด้วยพยัญชนะ)

หมายเหตุ: รูปแบบที่ง่ายที่สุดที่คุณมีคำทั้งหมดสร้างเป็นCVCVCVCVC( Cเป็นพยัญชนะและVสระ) ให้ 4147200000 ชุดและจำนวนเต็ม 32 บิตมีค่าที่เป็นไปได้ 4294967296 ดังนั้นมันไม่เพียงพอ คุณต้องขยายจำนวนชุดค่าผสมไม่ว่าจะโดยการอนุญาตให้ใช้คำที่สั้นกว่าหรือการอนุญาตVCVCVCVCVรวมกัน

ใช้กฎมาตรฐานอื่น ๆ และห้ามมีช่องโหว่มาตรฐาน

อินพุต / เอาท์พุท

สำหรับการส่งแต่ละครั้งจะต้องมีรหัสสองชิ้น:

  • หนึ่งที่ใช้จำนวนเต็มเป็นอาร์กิวเมนต์ / อินพุตและส่งกลับ / พิมพ์คำที่เกี่ยวข้อง
  • หนึ่งที่ใช้คำว่าอาร์กิวเมนต์ / input และผลตอบแทน / พิมพ์จำนวนเต็มที่สอดคล้องกัน

หรือคุณสามารถเลือกที่จะส่งรหัสชิ้นเดียวที่จัดการการดำเนินการทั้งสอง:

  • เมื่อได้รับจำนวนเต็มเป็นอินพุทก็จะส่งออกคำที่สอดคล้องกัน
  • เมื่อได้รับสตริงเป็นอินพุตมันจะส่งออกจำนวนเต็มที่สอดคล้องกัน

สภาพการชนะ

นี่คือคำตอบที่มีจำนวนไบต์น้อยที่สุด (เมื่อรวมทั้งสองส่วนของรหัสสำหรับการแก้ปัญหาการเลือกรหัสแยกส่วน) ชนะ


มีข้อ จำกัด ของพื้นที่หรือเวลาหรือไม่? เราต้องใส่ในหน่วยความจำ 32GB หรือไม่?
John Dvorak

@JanDvorak เราควรจะสามารถทดสอบโปรแกรมของคุณบนคอมพิวเตอร์ "มาตรฐาน" แต่อัลกอริธึมควรง่ายสิ่งที่คุณมีอยู่ในใจที่ต้องใช้หน่วยความจำขนาดใหญ่เช่นนี้?
สลัว

ฉันสามารถสร้างคำเก้าตัวอักษรที่เป็นไปได้ทั้งหมดที่ตรงกับสูตรของคุณแล้วสร้างดัชนีลงในชุดหรือทำการค้นหาแบบไบนารี
John Dvorak

@JanDvorak ฉันต้องยอมรับว่าฉันไม่ได้คิดอย่างนั้น ฉันคิดเกี่ยวกับการแก้ปัญหาที่โดยทั่วไปแล้วทำการแปลงที่ฐาน 26 โดยมีการปรับเปลี่ยนบางอย่างเพื่อสนองความต้องการของสระ / พยัญชนะ แต่อย่างใดฉันสงสัยว่า "โหดร้าย" วิธีที่คุณมีอยู่ในใจสามารถรหัสกอล์ฟที่มีประสิทธิภาพ อย่างไรก็ตามถ้าฉันต้องชี้แจงเรื่องนี้จริงๆสมมติว่าคุณไม่ได้รับอนุญาตให้จัดสรรหน่วยความจำมากกว่า 4GB
สลัว

คุณอาจต้องการให้ผู้ตอบคำถามเรียกใช้รหัสสำหรับค่าที่กำหนดไว้ล่วงหน้า (0,1,10,2 ** 32-1 และอื่น ๆ ) จากนั้นย้อนกลับและรวมผลลัพธ์ไว้ในคำตอบ
John Dvorak

คำตอบ:


1

JavaScript (ES6), 205 ไบต์

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

จุดตัดระหว่าง CVCVCVCVC และ VCVCVCVCV คือ 4e9 ดังนั้นเริ่มผิดที่ 5244160000 (อินพุตตัวเลข) หรือzesuwurib(อินพุตสตริง)


หกเดือนต่อมา ... ฉันได้รับรางวัลจากคุณเนื่องจากคุณเป็นคนที่สั้นที่สุด (และฉันไม่สามารถยอมรับคำตอบของ rturnbull ซึ่งไม่ตรงกับคำชี้แจงที่ฉันทำไว้ในความคิดเห็น)
สลัว

2

PHP, 353 ไบต์

การเข้ารหัส + การถอดรหัส

is_numeric($argn)มีบูลีน เป็นจริงถ้าอินพุตเป็นจำนวนเต็ม

$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 ไบต์ (เข้ารหัส) + 195 ไบต์ (ถอดรหัส) = 385 ไบต์

การเข้ารหัส

$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 แบบให้เลือก

การเข้ารหัสเวอร์ชันออนไลน์โดยไม่มี E_NOTICE

ขยาย

$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

อินพุต => เอาท์พุท

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

หากคุณต้องการผลลัพธ์ 9 ไบต์เสมอโปรดแทนที่while($a)ด้วยwhile(strlen($r)<9)+ 10 ไบต์

ถอดรหัส

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

ขยาย

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

อินพุต => เอาท์พุท

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

การถอดรหัสเวอร์ชั่นออนไลน์แบบไม่มี E_NOTICE

ตรวจสอบเพิ่มเติม

ถ้าเราต้องการตรวจสอบว่าสตริงถูกต้อง

เพิ่ม$x.=$b?:0;ในตอนท้ายของลูปการถอดรหัส + 10 ไบต์

แทนที่echo$s;ด้วยecho!preg_match('#([01])\1$#',$x)?$s:_;+32 ไบต์


1

R, 165 ไบต์

การเข้ารหัสและถอดรหัสในฟังก์ชั่นเดียว

ฟังก์ชั่นนี้ใช้วิธีการเดรัจฉานบังคับของการสร้างค่าที่เป็นไปได้ทั้งหมดแล้วกลับดัชนีเมื่อมันได้รับการป้อนสตริงและกลับสตริงเมื่อได้รับการป้อนจำนวนเต็ม ผลก็คือมันช้ามากและใช้หน่วยความจำ 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 สิ่งนี้ครอบคลุมสตริงทั้งหมดของรูปแบบ CVCVCVCV (C) โดยที่ C ล่าสุดนั้นเป็นทางเลือก


@ mbomb007 Gigabytes ขอโทษที่พิมพ์ผิด ฟังก์ชั่นทำการเข้ารหัสและถอดรหัสขึ้นอยู่กับว่าอาร์กิวเมนต์เป็นสตริงหรือจำนวนเต็ม ฉันได้อัปเดตโพสต์เพื่อชี้แจงว่า
rturnbull

downvoter สามารถแสดงความคิดเห็นเพื่อแนะนำการปรับปรุงได้หรือไม่? ขอบคุณ
rturnbull

1
ในความคิดเห็นของคำถามติ่มซำชี้แจงว่าคุณไม่สามารถใช้หน่วยความจำมากกว่า 4gb ....
Socratic Phoenix
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.