Боже, це вкладено в вкладки!


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=буде висунуто значення truthy для першого символу, символу, якому передує передача рядків, або символу, якому передує рядок пробілів (відступ, який вже замінено).

    У всіх інших випадках (включаючи табулятор, який був замінений символом пробілу ), NA=буде висуватися помилкове значення.


6
Добре, що ви робите послугу в Інтернеті, видаляючи шкідливі вкладки. ;)
Олексій А.

19

K5, 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
Це потрібно, щоб закінчити найкращу відповідь, просто щоб люди побачили виноску.
Геобіт

Ви можете повернути результат замість того, щоб роздрукувати його на 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"," ")

Безголівки:

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 байт та виправлено проблему завдяки Глен О!


Чи є користь замінити провідні вкладки відступів окремо? Мені здається, що з ним слід обробляти безпосередньо частину "вкладки, що залишилися". Крім того, ваша частина "замінити вкладки між текстом" відповідатиме лише одній вкладці, що робити, якщо у вас є "hello\t\t1"?
Глен О

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

@GlenO Вау, це справді геніально. Дуже дякую!
Олексій А.

Я помітив, що моя відповідь була знижена. Чи є щось, що я зробив неправильно? Я буду радий вирішити будь-які проблеми.
Алекс А.

Я не бачу жодної проблеми. Можливо, це просто один із тих мстивих типів, які зводяться за те, що вони не люблять мову, або подібні речі? Я не бачу жодних недоліків.
Glen O


2

Математика, 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

Пітон, 72 68 байт

Вкладки - це буквальні вкладки (1 байт), тому r'...'вони не потрібні. На жаль, Python вимагає "фіксованої ширини" оглядових панелей / окулярів, тому я не можу використовувати (?<!^|\t). Використовує майже той самий метод, що і мій розчин сітківки.

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

Спробуйте в Інтернеті! Це передбачає, що вхід містить лише символи для друку, а також вкладки та нові рядки, як це дозволено ОП у коментарях.

Пояснення:

Зовнішня #функція приймає рядок 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.