Замикаючі кронштейни


30

Напишіть програму або функцію, яка містить вісім байтових рядків, що містять один з кожного символу, ()[]{}<>розташованих будь-яким чином, так що чотири відповідні типи дужок відповідають. Наприклад, ]<([){}>недійсне введення, оскільки квадратні дужки не збігаються (хоча всі інші).

Друк або повертати ціле число від 0до 6, що позначають , скільки з шести можливих пар з чотирьох типів дужок зчеплені. Пари кронштейнів вважаються замкненими, якщо між дужками іншого типу трапляється саме одна дужка одного типу. Так ([)]і [(])зчіплюються , але ()[], [](), ([])і [()]немає.

Виграє найкоротший код у байтах.

Приклади введення / виводу

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

Відповіді:


17

CJam, 18

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

Дякую isaacg за деякі ідеї для гольфу :)
Спробуйте в Інтернеті або спробуйте всі приклади

Пояснення:

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
О, значить, ти хлопець, який створив CJam ?? Ти завдячуєш мені за всі відповіді, які я втратив, що мене побили відповіді CJam! ;)
kirbyfan64sos

6
@ kirbyfan64так добре, вам також краще почати вчитися, якщо хочете перемогти :)
aditsu

9
7~f&? Мені ця відповідь вже подобається, а решту я навіть не читав.
Денніс

11

Пітон 2, 163 байти

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

Тут розглядаються дані між кожною парою відповідних дужок та підраховується кількість присутніх окремих лівих чи правих дужок. Сума їх ділиться на два - це вихід.

Я впевнений, що кращі гольфісти, ніж я, могли б набагато більше пограти в гольф.


31
Ну, сталося. Калвін опублікував відповідь. Кінцеві часи наступають перед нами.
Олексій А.

4

GNU sed -r, 147

Висновок не є одинаковим відповідно до цього метавідповіді .

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

Примітка: замініть \tфактичними tabсимволами, щоб отримати правильний бал. Однак програма буде працювати в будь-якому випадку з GNU sed.

Спробуйте в Інтернеті .


3

Perl, 77 байт

76 код + 1 перемикач

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

Бере вхід з STDIN, і програма повинна бути запущена нова для кожного введення.

Пояснення

  1. Замініть всі кронштейни, що закриваються, їх відкритими аналогами ( y/.../.../).
  2. Потім для кожного символу вхідного рядка ( for$x...) збільште лічильник символу ( $h{$x}++).
  3. Якщо це вже другий раз, коли ми бачимо символу, length $1дістаньте відстань між двома окулярами ( ) та видаліть обидві події цього символу з рядка. Наприклад, якщо рядок був ([{([{<<, є два символи [і {між двома (s. Після (оброблення s, рядок стає, [{[{<<і ми додаємо 2 до загальної кількості ( $z) замикаючих дужок.
  4. Результат взято з $z( $_=$z)

3

Pyth, 20 байт

JmC/CdTzlsm@FPcsJd{J

Тестовий набір

JmC/CdTz: По-перше, це перетворює кожну пару символів в один символ, позначаючи кожен вхідний символ на його код символу ( Cd), розділений на 10 ( / T), який однаковий для кожної пари, але різний між усіма парами. Отримане число перетворюється назад в символ для цілей, які будуть розкриті пізніше ( C). Отриманий список символів зберігається в J.

lsm@FPcsJd{J: Тепер ми відображаємо унікальні символи в J( {J). Почнемо з подрібнення рядка, утвореного об'єднанням, Jвикористовуючи поточний символ як деліметр ( csJd). Пара дужок перекриває поточну пару, якщо вона з’являється у другій групі, або в першій, або в третій групі. Щоб уникнути подвійного підрахунку, ми просто порахуємо випадок першої та другої груп. Отже, видаляємо третю групу ( P) і беремо перетин решти груп ( @F). Нарешті, ми sз'єднуємо символи, що перекриваються ( ), і друкуємо довжину resut ( l).


3

Пітон 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)

На основі мого рішення CJam.


3

Сітківка , 128 108 64 62 55 байт

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

Де <empty>представлений порожній проміжний рядок. Для підрахунку даних кожен рядок помістіть в окремий файл і замініть \nфактичними символами передачі рядків. Для зручності ви можете використовувати цей еквівалентний код із -sпрапором з одного файлу:

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

Вихід є одинаковим .

Пояснення

Перший (повідомляє Retina виконувати весь код у циклі, поки ітерація не перестане змінювати рядок. У цьому випадку вона завжди повторюватиметься чотири рази, один раз для кожного типу дужок.

T`)]>}`([<{

Це просто перетворює кожну закриваючу дужку у відповідну відкриваючу дужку, так що ми зможемо згодом відповідні дужки зіставити з простим зворотним відношенням. (Цей етап стає безрезультатним після першої ітерації. Він включається лише у цикл, тому що Tвже потрібна функція зворотного вибору, тому додавання (коштує лише один замість двох байтів.)

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

Це замінює саму ліву пару дужок новими рядками. Ми використовуємо \Dдля того, щоб відрізнити дужки від 1s, які ми додамо згодом у циклі для підрахунку. (.*)На кінцях гарантує , що замінюється лише одна пара (бо сірники не можуть перекриття).

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

Весь регулярний вираз знаходиться в підказці, тому це відповідає позиції . Більш конкретно, вона відповідає одній позиції для кожної пари дужок, яка була розділена іншими дужками, які ми щойно перетворили на нові рядки. A 1вставляється у кожну з цих позицій. Ми можемо просто залишити 1s, тому що вони не впливають на жоден з інших регексів (тому \Dщо вони гарантують, що ми їх не випадково збігаємо).

\n
<empty>

Нарешті, ми видаляємо нові рядки (тобто заповнювачі для поточного типу дужок) - це означає, що ми звели решту проблеми до рядка довжиною 6, що містить лише 3 типи дужок, але в іншому випадку вона працює точно так само.

Наприкінці 1залишиться лише вставлене нами s, і їх кількість точно відповідає кількості дужок, що перемикаються.


2

JavaScript (ES7), 121 117 байт

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

Ого. Це було весело. Коли я вперше з’явився цей виклик, я накреслив ідею відповіді, але це було понад 150 байт, і я не хотів докладати зусиль, щоб пограти у нього. Я вчора зіткнувся з цією ідеєю у своєму зошиті і вирішив, що не переставатиму думати про це, поки повністю не заграю в неї. Я закінчив виписати два абсолютно нових алгоритми, перший з яких закінчився на кілька байт коротше після гри в гольф близько 25 байтів з тоннами злому.

Як це працює

Спочатку встановлюємо змінні aі bна 0. aце 4-розрядний двійковий масив, з парних дужок яких ми зараз перебуваємо, і bє 16-бітовим двійковим масивом, який дужки пари пов'язані між собою.

Потім ми виконуємо цикл по кожному символу cв x, і кожен напівкоксу dв '0123'. Спочатку визначимо, який тип дужки cмає e=c.charCodeAt()/26-1|0. Десяткові знаки коду кожного типу дужок такі:

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

Ділення на 26, віднімання 1 і підлоги, ми відображаємо їх відповідно 0, 1, 2 і 3.

Далі ми перевіряємо, чи дорівнює це число поточному значенню d. Якщо так, то ми або вхід або вихід з dго типу кронштейна, тому ми перевертати dй біт в aс a^=1<<d. Якщо це не так, але ми перебуваємо всередині dтипу дужки, нам потрібно перевернути цей eбіт у d4-бітному розділі b. Це робиться так:

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

(a>>d&1)Повертає dбіт у a. Якщо ми знаходимось у dтипі дужок, це повертає 1; в іншому випадку вона повертається 0. Далі, ми пересуваємо цю ліву на d*4+eбіти, а XOR bза результатом. Якщо ми знаходимось у dтипі дужок, цей XOR - це d*4+eбіт b; інакше нічого не робить.

Наприкінці всього циклу bбуде міститися число 1-бітів, що дорівнює подвоєному бажаному поверненому значенню. Але нам ще потрібно розібратися, скільки це біт. Ось де підфункція fнадходить:

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

Якщо y0, це просто повертає 0. В іншому випадку він бере останній біт yз y%2, а потім додає результат yповторного запуску всіх, крім останнього біта . Наприклад:

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

Ми виконуємо bцю функцію і ділимо результат на 2, і є наша відповідь.


1

Oracle SQL 11.2, 206 байт

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;

Без гольфу:

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  
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.