Tìm kích thước chưa mở của kích thước của danh sách


12

Hãy xác định chức năng "kích thước không bao bọc" ucủa danh sách lồng nhau l(chỉ chứa danh sách) theo các quy tắc sau:

  • Nếu ltrống, thì u(l)là 1.
  • Nếu lkhông trống, u(l)bằng tổng kích thước chưa mở của mọi phần tử trong l, cộng với một.

Nhiệm vụ của bạn là viết một chương trình (hoặc hàm) lấy danh sách làm đầu vào và đầu ra (hoặc trả về) kích thước chưa mở của danh sách.

Các trường hợp thử nghiệm:

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

Đây là , vì vậy chương trình ngắn nhất (tính bằng byte) sẽ thắng.


2
Đầu vào có thể được lấy dưới dạng một chuỗi, tức là có dấu ngoặc kép kèm theo không? Chúng ta có thể sử dụng ()thay vì []?
Luis Mendo

chúng ta có thể lấy đầu vào ở định dạng này [[[]][]]thay vì [[[]],[]]trong ví dụ thứ hai của bạn không?
Mukul Kumar

Kích thước của là ["This is some text [with square brackets in] ...[& maybe more than one pair]"]gì?
Jonathan Allan


2
@DrMcMoylex Tôi không đồng ý. Mặc dù đếm số lượng ]dường như là giải pháp ngắn nhất trong nhiều ngôn ngữ, nhưng cũng có rất nhiều câu trả lời thực sự giải quyết thách thức này thông qua thao tác danh sách, và ít nhất là trong esolang đếm số lần xuất hiện của một ký tự cố định cũng khác hoàn toàn với việc đếm sự xuất hiện của một nhân vật đầu vào.
Martin Ender

Câu trả lời:


23

Võng mạc , 1 byte

]

Hãy thử trực tuyến! (Dòng đầu tiên cho phép bộ kiểm tra được phân tách bằng nguồn cấp.)

Theo mặc định, Retina đếm số lượng trận đấu của regex đã cho trong đầu vào. Kích thước không được bao bọc chỉ đơn giản bằng số lượng []cặp trong đầu vào và do đó với số lượng ].


1
Đó là công cụ phù hợp cho công việc!
Cyoce

@MartinEnder bạn có bao giờ thêm các chức năng mới vào ngôn ngữ của mình để lưu byte trong câu hỏi về codegolf không?
lois6b

5
@ lois6b không hồi tố, nhưng tôi thỉnh thoảng cải thiện ngôn ngữ để làm cho nó mạnh hơn cho các mục đích sử dụng trong tương lai. Điều đó nói rằng, câu trả lời này sẽ hoạt động trong phiên bản đầu tiên của Retina từ khi nó chỉ đơn giản là một cách để chạy một regex (/ thay thế) duy nhất đối với đầu vào mà không cần cú pháp cú pháp.
Martin Ender

11

Toán học, 9 byte

LeafCount

Hóa ra có tích hợp sẵn cho ...

Lưu ý rằng điều này sẽ không hoạt động nếu danh sách thực sự có chứa các yếu tố không phải là danh sách. Những gì LeafCountthực sự làm là đếm số lượng các nguyên tử phụ. Đối với đầu vào {{}, {{}}}, biểu thức thực sự đọc:

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

Ở đây các biểu hiện nguyên tử thực sự là những cái đầu List .


1
Mathematica có tích hợp sẵn cho mọi thứ ...
kirbyfan64sos

2
@ Challenger5 Oy, đạo văn. : P
Martin Ender

7

Brainfuck, 71 61 59 byte

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

Đưa đầu vào từ STDIN theo định dạng được nêu trong câu hỏi và xuất ký tự có mã ASCII là "kích thước không được bao bọc" của danh sách.

Tôi vẫn là một người nghiệp dư hoàn toàn tại Brainfuck, vì vậy rất có thể nhiều tối ưu hóa vẫn có thể được thực hiện.

Hãy thử trực tuyến!

Ung dung:

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 byte

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

tôi thích nó khi một đệ quy hóa ra điều này một cách sạch sẽ. Về cơ bản, đây là một tìm kiếm theo chiều sâu của đầu vào, thêm 1 bất cứ khi nào kết thúc một mảng.

Nếu một mảng trống bị làm sai trong JS, thì đây có thể là 24 byte:

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

Nhưng than ôi, không phải vậy. Những nỗ lực khác:

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

Sẽ f=a=>a[0]?f(a.pop())+f(a):1làm việc? (Mặc dù số byte tương tự.)
Neil

@Neil Vâng, đó là một trong những giải pháp tôi đã thử. Tôi không nghĩ có thể rút ngắn được nữa ...
ETHproductions 10/11/2016

(Bằng cách này, tôi sẽ phải ra đi cho ngông cuồng f=a=>a.reduce((n,a)=>n+f(a),1)Bây giờ,. f=(n,a)=>n+a.reduce(f,1)Là chỉ có 24 byte, nhưng buồn thay các thông số theo thứ tự sai.)
Neil

@Neil Tôi thực sự đã làm điều đó trước tiên, ngoại trừ rút ngắn nó xuống 1 byte:f=a=>a.map(a=>n+=f(a),n=1)&&n
ETHproductions 10/11/2016

À, xin lỗi, tôi đã không nghĩ đến việc duyệt lịch sử chỉnh sửa.
Neil

4

Perl, 9 8 7 + 1 = 8 byte

Yêu cầu -pcờ

$_=y;[;

Cảm ơn @Dada về hai byte tiết kiệm (Tôi yêu btw khai thác dấu chấm phẩy này)


1
-pđể tiết kiệm 1 byte;)
Dada

Bạn có thể sử dụng y;[;để lưu thêm một byte
Dada


3

05AB1E , 4 byte

I'[¢

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

Hãy thử trực tuyến!

Tôi nghĩ rằng nó có thể được đánh gôn nhiều hơn nhưng 'Tôi' là bắt buộc, nếu không, đầu vào được coi là một mảng thực tế thay vì một chuỗi


2
"[[[]],[[[[]],[]]],[[[]],[[[[]],[[],[[]]]]]]]"trong đầu vào loại bỏ Iyêu cầu đó , mặc dù tôi không biết nếu điều đó được cho phép.
Bạch tuộc ma thuật Urn

1
@carusocomputing: Hiện tại không được phép, nhưng điều đó có thể thay đổi (tôi thấy Luis hỏi OP cùng câu hỏi đó)
Emigna

Dang, 14 giờ trước tôi.
Oliver Ni

3

Mê cung , 8 byte

&-
#,(/!

Hãy thử trực tuyến!

Giải trình

Điều này đếm các dấu ngoặc mở thông qua một chút ma thuật bitwise. Nếu chúng ta xem xét các kết quả của các mã ký tự của các phép toán AND [, ,]với 2, chúng tôi nhận được:

[ , ]
2 0 0

Vì vậy, nếu chúng ta chỉ tổng hợp kết quả của thao tác này cho mỗi ký tự, chúng ta sẽ nhận được gấp đôi giá trị chúng ta muốn.

Đối với bản thân mã, khối 2x2 ở đầu là một vòng lặp nhỏ. Trong lần lặp đầu tiên, &-bạn không thực sự làm bất cứ điều gì ngoại trừ việc họ đặt một số 0 rõ ràng lên trên các số ẩn ở dưới cùng của ngăn xếp. Đây sẽ là tổng số đang chạy (và nó thực sự sẽ âm để lưu một byte sau này). Sau đó, vòng lặp như sau:

,   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.

Khi chúng ta rời khỏi vòng lặp, bit tuyến tính sau được thực thi:

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

IP sau đó đánh chết và quay lại. Khi nó cố thực hiện /lại, chương trình sẽ kết thúc do phép chia bằng 0.


3

Python 3 2, 36 23 byte

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

Tôi nhận thấy rằng u(l)nó bằng với số [trong biểu diễn chuỗi l, vì vậy chương trình này cố gắng làm điều đó. Có lẽ nó có thể được đánh gôn hơn nữa bằng cách tìm một cách khác để làm điều này, mặc dù ...


6
23 byte:lambda x:`x`.count("[")
acrolith 10/11/2016


2

C #, 46 41 byte

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

l là chuỗi danh sách lồng nhau. Kiểm tra nó ở đây .


Sử dụng 4 khoảng trắng (trước mã) để định dạng nó thành một khối mã
Kritixi Lithos

@KritixiLithos ôi, tôi quên làm điều đó một cách chính xác. Cảm ơn bạn đã chỉ ra :)
Ave

Và đây phải là một chương trình hoặc một chức năng, điều này cũng không.
Kritixi Litva

@KritixiLithos oops, cảm ơn bạn đã chỉ ra, chỉ cần sửa nó.
Ave

2
Bạn có thể thả các dấu ngoặc nhọn và return bằng cách sử dụng hàm biểu thức. Cũng thếchar ngầm định để intbạn có thể sử dụng 91thay vì '[': int u(string l)=>l.Count(c=>c==91);Hơn nữa, bạn có thể bỏ chữ ký hàm và sử dụng phương thức lambda : l=>l.Count(c=>c==91);.
sữa


2

Ruby, 13 (+1) byte

p $_.count ?[

Được gọi với -nđối số:

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

EDIT: Thay đổi để thực sự in ra câu trả lời


Điều này dường như không in bất cứ điều gì. (Trừ khi đây là câu trả lời REPL, trong trường hợp đó, ngôn ngữ nên được chỉ định là Ruby REPL.)
Martin Ender

@Martin Ender ♦ Thông số kỹ thuật được phép trả về giá trị thay vì in nó.
Lee W

Điều đó đề cập đến đệ trình chức năng. Ví dụ, ->s{s.count ?[}sẽ là một đệ trình hợp lệ.
Martin Ender

Đó có phải là một quy tắc chung?
Lee W



2

Brain-Flak , 63 , 61 byte

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

Hãy thử trực tuyến! 58 byte mã và +3 cho-a cờ cho phép nhập ASCII.

Phiên bản / giải thích dễ đọc:

#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 byte

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

preg_match_all tìm thấy tất cả các trường hợp khớp của biểu thức chính quy và trả về một số, đó là lý do tại sao các thẻ echo ngắn là cần thiết.

Giống như hầu hết các câu trả lời, nó đếm số lượng [trong đầu vào và đầu ra số đó


1
Nếu bạn sử dụng ]thay vì [, bạn sẽ không phải thoát nó.
Martin Ender

2
count_chars()[91];làm nhiều điều tương tự nhưng ngắn hơn.
dùng59178

1

Vợt 82 byte

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

Ung dung:

(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)

Kiểm tra:

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

Đầu ra:

1
4
19
4

1

V , 10 byte

ÓÛ
ÒC0@"

Hãy thử trực tuyến!

Điều này có chứa một số ký tự không thể in, đây là phiên bản có thể đọc được:

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

<C-a>đại diện cho "ctrl-a" (ASCII 0x01) và <esc>đại diện cho khóa thoát (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

Phiên bản vui hơn, ít chơi gôn hơn:

o0kòf]m`jòd

Hãy thử trực tuyến!

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 byte

s=>s.count(92<)

Ung dung:

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

countđếm có bao nhiêu phần tử thỏa mãn một vị ngữ, trong trường hợp này 92<, đó là phương thức <của 92.


1

O , 15 byte

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

Hãy thử nó ở đây!

Trong đầu vào, bất kỳ dấu phẩy nào cũng phải được xóa hoặc thay thế bằng dấu cách.

Giải trình

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.

Nếu chúng tôi được phép thực hiện công việc trên một chuỗi: 10 byte

ie\']-e@-p

1

> <> , 21 20 18 byte

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

Chỉnh sửa: điểm 1 cho các tuyên bố goto!

Chỉnh sửa 2: Rõ ràng> <> khác với Befunge ở chỗ nó cho phép bù IP khác không sau khi gói (nói cách khác, bằng cách sử dụng lệnh trampoline, tôi có thể gói thành (1, 0) thay vì (0, 0)). Hấp dẫn.

Dùng thử trực tuyến!


1

Brainfuck, 28 byte

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

Hãy thử trực tuyến.

Điều này đếm số lượng ký tự đầu vào chia hết cho 3, tức là số lượng ] ký tự.

Giải pháp thay thế 34 byte đếm [ký tự trực tiếp và dựa vào các ô 8 bit:

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

1

C, 48 46 byte

Đã lưu hai byte nhờ 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;}

Mã kiểm tra

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

Các trường hợp thử nghiệm

a.exe
1
4
19

Thay đổi *v++^91?0:i++để i+=*v==91lưu 3 byte.
kirbyfan64sos

@ kirbyfan64sos Cảm ơn! Tôi vẫn cần tăng v nhưng tôi có thể sử dụng i+=*v++==91để lưu hai byte.
cleblanc

1

tinylisp thay thế , 39 byte

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

Xác định một hàm ucó thể được gọi là như(u (q ((())()) )) (đối với trường hợp thử nghiệm thứ hai). Làm điều đó trong thay thế tiết kiệm 4 byte do dấu ngoặc tự động đóng.

Giải trình

(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

Cấu x-(0-y)trúc là cần thiết bởi vì tinylisp không có chức năng bổ sung tích hợp, chỉ trừ.



1

Haskell, 20 19 17 byte

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

Hãy thử trực tuyến!

Lấy danh sách dưới dạng chuỗi và đặt 1một danh sách cho mỗi danh sách ], sau đó tổng hợp tất cả các 1s.


Phiên bản Pointfree: (19 byte)

length.filter(>'[')

Giả sử , [ ]là ký tự duy nhất trong chuỗi. Lọc danh sách để có được tất cả các ký tự lớn hơn [, đó là tất cả ]và trả về độ dài.

Sử dụng:

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

0

Bash + coreutils, 29 byte

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

Bạn có thể loại bỏ hầu hết những điều này và chỉ cần làm tr -d -c [|wc -c, theo mặc định sẽ đọc danh sách từ đầu vào tiêu chuẩn.
kirbyfan64sos

0

DASH , 14 byte

(ss[len;!> ="]

Đơn giản chỉ cần đếm ]. Sử dụng:

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

Giải pháp thưởng, 15 byte

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

Điều này đệ quy tính từ một danh sách thực sự. Sử dụng:

(f\@+1sum ->#f#0)[[]]
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.