Nehmen Sie CR und LF wörtlich

22

Zur Feier des guten alten Notizblocks werden wir Wagenrückläufe und Zeilenvorschübe als das behandeln, was sie ursprünglich bedeuteten, und nicht als das, wofür sie heute (ab-) verwendet werden.

Einen String gegeben von druckbaren ASCII und Zeilenvorschübe aus (␊; LF; esc \n; hex 0A, 10. Dezember) und Wagenrücklauf (␍; CR; esc \r; hex 0D, 13. Dezember), Ursache Online ausprobieren , wie die druckbare Zeichen zu zeigen , würde positioniert, wenn auf einem Drucker gedruckt würde, der diese beiden Steuerzeichen wörtlich nimmt:

  1. Drucken Sie nach einem Zeilenvorschub eine Zeile weiter nach unten
  2. Bei einem Wagenrücklauf fahren Sie mit dem Drucken am linken Rand fort
  3. Mehrere aufeinanderfolgende Wagenrückläufe verhalten sich wie ein einzelner Wagenrücklauf

Aufgrund moderner Geräte, die Probleme mit dem Überschlagen haben , wird ein Durchlauf von einem oder mehreren Wagenrückläufen, mit Ausnahme von zu Beginn der Eingabe, niemals ohne mindestens einen vorhergehenden und / oder folgenden Zeilenvorschub stattfinden. Zwei Zeilenumbrüche können jedoch durch einen einzelnen Zeilenvorschub getrennt werden.

Jeder zusätzliche Leerraum am Ende der Zeile und unterhalb des gesamten Texts ist zulässig, sofern mindestens der in der Eingabe angegebene Leerraum beibehalten wird.

Beispiele (mit \nund \rfür Zeilenvorschub und Wagenrücklauf)

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 (Beachten Sie die nachstehenden Leerzeichen)

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

Übung
ullamco laboris

nisi ut aliquip ex

ea commodo consequat.


Adam
quelle
28
Vorgeschlagene Antwort: Notizblock, 179712 Bytes
Nit
3
@Nit: | Notizblock ist nicht TC
ASCII
2
Schade, dass TIO kein richtiges Terminal benutzt, sonst wäre ein netter Shell-Gewinner stty -onlcr;cat.
Toby Speight
1
Ich habe Probleme, die Wagenrücklaufzeichen in das "Eingabe" -Feld von TIO einzugeben. Sie scheinen beim Einfügen nur verschluckt (oder in Zeilenumbrüche umgewandelt) zu werden - ist das mein Browser oder ist es TIO?
Toby Speight
2
@Adám Nicht alle Ausgänge als TIO verbieten. Beschränken Sie Programme stattdessen auf die Verwendung bestimmter Terminaltypen oder auf die Dateiausgabe. Oder fordern Sie, dass die Ausgabe in neuen Zeilen die erforderlichen Leerzeichen vor dem Text enthält.
mbomb007

Antworten:

6

Kohle , 10 Bytes

UTFθ«ι≡ι⸿↑

Probieren Sie es online! Link ist eine ausführliche Version des Codes. Erläuterung:

UT

Deaktivieren Sie die rechte Polsterung.

Fθ«

Schleife über den Eingang.

ι

Druckt das aktuelle Zeichen. Dies behandelt automatisch \n(was Charcoal wie \vin diesem Kontext behandelt), aber Charcoal übersetzt \rin \r\n, also ...

≡ι⸿

... nach einem \r... suchen

... und wenn ja, dann gehe eine Zeile zurück.

Neil
quelle
Sollten Sie die lFlagge nicht von Ihrem TIO-Link entfernen ?
Adám
@ Adám Was hindert mich daran, irgendeinen Kauderwelsch in meine Antwort einzufügen und dann auf ein suboptimales Programm zu verlinken?
Neil
Aha. Vielleicht sollte Charcoal den TIO-Link an stderr (Debug) ausgeben?
Adám
@ Adám Das schlage ich nur bei @ ASCII vor.
Neil
@Neil behoben, denke ich?
Nur ASCII
5

Ruby , 24 17 Bytes

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

Probieren Sie es online!

Es funktioniert nicht mit TIO, aber mit der Linux-Konsole.

GB
quelle
Sie können den Raum zwischen fallen lassen, tr "denke ich.
Kevin Cruijssen
Äh, ich habe nicht an diese Lösung gedacht, sie funktioniert möglicherweise nur für jede Sprache, in die alle \ns geändert werden, \vwenn sie in einer Linux-Konsole ausgeführt werden.
Adám
@ Adám Wie sieht es mit einigen Sprachen aus, die nichts ändern und in einer DOS-Konsole funktionieren?
9.
Es tut mir leid, dass ich die Spezifikation mitten in der Herausforderung geändert habe, aber um die Herausforderung interessanter und weniger abhängig von trivialen Antworten zu machen, benötige ich jetzt eine ordnungsgemäße Ausgabe auf TIO .
Adám
5
Änderung der Spezifikation: Ich denke nicht, dass es fair ist. Aber ich werde meine Antwort löschen, wenn ich muss.
GB
4

Java 10, 211 207 206 Bytes

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

Probieren Sie es online aus.

Erläuterung:

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

Alte Antwort vor der Challenge wurde geändert 151 148 Bytes :

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

Erläuterung:

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

Funktioniert nicht mit TIO, funktioniert mit Windows-Eingabeaufforderung:

Bildbeschreibung hier eingeben

Kevin Cruijssen
quelle
3

Python 2 , 150 128 122 104 103 Bytes

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

Probieren Sie es online!


Gerettet:

  • -1 Byte, danke an Lynn
TFeld
quelle
Es scheint l,n,i=[l,l+c,l+' '*i*n+c,n,1,0,0,i,i+1]['\r\n'.find(c)%3::3]nur knapp kürzer zu sein.
Lynn
3

C (GCC) , 100 94 Bytes

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

Übernimmt die ASCII-Codierung ( '\r'==13, '\n'==10); an andere Systeme anpassen.

Probieren Sie es online! (erfordert Javascript)

Lesbare Version

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

cist die aktuelle Spaltenposition; dist die Anzahl der Leerzeichen, die vor einem druckbaren Zeichen eingefügt werden müssen. Beide werden beim Eintritt in die Funktion als Null angenommen.

Testprogramm

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
quelle
chars sind nur kleine ints, sie sollten (theoretisch) austauschbar sein. Vielleicht gccwird eine implizite Besetzung
Stan Strum
91 Bytes .
Jonathan Frech
Ich glaube übrigens nicht, dass Sie nach unserem Konsens Ihre globalen Variablen zurücksetzen dürfen c,d. Ihre Funktion sollte - ohne anderen Bereinigungscode - mehrere Male ausgeführt werden können. Daher müssen Sie höchstwahrscheinlich eine hinzufügen c=d=0.
Jonathan Frech
Für Ihr Interesse die entsprechende Metapost .
Jonathan Frech
Es ist jetzt eine wiederverwendbare Funktion.
Toby Speight
2

Python 3 , 101 94 Bytes

Basierend auf der Antwort von 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

Probieren Sie es online!


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)
ovs
quelle
2

Sauber , 92 91 Bytes

-1 Danke an Laikoni!

Hinweis: \ in \rwird von bytecount weggelassen, da Linux CG mit Literalen \rund \ns umgeht .
Hinweis: Windows CG erfordert \nund \rmuss maskiert werden, also +3, wenn es unter Windows ausgeführt werden muss.

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

?0

Probieren Sie es online!

Eine teilweise Anwendung von ? :: Int [Char] -> [Char]mit 0 als erstes Argument. Dabei wird für jedes Zeichen nachverfolgt, wie viele Zeichen durchlaufen wurden. Der Zähler wird zurückgesetzt, wenn ein Zeilenumbruch auftritt, und wenn eine neue Zeile angezeigt wird, werden Leerzeichen hinzugefügt, die der Anzahl der an diesem Punkt durchlaufenden Zeichen entsprechen.

Οurous
quelle
1
Ich denke ?_[]=[]kann sein ?_ e=e.
Laikoni
@ Laikoni Du hast recht. Ich schwöre, ich habe genau dasselbe schon ein Dutzend Mal verpasst.
Οurous
1

Haskell , 93 87 Bytes

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

Probieren Sie es online!


Ziemlich einfache Lösung. # ist eine Infix-Funktion, die rekursiv die Ausgabe eines Zeichens nach dem anderen erstellt, während ein Zeichenpositionszähler (n) und ein Flag für das Hinzufügen von Leerzeichen nach einer neuen Zeile (x) beibehalten wird.

Aoemica
quelle
1
Sie können anstelle von c, l$ranstelle von c 0 0rund c _ _ e=e(oder vielmehr (_#_)e=e) eine Infix-Funktion definieren .
Laikoni
Insgesamt 87 Bytes: Probieren Sie es online!
Laikoni
@Laikoni Danke, ich wusste nicht, dass Sie diesen Infix-Trick mit so vielen Parametern verwenden können.
aoemica