Боже мой, это покрыто вкладками!


26

Пользователи космического отступа, объединяйтесь ! Мы должны бороться со всеми непритязательными пользователями вкладок !

Ваша миссия (если вы решите принять это) - написать программу или функцию, которая принимает два аргумента:

  • Строка: это вход.
  • Целое положительное число: это количество пробелов на вкладке.

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

Обратите внимание, что такие строки, как \t \tabcнеопределенное поведение; они были вставлены злыми пользователями вкладки, чтобы усложнить ваши программы.

Согласно Обществу Tabs Must Die, ваша программа должна быть максимально короткой, чтобы ее не могли обнаружить злые пользователи вкладок.

пример

\t используется для представления вкладок здесь.

Строка ввода:

a
\t\tb\tc
d

Введите номер:

4

Выход:

a
        b c
d

Средняя строка была с отступом в 8 пробелов, по 4 на табуляцию (так как данное число было 4).

Строка ввода:

\ta\t\tb

Введите номер:

4

Выход:

    a  b

ПРИМЕЧАНИЕ. Это не является дубликатом задачи расширения вкладки ; это требует совсем другого формата ввода и немного других требований.


1
Да , до тех пор, пока вопрос явно не задает десятичные числа (чего не происходит).
Мартин Эндер


1
Можем ли мы предположить, что входные данные содержат только печатные ASCII, вкладки и переводы строк?
Деннис

2
Предлагаемый тест: \ta\t\tb, 4(мой предыдущий пересмотр был провал , что один)
Деннис

2
Нам нужен ответ в Whitespace.
Каз Вулф

Ответы:


7

CJam, 30 24 23 байта

q{_9=NA=Seasi*' ?@?:N}/

Я обычно отказываюсь размещать вредоносный код в интернете ...

Это полная программа, которая читает строку из STDIN и число в качестве аргумента командной строки.

Попробуйте онлайн в интерпретаторе CJam .

Как это работает

q                        Read all input from STDIN.
 {                   }/  For each character C in the input:
  _9=                      Push 1 if C is a tab and 0 otherwise.
     NA=                   See below.
        Seasi*             Push a string of W spaces, where W is the integer from
                           the command-line arguments.
              '            Push a spaces character.
                ?          Select the string if NA= pushed a truthy value, the
                           single space otherwise.
                 @         Rotate C on top of the stack.
                  ?        Select the string of spaces or the single space if _9=
                           pushed 1, the character C otherwise.
                   :N      Save the result in N.

Что NA=делает:

  • Для первого символа Nбудет содержать значение по умолчанию, т. Е. Строку "\n".

    Для всех последующих символов Nбудет содержать результат последней итерации, т. Е. Последний символ ввода, пробел или строку из одного или нескольких пробелов.

  • Если Nэто строка, NA=выбирается элемент с индексом 10 из N (обтекание). Результатом будет пробел или символ перевода строки. Оба правдивы.

    Если N символ, NA=нажимает 1 для перевода строки и 0 в противном случае.

  • Из-за вышеизложенного NA=будет выдано истинное значение для первого символа, символа, которому предшествует перевод строки, или символа, которому предшествует строка пробелов (отступ, который уже был заменен).

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


6
Хорошо, что вы делаете интернет-сервис, удаляя вредоносные вкладки. ;)
Алекс А.

19

К5, 53 45 байт

{{,/(b+a&~b:x*&\a:9=y){$[x;x#" ";y]}'y}[x]'y}

В бою:

  {{,/(b+a&~b:x*&\a:9=y){$[x;x#" ";y]}'y}[x]'y}[4;(,"a";"\t\tb\tc";,"d")]
(,"a"
 "        b c"
 ,"d")

Я просто хочу, чтобы запись показала, что этот вопрос морально предосудителен.


11
-21346106841 для... this question is morally reprehensible.
TheNumberOne

3
Это должно закончиться самым популярным ответом, просто чтобы люди увидели сноску.
Geobits

Вы можете вернуть результат вместо 3 байтов.
kirbyfan64sos

1
@ kirbyfan64sos: Я печатаю результат, чтобы избежать необходимости соединять строки. Если я могу принять и вернуть результат в виде списка строк, по одной на каждую строку, я мог бы сохранить `0:и `" \ n "\`.
JohnE

@JohnE Я не ввел правило, говорящее, что ты не можешь, поэтому я предполагаю, что ты можешь. :)
kirbyfan64sos

8

Perl, 23 байта

Код 22 байта + командная строка 1 байт

Надеюсь, не слишком дерзко предположить, что числовой ввод может быть задан параметром -i! Обязательно замените \ t в приведенном ниже коде реальным символом табуляции.

s/\G\t/$"x$^I/ge;y/\t/ /

Пример использования:

printf "a\n\t\tb\tc\nd" | perl -p entry.pl -i4

Или для удобства:

printf "a\n\t\tb\tc\nd" | perl -pe 's/\G\t/$"x$^I/ge;y/\t/ /' -i4

Объяснение:

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

В приведенном выше примере замена регулярного выражения заменяется \G\tна " "x4(пробел повторяется четыре раза). \Gявляется малоизвестной конструкцией регулярного выражения, которая соответствует либо позиции первого совпадения, если первая итерация, либо позиции предыдущего совпадения, если не первой итерации, то есть она заменит все вкладки в начале строки и будет сделать это один за другим. y/\t/ /Просто заменяет все остальные вкладки с пробелами.


2

Юлия, 69 59 байт

f(s,n)=(r=replace)(r(s,r"^\t*"m,i->" "^endof(i)n),"\t"," ")

Ungolfed:

function f(s::String, n::Int)
    # Replace the leading indentation tabs
    r1 = replace(s, r"^\t*"m, i -> " "^endof(i)n)

    # Replace any remaining tabs between words
    r2 = replace(r1, r"\t", " ")

    # Return
    r2
end

Сохранено 10 байт и исправлена ​​проблема благодаря Glen O!


Есть ли какая-то польза от замены ведущих вкладок отступов отдельно? Мне кажется, что это должно быть обработано непосредственно частью «оставшихся вкладок». Кроме того, ваша часть «заменить вкладки между текстом» будет соответствовать только одной вкладке, что если у вас есть "hello\t\t1"?
Глен О

Если мы предположим, что все отступы выполняются с помощью вкладок (без "\t \t"ситуаций), вы можете сделать это:, f(s,n)=(r=replace)(r(s,r"^\t*"m,i->" "^endof(i)n),"\t"," ")которая использует функцию замены и поймает все вкладки отступа за один удар.
Глен О

@GlenO Ого, это действительно гениально. Спасибо!
Алекс А.

Я заметил, что мой ответ получил отрицательный голос. Что-то я сделал не так? Я был бы рад решить любые вопросы.
Алекс А.

Я не вижу никаких проблем. Может быть, это просто один из тех злопамятных типов, которые понижают голос, потому что им не нравится язык или тому подобное? Я не вижу никаких недостатков.
Глен О


2

Mathematica, 42 37 байт

Спасибо @ LegionMammal978 за несколько предложений по сохранению кода. Первый параметр #- для входного текста, второй параметр #2- для количества пробелов на вкладке.

StringReplace[#,"\t"->" "~Table~{#2}]&

Кроме того , вы можете изменить , Table[" ",{#2}]чтобы " "~Table~{#2}сохранить байты. Почему вы StringJoinвставляете на него пустую строку?
LegionMammal978


1

JavaScript (ES6), 70

Используя строки шаблона, новая строка значима и считается

(s,n,r=n)=>[...s].map(c=>c<`
`?` `.repeat(r):(r=c<` `?n:1,c)).join``

Попробуйте запустить фрагмент ниже в Firefox.

F=(s,n,r=n)=>[...s].map(c=>c<`
`?` `.repeat(r):(r=c<` `?n:1,c)).join``

// TEST
out=x=>O.innerHTML+=x+'\n\n'

out('Input: "A\\n\\t\\tB\\tC\\nD" 4\nOutput:\n'+F('A\n\t\tB\tC\nD',4))

out('Input: "\\tA\\t\\tB" 4\nOutput:\n'+F('\tA\t\tB', 4))
<pre id=O></pre>


1
Ух одна даунвот! Может быть кто-то, кто не может читать или понимать «Тест в Firefox»?
edc65

Я подозреваю языковой уклон. Джулия и CJam также получили отрицательные голоса.
Деннис

1

CoffeeScript, 72 байта

(s,n)->s.replace(/^\t+/mg,(m)->" ".repeat(m.length*n)).replace /\t/g," "

(Попытка сыграть в гольф еще как минимум на 2 укуса, чтобы он побил решение ES6 ... Помощь оценена: D)

Использование:

f=(s,n)->s.replace(/^\t+/mg,(m)->" ".repeat(m.length*n)).replace /\t/g," "
str="""
My nice\tString
\tIndent <--
\t\tDouble
""" #\t is recognized as tab by CS
alert(f(str,4))

1

Сетчатка, 42 байта

Все вхождения .являются пробелами, все \tявляются буквенными табуляциями (1 байт) и <empty>представляют собой пустой файл. Это просто для удобства чтения. Я также не совсем уверен, что делаю цикл правильно, но я так думаю. Каждая строка должна быть размещена в своем собственном файле. Я добавил 1 байт для каждого дополнительного файла.

Предполагается, что ввод в унарном формате находится на отдельной строке в конце ввода.

(1*)$
_$1
m+`(?<!^|\t)\t
.
(`1$
<empty>
)`\t
\t.
\t|_
<empty>

объяснение

Я добавляю _перед входом Unary, чтобы разделить его во время замены, чтобы не удалять концевые из входной строки. Затем я заменяю все вкладки не в начале строки одним пробелом. Затем я зацикливаюсь, удаляя один 1и добавляя один пробел после каждой вкладки, пока у меня не закончится ввод. Наконец, я очищаю, удаляя вкладки и подчеркивания.


1

Python, 72 68 байт

Вкладки являются буквенными (1 байт), поэтому r'...'не нужны. К сожалению, Python требует «предопределенной ширины», поэтому я не могу использовать (?<!^|\t). Использует почти тот же метод, что и мое решение Retina.

import re
lambda s,n:re.sub('\t',' '*n,re.sub('(?<!^)(?<!\t)\t',' ',s))




0

Haskell , 75 байт

s#m|let('\t':r)#n=(' '<$[1..n])++r#n;(x:r)#n=x:r#(m^sum[1|x<' ']);e#_=e=s#m

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

Объяснение:

Внешняя #функция принимает строку sи число mи вызывает внутреннюю локально определенную #функцию с теми же аргументами. Это делается для отслеживания исходного mзначения, так как внутренняя #функция меняет число:

  • ('\t':r)#n=(' '<$[1..n])++r#nЕсли вы встретите вкладку, замените ее nпробелами и оставьте nбез изменений.
  • (x:r)#n=x:r#(m^sum[1|x<' '])Если xвстречается что- то, что не является вкладкой, оставьте это как есть, но установите nисходное число, mесли xэто новая строка, и в 1противном случае. Это делается путем m^sum[1|x<' ']: mберется в силу sum[1|x<' ']которого оценивается, 1когда xменьше, чем пробел (то есть, новая строка), так что мы получаем m^1 = m. В противном случае это 0и у нас m^0 = 1.

0

Java 11, 134 байта

n->s->{var r="";for(var p:s.split("\n")){for(;p.charAt(0)==9;p=p.substring(1))r+=" ".repeat(n);r+=p+"\n";}return r.replace('\t',' ');}

Попробуйте онлайн.
ПРИМЕЧАНИЕ: Java 11 еще не на TIO, поэтому " ".repeat(n)эмулируется, как repeat(" ",n)вместо этого (с тем же количеством байтов).

Объяснение:

n->s->{                 // Method with integer & String parameters and String return-type
  var r="";             //  Result-String, starting empty
  for(var p:s.split("\n")){
                        //  Loop over the rows (split by new-lines)
    for(;p.charAt(0)==9;//   Inner loop as long as the current row starts with a tab
       p=p.substring(1))//     After every iteration: remove the first character (tab)
      r+=" ".repeat(n); //    Append `n` amount of spaces to the result-String
    r+=p+"\n";}         //   Append the rest of the row with a newline to the result
  return r.replace('\t',' ');} 
                        //   Replace any remaining tabs with a space, and return the result
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.