Некоторые люди настаивают на использовании пробелов для табуляции и отступов.
Для подведения итогов, это бесспорно так. По определению табуляторы должны использоваться для табулирования.
Даже для отступов табуляторы объективно превосходят:
В сообществе Stack Exchange существует явный консенсус .
Использование одного пробела для отступа визуально неприятно; использование более чем одного расточительно.
Как знают все игроки в
гольф, программы должны быть максимально короткими. Это не только экономит место на жестком диске, но также сокращает время компиляции, если нужно обрабатывать меньше байтов.Регулируя ширину вкладки 1 , один и тот же файл выглядит по-разному на каждом компьютере, поэтому каждый может использовать свою любимую ширину отступа, не изменяя фактический файл.
Все хорошие текстовые редакторы используют табуляторы по умолчанию (и определение).
Я так говорю и я всегда прав!
К сожалению, не все слушают разум. Кто - то прислал вам файл , который делает это неправильно TM , и вы должны это исправить. Вы можете просто сделать это вручную, но будут и другие.
Достаточно плохо, что проставки тратят ваше драгоценное время, поэтому вы решаете написать самую короткую из возможных программ для решения проблемы.
задача
Напишите программу или функцию, которая выполняет следующее:
Прочитать одну строку из STDIN или в качестве аргумента командной строки или функции.
Определите все места, где пробелы были использованы для табуляции или отступа.
Пробел - это отступ, если он происходит в начале строки.
Выполнение двух или более пробелов является табуляцией, если это не отступ.
Единое пространство , которое не отступ может или не может быть использовано для подведения итогов. Как и ожидалось, когда вы используете один и тот же символ для разных целей, нет простого способа узнать. Поэтому скажем, что это место было использовано для путаницы .
Определите максимально возможную ширину табуляции 1, для которой все пробелы, используемые для табуляции или отступа, можно заменить табуляторами, не изменяя внешний вид файла.
Если входные данные не содержат ни табуляции, ни отступа, невозможно определить ширину вкладки. В этом случае пропустите следующий шаг.
Используя ранее определенную ширину табуляции, замените все пробелы, используемые для табуляции или отступа, табуляторами.
Кроме того, по возможности, не изменяя внешний вид файла, замените все пробелы, используемые для путаницы, табуляторами. (Если сомневаетесь, избавьтесь от пробелов.)
Верните измененную строку из вашей функции или распечатайте ее в STDOUT.
Примеры
Все пространства
a bc def ghij
Табулирование
Каждый цикл пробелов дополняет предыдущую строку непробельных символов шириной 5, поэтому правильная ширина табуляции равна 5, а правильный вывод 2 равен
a--->bc-->def->ghij
Первые два пространства
ab cde f ghi jk lm
Табулирование, другие путаницы.
Правильная ширина вкладки 4, так что правильный выход 2 является
ab->cde>f ghi>jk lm
Последний пробел остается нетронутым, так как он будет представлен как два пробела, если заменить его табулятором:
ab->cde>f ghi>jk->lm
Все, кроме одного пробела
int main( ) { puts("TABS!"); }
отступы, другая путаница.
Уровни отступов - 0, 4 и 8 пробелов, поэтому правильная ширина табуляции равна 4, а правильный вывод 2 равен
int --->main( ) --->{ --->--->puts("TABS!"); --->}
Пробел в
( )
будет представлен как три пробела, если заменить его табулятором, поэтому он останется нетронутым.Первые два пространства
x yz w
отступы, другие путаница.
Правильная ширина вкладки равна 2, а правильный вывод 2 равен
->x>yz w
Последний пробел будет представлен как два пробела, если он будет заменен табулятором, поэтому он останется нетронутым.
Первые два пространства
xy zw
отступы, остальные три - табуляция.
Только ширина вкладка 1 позволяет устранить все пробелы, поэтому правильный выход 2 является
>>xy>>>zw
Все пространства
a b c d
путаница
Там нет длинной возможной ширины вкладки, так что правильный выход 2 является
a b c d
Дополнительные правила
Ввод будет полностью состоять из печатных символов ASCII и перевода строки.
Вы можете предположить, что текст содержит не более 100 строк и не более 100 символов в каждой строке.
Если вы выберете STDOUT для вывода, вы можете распечатать один завершающий перевод строки.
Применяются стандартные правила игры в гольф .
1 Ширина табуляции определяется как расстояние в символах между двумя последовательными остановками табуляции с использованием моноширинного шрифта.
2 Стрелки ASCII представляют табуляторы, которые Stack Exchange отказывается отрисовывать должным образом, для которых я представил отчет об ошибке. Фактический вывод должен содержать фактические табуляторы.
источник
programs should be as short as possible
Я считаю, что нашел давно потерянного брата Артура Уитни !!Ответы:
Pyth,
102103 байтаПопробуйте онлайн
Интересная идея, но поскольку вкладки на входе нарушают концепцию, не очень удобны в использовании.
Редактировать: Исправлена ошибка. большое спасибо @aditsu
источник
PowerShell,
414409 байтЯ пошел дальше и использовал новые строки вместо того, чтобы по
;
возможности облегчить отображение. Я использую конец строки Unix, поэтому он не должен влиять на количество байтов.Как выполнить
Скопируйте код в
SpaceMadness.ps1
файл, затем передайте ввод в скрипт. Я предполагаю, что файл, который нужно преобразовать, называетсяtaboo.txt
:Из PowerShell:
Из командной строки:
Я протестировал его с PowerShell 5, но он должен работать на 3 или выше.
тестирование
Вот быстрый скрипт PowerShell, который полезен для тестирования выше:
Поместите это в тот же каталог
SpaceMadness.ps1
, в котором я его называюtester.ps1
, назовите так:Вы поняли идею. Он выкладывает содержимое каждого файла после конвертации, прогон
[RegEx]::Escape()
которого проходит через пробелы и табуляции, поэтому очень удобно видеть, что на самом деле было изменено.Вывод выглядит так (но с цветами):
объяснение
Самая первая строка определяет наибольший общий множитель / функцию делителя
g
настолько кратко, насколько мне удалось, которая принимает массив (произвольное число чисел) и рекурсивно вычисляет GCD, используя евклидов алгоритм .Цель этого заключалась в том, чтобы выяснить «максимально возможную ширину табуляции», взяв индекс + длину каждого отступа и табуляции, как определено в вопросе, а затем подав его в эту функцию, чтобы получить GCD, который, я думаю, является наилучшим из возможных. сделать для ширины вкладки. Длина путаницы всегда будет равна 1, поэтому она ничего не вносит в этот расчет.
$b
определяет блок скриптов, потому что, к сожалению, мне нужно дважды вызывать этот фрагмент кода, поэтому я сохраняю несколько байтов таким образом. Этот блок принимает строку (или массив строк)$n
и запускает регулярное выражение в ней (sls
илиSelect-String
), возвращая совпадающие объекты. На самом деле я получаю здесь и отступы, и таблицы в одном, что действительно сэкономило мне дополнительную обработку, захватив их отдельно.$n
используется для разных вещей внутри и вне основного цикла (очень плохо, но необходимо здесь, чтобы я мог встроить его в$b
скрипт-блок и использовать его как внутри, так и снаружи цикла без длинногоparam()
объявления и передачи аргументов.$s
получает назначенную ширину табуляции, вызывая$b
блок массива строк во входном файле, затем суммируя индекс и длину каждого совпадения, возвращая массив сумм в качестве аргумента в функцию GCD. Так$s
что размер нашей вкладки теперь останавливается.Затем цикл начинается. Мы перебираем каждую строку в массиве входных строк
$n
. Первое, что я делаю в цикле, это присваиваю$n
(локальная область) значение текущей строки по вышеуказанной причине.$w
получает значение вызова scriptblock только для текущей строки (отступы и табуляции для текущей строки).$c
получает аналогичное значение, но вместо этого мы находим все путаницы .Я складываю
$w
и$c
представляю собой массивы, давая мне один массив со всеми необходимыми совпадениями пробеловsort
в порядке убывания по индексу и начинаю итерацию по каждому совпадению для текущей строки.Сортировка важна. Ранее я обнаружил, что замена частей строки на основе значений индекса - плохая идея, когда строка замены меньше и меняет длину строки! Другие индексы становятся недействительными. Поэтому, начиная с наивысших индексов в каждой строке, я проверяю, чтобы строка была только короче с конца и перемещалась назад, чтобы индексы всегда работали.
В этот цикл
$x
входит в индекс текущего совпадения и$l
является длиной текущего совпадения.$s
на самом деле может быть,0
и это вызывает досадную ошибку деления на ноль, поэтому я проверяю ее достоверность, а затем делаю математику.В
!(($x+$l)%$s)
этом есть единственная точка, где я проверяю, следует ли заменить путаницу вкладкой или нет. Если индекс плюс длина, разделенная на ширину табуляции, не имеют остатка, то лучше заменить это совпадение на табуляцию (эта математика всегда будет работать с отступами и табуляциями , потому что их размер определяет ширину табуляции). начать с).Для замены каждая итерация цикла соответствия работает с текущей строкой ввода, поэтому это совокупный набор замен. Регулярное выражение просто ищет
$l
пробелы, которым предшествует$x
любой символ. Мы заменяем его$l/$s
символами табуляции (или 1, если это число меньше нуля).Эта часть
(($l/$s),1-ge1)[0]
- причудливый замысловатый способ сказатьif (($l/$s) -lt 0) { 1 } else { $l/$s }
или альтернативно[Math]::Max(1,($l/$s))
. Он создает массив$l/$s
и1
, затем использует-ge 1
для возврата массив, содержащий только элементы, которые больше или равны единице, затем берет первый элемент. Он поставляется на несколько байт короче, чем[Math]::Max
версия.Поэтому, как только все замены выполнены, текущая строка возвращается из итерации
ForEach-Object
(%
), а когда все они возвращаются (массив фиксированных строк), она-join
редактируется с помощью новых строк (так как мы разбиваем на новые строки в начале).Я чувствую, что здесь есть возможности для совершенствования, что я слишком перегорел, чтобы поймать его сейчас, но, возможно, я увижу что-нибудь позже.
источник
PHP -
278210 байтФункция работает путем проверки ширины каждой вкладки, начиная со значения 100, максимальной длины строки и, следовательно, максимальной ширины вкладки.
Для каждой ширины вкладки мы разбиваем каждую строку на «блоки» этой длины. Для каждого из этих блоков:
Как только каждый блок строки был проанализирован, мы запоминаем перевод строки. Если все блоки всех строк были успешно проанализированы, мы возвращаем строку, которую мы запомнили. В противном случае, если каждая строго положительная ширина табуляции была опробована, не было ни табуляции, ни отступа, и мы возвращаем исходную строку.
Вот негольфированная версия:
Отдельное спасибо DankMemes за сохранение 2 байта.
источник
for($t=101;--$t;)
вместоfor($t=100;$t;--$t)
CJam, 112
Попробуйте онлайн
Я должен был ответить на этот вызов, потому что я должен внести свой вклад, чтобы помочь избавить мир от этой мерзости. Вкладки, очевидно, лучше, но, к сожалению, некоторые люди просто не могут быть аргументированы.
Объяснение:
источник
PowerShell ,
165160153152142138137 байтПопробуйте онлайн!
Менее гольф:
источник