用集合构造自然数


17

这种构造是表示自然数的一种方式。

在此表示形式中,0被定义为空集,而对于所有其他数字,n是{0}和{n-1}的并集。

例如,构造3我们可以遵循以下算法:

3 =
{ø, 2} =
{ø, {ø, 1}} =
{ø, {ø, {ø}}}

任务

您可能已经猜到,您的任务是取一个自然数(包括零)并输出其构造。

如果您选择的语言支持这样的对象,则可以将其输出为字符串或设置为对象。

如果选择输出为字符串,则应使用花括号({})表示一个集合。您可以选择将空集表示为ø(否则,它应该是没有条目的集{})。您也可以选择在集合中的条目之间和之后添加逗号和空格。

顺序并不重要,但是输出的集合中可能没有重复的元素(例如{ø,ø}

这是因此目标是拥有最少的字节数

测试用例

这是一些带有一些示例输出的测试案例。

0 -> {}
1 -> {{}}
2 -> {{}{{}}}
3 -> {{}{{}{{}}}}
4 -> {{}{{}{{}{{}}}}}

4
@ mbomb007定义是否“错误”都没有关系。这仍然是一个很好的挑战(也是一个不同的挑战)。
马丁·恩德


4
@ mbomb007此挑战中给出的测试用例和定义相匹配,并且不同于其他挑战。如果有的话,可以改进链接,但是我认为链接与挑战本身无关。
马丁·恩德

不过,他称其为冯·诺依曼(Von Neumann)建筑,而这并不是挑战。那就是dup。因此,每个自然数等于等于所有自然数的集合
mbomb007

1
我们可以从函数返回类似集合的对象(例如列表列表)还是将我们的语言表示形式打印到STDOUT?
丹尼斯

Answers:


12

Python,28个字节

lambda x:"{{}"*x+x*"}"or"{}"

在线尝试!

这是解决该问题的平淡方法。对于大于零的数字,您可以使用字符串公式表示"{{}"*x+"}"*x。但是,对于这是空字符串的零,这不起作用。我们可以利用这个事实来短路or并返回空集。

我想使用python的内置set对象解决此问题,但不幸的是:

TypeError: unhashable type: 'set'

您不能在python中将集合放入集合中。


2
您可以将其保存x"{{}"*x+x*"}"or一个字节
Rod

1
f=可以被删除。
Yytsi'3


frozenset,但没人有个字节为...
Esolanging水果

9

Haskell,37个字节

f 0="{}"
f n=([1..n]>>)=<<["{{}","}"]

在线尝试!

直到10分钟前,这样的回答对我来说还是没有意义的。所有的学分都归功于此技巧的答案

基本上,我们使用>>as concat $ replicate(但将n个元素的列表传递给它,而不是简单地传递n),并使用=<<as concatMap,然后将列表中的每个字符串复制n次,然后将结果串联为单个字符串。

0案件分开处理,因为它会返回一个空字符串。


@Laikoni我也尝试过类似的方法,但是您也需要特殊情况f 1才能使其正常工作
Leo

确实。然后,我更喜欢您的版本。
Laikoni'3

6

JavaScript,28个字节

f=n=>n?--n?[[],f(n)]:[[]]:[]

表示使用数组的集合。38字节的非递归解决方案:

n=>'{{}'.repeat(n)+'}'.repeat(n)||'{}'

返回示例输出字符串。


6

Mathematica,27个字节

在此字节数下,我有两种解决方案:

Nest[{{}}~Union~{#}&,{},#]&
Union//@Nest[{{},#}&,{},#]&

1
32字节附近未命中:#//.{1->{{}},x_/;x>1->{{},x-1}}&。尽管我猜想它会弄乱输入0
Greg Martin

5

Perl 6、37个字节

{('{}','{{}}',{q:s'{{}$_}'}...*)[$_]}

尝试一下

展开:

{   # bare block lambda with implicit parameter 「$_」

  (
    # generate a sequence

    '{}',   # seed it with the first two values
    '{{}}',

    {   # bare block lambda with implicit parameter 「$_」

      q         # quote
      :scalar   # allow scalar values

      '{{}$_}'  # embed the previous value 「$_」 in a new string

    }

    ...         # keep using that code block to generate values

    *           # never stop

  )[ $_ ] # get the value at the given position in the sequence
}

您缺少引号终止符:还是Perl 6的新功能?
CraigR8806

@ CraigR8806您不能使用冒号来分隔Perl 6中的引号构造,因为它们用于副词。(查看扩展版本)
布拉德·吉尔伯特b2gills


4

视网膜,22字节

.+
$*
\`.
{{}
{

^$
{}

在线尝试!

说明

.+
$*

将输入转换为一元。

\`.
{{}

用替换每个一进制数字,{{}并在结果后不加换行符(\)。

{

移除开口{s,以便剩下}的正是我们仍然需要打印以关闭所有集合的开口。但是,上述过程对于input 0来说是失败的,在这里我们不会打印任何内容。所以...

^$
{}

如果字符串为空,则将其替换为空集。


我想知道如何n在Retina 上重复一遍字符串……
尼尔

4

Brain-Flak,135字节

包括+1的 -A

(({}())<{({}[()]<((((((()()()()()){}){}){}())()){}{})>)}{}({}[()()])>)(({})<{({}[()]<(((({}()())[()()])))>)}{}>[()]){(<{}{}{}>)}{}{}{}

在线尝试!

(({}())<                 # Replace Input with input + 1 and save for later
  {({}[()]<              # For input .. 0
    (...)                # Push '}'
  >)}{}                  # End for and pop counter
  ({}[()()])             # change the top '}' to '{'. This helps the next stage
                         # and removes the extra '}' that we got from incrementing input
>)                       # Put the input back on

(({})<                   # Save input
  {({}[()]<              # For input .. 0
    (((({}()())[()()]))) # Replace the top '{' with "{{{}"
  >)}{}                  # end for and pop the counter
>[()])                   # Put down input - 1
{(<{}{}{}>)}             # If not 0, remove the extra "{{}"
{}{}{}                   # remove some more extras


4

CJam,11个字节

Lri{]La|}*p

打印由列表列表组成的类似集合的对象。CJam将空列表打印为空字符串,因为列表和字符串几乎可以互换。

在线尝试!

说明

L            Push an empty array 
 ri          Read an integer from input
   {    }*   Run this block that many times:
    ]          Wrap the entire stack in an array
     La        Wrap an empty list in an array, i.e. [[]]
       |       Set union of the two arrays
          p  Print the result

旧答案,21 18字节

这是在确认可以打印嵌套列表结构之前。使用字符串重复算法。

感谢Martin Ender,节省了3个字节!

ri{{}}`3/f*~_{{}}|

说明

ri                  Read an integer from input
  {{}}`             Push the string "{{}}"
       3/           Split it into length-3 subtrings, gives ["{{}" "}"]
         f*         Repeat each element of that array a number of times equal to the input
           ~_       Dump the array on the stack, duplicate the second element
             {{}}|  Pop the top element, if it's false, push an empty block, which gets 
                      printed as "{}". An input of 0 gives two empty strings on the 
                      repetition step. Since empty strings are falsy, we can correct the 
                      special case of 0 with this step.

4

果冻,6个字节

⁸,⁸Q$¡

这是一条Niladic链接,可从STDIN中读取一个整数并返回一个参差不齐的数组。

在线尝试!

怎么运行的

⁸,⁸Q$¡  Niladic link.

⁸       Set the return value to [].
    $   Combine the three links to the left into a monadic chain.
 ,⁸     Pair the previous return value with the empty array.
   Q    Unique; deduplicate the result.
     ¡  Read an integer n from STDIN and call the chain to the left n times.


3

基数51 50字节

%:#>"{"#? v
x  ^?-"}{"<
v <8/ ?<
>  8\
v"}"<
>?-?^

在线尝试!

说明

%:#
x

接收输入并从#上下发送

   >"{" ? v
   ^?-"}{"<

一次打印“ {”一次,如果n> 1,则打印“ {} {” n-1次;如果n> 0,则打印“ {}”

       #

v <8/ ?<
>  8\

保留输入值,直到第一个循环完成

v"}"<
>?-?^

打印一次“}”,如果n> 1,则重复n-1次


2

AHK,55字节

IfEqual,1,0
s={{}{}}
Loop,%1%
s={{ 2}{}}%s%{}}
Send,%s%

这不是最短的答案,但我很喜欢这样做,因为AutoHotkey的特质使此递归方法显得超级错误。IfLoop语句假定如果不使用方括号,则仅包括下一行。圆括号是转义字符,因此您必须将其与其他花括号一起转义才能将其用作文本。同样,该变量1是第一个传递的参数。当我在不知道这些花哨的情况下阅读代码时,逻辑看起来像这样:

  • 如果1 = 0,则设置 s为错误的答案
  • 循环并在每次开始时添加一堆括号,并在每次结束时添加一些括号
  • 通过将结果字符串发送到当前窗口来返回

如果没有所有括号转义字符,它将如下所示:

IfEqual,1,0
   s={}
Loop,%1%
   s={{}%s%}
Send,%s%

1

JavaScript 50字节

g=n=>n==0?"":"{{}"+g(n-1)+"}"
z=m=>m==0?"{}":g(m)

当数字等于0时,它是JavaScript的虚假值。因此,如果您反转三元表达式,则可以删除== 0
fəˈnɛtɪk

1

tinylisp,52个字节

(d f(q((n)(i n(i(e n 1)(c()())(c()(c(f(s n 1))())))(

在线尝试!(测试线束)。

说明

请注意,这(cons x (cons y nil))是在Lisp中构建包含x和的列表的方式y

(d f           Define f to be
 (q(           a quoted list of two items (which acts as a function):
  (n)           Arglist is a single argument n
  (i n          Function body: if n is truthy (i.e. nonzero)
   (i(e n 1)     then if n equals 1
    (c()())       then cons nil to nil, resulting in (())
    (c            else (if n > 1) cons
     ()            nil to
     (c            cons
      (f(s n 1))    (recursive call with n-1) to
      ())))         nil
   ()))))        else (if n is 0) nil



1

直流电,46字节

[[{}]]sx256?^dd3^8d^1-/8092541**r255/BF*+d0=xP

在线尝试!

在stdin上输入,在stdout上输出。

通过计算所需输出的公式(以256为基数)可以起作用。然后,使用dc中的P命令将base-256数字打印为字符串。


进一步说明:

令n为输入n。dc程序计算

A =下限(256 ^ n / 255)* 125(直流将BF解释为11 * 10 + 15 = 125)

B =楼板((256 ^ n)^ 3 /(8 ^ 8-1))* 8092541 *(256 ^ n)。

 

为一个:

通过几何级数公式,观察到1 + 256 + 256 ^ 2 + ... + 256 ^(n-1)等于(256 ^ n-1)/ 255,这等于floor(256 ^ n / 255) )。因此,这是由以256为底的n 1组成的数字。

当您将其乘以125得到A时,结果是由以256为底的n 125组成的数字(当然,125是以256为底的一位数字)。最好将基数为256的数字写为十六进制数字。125是十六进制7D,所以A是以256为基数的n个连续的n个7D。

 

B是类似的:

这次观察到1 + 16777216 + 16777216 ^ 2 + ... + 16777216 ^(n-1)等于(16777216 ^ n-1)/ 16777215,这等于下限(16777216 ^ n / 16777215)。

现在,256 ^ 3 = 16777216,而8 ^ 8-1 = 16777215,所以这就是我们要计算的floor((256 ^ n)^ 3 /(8 ^ 8-1))。

从几何级数表示中,基数256中的此数字是100100100 ... 1001,其中n个数字为1,其余数字为0。

它乘以8092541,即十六进制的7B7B7D。在基数256中,这是一个由数字7B,7B和7D组成的三位数(为方便起见,将这些数字写成十六进制)。

因此,写在基数256中的乘积是一个3n位数字,由重复n次的3位数字7B 7B 7D组成。

这乘以256 ^ n,得到一个4n位以256为底的数字,该数字由重复n次的3位7B 7B 7D组成,后跟n 0。是B。

 

现在加A + B会产生4n位以256为基数的数字,该数字由重复n次的3位7B 7B 7D组成,后跟n 7D。由于图7B和图7D是ASCII代码{},分别,这是由n个拷贝的串的{{}随后的n个拷贝},而这正是我们希望对于n> 0的直流P指令打印基地-256数就像我们需要的那样。

不幸的是,必须将n = 0视为特例。上面的计算碰巧对n = 0得出0的结果;在那种情况下,我只是对字符串的打印进行了硬编码{}


使用该打印命令鲜为人知的行为,这是一种非常有趣的方法。做得很好!对这是如何工作的解释将改善答案。
seshoumara

@seshoumara谢谢-我已经添加了详细的说明。
米切尔·史派克特


0

批处理,88字节

@set s={}
@if %1 gtr 0 set s=&for /l %%i in (1,1,%1)do @call set s={{}%%s%%}
@echo %s%

0

Brainf ***,99字节

>+>+>+>+<[>[-<+++++>]<-<]>--[->+>+<<]
>[-<+>]>++<,[[->>+>+<<<]>>[-<<<..>>.>]>[-<<.>>]+[]]<.>>.

(为了美观起见,请输入换行符)由于它很聪明,因此将输入作为ascii字符代码(输入“ a”对应于96)

Braineasy,60个字节

另外,以我的自定义语言(基于brainf **,此处为解释器):

#123#[->+>+<<]>++<,[[-<+<+>>]<[->>>..<.<<]<[->>>.<<<]!]>>.<.

由于我很懒,因此您必须将程序输入硬编码到解释器中。


欢迎光临本站!为什么会有一个[]?似乎可以将其删除
发布Rock Garf Hunter,

如果没有,它将在末尾输出一个额外的{}(它无限循环)。
internet_user

0

05AB1E5 3字节

F¯)

在线尝试!

这个版本是在他澄清设置好的之后。

F   # From 1 to input...
 ¯  # Push global array (default value is []).
  ) # Wrap stack to array.

旧版本(使用ø):

05AB1E5 4字节

FX¸)

在线尝试!

哪里1等于ø

F    # From 1 to input...
 X   # Push value in register X (default is 1).
  ¸  # Wrap pushed value into an array.
   ) # Wrap whole stack into an array.
     # Implicit loop end (-1 byte).
     # Implicit return.
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.