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

10

Фон

Многие эзотерические языки программирования не имеют чисел, встроенных в литералы, поэтому их нужно вычислять во время выполнения; и во многих из этих случаев представление чисел может быть довольно интересным. У нас уже была проблема с представлением чисел для Underload. Эта задача заключается в представлении чисел в модульном SNUSP . (Обратите внимание, что вам не нужно изучать SNUSP, чтобы выполнить эту задачу - вся необходимая информация находится в спецификации - но вы можете найти интересный фон).

Задание

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

Значение модульного номера 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
ASCII-only

Ответы:

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 quit, потому что SE - ЗЛО
Даже для 12 это дает "@@@ +++ #", что оценивается как 13
aditsu quit, потому что SE ЗЛО
Хм, я думаю , что изменения t<nв t-nмогли бы работать ...
Neil
2

Pyth, 41 байт

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

Тестирование

Как это работает:

Есть две части. Рекурсивная функция, которая вычисляет значение выражения SNUSP без трейлинга #и процедуры грубой силы.

Evalutaion:

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
isaacg
источник
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

Попробуйте онлайн

Это использует динамическое программирование.

уйти, потому что SE это зло
источник
1

Haskell , 89 86 байтов

РЕДАКТИРОВАТЬ:

  • -3 байта: архивирование было короче индексации.

Еще одно решение грубой силы, которое во многом вдохновило ответ Нейла. (Хотя это работало больше как Pyth Исаака, прежде чем гольф представил 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.
Орджан Йохансен
источник