Возьмите CR и LF буквально


22

Как праздник старого доброго Блокнота , мы будем рассматривать возврат каретки и перевод строки как то, что они изначально имели в виду, а не как они (ab-) используются сегодня.

Дана строка , состоящая из печати ASCII плюс каналы линии (␊; LF; ESC \n; шестигранной 0A; разл 10) и возврат каретки (␍; CR; ESC \r; шестигранный 0D; реш 13), причина попробовать Интернет , чтобы показать , как печатные символы будет расположен, если напечатано на принтере, который принимает эти два управляющих символа буквально:

  1. после перевода строки продолжайте печатать еще одну строку вниз
  2. при возврате каретки продолжить печать с левого края
  3. несколько последовательных возвратов каретки ведут себя как одиночный возврат каретки

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

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

Примеры (использование \nи \rдля перевода строки и возврата каретки)

Lorem ipsum dolor sit amet,

Lorem ipsum dolor sit amet,

consectetur adipiscing\nelit, sed

consectetur adipiscing
                      elit, sed

do eiusmod\r\ntempor incididunt\n\n ut labore

do eiusmod
tempor incididunt

                  ut labore

et dolore\n\rmagna \r\r\naliqua. Ut (обратите внимание на пробелы)

et dolore
magna          
aliqua. Ut

\nenim ad minim veniam,\n\r quis nostrud

Enim Ad Minim Veniam,
     Quis Nostrud

\rexercitation\r\n\rullamco laboris\n\r\nnisi ut aliquip ex\n\n\rea commodo consequat.\n\n

упражнение
Ullamco Labouris

Ниси ут аликип экс

коммандос.



28
Предложенный ответ: Блокнот, 179712 байт
Nit

3
@Nit: | Блокнот не TC
ASCII-only

2
Позор, что TIO не использует надлежащий терминал, иначе будет хороший победитель оболочки stty -onlcr;cat.
Тоби Спейт

1
У меня проблемы с вводом символов возврата каретки в поле ввода TIO. Кажется, они просто проглатываются (или преобразуются в новые строки) при вставке - это мой браузер виноват или это TIO?
Тоби Спейт

2
@ Adám Не запрещайте все выходы, кроме TIO. Вместо этого ограничьте программы использованием определенных типов терминалов или вывода файлов. Или требовать, чтобы выходные данные имели необходимые пробелы, предшествующие тексту в новых строках.
mbomb007

Ответы:


6

Древесный уголь , 10 байт

UTFθ«ι≡ι⸿↑

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

UT

Отключить правый отступ.

Fθ«

Цикл по входу.

ι

Распечатать текущий символ. Это автоматически обрабатывает \n(что уголь рассматривает как \vв этом контексте), но уголь переводится \rв \r\n, так что ...

≡ι⸿

... проверить на \r...

... и если так, то вернитесь на линию вверх.


Разве вы не должны удалить lфлаг из вашей ссылки TIO?
Адам

@ Adám Что помешает мне вставить в мой ответ какую-нибудь тарабарщину, а затем добавить ссылку на неоптимальную программу?
Нил

Понимаю. Может быть, Charcoal должен вывести ссылку TIO на stderr (Debug)?
Адам

@ Adám Я предложу это только для ASCII.
Нил

@ Нил починил, я думаю?
Только для ASCII

5

Рубин , 24 17 байт

->s{s.tr $/,"\v"}

Попробуйте онлайн!

Он не работает на TIO, но работает на консоли Linux.


Вы можете отбросить промежуток между, tr "я думаю.
Кевин Круйссен

Э - э, я не думаю , что из этого решения, он может просто работать на любой язык , чтобы изменить все \nS в \vпри запуске в консоли Linux.
Адам

@ Adám Что насчет некоторых языков ничего не меняет и работает в консоли DOS?
1818 года

Я прошу прощения за изменение спецификации mid-challenge, но чтобы сделать задачу более интересной и менее подверженной тривиальным ответам, мне теперь требуется правильный вывод на TIO .
Адам

5
Изменение спецификации: я не думаю, что это справедливо. но я удалю свой ответ, если придется.
ГБ

4

Java 10, 211 207 206 байт

s->{var a=s.replace("\r\n","\n\r").split("(?<=\n)");int i=0,p=0,j;for(var x:a){for(j=x.charAt(0)<14?0:p;j-->0;x=" "+x);j=(a[i++]=x.replace("\r","")).length()-1;p=x.matches("\\s+")?p:j;}return"".join("",a);}

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

Объяснение:

s->{                      // Method with String as both parameter and return-type
  var a=s.replace("\r\n","\n\r")
                          //  Replace all "\r\n" with "\n\r"
        .split("(?<=\n)");//  Create String-array split by "\n",
                          //  without removing the trailing "\n" delimiter
  int i=0,                //  Index integer
      p=0,                //  Previous line-length, starting at 0
      j;                  //  Temp integer
  for(var x:a){           //  Loop over the String-array
    for(j=x.charAt(0)<14?0//   If the current line starts with either '\r' or '\n':
        0                 //    Prepend no spaces
       :                  //   Else:
        p;j-->0;x=" "+x); //    Prepand `p` amount of spaces for the current item
    j=(a[i++]=x.replace("\r",""))
                          //   Remove all "\r" from the current line
       .length()-1;       //   Set `j` to the current line-length (minus the trailing '\n')
    p=x.matches("\\s+")?  //   If the current line only contains '\r', '\n' and/or spaces:
       p                  //    Leave `p` unchanged
      :                   //   Else:
       j;}                //    Change `p` to this line-length minus 1
  return"".join("",a);}   //  Return the String-array joined together

Старый ответ перед вызовом был изменен на 151 148 байт :

s->{String a[]=s.replace("\r\n","\n\r").split("(?<=\n)"),r="";int p=0,i;for(var x:a){for(i=p;i-->0;r+=" ");i=x.length()-1;p=i<1?p:i;r+=x;}return r;}

Объяснение:

s->{                            // Method with String as both parameter and return-type
  String a[]=s.replace("\r\n","\n\r") 
                                //  Replace all "\r\n" with "\n\r"
              .split("(?<=\n)"),//  Create String-array split by "\n",
                                //  without removing the trailing "\n" delimiter
         r="";                  //  Result-String, starting empty
  int p=0,                      //  Previous line-length, starting at 0
      i;                        //  Index (and temp) integer
  for(var x:a){                 //  Loop over the String-array
    for(i=p;i-->0;r+=" ");      //   Append `p` amount of spaces to the result
    i=x.length()-1;p=i<1?p:j;   //   If the current line is not empty:
                                //    Replace `p` with the length of this current line
    r+=x;}                      //   Append the current item
  return r;}                    //  Return the result-String

Не работает в TIO, работает в командной строке Windows:

введите описание изображения здесь



3

Python 2 , 150 128 122 104 103 байта

def f(s):
 i=n=0;l=''
 for c in s:l,n,i=[l,l+c,l+' '*i*n+c,n,1,0,0,i,i+1]['\r\n'.find(c)%3::3]
 print l

Попробуйте онлайн!


Добавлено:

  • -1 байт, спасибо Линн

Кажется, l,n,i=[l,l+c,l+' '*i*n+c,n,1,0,0,i,i+1]['\r\n'.find(c)%3::3]чуть короче.
Линн

3

C (gcc) , 100 94 байта

b,c,d;f(char*s){for(b=13;b;b=*s++)b==13?c=d=0:b-10?d=!printf("%*c",++d,b),++c:putchar(b,d=c);}

Предполагает кодирование ASCII ( '\r'==13, '\n'==10); настроить в соответствии с другими системами.

Попробуйте онлайн! (требуется Javascript)

Читаемая версия

int c = 0;
int d = 0;

f(char*s)
{
    for (;*s;++s) {
        switch (*s) {
        case'\r':
            c = d = 0;
            break;
        case'\n':
            d = c;
            putchar(*s);
            break;
        default:
            printf("%*s%c", d, "", *s);
            d = 0;
            ++c;
        }
    }
}

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

Тестовая программа

int main(int argc, char **argv)
{
    char s[1024];
    if (argc <= 1)
        while (fgets(s, sizeof s, stdin))
               f(s);
    else
        for (int i = 1;  i < argc;  ++i)
            f(argv[i]);
}

chars просто маленькие int, они должны быть взаимозаменяемыми (в теории). Может быть, gccбудет делать неявное приведение
Стэн Струм


Кстати, я не думаю, что, по нашему мнению, вам разрешено сбрасывать глобальные переменные c,d. Ваша функция должна - без другого кода очистки - запускаться несколько раз. Таким образом, вам, скорее всего, нужно добавить c=d=0.
Джонатан Фрех


Теперь это функция многократного использования.
Тоби Спейт

2

Python 3 , 101 94 байта

На основании ответа TFeld .

def f(s):
 i=n=0
 for c in s:k='\r\n'.find(c);a=k&1;print(end=-k*' '*i*n+c*a);n=k>0;i=i*a-k//2

Попробуйте онлайн!


Ungolfed

def f(s):
  i=0  # position of the cursor
  n=0  # was the last character LF?
  for c in s:        # iterate over the input
    k='\r\n'.find(c) # k := 0 for CR, 1 for LF and -1 for every other character
    a=k&1            # as (-1)&1 == (1)&1 == 1, this is a := abs(k)
    print(end=-k*' '*i*n+c*a) # If c is a normal character (k == -1) and the last character was LF, 
                              # print leading spaces. If c is not CR, print it
    n=k>0            # n := True if c is LF, False otherwise
    i=i*a-k//2       # If c is either a newline or a printable character (a == 1),
                     # keep the cursor's position and increment it for a printable character ((-1)//2 == -1)

2

Чисто , 92 91 байт

-1 спасибо Лайкони!

Примечание: \ in \rисключен из bytecount, так как Linux CG обрабатывает литерал \rи \ns.
Примечание: Windows CG требует \nи \rдолжен быть экранирован, так что +3, если он должен работать в Windows.

import StdEnv
?n['\r':t]= ?0t
?n['
':t]=['
':spaces n]++ ?n t
?n[h:t]=[h: ?(n+1)t]
?_ e=e

?0

Попробуйте онлайн!

Частичное применение ? :: Int [Char] -> [Char]с 0 в качестве начального первого аргумента. Это происходит по каждому символу, отслеживая, сколько пройдено, счетчик сбрасывается, когда он встречает возврат каретки, и когда он встречает символ новой строки, он добавляет пробелы, равные количеству символов, пройденных в этой точке.


1
Я думаю, что ?_[]=[]может быть ?_ e=e.
Лайкони

@ Laikoni Ты прав. Клянусь, я пропустил одно и то же уже десятки раз.
Οurous

1

Haskell , 93 87 байтов

l=0#0
(n#x)(t:r)|t=='\n'=t:(n#1)r|t=='\r'=l$r|m<-n+1=(' '<$[1..n*x])++t:(m#0)r
(_#_)e=e

Попробуйте онлайн!


Довольно простое решение. # - это инфиксная функция, которая рекурсивно создает вывод по одному символу за раз, сохраняя при этом счетчик положения символа (n) и флаг, когда следует добавлять пробелы после новой строки (x).


1
Вы можете определить инфиксную функцию вместо c, использовать l$rвместо c 0 0rи c _ _ e=e(или скорее (_#_)e=e).
Лайкони

Все вместе 87 байтов: попробуйте онлайн!
Лайкони

@Laikoni Спасибо, я не понимал, что ты можешь использовать этот инфиксный трюк с таким количеством параметров.
Aoemica
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.