Рассмотрим непустую строку правильно сбалансированных скобок:
(()(()())()((())))(())
Мы можем представить, что каждая пара скобок представляет собой кольцо в свернутой телескопической конструкции . Итак, давайте расширим телескоп:
( )( )
()( )()( ) ()
()() ( )
()
Другой способ взглянуть на это заключается в том, что скобки на глубине n перемещаются в строку n , сохраняя при этом их горизонтальное положение.
Ваша задача - взять такую строку сбалансированных скобок и создать расширенную версию.
Вы можете написать программу или функцию, используя ввод через STDIN (или ближайший эквивалент), аргумент командной строки или параметр функции и производя вывод через STDOUT (или ближайший эквивалент), возвращаемое значение или параметр функции (out).
Вы можете предположить, что входная строка верна, то есть содержит только круглые скобки, которые правильно сбалансированы.
Вы можете печатать завершающие пробелы в каждой строке, но не больше начальных пробелов, чем необходимо. Всего строки не должны быть длиннее, чем удвоенная длина входной строки. При желании вы можете распечатать один завершающий символ новой строки.
Примеры
В дополнение к приведенному выше примеру, вот еще несколько тестовых случаев (вход и выход разделены пустой строкой).
()
()
(((())))
( )
( )
( )
()
()(())((()))(())()
()( )( )( )()
() ( ) ()
()
((()())()(()(())()))
( )
( )()( )
()() ()( )()
()
Связанные проблемы:
- Топографические строки , которые просят вас произвести то, что по сути является дополнением к выходным данным в этой задаче.
- Code Explanation Formatter , широкое обобщение идей этой задачи, недавно опубликованное PhiNotPi. (Фактически, оригинальное описание PhiNotPi его идеи было тем, что вдохновило этот вызов.)
Leaderboards
Да, в этом приняли участие довольно много, так что вот фрагмент стека, который генерирует как регулярную таблицу лидеров, так и обзор победителей по языкам.
Чтобы убедиться, что ваш ответ обнаружен, начните его с заголовка, используя следующий шаблон уценки:
# Language Name, N bytes
где N
размер вашего представления. Если вы улучшите свой счет, вы можете сохранить старые результаты в заголовке, вычеркнув их. Например:
# Ruby, <s>104</s> <s>101</s> 96 bytes
function answersUrl(e){return"http://api.stackexchange.com/2.2/questions/"+QUESTION_ID+"/answers?page="+e+"&pagesize=100&order=desc&sort=creation&site=codegolf&filter="+ANSWER_FILTER}function getAnswers(){$.ajax({url:answersUrl(page++),method:"get",dataType:"jsonp",crossDomain:true,success:function(e){answers.push.apply(answers,e.items);if(e.has_more)getAnswers();else process()}})}function shouldHaveHeading(e){var t=false;var n=e.body_markdown.split("\n");try{t|=/^#/.test(e.body_markdown);t|=["-","="].indexOf(n[1][0])>-1;t&=LANGUAGE_REG.test(e.body_markdown)}catch(r){}return t}function shouldHaveScore(e){var t=false;try{t|=SIZE_REG.test(e.body_markdown.split("\n")[0])}catch(n){}return t}function getAuthorName(e){return e.owner.display_name}function process(){answers=answers.filter(shouldHaveScore).filter(shouldHaveHeading);answers.sort(function(e,t){var n=+(e.body_markdown.split("\n")[0].match(SIZE_REG)||[Infinity])[0],r=+(t.body_markdown.split("\n")[0].match(SIZE_REG)||[Infinity])[0];return n-r});var e={};var t=0,c=0,p=-1;answers.forEach(function(n){var r=n.body_markdown.split("\n")[0];var i=$("#answer-template").html();var s=r.match(NUMBER_REG)[0];var o=(r.match(SIZE_REG)||[0])[0];var u=r.match(LANGUAGE_REG)[1];var a=getAuthorName(n);t++;c=p==o?c:t;i=i.replace("{{PLACE}}",c+".").replace("{{NAME}}",a).replace("{{LANGUAGE}}",u).replace("{{SIZE}}",o).replace("{{LINK}}",n.share_link);i=$(i);p=o;$("#answers").append(i);e[u]=e[u]||{lang:u,user:a,size:o,link:n.share_link}});var n=[];for(var r in e)if(e.hasOwnProperty(r))n.push(e[r]);n.sort(function(e,t){if(e.lang>t.lang)return 1;if(e.lang<t.lang)return-1;return 0});for(var i=0;i<n.length;++i){var s=$("#language-template").html();var r=n[i];s=s.replace("{{LANGUAGE}}",r.lang).replace("{{NAME}}",r.user).replace("{{SIZE}}",r.size).replace("{{LINK}}",r.link);s=$(s);$("#languages").append(s)}}var QUESTION_ID=49042;var ANSWER_FILTER="!t)IWYnsLAZle2tQ3KqrVveCRJfxcRLe";var answers=[],page=1;getAnswers();var SIZE_REG=/\d+(?=[^\d&]*(?:<(?:s>[^&]*<\/s>|[^&]+>)[^\d&]*)*$)/;var NUMBER_REG=/\d+/;var LANGUAGE_REG=/^#*\s*([^,]+)/
body{text-align:left!important}#answer-list,#language-list{padding:10px;width:290px;float:left}table thead{font-weight:700}table td{padding:5px}
<script src=https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js></script><link rel=stylesheet type=text/css href="//cdn.sstatic.net/codegolf/all.css?v=83c949450c8b"><div id=answer-list><h2>Leaderboard</h2><table class=answer-list><thead><tr><td></td><td>Author<td>Language<td>Size<tbody id=answers></table></div><div id=language-list><h2>Winners by Language</h2><table class=language-list><thead><tr><td>Language<td>User<td>Score<tbody id=languages></table></div><table style=display:none><tbody id=answer-template><tr><td>{{PLACE}}</td><td>{{NAME}}<td>{{LANGUAGE}}<td>{{SIZE}}<td><a href={{LINK}}>Link</a></table><table style=display:none><tbody id=language-template><tr><td>{{LANGUAGE}}<td>{{NAME}}<td>{{SIZE}}<td><a href={{LINK}}>Link</a></table>
Ответы:
CJam,
171615 байтовВыше приведен обратимый дамп xxd, поскольку исходный код содержит непечатаемые символы VT (0x0b) и CSI (0x9b).
Как и этот ответ , он использует escape-последовательности ANSI , но также использует вертикальные табуляции и печатает управляющие символы напрямую, чтобы избежать использования printf .
Для этого требуется поддерживающий видео текстовый терминал, который включает большинство эмуляторов терминала, отличных от Windows.
Тестовый забег
Мы должны установить переменную оболочки LANG и кодировку эмулятора терминала на ISO 8859-1. Первое достигается путем выполнения
Кроме того, перед выполнением действительного кода мы отключим запрос и очистим экран.
Это гарантирует, что вывод отображается правильно.
Чтобы восстановить LANG и подсказку, выполните это:
Как это устроено
Мы вставляем вертикальную вкладку после каждого ( чтобы переместить курсор вниз и последовательность байтов 9b 41 (
"\x9bA"
) перед каждым ), чтобы переместить курсор вверх.источник
машинный код x86,
3934333029 байтСборка x86 для DOS, с некоторыми хитростями:
Ограничения :
cls
перед запуском является почти обязательным;bh=0
и флаг направления сбрасывается при запуске, оба недокументированы; OTOH,bx
явно установлен на ноль во всех вариантах DOS, которые я видел (DosBox, MS-DOS 2, FreeDOS), и везде, где я тестировал, флаги уже были в порядке.источник
cld
?add
/sub
.lop
наloop
?nasm
междуloop
меткой иloop
инструкцией по сборке нет различий, поэтому я просто пишу,lop
как и все остальные.J,
3228 байтЭто было весело.
объяснение
Вот как это решение работает, в том числе объяснение того, как оно было в гольф.
источник
:')
C, 150 байтов
Это было безумно весело для гольфа. Я все еще не убежден, что я закончил с этим.
Мы определяем одну функцию,
f
которая принимает строку в качестве входных данных и выводит в стандартный вывод.Давайте пройдемся по коду, строка за строкой:
Я отвечу на любые ваши вопросы!
Попробуйте тестовую программу онлайн !
источник
f
,m
будет не сбрасывается в 0. Это рассчитывает как «нарушение среды,» вне закона здесь .Retina + Bash, 27 байт (14 + 10 + 3 = 27)
Это использует ANSI Escape:
Эквивалент
sed -e "s/(/(\\\e[B/g;s/)/\\\e[A)/g"
.\e[B
Код выхода означает перемещение курсора вниз на одну строку, и\e[A
средство перемещения курсора вверх на одну строку, так что это решение просто вставляет эти коды после того, как и перед началом и в конце каждой вложенной пары скобок. Ввод передается через STDIN.Вам нужно будет позвонить,
printf $(Retina ...)
чтобы увидеть результат правильно.Выход
источник
printf
этом, было бы здорово. В противном случае, я думаю, было бы справедливо добавить| printf
к счетчику байтов.printf $()
илиprintf $(Retina )
.\e
плюсprintf
? Вы можете просто поместить управляющие символы в шаблоне замены.TI-BASIC,
69 60 5655 байтовЭто для калькуляторов семейства TI-83 + / 84 +, хотя оно было написано в версии 84+ C Silver Edition.
Программа отображается как более крупная на счету из-за НДС + информация о размере. Также здесь более 56 символов; причина в том, что он составляет 56 байт, потому что все команды, состоящие более чем из одного символа, сжимаются до токенов, размер которых составляет один или два байта.
Побрил еще один байт благодаря Томасу-Кве ! (также от него был скачок с 60 до 56.)
источник
cos(piAns
хитрость, чтобы сохранить другой байт.Python 2, 115 байт
Вызовите как
f("((()())()(()(())()))")
, и вывод на STDOUT.объяснение
Начнем с
n = 0
. Для каждого символа в строке ввода:(
, мы добавляемn
пробелы, то увеличиваемn
)
, мы уменьшаем,n
затем добавляемn
пробелыРезультат затем архивируется и печатается. Обратите внимание, что почтовые
zip
индексы Python соответствуют длине самого короткого элемента, напримерОбычно можно использовать
itertools.zip_longest
(izip_longest
), если они хотят дополнитьzip
длину самого длинного элемента.Но в Python 2 это поведение можно смоделировать с помощью отображения
None
:Python 3, 115 байт
Никакой молнии, просто добавьте соответственно
ljust
. У этого, кажется, есть некоторый потенциал игры в гольф.источник
R,
151127 символовС отступами и переводами строки:
Использование:
Он читает строку как stdin, разбивает ее как вектор из отдельных символов, вычисляет кумулятивную сумму
(
и)
, вычитает первое с последним (с запаздыванием), таким образом вычисляя «уровень» каждой круглой скобки. Затем он выводит на стандартный вывод для каждого уровня либо соответствующие скобки, либо пробел.Спасибо @MickyT за помощь в значительном сокращении!
источник
for(i in n)cat(ifelse(D[i]-j," ",S[i]));cat("\n")
наX=S;X[which(D!=j)]=' ';cat(X,sep='',fill=T)
. Тогдаn
это на самом деле не требуется, но вам нужно будет немного изменить составную часть.D=c(C(S=="("),0)-c(0,C(S==")"));
снижая его до 135.which
хотя в этом нет необходимости (D!=j
поскольку он уже является вектором логических значений, допускающих индексацию). Я не знаю , аргументfill
дляcat
, это отличный трюк! Спасибо за то, что заставили меня сократить его на 24 символа!C
58 53 52 5149 байтИспользует escape-последовательности ANSI для перемещения курсора.
Если не используется gcc или другой поддерживающий компилятор,
\e
его можно заменить\x1B
на 2 дополнительных байта.\e[A
перемещает курсор вверх на одну строку и\e[B
перемещает курсор вниз на одну строку. Нет необходимости использовать\e[B
для перемещения вниз на одну строку, так как для использования символа вертикальной табуляции ASCII на два байта короче0xB
или\v
.Предполагается, что входная строка в вопросе состоит только из (сбалансированных) скобок, поэтому проверки четности символа с помощью
&1
достаточно, чтобы различить(
и)
.источник
Пип, 53 байта
Пип является языком код-гольфа моего изобретения. Первая версия была опубликована в субботу, так что я могу официально принять ее за спин! Решение, представленное ниже, не очень конкурентоспособно, поскольку языки игры в гольф идут, но это отчасти потому, что я еще не реализовал такие вещи, как zip и max.
Ожидает строку скобок в качестве аргумента командной строки.
"Ungolfed" версия:
Объяснение:
В отличие от большинства языков игры в гольф, Pip обязателен для инфиксных операторов, поэтому синтаксис несколько ближе к C и его производным. Он также заимствует идеи из функционального и основанного на массивах программирования. Смотрите хранилище для дальнейшей документации.
Программа сначала генерирует список глубин (сохраняя его
z
) путем сопоставления функции с входной строкойa
. Глобальная переменнаяv
отслеживает текущий уровень. (Переменныеa-g
в Pip являются функционально-локальными переменными, ноh-z
являются глобальными.v
Удобно, потому что они предварительно инициализированы в -1.)Затем мы используем
W
цикл hile для генерации и печати каждой строки, пока сгенерированная строка не будет состоять из всех пробелов.v
теперь используется для столбцов иi
для строк.{z@++v=i?as}
Функция, неоднократно сопоставляется с исходной входной строки, проверяет , является ли текущая строкаi
совпадения линии тока скобка должна быть (как хранится вz
списке). Если это так, используйте скобки (a
); если нет, используйтеs
(preinitialized to space). Конечным результатом является то, что на каждой итерацииo
присваивается список символов, эквивалентный следующей строке вывода.Чтобы проверить, следует ли нам продолжать цикл, мы проверяем, является ли
o
со всеми пробеламиRM
d пустым. Если нет, выведите его (который по умолчанию объединяет все вместе, как в CJam), сбросьте номер столбца до -1 и увеличьте номер строки.(Забавный факт: сначала у меня было 51-байтовое решение ... которое не сработало, потому что оно обнаружило ошибку в интерпретаторе.)
источник
Pyth, 31 байт
Попробуйте онлайн.
-/<zk\(/<zhk\)
: Находит соответствующий уровень для текущей позиции персонажа.?YqN-/<zk\(/<zhk\)d
: Пробел, если соответствующий уровень не является текущим, в противном случае текущий символ.Js.e?YqN-/<zk\(/<zhk\)dz
: Создать строку, сохранить ее вJ
.I-JdJ
: ЕслиJ
не все пробелы, распечатайте его.Vz
: Циклz
раз.источник
GNU Bash + coreutils + отступ, 135
Ввод / вывод через STDIN / STDOUT:
indent
делает большую часть тяжелой работы, но должен работать с фигурными скобками вместо паренов. Остальное - модификация этого ответа, чтобы транспонировать выводindent
.источник
Python 2, 92
Печатает построчно. Для данного номера строки
i
(на самом деле, его отрицание) проходит через входную строкуs
и создает новую строку,z
которая содержит только символыs
на глубинеi
. Это делается путем увеличения или уменьшений ,i
чтобы отслеживать текущую глубину, и добавления текущих символов , когдаi
это с0
поправкой на скобку типа, а в противном случае добавления пробела.Затем печатает и возвращается к следующему,
i
если текущая строка не была пробелами. Обратите внимание, что, поскольку парены сбалансированы,i
цикл после цикла такой же, как и в начале.Python 3 будет таким же, за исключением символа для
print(z)
.источник
измена :(
Retina + TeX, N байтизмена :(Это работает, только если вы отображаете (?) Вывод, используя MathJax или какой-либо другой TeX, который в настоящее время отключен для этого SE :(
Каждая строка должна находиться в отдельном файле, но вы можете проверить это с помощью
Retina -e "\(" -e "({" -e "\)" -e "})" -e "\{\(" -e "_{("
(или эквивалентной команды sedsed -e "s/(/({/g;s/)/})/g;s/{(/_{(/g"
). Ввод передается через STDIN.Это работает, заключая содержимое каждой пары скобок в фигурные скобки, а затем подписывая все элементы внутри них.
Выход
источник
In total the lines must not be longer than twice the length of the input string
, Изменение строки 2 на(\,{
и строки 4}\,)
означает, что выход соответствует этому (хотя вертикальная глубина по-прежнему неверна: ()Java,
232226224222 байтаГольф версия:
Длинная версия:
Входная строка сначала анализируется, ища «(» и «)», чтобы сложить / вычесть счетчик и сохранить его значение, определяющее, как далеко скобки должны идти вниз в массиве, а также отслеживать глубину самого глубокого из них. Затем массив анализируется; круглые скобки с меньшими значениями печатаются первыми и будут продолжать печатать построчно, пока не будет достигнут максимум.
Я, вероятно, найду способ играть в гольф позже.
источник
Javascript / ES6, 97 символов
использование
объяснение
источник
n<m?console.log(o):0
вы можете использоватьn<m&&console.log(o)
который сохраняет 1 байт.CJam,
43 4136 байтНе слишком удачно (я думаю), но вот моя первая попытка:
Как это устроено
Я использую очень удобный факт, что
)
и(
в CJam означают увеличение и уменьшение соответственно. Таким образом, я просто оцениваю скобки, чтобы получить глубину.Попробуйте онлайн здесь
источник
Октава, 85 символов
Это оптимизация наивного подхода, что на самом деле вполне естественно для Matlab и Octave:
Таблица
t
может даже еще не существовать, и мы можем сразу назначить любой элемент, и она преобразуется в наименьшее измерение, необходимое для существования этого элемента, что весьма удобно.источник
Perl,
918988848079 байтисточник
Haskell, 154 байта
та же идея, что и у другого решения на Haskell, но несколько короче. - Использование:
источник
J, 46
Не так хорошо, как другие «языки игры в гольф», но в мою защиту: J ужасен со струнами.
Принимает строку в качестве входных данных для функции. Там также, вероятно, лучший способ сделать это в J.
Использование:
источник
Рубин,
119115114Объяснение:
источник
Java,
233214 байтОтступ:
Я думаю, что последний цикл может быть сокращен, но я оставлю это в качестве упражнения для читателя. ;-)
Старый, 233 байта ответа:
Отступ:
источник
for(x=0;x<l*l;x++)System.out.print((x%l==0?"\n":"")+m[x]);
наfor(x=0;x<l*l;)System.out.print((x%l==0?"\n":"")+m[x++]);
на -1 байт. Кроме того, вы можете сохранить еще 2 байта, удалив ихp=x=0
и просто используяint p=0,x=0,
при инициализации полей. Всего становится 211 байт .C #, 195 байт
Сначала попробуйте в гольф - кричите, если я сделал что-то не так.
Альтернативная версия C #, использующая SetCursorPosition и работающая слева направо, принимающая ввод в качестве аргумента командной строки.
Я подумал, что было бы интересно отрегулировать положение записи, основываясь на парене открытия / закрытия, а не на полных строках. Close paren перемещает позицию вверх перед записью; open paren перемещает его вниз после записи. Действие SetCursorPosition сохраняет пять байтов. Перемещение курсора на следующую строку после вывода заняло бы немного больше.
источник
Партия,
356335 байтЯ знаю, что уже существует пакетное решение для этой задачи, но это значительно больше и кажется, что он использует другой подход. Что наиболее важно, другое пакетное решение содержит по крайней мере одну команду powershell; этого решения нет.
На
U+0008
последней второй строке, следующей за точкой, стоит символ возврата ( ) (строка 12, столбец 57). Это не видно в коде, размещенном здесь, но включено в число байтов.источник
Пакетный, 424 байта
Un-golfed:
Пример:
источник
C
118117 байтЕще один ответ на С, но мой короче.
Безголовая версия:
И это работает!
источник
putchar(c-d?32:*p)
на один символ корочеputchar(c==d?*p:32)
.Haskell, 227 байт
источник
n#[]
вместоm n []
.Perl, 76 байт
Нет
use strict
здесь :)источник
Lex, 94 байта
Зависит от консольных кодов Linux. С помощью gcc вы можете вырезать четыре байта, заменив оба экземпляра
\33
фактическим escape-символом.Чтобы скомпилировать и запустить:
источник