Знайдіть найкоротше представлення числа в модульному SNUSP


10

Фон

Багато езотеричних мов програмування не мають вбудованих чисел в буквальних знаках, тому вам доведеться їх обчислювати під час виконання; і в багатьох із цих випадків представлення чисел може бути досить цікавим. У нас уже виникло завдання щодо представлення номерів для Underload. Ця проблема полягає у представленні чисел у модульному SNUSP . (Зверніть увагу, що вам не потрібно вивчати SNUSP для того, щоб виконати це завдання. Вся необхідна інформація знаходиться у специфікації - але фон може бути цікавим.)

Завдання

Для цього завдання виклик, модульний номер SNUSP - це рядок, сформований з символів @, +і =, за винятком того, що останній символ є a #, і передостанній символ повинен бути +або =(він не може бути @). Наприклад, дійсні числа включають @+#, ==#і @@+@=#; приклади неприпустимих чисел включають в себе +=, @@#і +?+#.

Значення модульного числа SNUSP обчислюється рекурсивно наступним чином:

  • # має значення 0 (це базовий випадок).
  • Якщо число має вигляд =xдля будь-якого рядка x, його значення дорівнює значенню x.
  • Якщо число має вигляд +xдля будь-якого рядка x, його значення дорівнює значенню xплюс 1.
  • Якщо число має форму @cxдля будь-якого окремого символу cта будь-якого рядка x, його значення дорівнює значенню xплюс значення cx.

Для цього завдання потрібно написати програму, яка приймає як вхідне невід'ємне ціле число, і виводить рядок, який є найкоротшим можливим номером Модульного SNUSP, який має значення, рівне вхідному.

Роз'яснення

  • Цілком можливо, що буде більше одного рядка з однаковим значенням, і, зокрема, для деяких цілих чисел буде крапка для найкоротшого модульного номера SNUSP з цим значенням. У такому випадку ви можете вивести будь-яке число, пов'язане з краваткою.
  • Не існує обмеження в алгоритмі, який ви використовуєте для пошуку числа; наприклад, грубі форсинг-рядки та їх оцінка є юридичною тактикою, але це робить щось розумніше, щоб зменшити простір пошуку.
  • Як звичайно в PPCG, ваше подання може бути як повноцінною програмою, так і функцією (виберіть те, що на вашій мові буде більш стислим).
  • Це не проблема щодо обробки вхідних та вихідних форматів, тому ви можете використовувати будь-які розумні засоби для введення неотрицательного цілого числа та виведення рядка. Існує повний посібник з мета , але найбільш часто використовувані юридичні методи включають аргументи / повернення функцій, аргументи командного рядка та стандартний вхід / стандартний вихід.

Тестові справи

Ось найкоротші зображення перших кількох чисел:

  • 0 :#
  • 1 :+#
  • 2 :++#
  • 3 : +++#або@++#
  • 4 : ++++#або +@++#або@=++#
  • 5 : @+++#або@@++#
  • 6 : +@+++#або +@@++#або @=+++#або @=@++#або@@=++#
  • 7 : @++++#або@+@++#
  • 8 : @@+++#або@@@++#
  • 9 : +@@+++#або +@@@++#або @+++++#або @++@++#або @+@=++#або @@=+++#або@@=@++#
  • 10 : @=@+++#або @=@@++#або @@@=++#( це досить важливий тестовий випадок для перевірки , оскільки всі можливі відповіді містять =)
  • 11 : @+@+++#або @+@@++#або @@++++#або@@+@++#
  • 12 : +@+@+++#або +@+@@++#або+@@++++# або +@@+@++#або @=+@+++#або @=+@@++#або @=@=+++#або @=@=@++#або @=@@=++#або @@=++++#або @@=+@++#або@@=@=++#
  • 13 : @@@+++#або@@@@++#
  • 14 : +@@@+++#або +@@@@++#або @=@++++#або @=@+@++#або @@+++++#або @@++@++#або@@+@=++#
  • 15 : @+@++++#або @+@+@++#або @@=@+++#або @@=@@++#або @@@=+++#або@@@=@++#

В якості тестового прикладу більшого, вихідний сигнал від входу 40 повинно бути @@@=@@+++#, @@@=@@@++#, @@@@=@+++#або @@@@=@@++#.

Стан перемоги

Як виклик з , переможець - найкоротший запис, виміряний в байтах.


1
=оптимально буде відбуватися лише як @=, правда?
orlp

3
До речі, подібні виклики зазвичай найкраще розміщувати як метагольф , оскільки навряд чи знайдеться якась цікава відповідь (просто оцініть рядок та цикл за всіма можливими рядками).
orlp

3
@orlp: Я не погоджуюся, цей виклик був би надто простим як метагольф, оскільки знайти оптимальну відповідь порівняно просто, а метагольф не встановлює жодних інших обмежень на оцінку. Я очікую, що більшість відповідей тут є грубою силою, але специфікація є досить складною, щоб груба сила а) не була найкоротшою, і б), швидше за все, буде цікавою для гольфу самостійно. Якщо ви хотіли змінити умову перемоги, ймовірно, єдиний інший цікавий - найшвидший-код , і це має більше сенсу як інший виклик.

Також у нас було багато викликів для гольфу для Brain-Flak
лише

Відповіді:


3

Oracle SQL 11.2, 341 262 байт

WITH e AS(SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),n(s,v,p,c,i)AS(SELECT'#',0,0,e,1 FROM e UNION ALL SELECT c||s,DECODE(c,'+',1,'@',p,0)+v,v,e,i+1 FROM n,e WHERE i<11)CYCLE s SET y TO 1 DEFAULT 0 SELECT s FROM n WHERE:1=v AND rownum=1;

Стара версія

WITH e AS(SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),n(s,v,p,c) AS(SELECT'#',0,0,e FROM e UNION ALL SELECT s||c,CASE c WHEN'+'THEN 1 WHEN'='THEN 0 WHEN'@'THEN p ELSE 0 END+v,v,e FROM n,e WHERE LENGTH(s)<10)CYCLE s SET y TO 1 DEFAULT 0 SELECT MIN(REVERSE(s))KEEP(DENSE_RANK FIRST ORDER BY LENGTH(s))FROM n WHERE v=:1;

: 1 число, яке потрібно представити в модульному SNUSP

Без гольфу:

WITH e AS (SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4),  
n(s,v,p,c,i) AS                   
(
  SELECT '#',0,0,e,1 FROM e
  UNION ALL
  SELECT s||c
       , DECODE(c,'+',1,'@',p,0)+v 
       , v
       , e
       , i+1
  FROM n,e
  WHERE i<11
) CYCLE s SET y TO 1 DEFAULT 0
SELECT s FROM n WHERE:1=v AND rownum=1;

Спочатку створіть подання з 3 рядків, по одному на кожен символ, який використовується для представлення чисел, мінус #, який використовується лише в кінці рядка:

SELECT DECODE(LEVEL,1,'=',2,'@','+')e FROM DUAL CONNECT BY LEVEL<4;    

Тоді рекурсивний вигляд n генерує кожну можливу рядок із цими 3 символами, з'єднує їх у # та оцінює їх.

Параметри:

s: модульне представлення SNUSP числа, що оцінюється
v: десяткове значення s, обчислене попередньою ітерацією
p: v, обчислене ітерацією i-2
c: наступний символ, що приєднується до s
i: лише довжина s необхідні для позбавлення від ДОВЖИНИ () для цілей гольфу

DECODE(c,'+',1,'@',p,0)+v 

Якщо останнім символом є +, тоді додайте 1
Якщо це @ додати значення i-2 ітерації.
Інакше символ є або #, або =. v ініціалізовано з 0 в початковій частині рекурсивного виду, тому нове v дорівнює попередньому v в будь-якому випадку.

WHERE i<11

Будь-яка можлива рядок із 3-ма символами обчислюється, ця частина гарантує, що запит не запускається до великої кризи.

CYCLE s SET y TO 1 DEFAULT 0

Оскільки немає правила побудови рядків, виникають дублікати. Перебуваючи в рекурсивному перегляді, Oracle трактує ці дублікати як цикли і видає помилку, якщо справа явно не вирішена.

SELECT s FROM n WHERE:1=v AND rownum=1;

Повертає перше модульне представлення SNUSP, яке оцінюють до десяткового числа, введеного як параметр: 1

У моїх тестах цей перший рядок завжди є одним із найкоротших уявлень.

У випадку, якщо ваша база даних не буде діяти однаково, тоді слід замінити цей останній пункт

SELECT MIN(s)KEEP(DENSE_RANK FIRST ORDER BY i)FROM n WHERE:1=v

2

JavaScript (ES6), 100 байт

n=>eval("for(a=[['#',0,0]];[[s,t,p],...a]=a,t-n;)a.push(['='+s,t,t],['+'+s,t+1,t],['@'+s,t+p,t]);s")

Простий алгоритм пошуку грубої сили.


Для 40 він повертає "@@@@@@ = ​​=++", який оцінює до 42
кинути aditsu, тому що SE

Навіть для 12 він дає "@@@ +++ #", який оцінює 13
aditsu кинути, тому що SE

Гм, я думаю, що змінитись t<nна це t-nможуть спрацьовувати ...
Ніл

2

Pyth, 41 байт

L?b+ytb@[yttb001)Chb0+hfqQyTs^L"+@="UhQ\#

Тестовий набір

Як це працює:

Є дві частини. Рекурсивна функція, яка обчислює значення виразу SNUSP без трейлінгу #, і рутину грубої сили.

Оцінка:

L?b+ytb@[yttb001)Chb0
L                        Define the function y(b) as follows
 ?b                      If b is nonempty
   +ytb                  The sum of y(tail(b)) and   # tail(b) = b[1:]
   @[       )            The element in the list at location
   Chb                   Character values of the first character.
                         Modular indexing means that 
                         + -> 3
                         @ -> 0
                         = -> 1
                         Index 2 is filler.
    [yttb001)            @ adds y(tail(tail(b)). Tail suppresses the error when
                         called on an empty list, so this treats @# as zero, but
                         this can't lead to problems because removing the @ will
                         always make the expression shorter.
                         + adds 1, = adds 0.
 0                       If b is the empty string, return 0

Груба сила:

+hfqQyTs^L"+@="UhQ\#
               UhQ      0 ... Q     # Q is the input
        ^L"+@="         Map that list to all strings formed from the characters
                        "+@=", with that many characters.
       s                Concatenate
  fqQyT                 Filter for strings which evaluate to the input
 h                      Take the first success, which is the shortest due to
                        the order the strings were generated.
+                 \#    Add a '#' and output

1

CJam, 58

ri:M;'#0_]]{_{M&}#_)!}{;{~[2,+1$f+"@=+"\]z\f+\af.+~}%}w=0=

Груба сила, трохи натхнившись відповіді Ніла. Спробуйте в Інтернеті

Ефективна версія, 107

ri0"#"a{_{:B\:A={'=A0j+}{A(B={'+B0j+}{AB>{BAB-j_N={'@\+}|}N?}?}?}{;_(0j'+\+a\,1>_W%.{j}Na-'@\f++{,}$0=}?}2j

Спробуйте в Інтернеті

Для цього використовується динамічне програмування.


1

Haskell , 89 86 байт

Редагувати:

  • -3 байти: блискавка була коротшою, ніж індексація.

Ще одне грубе рішення, яке закінчилося з великим натхненням у відповіді Ніла. (Хоча це працювало більше як Pyth Isaacg до того, як гольф представив l.)

f n=[s|(a,_,s)<-l,a==n]!!0
l=(0,0,"#"):[(a+c,a,d:s)|(a,b,s)<-l,(c,d)<-zip[0,1,b]"=+@"]

Спробуйте в Інтернеті!

  • f є основною функцією, яка приймає ціле число і повертає рядок.
  • l- це нескінченний перелік кортежів (a,b,s), найкоротших зображень sспочатку, разом із їх значенням aта значенням bпредставлення з першим позбавленим знака. (як і інші зауважили / помітили, нешкідливо ставитися до останнього як до 0. #)
  • Елементи, lокрім першого, генеруються рекурсивно із розумінням списку. d- це символ, який повинен бути попередньо sстворений для створення нового представлення у списку, а "c" - відповідний приріст a.
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.