Weź CR i LF dosłownie

22

Jako święto starego, dobrego Notatnika , będziemy traktować zwroty karetki i wiadomości liniowe jako to, co pierwotnie mieli na myśli, a nie to, z czego są (ab-) obecnie używane.

Biorąc pod uwagę ciąg znaków składający się z drukowalnych znaków ASCII oraz linii (␊; LF; esc \n; hex 0A; dec 10) i zwrotów karetki (␍; CR; esc \r; hex 0D; dec 13), spraw, aby Try It Online pokazał, w jaki sposób znaki do wydruku zostałby umieszczony, gdyby wydrukowano go na drukarce, która dosłownie przyjmuje te dwa znaki kontrolne:

  1. po przesunięciu linii kontynuuj drukowanie o jedną linię dalej w dół
  2. po powrocie karetki kontynuuj drukowanie od lewej krawędzi
  3. wiele kolejnych zwrotów karetki zachowuje się jak pojedynczy powrót karetki

Ze względu na to, że nowoczesne urządzenia mają problemy z przesuwaniem , jeden lub więcej powrotów karetki, z wyjątkiem początku wejścia, nigdy nie nastąpi bez przynajmniej jednego poprzedzającego i / lub następującego po linii przesuwu. Jednak dwa przebiegi powrotów karetki mogą być oddzielone pojedynczym wierszem.

Dopuszczalna jest dowolna ilość dodatkowej białej spacji, zarówno po prawej stronie dowolnych linii, jak i pod całym tekstem, o ile zachowana jest przynajmniej ilość białej spacji podana na wejściu.

Przykłady (używanie \ni \rdo podawania wiersza i powrotu karetki)

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 (zwróć uwagę na spacje końcowe)

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

ćwiczenia
ullamco laboris

nisi ut aliquip ex

ea commodo konsekwencji.


Adám
źródło
28
Sugerowana odpowiedź: Notatnik, 179712 bajtów
Nit
3
@Nit: | Notatnik nie jest TC
tylko ASCII
2
Szkoda, że ​​TIO nie używa odpowiedniego terminala, w przeciwnym razie byłby miły zwycięzca powłoki stty -onlcr;cat.
Toby Speight
1
Mam problem z wprowadzeniem znaków powrotu karetki w polu „wejściowym” TIO. Po prostu wydają się zostać połknięte (lub zamienione na nowe wiersze) podczas wklejania - czy to wina mojej przeglądarki, czy to TIO?
Toby Speight
2
@ Adám Nie zakazuj wszystkich wyjść niż TIO. Zamiast tego ogranicz programy do korzystania z określonych typów terminali lub do plików wyjściowych. Lub wymagaj, aby dane wyjściowe zawierały niezbędne spacje poprzedzające tekst w nowych wierszach.
mbomb007

Odpowiedzi:

6

Węgiel drzewny , 10 bajtów

UTFθ«ι≡ι⸿↑

Wypróbuj online! Link jest do pełnej wersji kodu. Wyjaśnienie:

UT

Wyłącz prawe wypełnienie.

Fθ«

Pętla nad wejściem.

ι

Wydrukuj bieżący znak. To automatycznie obsługuje \n(co węgiel traktuje jak \vw tym kontekście), ale węgiel przekłada się \rna \r\n, więc ...

≡ι⸿

... sprawdź, czy \r...

... a jeśli tak, to cofnij się o linię.

Neil
źródło
Czy nie powinieneś usunąć lflagi z linku TIO?
Adám,
@ Adám Co powstrzyma mnie przed wklejeniem bełkotu w moją odpowiedź, a następnie linkowaniem do suboptymalnego programu?
Neil,
Widzę. Może Charcoal powinien wysyłać link TIO do stderr (Debugowanie)?
Adám,
@ Adám Zasugeruję to tylko @ ASCII.
Neil,
@Neil naprawiony, tak myślę?
Tylko ASCII,
5

Ruby , 24 17 bajtów

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

Wypróbuj online!

Nie działa na TIO, ale działa na konsoli Linux.

GB
źródło
tr "Myślę, że możesz upuścić przestrzeń między .
Kevin Cruijssen
Uh, nie myślałem o tym rozwiązaniu, może po prostu działać dla dowolnego języka, aby zmienić wszystkie \ns, \vgdy jest uruchamiany w konsoli Linux.
Adám
@ Adám Co z niektórymi językami nic nie zmieniają i działa w konsoli DOS?
tsh
Przykro mi, że zmieniłem specyfikację średniego wyzwania, ale aby uczynić wyzwanie bardziej interesującym i mniej podatnym na trywialne odpowiedzi, potrzebuję teraz odpowiedniego wyjścia w TIO .
Adám
5
Zmieniamy specyfikację: nie sądzę, żeby to było sprawiedliwe. ale w razie potrzeby usunę odpowiedź.
GB
4

Java 10, 211 207 206 bajtów

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);}

Wypróbuj online.

Wyjaśnienie:

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

Stara odpowiedź przed wyzwaniem została zmieniona 151 148 bajtów :

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;}

Wyjaśnienie:

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

Nie działa w TIO, działa w wierszu polecenia systemu Windows:

wprowadź opis zdjęcia tutaj

Kevin Cruijssen
źródło
3

Python 2 , 150 128 122 104 103 bajtów

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

Wypróbuj online!


Zapisano:

  • -1 bajt, dzięki Lynn
TFeld
źródło
Wydaje się, że l,n,i=[l,l+c,l+' '*i*n+c,n,1,0,0,i,i+1]['\r\n'.find(c)%3::3]jest tylko nieco krótszy.
Lynn,
3

C (gcc) , 100 94 bajtów

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);}

Zakłada kodowanie ASCII ( '\r'==13, '\n'==10); dopasuj do innych systemów.

Wypróbuj online! (wymaga Javascript)

Wersja do odczytu

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;
        }
    }
}

cjest bieżącą pozycją kolumny; dto liczba spacji, które należy wstawić przed znakiem do wydrukowania. Przyjmuje się, że oba są zerowe przy wejściu do funkcji.

Program testowy

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]);
}
Toby Speight
źródło
charsą tylko małymi int, powinny być wymienne (teoretycznie). Może gcczrobi niejawną obsadę
Stan Strum
91 bajtów .
Jonathan Frech
Nawiasem mówiąc, nie sądzę, aby według naszego konsensusu można było resetować zmienne globalne c,d. Twoja funkcja powinna - bez innego kodu czyszczenia - być w stanie uruchomić się wiele razy. Dlatego najprawdopodobniej musisz dodać c=d=0.
Jonathan Frech,
Dla Twojego zainteresowania odpowiedni meta post .
Jonathan Frech
Teraz jest to funkcja wielokrotnego użytku.
Toby Speight
2

Python 3 , 101 94 bajtów

Na podstawie odpowiedzi 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

Wypróbuj online!


Nie golfił

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)
ovs
źródło
2

Czysty , 92 91 bajtów

-1 dzięki Laikoni!

Uwaga: \ in \rjest pomijane w bajtecount, ponieważ Linux CG obsługuje literały \ri \ns.
Uwaga: System Windows wymaga CG \ni \rbyć uciekł, więc +3 jeśli ma działać na systemie Windows.

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

?0

Wypróbuj online!

Częściowe zastosowanie ? :: Int [Char] -> [Char]z 0 jako początkowym pierwszym argumentem. Zstępuje ona przez każdy znak, śledząc liczbę przemierzonych, licznik resetuje się, gdy napotka powrót karetki, a gdy napotka nowy wiersz, dodaje spacje równe liczbie znaków przemierzonych w tym punkcie.

Obrzydliwe
źródło
1
Myślę, że ?_[]=[]może być ?_ e=e.
Laikoni
@Laikoni Masz rację. Przysięgam, że kilkakrotnie tęskniłem dokładnie za tym samym.
tragiczny
1

Haskell , 93 87 bajtów

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

Wypróbuj online!


Całkiem proste rozwiązanie. # to funkcja infiksowa, która rekurencyjnie tworzy dane wyjściowe jeden znak na raz, jednocześnie zachowując licznik pozycji znaku (n) i flagę określającą, kiedy dodać spacje po nowej linii (x).

Aoemica
źródło
1
Możesz zdefiniować funkcję infix zamiast c, użyj l$rzamiast c 0 0ri c _ _ e=e(a raczej (_#_)e=e).
Laikoni
Łącznie 87 bajtów: Wypróbuj online!
Laikoni
@Laikoni Dziękuję, nie zdawałem sobie sprawy, że można użyć tej sztuczki z tak wieloma parametrami.
aoemica,