Prenez CR et LF littéralement

22

Pour célébrer le bon vieux bloc - notes , nous allons traiter les retours chariot et les sauts de ligne comme ce qu'ils signifiaient à l'origine, plutôt que pour ce qu'ils sont (ab-) utilisés aujourd'hui.

Étant donné une chaîne constituée de flux ASCII imprimable plus ligne (␊, LF, esc \n, 0A hexagonale, 10 décembre) et le retour chariot (␍, CR, esc \r, hex 0D, 13 décembre), la cause essayer en ligne pour montrer comment les caractères imprimables serait positionné s'il était imprimé sur une imprimante qui prend littéralement ces deux caractères de contrôle:

  1. après un saut de ligne, continuez d'imprimer une ligne plus bas
  2. lors d'un retour chariot continuer l'impression à partir du bord gauche
  3. plusieurs retours chariot consécutifs se comportent comme un seul retour chariot

Du fait que les appareils modernes rencontrent des problèmes de surcharge , une exécution d'un ou plusieurs retours chariot ne se produira jamais, sauf au début de l'entrée, sans au moins un saut de ligne précédent et / ou suivant. Cependant, deux séries de retours chariot peuvent être séparées par un saut de ligne unique.

Toute quantité d'espace blanc de fin supplémentaire est acceptable, à la fois sur le côté droit de toutes les lignes et en dessous du texte entier, tant qu'au moins la quantité d'espace blanc donnée dans l'entrée est préservée.

Exemples (utilisation de \net \rpour le saut de ligne et le retour chariot)

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 (remarquez les espaces de fin)

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

exercice
ullamco laboris

nisi ut aliquip ex

ea commodo conséquat.


Adam
la source
28
Réponse suggérée: Bloc-notes, 179712 octets
Nit
3
@Nit: | le bloc-notes n'est pas TC
ASCII uniquement
2
Dommage que TIO n'utilise pas un terminal approprié, sinon un bon gagnant de shell serait stty -onlcr;cat.
Toby Speight
1
J'ai du mal à saisir les caractères de retour chariot dans le champ "entrée" de TIO. Ils semblent juste être engloutis (ou convertis en nouvelles lignes) lors du collage - est-ce que mon navigateur est en faute, ou est-ce TIO?
Toby Speight
2
@ Adám N'interdisez pas toutes les sorties que TIO. Limitez plutôt les programmes à l'utilisation de certains types de terminaux ou à la sortie de fichiers. Ou exigez que la sortie ait les espaces nécessaires précédant le texte sur les nouvelles lignes.
mbomb007

Réponses:

6

Fusain , 10 octets

UTFθ«ι≡ι⸿↑

Essayez-le en ligne! Le lien est vers la version détaillée du code. Explication:

UT

Désactivez le rembourrage droit.

Fθ«

Boucle sur l'entrée.

ι

Imprime le caractère actuel. Cela gère automatiquement \n(que Charcoal traite comme \vdans ce contexte) mais Charcoal se traduit \rpar \r\n, donc ...

≡ι⸿

... recherchez un \r...

... et si c'est le cas, remontez d'une ligne.

Neil
la source
Ne devriez-vous pas supprimer le ldrapeau de votre lien TIO?
Adám
@ Adám Qu'est-ce qui m'empêche de coller du charabia dans ma réponse, puis de créer un lien vers un programme sous-optimal?
Neil
Je vois. Peut-être que Charcoal devrait sortir le lien TIO vers stderr (Debug)?
Adám
@ Adám, je proposerai cela à @ ASCII uniquement.
Neil
@Neil fixe, je pense?
ASCII uniquement
5

Rubis , 24 17 octets

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

Essayez-le en ligne!

Il ne fonctionne pas sur TIO, mais fonctionne sur la console Linux.

GB
la source
Vous pouvez laisser tomber l'espace entre tr "je pense.
Kevin Cruijssen
Euh, je n'ai pas pensé à cette solution, cela peut juste fonctionner pour n'importe quelle langue pour changer tous les \ns \vlorsqu'ils sont exécutés dans une console Linux.
Adám
@ Adám Et certaines langues ne changent rien et fonctionnent dans une console DOS?
tsh
Je suis désolé d'avoir changé la spécification à mi-parcours, mais pour rendre le défi plus intéressant et moins sujet à des réponses triviales, j'ai maintenant besoin d'une sortie appropriée sur TIO .
Adám
5
Changer les spécifications: je ne pense pas que ce soit juste. mais je supprimerai ma réponse si je le dois.
GB
4

Java 10, 211 207 206 octets

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

Essayez-le en ligne.

Explication:

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

Ancienne réponse avant la modification du défi 151 148 octets :

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

Explication:

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

Ne fonctionne pas sur TIO, fonctionne sur l'invite de commandes Windows:

entrez la description de l'image ici

Kevin Cruijssen
la source
3

Python 2 , 150 128 122 104 103 octets

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

Essayez-le en ligne!


Enregistré:

  • -1 octet, merci à Lynn
TFeld
la source
Il semble l,n,i=[l,l+c,l+' '*i*n+c,n,1,0,0,i,i+1]['\r\n'.find(c)%3::3]à peine plus court.
Lynn
3

C (gcc) , 100 94 octets

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

Suppose un codage ASCII ( '\r'==13, '\n'==10); ajuster pour convenir à d'autres systèmes.

Essayez-le en ligne! (nécessite Javascript)

Version lisible

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

cest la position actuelle de la colonne; dest le nombre d'espaces qui doivent être insérés avant un caractère imprimable. Les deux sont supposés être nuls à l'entrée de la fonction.

Programme de test

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
la source
chars sont juste ints petits , ils devraient être interchangeables (en théorie). Peut gcc- être fera un casting implicite
Stan Strum
91 octets .
Jonathan Frech
Soit dit en passant, je ne pense pas que selon notre consensus, vous êtes autorisé à réinitialiser vos variables globales c,d. Votre fonction devrait - sans autre code de nettoyage - pouvoir s'exécuter plusieurs fois. Vous devrez donc probablement ajouter un c=d=0.
Jonathan Frech
Pour votre intérêt, le meta post pertinent .
Jonathan Frech
C'est maintenant une fonction réutilisable.
Toby Speight
2

Python 3 , 101 94 octets

Basé sur la réponse de 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

Essayez-le en ligne!


Non golfé

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
la source
2

Nettoyer , 92 91 octets

-1 merci à Laikoni!

Remarque: \ in \rest omis de bytecount car Linux CG gère littéral \ret \ns.
Remarque: Windows CG requiert \net doit \rêtre échappé, donc +3 s'il doit s'exécuter sur Windows.

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

?0

Essayez-le en ligne!

Une application partielle de ? :: Int [Char] -> [Char]avec 0 comme premier argument initial. Cela descend à travers chaque caractère en gardant une trace du nombre de personnes traversées, le décompte se réinitialise lorsqu'il rencontre un retour chariot et lorsqu'il rencontre une nouvelle ligne, il ajoute des espaces égaux au nombre de caractères traversés à ce point.

Οurous
la source
1
Je pense que c'est ?_[]=[]possible ?_ e=e.
Laikoni
@Laikoni Vous avez raison. Je jure que j'ai raté exactement la même chose une douzaine de fois maintenant.
Οurous
1

Haskell , 93 87 octets

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

Essayez-le en ligne!


Solution assez simple. # est une fonction d'infixe qui crée récursivement la sortie un caractère à la fois tout en conservant un compteur de position de caractère (n) et un indicateur pour quand ajouter des espaces après une nouvelle ligne (x).

aoemica
la source
1
Vous pouvez définir une fonction infixe à la place de c, utiliser à la l$rplace de c 0 0ret c _ _ e=e(ou plutôt (_#_)e=e).
Laikoni
Tous ensemble 87 octets: essayez-le en ligne!
Laikoni
@Laikoni Merci, je ne savais pas que vous pouviez utiliser cette astuce d'infixe avec autant de paramètres.
aoemica