정수와 발음 가능한 단어 사이의 매핑


10

목적

이 아이디어는 32 비트 정수를 최대 9 자의 발음 할 수없는 단어와 매핑하는 데 필요한 코드를 제공하는 것입니다. 예를 들어 일련 번호를 더 쉽게 기억하거나 양식을 입력하는 데 유용 할 수 있습니다.

정수를 대응하는 단어로 번역하고 단어를 대응하는 정수로 다시 변환하는 방법이 모두 필요하다.

규칙

정수와 단어 사이에 일대일 매핑이 있어야하고 32 비트 정수 전체 (또는 다른 방법으로 0에서 4294967295까지의 정수)를 매핑 할 수 있어야합니다. 물론 모든 단어가 의미있는 것은 아니지만 정수에 매핑되지 않은 단어를 입력하면 지정되지 않은 동작이있을 수 있습니다.

의미있는 "발음 할 수있는"단어 집합과 의미있는 매핑 방법을 자유롭게 결정할 수 있지만 단어는 최소한 다음 규칙을 따라야합니다.

  • 기본 26 자 (A ... Z) 만 문자로 사용해야합니다. 악센트, 케이스 등을 사용하여 가능한 조합을 확장해서는 안됩니다.
  • 단어 당 최대 9 자입니다.
  • 두 자음 (BCDFGHJKLMNPQRSTVWXZ-20 가능성)을 나란히 배치해서는 안됩니다 (모음으로 묶어야합니다).
  • 두 모음 (AEIOUY-6 가능성)을 나란히 배치해서는 안됩니다 (자음으로 둘러싸여 야 함).

참고 : CVCVCVCVC( C자음과 V모음으로) 구성된 모든 단어를 갖는 가장 간단한 체계 는 4147200000 조합을 제공하며 32 비트 정수는 4294967296의 가능한 값을 가지므로 충분하지 않습니다. 더 짧은 단어를 허용하거나 VCVCVCVCV조합 을 허용하여 조합 수를 확장해야합니다 .

다른 표준 규칙이 적용되며 표준 허점이 금지됩니다.

입력 / 출력

제출할 때마다 두 가지 코드가 제공되어야합니다.

  • 정수를 인수 / 입력으로 받아서 해당 단어를 반환 / 인쇄하는 것
  • 단어를 인수 / 입력으로 받아서 해당 정수를 반환 / 인쇄하는 것

또는 두 작업을 모두 처리하는 단일 코드를 제출하도록 선택할 수 있습니다.

  • 입력으로 정수가 주어지면 해당 단어를 출력합니다.
  • 문자열을 입력으로 받으면 해당 정수를 출력합니다.

승리 조건

이것은 이며, 가장 적은 바이트 (두 코드 조각을 합할 때 분리 된 코드 조각을 선택하는 솔루션에 대한 답변)가 가장 좋습니다.


공간이나 시간 제약이 있습니까? 32GB 메모리에 맞아야합니까?
John Dvorak

@JanDvorak "표준"컴퓨터에서 프로그램을 테스트 할 수있을 것입니다. 그러나 알고리즘은 간단해야합니다. 방대한 양의 메모리가 필요한 것은 무엇입니까?
dim

수식과 일치하는 가능한 모든 9 글자 단어를 생성 한 다음 세트로 색인하거나 이진 검색을 수행 할 수 있습니다.
John Dvorak

@ JanDvorak 나는 그것을 생각하지 않았다는 것을 인정해야합니다. 모음 / 자음 제약 조건을 만족시키기 위해 약간의 조정으로 기본적으로 base-26 변환을 수행하는 솔루션에 대해 더 많이 생각하고있었습니다. 그러나 나는 당신이 생각한 "잔인한"방식이 코드 골프 효율적일 수 있다고 의심한다. 어쨌든, 이것을 명확히해야한다면 4GB 이상의 메모리를 할당 할 수 없다고 가정 해 봅시다.
희미 함

응답자는 미리 정해진 값 (0,1,10,2 ** 32-1 등)에 대해 코드를 실행 한 다음 되돌아 와서 결과를 답에 포함하도록 요구할 수 있습니다.
John Dvorak

답변:


1

자바 스크립트 (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(문자열 입력) 에서 잘못 시작됩니다 .


6 개월 후 ... 나는 당신이 가장 짧기 때문에 당신에게 수락 포인트를 수여합니다. (그리고 나는 rturnbull의 대답을 받아 들일 수 없습니다.
dim

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 기가 바이트, 오타가 유감입니다. 이 함수는 인수가 문자열인지 정수인지에 따라 인코딩과 디코딩을 모두 수행합니다. 명확히하기 위해 게시물을 업데이트했습니다.
rturnbull

downvoter가 개선을 제안하기 위해 의견을 남길 수 있습니까? 감사.
rturnbull

1
질문의 의견에서, 희미한 관계를 설명 당신은 .... 4GB 이상의 메모리 사용할 수 없습니다
소크라테스 피닉스
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.