Складання карти між цілим і вимовляється слово


10

Призначення

Ідея полягає в наданні коду, необхідного для відображення 32-бітного цілого числа на / з вимовляючого слова максимум 9 символів. Це може бути корисно, наприклад, щоб спростити запам’ятовувати серійний номер або набрати форму.

Потрібен як метод переведення цілого числа на відповідне слово, так і для переведення назад слова у відповідне ціле число.

Правила

Повинно бути чітке відображення між цілими числами та словами, і весь набір 32-бітових цілих чисел (або, кажучи іншим чином, будь-яке ціле число від 0 до 4294967295) має бути відображеним. Хоча, очевидно, не всі слова будуть значущими, і введення слів, які не відображають ціле число, може мати не визначене поведінку.

Ви можете вирішити, який саме набір "вимовляючих" слів має значення, і як робиться відображення, але слова повинні відповідати принаймні цим правилам:

  • В якості символів слід використовувати лише основні 26 літер (A ... Z). Акценти, кожухи тощо ... не слід використовувати для розширення можливих комбінацій.
  • Максимум 9 символів за кожне слово.
  • два приголосні (BCDFGHJKLMNPQRSTVWXZ - 20 можливостей) не повинні розташовуватися поруч (вони повинні бути оточені голосними голосами).
  • два голосні (AEIOUY - 6 можливостей) не повинні ставитись поруч (вони повинні бути оточені приголосними).

Зауважте: найпростіша схема, у якій усі слова побудовані як CVCVCVCVC( Cяк приголосний і Vголосний), дає 4147200000 комбінацій, а 32-бітове ціле число має 4294967296 можливих значень, тому його недостатньо. Вам потрібно розширити кількість комбінацій, або шляхом дозволу коротших слів, або шляхом дозволу VCVCVCVCVкомбінацій.

Діють інші стандартні правила, а стандартні лазівки заборонені.

Входи / виходи

Для кожного подання необхідно надати два фрагменти коду:

  • Таке, яке приймає ціле число як аргумент / вхід і повертає / друкує відповідне слово
  • Та, яка приймає слово як аргумент / вхід і повертає / друкує відповідне ціле число

Можна також подати єдиний фрагмент коду, який обробляє обидві операції:

  • Якщо вводиться ціле число як вхідне, воно виводить відповідне слово
  • Якщо дано рядок як вхід, він виводить відповідне ціле число

Умова виграшу

Це , відповідь на який має найменше байтів (при підсумовуванні обох фрагментів коду, для рішень, які вибирають окремі частини коду) виграє.


Чи є обмеження у просторі чи часі? Чи маємо ми вміщуватися в 32 Гб пам'яті?
Джон Дворак

@JanDvorak Ну, ми повинні мати можливість протестувати вашу програму на "стандартному" комп'ютері. Але алгоритм повинен бути простим, що ви маєте на увазі, що потрібен такий великий об'єм пам'яті?
дим

Я міг би просто генерувати всі можливі дев'ятибуквні слова, які відповідають вашій формулі, а потім індексувати у набір або робити двійковий пошук.
Джон Дворак

@JanDvorak Я мушу визнати, що не думав про це. Я більше роздумував над рішеннями, які в основному робили перетворення базових 26, з деякими коригуваннями, щоб задовольнити обмеження голосних / приголосних. Але я якимось чином сумніваюся, що "жорстокий" спосіб, який ви мали на увазі, може бути ефективним для коду. У будь-якому випадку, якщо я повинен це дійсно уточнити, скажімо, вам не дозволяється виділяти більше 4 Гб пам'яті.
тьма

Ви можете вимагати від відповідачів запустити свій код для деяких заздалегідь заданих значень (0,1,10,2 ** 32-1 і таке інше), а потім повернути назад і включити результати у відповідь.
Джон Дворак

Відповіді:


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 байт

Кодування та декодування в одній функції.

Ця функція використовує грубу силу методу створення всіх можливих значень, а потім просто повернення індексу при введенні рядка і повернення рядка при заданому цілому введенні. Як наслідок, це дуже повільно і використовує 16 ГБ + пам'яті!

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

Чи може залишити коментар, щоб запропонувати покращення? Дякую.
rturnbull

1
У коментарях до запитання dim роз'яснює, що ви не можете використовувати більше 4 Гб пам'яті ....
Сократичний Фенікс
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.