Chân đế lồng vào nhau


30

Viết chương trình hoặc hàm có chuỗi tám byte chứa một trong mỗi ký tự ()[]{}<>được sắp xếp theo bất kỳ cách nào sao cho bốn loại khung tương ứng khớp với nhau. Ví dụ: ]<([){}>là đầu vào không hợp lệ vì dấu ngoặc vuông không khớp (mặc dù tất cả các dấu ngoặc khác đều làm được).

In hoặc trả lại một số nguyên từ 0để 6biểu thị có bao nhiêu trong số sáu cặp có thể của bốn loại khung được đan cài. Các cặp loại khung được coi là lồng vào nhau nếu chính xác một khung của một loại xảy ra giữa các dấu ngoặc của loại khác. Vì vậy, ([)][(])được đan cài nhưng ()[], [](), ([]), và [()]không.

Mã ngắn nhất tính bằng byte thắng.

Ví dụ đầu vào / đầu ra

()[]{}<> : 0
([{<>}]) : 0
<>{[]}() : 0
{<>([])} : 0
<(>)[{}] : 1
<[({)}]> : 1
[{<}]>() : 2
{<>([}]) : 2
<{(>})[] : 3
[(]<){>} : 3
<([>{)}] : 4
(<{[>})] : 4
(<[{)>}] : 5
<{[(>})] : 5
[{<(]}>) : 6
(<{[)>}] : 6

Câu trả lời:


17

CJam, 18

l7~f&_f{\/~;&}s,2/

Cảm ơn isaacg cho một số ý tưởng chơi golf :)
Hãy thử trực tuyến hoặc thử tất cả các ví dụ

Giải trình:

l         read a line of input
7~f&      clear the lowest 3 bits of each character
           the goal is to convert brackets of the same type to the same char
_         duplicate the resulting string, let's call it S
f{…}      for each character in S, and S (the char and S are pushed every time)
  \       swap the character with S
  /       split S around that character, resulting in 3 pieces:
           before, between, after
  ~       dump the pieces on the stack
  ;       pop the last piece
  &       intersect the first 2 pieces
          after the loop, we have an array of strings
          containing the chars interlocking to the left with each char of S
s         join all the string into one string
,         get the string length
2/        divide by 2, because S has duplicated characters

1
Oh, vậy bạn là người đã tạo ra CJam ?? Bạn nợ tôi vì tất cả những câu trả lời tôi đã mất đã bị đánh bại bởi câu trả lời của CJam! ;)
kirbyfan64sos

6
@ kirbyfan64sos, bạn cũng nên bắt đầu học nó nếu bạn muốn giành chiến thắng :)
aditsu

9
7~f&? Tôi thích câu trả lời này rồi, và tôi thậm chí còn không đọc phần còn lại của nó.
Dennis

11

Python 2, 163 byte

def f(b,e='([{<)]}>',q=range(4)):
 b=[b[b.index(e[j])+1:b.index(e[j+4])]for j in q]
 print sum(sum(abs(b[k].count(e[j])-b[k].count(e[j+4]))for j in q)for k in q)/2

Cái này xem xét các thứ giữa mỗi cặp dấu ngoặc phù hợp và đếm số lượng dấu ngoặc trái hoặc phải riêng lẻ hiện tại. Tổng của hai chia cho hai là đầu ra.

Tôi chắc chắn rằng nó có thể được chơi golf nhiều hơn bởi những người chơi golf giỏi hơn tôi.


31
Vâng, nó đã xảy ra. Calvin đăng một câu trả lời. Thời gian kết thúc là khi chúng ta.
Alex A.

4

GNU sed -r, 147

Đầu ra là đơn nhất theo câu trả lời meta này .

y/([{</)]}>/
s/.*/\t& & & & /
:b
y/)]}>/]}>)/
s/\S*>(\S*)>\S* /\1\t/
t
s/\S* //
:
s/(\t\S*)(\S)(\S*)\2(\S*\t)/\1\3\4/
t
s/\S *$/&/
tb
s/\s//g
s/../1/g

Lưu ý: Thay thế \tbằng các tabký tự thực tế để có được điểm chính xác. Tuy nhiên, chương trình sẽ hoạt động theo cách nào đó với GNU sed.

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


3

Perl, 77 byte

76 mã + 1 công tắc

perl -pe 'y/)]}>/([{</;for$x(/./g){$h{$x="\\$x"}++&&s!$x(.*)$x!$z+=length$1,$1!e}$_=$z'

Lấy đầu vào từ STDIN và chương trình phải được khởi động mới cho mọi đầu vào.

Giải trình

  1. Thay thế tất cả các dấu ngoặc đóng bằng các đối tác mở của chúng ( y/.../.../).
  2. Sau đó, với mỗi ký tự trong chuỗi đầu vào ( for$x...), hãy tăng bộ đếm cho ký tự ( $h{$x}++).
  3. Nếu đây là lần thứ hai chúng ta nhìn thấy nhân vật, hãy lấy khoảng cách giữa hai lần xuất hiện ( length $1) và xóa cả hai lần xuất hiện của ký tự này khỏi chuỗi. Ví dụ: nếu chuỗi là ([{([{<<, có hai ký tự [{giữa hai (s. Sau khi (s được xử lý, chuỗi trở thành [{[{<<và chúng ta thêm 2 vào tổng số ($z ) của dấu ngoặc lồng.
  4. Kết quả được lấy từ $z( $_=$z)

3

Bình thường, 20 byte

JmC/CdTzlsm@FPcsJd{J

Bộ kiểm tra

JmC/CdTz: Đầu tiên, điều này chuyển đổi từng cặp ký hiệu thành một ký tự bằng cách ánh xạ mỗi ký tự đầu vào thành mã ký tự của nó ( Cd) chia cho 10 ( / T), giống nhau cho mỗi cặp nhưng khác nhau giữa tất cả các cặp. Số kết quả được chuyển đổi trở lại thành một ký tự cho các mục đích sẽ được tiết lộ sau ( C). Danh sách kết quả của các ký tự được lưu vào J.

lsm@FPcsJd{J: Bây giờ, chúng tôi ánh xạ qua các ký tự duy nhất trong J( {J). Chúng tôi bắt đầu bằng cách cắt chuỗi được hình thành bằng cách nối Jbằng cách sử dụng ký tự hiện tại làm dấu phân cách ( csJd). Một cặp dấu ngoặc chồng lên cặp hiện tại nếu nó xuất hiện trong nhóm thứ hai và nhóm thứ nhất hoặc thứ ba. Để tránh tính hai lần, chúng ta sẽ chỉ đếm trường hợp nhóm thứ nhất và thứ hai. Vì vậy, chúng tôi loại bỏ nhóm thứ ba ( P) và lấy giao điểm của các nhóm còn lại ( @F). Cuối cùng, chúng tôi ghép các ký tự chồng chéo ( s) và in độ dài của resut ( l).


3

Trăn 3, 107

t=0
s=""
for x in input():s+=chr(ord(x)&~7)
for x in s:a=s.split(x);t+=len(set(a[0])&set(a[1]))
print(t//2)

Dựa vào giải pháp CJam của tôi.


3

Võng mạc , 128 108 64 62 55 byte

(T`)]>}`([<{
(\D)(.*)\1(.*)
\n$2\n$3
(?=(\D).*\n.*\1)
1
\n
<empty>

Trường hợp <empty>đại diện cho một dòng dấu trống. Để đếm mục đích, hãy đặt từng dòng trong một tệp riêng biệt và thay thế \nbằng các ký tự dòng thực tế. Để thuận tiện, bạn có thể sử dụng mã tương đương này với -scờ từ một tệp duy nhất:

(T`)]>}`([<{
(\D)(.*)\1(.*)
#$2#$3
(?=(\D)[^#]*#[^#]*\1)
1
#
<empty>

Đầu ra là đơn nguyên .

Giải trình

Cái đầu tiên (bảo Retina thực thi toàn bộ mã trong một vòng lặp cho đến khi phép lặp dừng thay đổi chuỗi. Trong trường hợp này, nó sẽ luôn lặp lại bốn lần, một lần cho mỗi loại khung.

T`)]>}`([<{

Điều này chỉ đơn giản là biến mỗi khung đóng thành khung mở tương ứng, để chúng ta có thể khớp các dấu ngoặc tương ứng với một phản hồi đơn giản sau này. (Giai đoạn này trở thành không hoạt động sau lần lặp đầu tiên. Nó chỉ được bao gồm trong vòng lặp, vì Tđã yêu cầu một backtick, vì vậy việc thêm (chi phí chỉ một thay vì hai byte.)

(\D)(.*)\1(.*)
\n$2\n$3

Điều này thay thế cặp dấu ngoặc trái nhất bằng dòng mới. Chúng tôi sử dụng \Dđể phân biệt dấu ngoặc với 1s chúng tôi thêm sau trong vòng lặp để đếm. Các (.*)tại này để thỏa mãn kết thúc mà chỉ có một cặp được thay thế (các trận đấu vì không thể chồng lên nhau).

(?=(\D).*\n.*\1)
1

Toàn bộ regex nằm trong một diện mạo, vì vậy điều này phù hợp với một vị trí . Cụ thể hơn, nó khớp với một vị trí cho mỗi cặp dấu ngoặc được phân tách bằng dấu ngoặc khác mà chúng ta vừa chuyển thành dòng mới. A 1được chèn vào từng vị trí này. Chúng ta chỉ có thể để 1chúng ở đó, vì chúng không ảnh hưởng đến bất kỳ chế độ nào khác (vì \Dchúng đảm bảo rằng chúng ta không vô tình khớp chúng).

\n
<empty>

Cuối cùng, chúng tôi xóa các dòng mới (tức là giữ chỗ cho loại dấu ngoặc hiện tại) - điều này có nghĩa là chúng tôi đã giảm vấn đề còn lại thành chuỗi có độ dài 6 chỉ chứa 3 loại dấu ngoặc, nhưng nếu không thì nó hoạt động giống hệt nhau.

Cuối cùng, chỉ còn lại 1s chúng tôi chèn và số lượng của chúng tương ứng chính xác với số lượng dấu ngoặc lồng.


2

JavaScript (ES7), 121 117 byte

x=>(a=b=0,[for(c of x)for(d of'1234')(e=c.charCodeAt()/26|0)==d?a^=1<<d:b^=(a>>d&1)<<d*4+e],f=y=>y&&y%2+f(y>>1))(b)/2

Ồ Đó là niềm vui. Tôi đã phác thảo một ý tưởng trả lời khi thử thách này lần đầu tiên xuất hiện, nhưng nó dài hơn 150 byte và tôi không muốn nỗ lực để chơi nó. Tôi đã chạy qua ý tưởng này trong cuốn sổ tay của mình ngày hôm qua và quyết định tôi sẽ không ngừng nghĩ về nó cho đến khi tôi hoàn toàn đánh golf nó. Cuối cùng tôi đã viết ra hai thuật toán hoàn toàn mới, thuật toán đầu tiên kết thúc ngắn hơn vài byte sau khi đánh gôn khoảng 25 byte với hàng tấn hack.

Làm thế nào nó hoạt động

Đầu tiên chúng ta đặt biến abthành 0. alà mảng nhị phân 4 bit trong đó các cặp khung mà chúng ta hiện đang ở bên trong và blà mảng nhị phân 16 bit trong đó các cặp khung được liên kết với nhau.

Tiếp theo, chúng ta lặp qua từng nhân vật ctrong x, và mỗi char dtrong '0123'. Đầu tiên chúng tôi xác định loại khung clà với e=c.charCodeAt()/26-1|0. Mã char thập phân của từng loại khung như sau:

() => 40,41
<> => 60,62
[] => 91,93
{} => 123,125

Bằng cách chia cho 26, trừ 1 và sàn, chúng tôi ánh xạ các giá trị này thành 0, 1, 2 và 3 tương ứng.

Tiếp theo chúng tôi kiểm tra xem con số này có bằng giá trị hiện tại của không d. Nếu đúng như vậy, chúng ta đang nhập hoặc thoát khỏi dloại khung thứ, vì vậy chúng ta lật dbit thứ avới a^=1<<d. Nếu không, nhưng chúng ta nằm trong dloại khung thứ, chúng ta cần lật ebit thứ trong phần d4 bit của b. Điều này được thực hiện như vậy:

b^=(a>>d&1)<<d*4+e

(a>>d&1)Trả về dbit thứ trong a. Nếu chúng ta ở trong dloại khung thứ, điều này trả về 1; mặt khác, nó trả về 0. Tiếp theo, chúng ta thay đổi kết quả này theo d*4+ebit và XOR btheo kết quả. Nếu chúng ta ở trong dkiểu khung thứ, thì XOR này là d*4+ebit thứ của b; mặt khác, nó không làm gì cả

Khi kết thúc tất cả các vòng lặp, bsẽ chứa một số bit 1 bằng hai lần giá trị trả về mong muốn. Nhưng chúng ta vẫn cần tính xem có bao nhiêu bit. Đó là nơi chức năng phụ fxuất hiện:

f=y=>y&&y%2+f(y>>1)

Nếu ylà 0, điều này chỉ đơn giản trả về 0. Nếu không, nó sẽ lấy bit cuối cùng yvới y%2, sau đó thêm kết quả của việc chạy tất cả trừ bit cuối cùng ythông qua hàm một lần nữa. Ví dụ:

f(y)         => y && y%2 + f(y>>1)
f(0b1001101) =>       1  + f(0b100110) = 4
f(0b100110)  =>       0  + f(0b10011)  = 3
f(0b10011)   =>       1  + f(0b1001)   = 3
f(0b1001)    =>       1  + f(0b100)    = 2
f(0b100)     =>       0  + f(0b10)     = 1
f(0b10)      =>       0  + f(0b1)      = 1
f(0b1)       =>       1  + f(0b0)      = 1
f(0b0)       => 0                      = 0

Chúng tôi chạy bqua chức năng này và chia kết quả cho 2, và đó là câu trả lời của chúng tôi.


1

Oracle SQL 11.2, 206 byte

WITH v AS(SELECT b,MIN(p)i,MAX(p)a FROM(SELECT SUBSTR(TRANSLATE(:1,'])>}','[(<{'),LEVEL,1)b,LEVEL p FROM DUAL CONNECT BY LEVEL<9)GROUP BY b)SELECT COUNT(*)FROM v x,v y WHERE x.i<y.i AND x.a<y.a AND y.i<x.a;

Chưa chơi gôn:

WITH v AS( -- Compute min and max pos for each bracket type
           SELECT b,MIN(p)i,MAX(p)a 
           FROM   ( -- replace ending brackets by opening brakets and split the string  
                    SELECT SUBSTR(TRANSLATE(:1,'])>}','[(<{'),LEVEL,1)b,LEVEL p 
                    FROM DUAL 
                    CONNECT BY LEVEL<9
                  )
           GROUP BY b
         )
SELECT COUNT(*)
FROM   v x,v y
WHERE  x.i<y.i AND x.a<y.a AND y.i<x.a -- Apply restrictions for interlocking brackets  
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.