查找列表的“展开大小”


12

让我们通过以下规则定义u嵌套列表l(仅包含列表)的“展开大小”功能:

  • 如果l为空,u(l)则为1。
  • 如果l为非空,u(l)则等于中每个元素的展开大小的总和l

您的任务是编写一个将列表作为输入并输出(或返回)列表未包装大小的程序(或函数)。

测试用例:

[]                                           ->  1
[[[]],[]]                                    ->  4
[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]] -> 19
[[[[]]]]                                     ->  4

这是,因此最短的程序(以字节为单位)获胜。


2
输入可以当作字符串,即用引号引起来吗?我们可以()代替使用[]吗?
路易斯·门多

我们可以采用这种格式[[[]][]]代替[[[]],[]]第二个示例中的输入吗?
Mukul Kumar

的大小是["This is some text [with square brackets in] ...[& maybe more than one pair]"]多少?
乔纳森·艾伦


2
@DrMcMoylex我不同意。虽然计数]的确是许多语言中最短的解决方案,但实际上还有很多答案可以通过列表操作来解决此难题,至少在esolangs中,计数固定字符的出现与计数有很大不同输入字符的出现。
Martin Ender

Answers:


23

视网膜,1个字节

]

在线尝试!(第一行启用换行分隔的测试套件。)

默认情况下,Retina会计算输入中给定正则表达式的匹配数。解开的大小仅等于[]输入中的对数,因此等于]


1
正确的工作工具!
Cyoce

@MartinEnder您是否曾经向您的语言添加新功能,以便在代码问题中保存字节?
lois6b

5
@ lois6b不是追溯性的,但是我偶尔会改进语言,使其更强大,以备将来使用。就是说,从最初的Retina版本开始,这个答案就可以用了,因为这只是对输入运行单个正则表达式(/ substitution)的一种方式,而没有语法开销。
Martin Ender

11

Mathematica,9个字节

LeafCount

原来有一个内置的...

请注意,如果列表实际包含非列表元素,则此方法将无效。LeafCount真正要做的是计算原子子表达式的数量。对于input {{}, {{}}},表达式实际上显示为:

List[List[], List[List[]]]

在这里,原子子表达式实际上是头部 List


1
Mathematica具有所有功能的内置...
kirbyfan64sos

2
@ Challenger5 好吧,抄袭。:P
马丁·恩德

7

Brainfuck,71 61 59字节

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

从STDIN中以问题中给出的格式输入,并输出其ASCII码为列表的“未包装大小” 的字符

我仍然是Brainfuck的一名完全业余爱好者,因此很可能仍然可以进行许多优化。

在线尝试!

取消高尔夫:

read input to tape
>>+[>,]<
current tape: (0 0 1 a b *c)
where abc represents input and * is IP

now we loop over each character (from the end)
this loops assumes we are starting on the (current) last char
and it zeroes the entire string by the time it finishes
[

  subtract 91 from this character
  technically we only subtract 85 here and correct the answer
  with the 6 minus signs below
  >-[<->---]
  current tape: (0 0 1 a b cminus91 *0)

  invert the result and put that in the next cell
  +<------[->[-]<]>
  current tape: (0 0 1 a b 0 *c==91)

  move that result back to the original cell
  [-<+>]<
  current tape: (0 0 1 a b *c==91)

  if the result is true we found a brace
  increment the very first cell if so
  [-<[<]<+>>[>]]<
  current tape: (count 0 1 a *b)

]
current tape: (count *0)

<.

5

JavaScript(ES6),29 27字节

f=([x,...a])=>x?f(x)+f(a):1

我很喜欢递归清楚地做到这一点。这基本上是对输入的深度优先搜索,每当到达数组末尾时加1。

如果在JS中有一个空数组,则可能是24个字节:

f=a=>a?f(a.pop())+f(a):1

但是,事实并非如此。其他尝试:

f=a=>a.reduce((n,x)=>n+f(x),1) // Works, but 3 bytes longer
f=a=>a.map(x=>n+=f(x),n=1)&&n  // Works, but 2 bytes longer
f=a=>(x=a.pop())?f(x)+f(a):1   // Works, but 1 byte longer
f=a=>a[0]?f(a.pop())+f(a):1    // Works, but same byte count
f=a=>a+a?f(a.pop())+f(a):1     // Doesn't work on any array containing 1 sub-array
f=a=>a-1?f(a.pop())+f(a):1     // Same

f=a=>a[0]?f(a.pop())+f(a):1工作吗?(尽管字节数相同。)
Neil

@Neil是的,那是我已经尝试过的解决方案之一。我认为不可能再缩短时间了
ETHproductions'Nov

(顺便说一句,我本来应该很奢侈的f=a=>a.reduce((n,a)=>n+f(a),1)。现在f=(n,a)=>n+a.reduce(f,1)只有24个字节,但是可悲的是参数的顺序不正确。)
Neil

@Neil实际上我首先这样做,只是将其缩短了1个字节:f=a=>a.map(a=>n+=f(a),n=1)&&n
ETHproductions

啊,对不起,我没想到要浏览编辑历史记录。
Neil



3

05AB1E,4个字节

I'[¢

I    Get input as a string
 '[¢ Count the opening square brackets and implicitly print them

在线尝试!

我认为可以打更多球,但是“ I”是强制性的,否则输入被视为实际数组而不是字符串


2
"[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]]"在输入中删除了该I要求,尽管我不知道是否允许这样做。
魔术章鱼缸

1
@carusocomputing:目前尚不允许,但这可能会改变(我看到路易斯问OP相同的问题)
Emigna

当,距离我14小时。
奥利弗·尼

3

迷宫,8字节

&-
#,(/!

在线尝试!

说明

这通过一些按位魔术来计算开括号。如果我们考虑的位与的字符码的结果[,]2得:

[ , ]
2 0 0

因此,如果仅对每个字符的操作结果求和,则得到的值是所需值的两倍。

至于代码本身,开头的2x2块是一个小循环。在第一个迭代中&-,除了将显式零放在堆栈底部的隐式变量顶上之外,什么都不做。这将是运行总计(实际上,它为负数以便以后保存一个字节)。然后循环如下:

,   Read character. At EOF this gives -1 which causes the instruction pointer to
    leave the loop. Otherwise, the loop continues.
#   Push the stack depth, 2.
&   Bitwise AND.
-   Subtract from running total.

一旦退出循环,将执行以下线性位:

(   Decrement to turn the -1 into a -2.
/   Divide negative running total by -2 to get desired result.
!   Print.

IP然后死机并转身。当它/再次尝试执行时,该程序由于尝试被零除而终止。


3

3 2,36的23个字节

lambda x:`x`.count("[")

我注意到,u(l)它等于[的字符串表示形式中的数量l,因此该程序尝试这样做。不过,通过寻找另一种方法可以进一步打高尔夫球。


6
23个字节:lambda x:`x`.count("[")
acrolith '16

2

Python,26个字节

f=lambda a:sum(map(f,a))+1

简单的递归公式。


2

C#,46 41个字节

int u(string l){return l.Count(c=>c=='[');}

l是嵌套列表的字符串。在这里测试


使用4个空格(在代码之前)将其格式化为代码块
user41805

@KritixiLithos糟糕,我忘了正确执行此操作。感谢您指出:)
2016年

这必须是程序或函数,两者都不是。
user41805

@KritixiLithos糟糕,感谢您指出来,将其修复。
2016年

2
您可以使用花括号return功能来删除花括号。也char隐式强制转换为,int因此您可以使用91代替'['int u(string l)=>l.Count(c=>c==91);此外,您可以删除函数签名并使用lambda方法:l=>l.Count(c=>c==91);
牛奶


2

Ruby,13(+1)个字节

p $_.count ?[

-n参数调用:

ruby -ne 'p $_.count ?['

编辑:更改为实际打印出答案


这似乎不打印任何内容。(除非这是REPL答案,在这种情况下,应将语言指定为Ruby REPL。)
Martin Ender

@Martin Ender♦该规范允许返回值而不是打印它。
李W

这是指功能提交。例如,->s{s.count ?[}将是有效的提交。
马丁·恩德

这是一般规则吗?
李W



2

脑高射炮63,61个字节

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

在线尝试! 58个字节的代码,+ 3表示-a启用ASCII输入的标志。

可读的版本/说明:

#While non-empty:
{

    #subtract
    ({}[

    #91
    (((()()()){}){}()){({}[()])}{}

    ])

    #if non-zero
    {

        # Remove the difference
        {}

        #Increment the counter on the other stack
        (<>{}())

        #Push a zero onto the main stack
        (<>)
    }

    #pop the left-over zero
    {}

#endwhile
}

#Move back to the stack with the counter, implicitly display
<>



1

PHP,35字节

<?=preg_match_all('/\[/',$argv[1]);

preg_match_all 查找正则表达式的所有匹配实例并返回一个数字,这就是为什么需要简短的echo标签的原因。

像大多数答案一样,它计算[输入中的数量并输出该数量


1
如果您使用]而不是[,则不必对其进行转义。
马丁·恩德

2
count_chars()[91];做同样的事情,但更短。
2016年

1

拍子82字节

(define n 0)(let p((l l))(if(null? l)(set! n(+ 1 n))(begin(p(car l))(p(cdr l)))))n

取消高尔夫:

(define (f l)
  (define n 0)
  (let loop ((l l))
    (if (null? l)
        (set! n (add1 n))
        (begin (loop (first l))
               (loop (rest l)))))
  n)

测试:

(f '[]) 
(f '[[[]] []]) 
(f '[[[]] [[[[]] []]] [[[]] [[[[]] [[] [[]]]]]]]) 
(f '[[[[]]]])  

输出:

1
4
19
4

1

V,10个字节

ÓÛ
ÒC0@"

在线尝试!

它包含一些不可打印的字符,这是可读的版本:

ÓÛ
Ò<C-a>C0<esc>@"

<C-a>代表“ ctrl-a”(ASCII 0x01),<esc>代表转义键(ASCII 0x1b)。

ÓÛ              " Remove all '['s
                "
Ò<C-a>          " Replace what's left with '<C-a>' (the increment command)
      C         " Delete this line
       0<esc>   " And replace it with a '0'
             @" " Run what we just deleted as V code (A bunch of increment commands

更多乐趣,更少高尔夫版本:

o0kòf]m`jòd

在线尝试!

o0<esc>                     " Put a '0' on the line below us
       k                    " Move back up a line
        ò               ò   " Recursively:
         f]                 "   Move to a right-bracket
           m`               "   Add this location to our jumplist
             j              "   Move down a line
              <C-a>         "   Increment this number
                   <C-o>    "   Move to the previous location
                         d  " Delete the bracket line
                            " Implicitly display

1

Scala,15个字节

s=>s.count(92<)

取消高尔夫:

s=>s.count(c=>92<c)

count计算满足谓词的元素数(在这种情况下92<,这是的方法<92


1

O,15个字节

i~{1\{nJ+}d}J;J

在这里尝试!

在输入中,任何逗号都必须删除或用空格代替。

说明

i~{1\{nJ+}d}J;J
i                Read a line of input.
 ~               Evaluate it.
  {        }J;   Define a function and save it into the `J` variable.
                 Currently, the input array is at the top of the stack.
   1\            Push 1 and swap it with the input array.
     {   }d      For each element in the array...
                 Because the array was popped by `d`, 1 is at the TOS.
      nJ+        Recurse and add the result to 1.
              J  Initiate the function call.
                 The result is printed implicitly.

如果允许我们处理字符串:10个字节

ie\']-e@-p

1

> <>21 20 18字节

0i:0(90.;n?|3%0=+!

编辑:goto语句得分1!

编辑2:显然> <>与Befunge的不同之处在于,它在换行后允许非零IP偏移(换句话说,通过使用蹦床指令,我可以换成(1,0)而不是(0,0))。有趣。

TryItOnline!


1

Brainfuck,28个字节

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

在线尝试。

这将计算被3整除的输入字符数,即]字符数。

替代的34字节解决方案,[直接计算字符并依赖8位单元:

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

1

C,48 46字节

感谢kirbyfan64sos,节省了两个字节

i;f(char*v){for(i=0;*v;i+=*v++==91);return i;}

i;f(char*v){for(i=0;*v;*v++^91?0:i++);return i;}

测试码

main()
{
    printf("%d\n", f("[]"));
    printf("%d\n", f("[[[]] []]"));
    printf("%d\n", f("[[[]] [[[[]] []]] [[[]] [[[[]] [[] [[]]]]]]]"));
}

测试用例

a.exe
1
4
19

更改*v++^91?0:i++i+=*v==91保存3个字节。
kirbyfan64sos

@ kirbyfan64sos谢谢!我仍然需要增加v,但是我可以i+=*v++==91用来节省两个字节。
cleblanc '16

1

tinylisp repl,39个字节

(d u(q((L)(i L(s(u(h L))(s 0(u(t L))))1

定义一个u可以调用的函数(u (q ((())()) ))(对于第二个测试用例)。由于自动关闭括号,因此在repl中执行此操作可节省4个字节。

说明

(d u                                      )  Define u as
    (q                                   )    the following, unevaluated
      (                                 )     list (which acts as a function in tinylisp):
       (L)                                   Given arglist of one element, L, return:
          (i L                         )     If L (is nonempty):
              (s(u(h L))             )        Call u on head of L and subtract
                        (s 0        )          0 minus
                            (u(t L))           call u on tail of L
                                      1      Else, 1

x-(0-y)构造是必要的,因为tinylisp没有内置的加法功能,只有减法。



1

Haskell,20 19 17字节

f s=sum[1|']'<-s]

在线尝试!

将列表作为字符串,并1为每个列表放入一个],然后将所有1s 相加。


无点版本:(19个字节)

length.filter(>'[')

假设, [ ]是字符串中唯一的字符。过滤列表以获取大于的所有字符[,这些字符全部为,]并返回长度。

用法:

Prelude> length.filter(=='[')$"[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]]"
19

0

Bash + coreutils,29个字节

f()(echo $1|tr -d -c [|wc -c)

您可以删除其中的大部分内容,而只需执行一下即可tr -d -c [|wc -c,默认情况下,它将从标准输入中读取列表。
kirbyfan64sos

0

DASH,14字节

(ss[len;!> ="]

简单地算一下]。用法:

(ss[len;!> ="]"])"[[]]"

奖励解决方案,15个字节

a\@+1sum ->#a#0

该递归从真实列表中计数。用法:

(f\@+1sum ->#f#0)[[]]
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.