在模块化SNUSP中找到数字的最短表示形式


10

背景

许多深奥的编程语言都没有在文字上内置数字,因此您必须在运行时进行计算。在许多情况下,数字表示可能会很有趣。在表示欠载数字时,我们已经遇到了挑战。这个挑战是关于在模块化SNUSP中表示数字。(请注意,您不需要学习SNUSP即可完成此挑战-所需的所有信息都在规范中-但您可能会发现背景很有趣。)

任务

出于此挑战的目的,模块化SNUSP数字是由字符@+和组成的字符串=,除了最后一个字符是#,并且倒数第二个字符必须为+=(不能为@)。例如,有效号码包括@+#==#,和@@+@=#; 无效号码的例子包括+=@@#,和+?+#

模块化SNUSP编号的值递归计算如下:

  • # 的值为0(这是基本情况)。
  • 如果数字具有形式=x,则对于任何字符串x,其值都等于的值x
  • 如果数字具有形式+x,对于任何字符串x,其值等于的值x加1。
  • 如果数字具有形式@cx,则对于任何单个字符c和任何字符串x,其值等于的值x加上的值cx

对于这个挑战,您必须编写一个程序,该程序将一个非负整数作为输入,并输出一个字符串,该字符串是可能的最短Modular SNUSP数字,其值等于输入。

澄清说明

  • 完全可能存在多个具有相同值的字符串,尤其是对于某些整数,该值与最短的模块化SNUSP编号会有关系。在这种情况下,您可以输出涉及平局的任何数字。
  • 查找数字的算法没有限制;例如,强制使用字符串并对其进行求值是一种合法策略,但这样做会更聪明以减少搜索空间。
  • 像在PPCG上一样,您的提交可以是完整程序也可以是函数(选择使用您的语言更简洁的那个)。
  • 这不是处理输入和输出格式的问题,因此您可以使用任何合理的方式输入非负整数并输出字符串。有上元一个完整的指南,但最常用的法律手段包括函数参数/返回,命令行参数和标准输入/标准输出。

测试用例

以下是前几个数字的最短表示形式:

  • 0#
  • 1+#
  • 2++#
  • 3+++#@++#
  • 4++++#+@++#@=++#
  • 5@+++#@@++#
  • 6+@+++#+@@++#@=+++#@=@++#@@=++#
  • 7@++++#@+@++#
  • 8@@+++#@@@++#
  • 9+@@+++#+@@@++#@+++++#@++@++#@+@=++#@@=+++#@@=@++#
  • 10@=@+++#@=@@++#@@@=++#这是一个非常重要的测试用例,因为所有可能的答案都包括在内=
  • 11@+@+++#@+@@++#@@++++#@@+@++#
  • 12+@+@+++#+@+@@++#+@@++++#+@@+@++#@=+@+++#@=+@@++#@=@=+++#@=@=@++#@=@@=++#@@=++++#@@=+@++#@@=@=++#
  • 13@@@+++#@@@@++#
  • 14+@@@+++#+@@@@++#@=@++++#@=@+@++#@@+++++#@@++@++#@@+@=++#
  • 15@+@++++#@+@+@++#@@=@+++#@@=@@++#@@@=+++#@@@=@++#

作为更大的试验情况下,从输入输出40应当是@@@=@@+++#@@@=@@@++#@@@@=@+++#,或@@@@=@@++#

胜利条件

作为挑战,获胜者是最短的参赛作品,以字节为单位。


1
=最好只会出现为@=,对吗?
orlp

3
顺便说一下,这类挑战通常最好以metagolf的形式发布,因为几乎没有任何有趣的答案(只需评估字符串并遍历所有可能的字符串)。
orlp

3
@orlp:我不同意,这个挑战作为metagolf来说太容易了,因为找到最佳答案相对容易,并且metagolf在得分上没有任何其他限制。我期望这里的大多数答案都是蛮力的,但规范非常复杂,以至于蛮力a)可能不是最短的,而b)本身就可能引起高尔夫的兴趣。如果您想改变胜利的条件,那么可能唯一有趣的是最快的代码,这将是另一种挑战,这更有意义。

我们也对Brain-flak进行了许多高尔夫挑战
仅使用ASCII码

Answers:


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;

首先创建一个包含三行的视图,每个符号用于表示数字,一个减号(仅在字符串的末尾使用):

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

然后,递归视图n生成可能包含这3个符号的每个字符串,并将它们连接为#并对其求值。

参数为:

S:数量的模块化SNUSP表示正在评估
ν:S按先前的迭代计算的十进制值
号码:V,由I-2的迭代中计算
C:下一个符号来连接至S
I:s的长度,只需要摆脱两个LENGTH()以打高尔夫球

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

如果最后一个符号为+,则加1;
如果最后一个符号为@,则添加i-2迭代的值。
否则,符号为#或=。v在递归视图的init部分中以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;

返回第一个Modular 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
由于SE为EVIL,Jai

即使是12,它也会给出“ @@@ +++#”,其结果为13
aditsu退出是因为SE是EVIL

嗯,我认为更改t<nt-n可能
Neil

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

果酱,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

Haskell89 86字节

编辑:

  • -3个字节:压缩比索引编制短。

另一个蛮力解决方案最终从尼尔的回答中得到了很多启发。(尽管它的工作方式更像是isaacg的《 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,以及它们的值ab去除第一个字符的表示形式的值。(正如其他人也指出/注意到的那样,将后者视为表示0是无害的#。)
  • l除第一个元素外的其他元素是通过列表理解递归生成的。d是要s在列表中生成新表示形式的字符,“ c”是的相应增量a
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.