Tome CR y LF literalmente

22

Como celebración del buen Bloc de notas antiguo , vamos a tratar los retornos de carro y los avances de línea como lo que originalmente significaban, en lugar de lo que se usan (ab-) para hoy.

Dada una cadena que consiste en avances de línea ASCII más imprimibles (␊; LF; esc \n; hex 0A; dec 10) y retornos de carro (␍; CR; esc \r; hex 0D; dec 13), haga que Try It Online muestre cómo los caracteres imprimibles se colocaría si se imprime en una impresora que toma esos dos caracteres de control literalmente:

  1. sobre un avance de línea, continúe imprimiendo una línea más abajo
  2. sobre un retorno de carro continúe imprimiendo desde el borde izquierdo
  3. múltiples retornos de carro consecutivos se comportan como un solo retorno de carro

Debido a que los dispositivos modernos tienen problemas con la sobrecarga , una ejecución de uno o más retornos de carro, excepto al comienzo de la entrada, nunca ocurrirá sin al menos un avance de línea anterior y / o siguiente. Sin embargo, dos carreras de retornos de carro pueden estar separadas por un solo avance de línea.

Cualquier cantidad de espacio en blanco adicional adicional es aceptable, tanto en el lado derecho de cualquier línea como debajo del texto completo, siempre que se mantenga al menos la cantidad de espacio en blanco dado en la entrada.

Ejemplos (uso \ny \rpara avance de línea y retorno de carro)

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 (observe los espacios finales)

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

ejercicio
ullamco laboris

nisi ut aliquip ex

ea commodo consequat.


Adán
fuente
28
Respuesta sugerida: Bloc de notas, 179712 bytes
Nit
3
@Nit: | el bloc de notas no es TC
solo ASCII
2
Es una pena que TIO no utilice un terminal adecuado, de lo contrario sería un buen ganador de shell stty -onlcr;cat.
Toby Speight
1
Tengo problemas para ingresar los caracteres de retorno de carro en el campo "entrada" de TIO. Simplemente parecen engullirse (o convertirse en nuevas líneas) al pegar: ¿es mi navegador el culpable o es TIO?
Toby Speight
2
@ Adám No prohíba todas las salidas que TIO. En su lugar, restrinja los programas al uso de ciertos tipos de terminales o al archivo de salida. O requiera que la salida tenga los espacios necesarios que preceden al texto en las nuevas líneas.
mbomb007

Respuestas:

6

Carbón de leña , 10 bytes

UTFθ«ι≡ι⸿↑

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

UT

Deshabilitar el relleno derecho.

Fθ«

Pase sobre la entrada.

ι

Imprime el personaje actual. Esto maneja automáticamente \n(que el carbón trata como \ven este contexto) pero el carbón se traduce \ren \r\n, así que ...

≡ι⸿

... busca un \r...

... y si es así, retroceda una línea.

Neil
fuente
¿No deberías eliminar la lbandera de tu enlace TIO?
Adám
@ Adám ¿Qué me impide pegar cualquier galimatías en mi respuesta y luego vincularme a un programa subóptimo?
Neil
Veo. ¿Quizás Charcoal debería enviar el enlace TIO a stderr (Debug)?
Adám
@ Adám, lo sugeriré solo a @ ASCII.
Neil
@Neil arreglado, creo?
Solo ASCII
5

Ruby , 24 17 bytes

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

Pruébalo en línea!

No funciona en TIO, pero funciona en la consola de Linux.

GB
fuente
Puedes dejar el espacio entre tr "creo.
Kevin Cruijssen
Uh, no pensé en esta solución, puede funcionar para que cualquier idioma cambie todos los \ns \vcuando se ejecuta en una consola Linux.
Adám
@ Adám ¿Qué pasa con algunos idiomas que no cambian nada y funciona en una consola de DOS?
tsh
Lamento cambiar la especificación a mitad del desafío, pero para hacer que el desafío sea más interesante y menos sujeto a respuestas triviales, ahora necesito una salida adecuada en TIO .
Adám
55
Cambiar la especificación: no creo que sea justo. pero eliminaré mi respuesta si es necesario.
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);}

Pruébalo en línea.

Explicación:

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

Respuesta anterior antes de que se cambiara el desafío 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;}

Explicación:

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

No funciona en TIO, funciona en el símbolo del sistema de Windows:

ingrese la descripción de la imagen aquí

Kevin Cruijssen
fuente
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

Pruébalo en línea!


Salvado:

  • -1 byte, gracias a Lynn
TFeld
fuente
Parece que l,n,i=[l,l+c,l+' '*i*n+c,n,1,0,0,i,i+1]['\r\n'.find(c)%3::3]es apenas más corto.
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);}

Asume la codificación ASCII ( '\r'==13, '\n'==10); ajustar para adaptarse a otros sistemas.

Pruébalo en línea! (requiere Javascript)

Versión legible

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

ces la posición actual de la columna; des el número de espacios que se deben insertar antes de un carácter imprimible. Se supone que ambos son cero al ingresar a la función.

Programa de prueba

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
fuente
chars son solo pequeños ints, deberían ser intercambiables (en teoría). Quizás gcchaga un reparto implícito
Stan Strum
91 bytes .
Jonathan Frech
Por cierto, no creo que, según nuestro consenso, se le permita restablecer sus variables globales c,d. Su función debería, sin otro código de limpieza, poder ejecutarse varias veces. Por lo tanto, lo más probable es que necesite agregar un c=d=0.
Jonathan Frech
Para su interés, la meta publicación relevante .
Jonathan Frech
Ahora es una función reutilizable.
Toby Speight
2

Python 3 , 101 94 bytes

Basado en la respuesta 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

Pruébalo en línea!


Sin 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
fuente
2

Limpio , 92 91 bytes

-1 gracias a Laikoni!

Nota: \ en \rse omite de bytecount ya que Linux CG maneja literal \ry \ns.
Nota: Windows CG requiere \ny \rdebe escaparse, por lo que +3 si tiene que ejecutarse en Windows.

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

?0

Pruébalo en línea!

Una aplicación parcial de ? :: Int [Char] -> [Char]con 0 como primer argumento inicial. Esto desciende a través de cada personaje haciendo un seguimiento de cuántos recorridos, el recuento se restablece cuando encuentra un retorno de carro y cuando encuentra una nueva línea, agrega espacios iguales al número de caracteres recorridos en ese punto.

Οurous
fuente
1
Creo que ?_[]=[]puede ser ?_ e=e.
Laikoni
@Laikoni Tienes razón. Juro que ya me he perdido exactamente esa misma cosa una docena de veces.
Precioso
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

Pruébalo en línea!


Solución bastante sencilla. # es una función infija que crea de forma recursiva la salida de un carácter a la vez mientras mantiene un contador de posición de caracteres (n) y marca cuándo agregar espacios después de una nueva línea (x).

aoemica
fuente
1
Puede definir una función infija en lugar de c, usar en l$rlugar de c 0 0ry c _ _ e=e(o más bien (_#_)e=e).
Laikoni
Todos juntos 87 bytes: ¡ Pruébelo en línea!
Laikoni
@Laikoni Gracias, no me di cuenta de que podrías usar ese truco infijo con tantos parámetros.
aoemica