Завершите ленивые скобки

17

Все скобки на моей клавиатуре изношены, и я хочу избегать их использования в максимально возможной степени. Ваша задача - сбалансировать строку, содержащую скобки, добавив их до и после каждой строки.

Это похоже на автоматические круглые скобки TI-Basic и закрытие строки (т.е. Output(1, 1, "Hello, World!). Это также экономит драгоценные байты из программы!

Пример ввода:

This line has no parentheses
alert(Math.max(1, 2
1+1)*2).toString()
function() { alert('Hello, World!'); })(

Пример (возможный) вывод:

This line has no parentheses
alert(Math.max(1, 2))
((1+1)*2).toString()
(function() { alert('Hello, World!'); })()

Спецификация:

  • Для каждой строки ввода

    • Добавьте столько открытых скобок в начало и закрывающих скобок в конец строки, сколько необходимо для балансировки скобок в строке.

      • Определение «баланса»:

        • Такое же количество (и )в линии

        • Для каждой подстроки, начинающейся с начала строки, эта подстрока не должна иметь больше закрывающих скобок, чем открывающих скобок

          • Например, (foo))(barне сбалансирован, потому что (foo))имеет больше закрывающих скобок, чем открывающих скобок
    • Вы можете добавить лишние скобки, если хотите, если это делает ваш код короче

    • Вам не нужно беспокоиться о строковых литералах или о чем-то подобном, предположим, что все скобки нуждаются в балансировке

  • Выведите каждую строку со сбалансированными скобками

Это , поэтому выиграет самый короткий код в байтах!

Дверная ручка
источник
Вы просто обеспокоены ()круглые скобки, или делать другие кронштейны {}, [], <>и т.д. Необходимо также учитывать?
Цифровая травма
@DigitalTrauma Нет, только (и ).
Дверная ручка
У вас есть какие-нибудь тесты?
Питер Тейлор
1
@ Питер Да, они прямо там в посте ...
Дверная ручка

Ответы:

21

GolfScript, 23 байта

n/{"()"1/{.2$\-,*}%*n}/

Лазейка, которую я эксплуатирую, - это решение, которое:

Вы можете добавить лишние скобки, если хотите, если это делает ваш код короче

По сути, для каждой строки этот код подсчитывает количество символов в строке, которые не открывают круглые скобки, и добавляет к строке много дополнительных открывающих скобок, а затем делает то же самое для закрывающих скобок. Это невероятно неэффективно, но гарантирует, что все скобки в строке вывода сбалансированы.

Например, с учетом ввода:

This line has no parentheses
alert(Math.max(1, 2
1+1)*2).toString()
function() { alert('Hello, World!'); })(

эта программа выведет:

((((((((((((((((((((((((((((This line has no parentheses))))))))))))))))))))))))))))
(((((((((((((((((alert(Math.max(1, 2)))))))))))))))))))
(((((((((((((((((1+1)*2).toString())))))))))))))))
(((((((((((((((((((((((((((((((((((((function() { alert('Hello, World!'); })()))))))))))))))))))))))))))))))))))))

Ps. Вы также можете проверить этот код онлайн .

Илмари Каронен
источник
4
Это напоминает мне о том, когда я программировал на Лиспе ... Несколько битов кода потерялись в море скобок.
Такон
7

Perl, 32 = 31 + 1 или 73 = 72 + 1 (минимизированные скобки)

32 = 31 + 1: с лишними лишними скобками

Редактирование:

  • Исправлено, скобки теперь учитываются y///.
  • Ненужная переменная $aудалена.
$_="("x y/)//.s|$|")"x y/(//|er

Используется с переключателем времени выполнения -p(+1 байт).

Тестовый файл input.txt:

This line has no parentheses
alert(Math.max(1, 2
1+1)*2).toString()
function() { alert('Hello, World!'); })(
(foo))(bar
)))(((
((
))

Командная строка:

perl -p script.pl <input.txt

или

perl -pe '$_="("x y/)//.s|$|")"x y/(//|er' <input.txt

Результат:

This line has no parentheses
alert(Math.max(1, 2))
(((1+1)*2).toString())
(((function() { alert('Hello, World!'); })()))
(((foo))(bar))
((()))((()))
(())
(())

Ungolfed:

Алгоритм прост, просто добавьте аналог для каждой найденной скобки.

$_ =                     # $_ is provided as input by switch `-p` and
                         # it is printed afterwards as output.
                         # y/X// is used to count the character 'X' in $_
    '(' x y/)//          # add opening parentheses for each closing parentheses
    . s|$|')' x y/(//|er # go right before the end of line and insert
                         # closing parentheses for each opening parentheses
                         # in the original string

73 = 72 + 1: добавление минимального количества скобок

Этот скрипт добавляет только минимальное количество скобок, чтобы получить сбалансированный вывод.

$a=y/()//cdr;1while$a=~s/\(\)//g;$_=$a=~y/)(/(/dr.$_;s|$|$a=~y/()/)/dr|e

Используется с переключателем времени выполнения -p(+1 байт).

perl -pe "$a=y/()//cdr;1while$a=~s/\(\)//g;$_=$a=~y/)(/(/dr.$_;s|$|$a=~y/()/)/dr|e" <input.txt

Результат:

This line has no parentheses
alert(Math.max(1, 2))
((1+1)*2).toString()
(function() { alert('Hello, World!'); })()
((foo))(bar)
((()))((()))
(())
(())

Ungolfed:

$a = y/()//cdr;            # filter parentheses and store in $a
1 while $a =~ s/\(\)//g;   # remove matching parentheses
$_ = $a =~ y/)(/(/dr . $_; # add missing opening parentheses at start of string
s|$|$a=~y/()/)/dr|e        # insert missing closing parentheses at end of string

81 = 80 + 1: добавление минимального количества скобок

Это более старый метод добавления минимального количества скобок для сбалансированного вывода.

my($l,$r);s/[()]/($&eq")"&&($r&&$r--||++$l))||$r++/ger;$_="("x$l.$_;s/$/")"x$r/e

Он использует Perl 5.14 (из-за неразрушающего модификатора замещения) и переключатель времени выполнения -p(+1 байт).

perl -p script.pl <input.txt

Результат:

This line has no parentheses
alert(Math.max(1, 2))
((1+1)*2).toString()
(function() { alert('Hello, World!'); })()
((foo))(bar)
((()))((()))
(())
(())

Ungolfed:

# The while loop is added by option "-p".
LINE:
while (<>) {

    # $_ contains the current line
    my ($l, $r); # initializes $l and $r (to undef/kind of indirect 0)
    # Modifiers for the following substitution of $_:
    # /g: process all parentheses
    # /e: evaluate code
    # /r: does not change the original input string $_ (Perl 5.14)
    s/[()]/
        # $& contains the matched parentheses
        # $r is a balance level counter; at the end $r contains
        #    the number of needed closing parentheses
        # $l is the number of needed opening parentheses;
        #    if $r would go negative, then an opening parentheses
        #    is missing and $l is increases and $r remains zero.
        (  
            $& eq ")" &&   # case ")"
            ($r && $r--    # close a parentheses group and update balance counter
                || ++$l)   # or update $l if an opening parentheses is needed
        )
        || $r++            # case "(": increase balance counter
    /ger;
    $_ = "(" x $l . $_;    # add opening parentheses at the begin of line
    s/$/")" x $r/e         # add closing parentheses before the line end

# the remainder is added by run-time switch "-p"
} continue {
    print or die "-p destination: $!\n";
}
Хайко Обердиек
источник
2
Ничего себе, это почти похоже на golfscript ;-)
Digital Trauma
@HeikoOberdiek Какой Perl вы используете для первой версии? Похоже, что он не работает на 18,1 из-за '('x/\)/gвсегда равных '(' ...
Mouq
@Mouq: Спасибо, исправлено использование y///вместо m//gподсчета скобок.
Хейко Обердик,
4

Python 2.7 3: 62 60 58 байт

while 1:s=input();c=s.count;print('('*c(')')+s+')'*c('('))

Не супер гольф, но вы знаете. Я мог бы выжать еще несколько байтов, если бы я действительно попытался.

Для каждой строки выведите (* номер )строки, затем строку, затем )* номер (строки. Если я правильно понимаю правила, это всегда даст правильный результат.

Выйти, выдав исключение, в результате того, как я сделал ввод. (Входные данные всегда являются трудной частью этих проблем.) Если это не приемлемо, это будет стоить мне несколько байтов, хотя я еще не уверен, сколько.

Пример вывода:

This line has no parentheses
alert(Math.max(1, 2))
(((1+1)*2).toString())
(((function() { alert('Hello, World!'); })()))
undergroundmonorail
источник
По-видимому, это не требует многострочного ввода, т.е. отпечатки чередуются со строками ввода. Но хорошая идея алгоритма, я не думал об этом;)
Дверная ручка
python2 balanced_parenthesis.py < input.txt 2>/dev/nullполучает вывод, который я написал, но если вы хотите многострочный ввод, делая это в интерактивном режиме, это будет стоить мне несколько байтов. Дайте мне секунду, я что-нибудь придумаю ...
подземный
Ах, ладно, не важно. Это будет работать!
Ручка двери
сохранить 2 символа:while 1:s=raw_input();c=s.count;print'('*c(')')+s+')'*c('(')
Джастин
@ Qui О, вау. Я был так близок к тому, чтобы понять это, но я не осознавал, что ты можешь это сделать c=s.count. Я думал , что ты должен был сделать c=s, s.c(). Благодарность!
подземная
1

Чистый Баш, 72 байта

Использует тот же алгоритм, что и ответ @groundmonorail:

while read a;do
o=${a//[!(]}
c=${a//[!)]}
echo ${c//)/(}$a${o//(/)}
done

Выход:

$ ./lazyparens.sh < input.txt
This line has no parentheses
alert(Math.max(1, 2))
(((1+1)*2).toString())
(((function() { alert('Hello, World!'); })()))
$ 
Цифровая травма
источник