Tome CR e LF literalmente

22

Como uma celebração do bom e velho bloco de notas , trataremos retornos de carro e feeds de linha como o que eles originalmente queriam dizer, e não como eles são usados ​​hoje.

Dada uma sequência que consiste em ASCII imprimível mais alimentações de linha (␊; LF; esc \n; hex 0A; dec 10) e retornos de carro (␍; CR; esc \r; hex 0D; dec 13), faça com que o Try It Online mostre como os caracteres imprimíveis seria posicionado se impresso em uma impressora que leva esses dois caracteres de controle literalmente:

  1. após uma alimentação de linha, continue imprimindo uma linha mais abaixo
  2. em um retorno de carro, continue imprimindo pela borda esquerda
  3. vários retornos de carro consecutivos se comportam como um único retorno de carro

Devido aos dispositivos modernos terem problemas com o impacto excessivo , uma execução de um ou mais retornos de carro, exceto no início da entrada, nunca ocorrerá sem pelo menos um avanço de linha anterior e / ou seguinte. No entanto, duas execuções de retorno de carro podem ser separadas por um único avanço de linha.

Qualquer quantidade de espaço em branco à direita adicional é aceitável, tanto no lado direito de todas as linhas quanto abaixo do texto inteiro, desde que pelo menos a quantidade de espaço em branco fornecida na entrada seja preservada.

Exemplos (usando \ne \rpara avanço de linha e 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 os espaços à direita)

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

exercício
ullamco laboris

nisi ut aliquip ex

e o consequodo.


Adão
fonte
28
Resposta sugerida: Bloco de notas, 179712 bytes
Nit
3
@Nit: | o bloco de notas não é TC
somente ASCII
2
Pena que o TIO não use um terminal adequado, caso contrário, seria um bom vencedor stty -onlcr;cat.
Toby Speight
1
Estou tendo problemas para inserir os caracteres de retorno de carro no campo "entrada" do TIO. Eles parecem engolidos (ou convertidos em novas linhas) ao colar - é o meu navegador que está com defeito ou é o TIO?
Toby Speight
2
@ Adám Não proíba todas as saídas além do TIO. Em vez disso, restrinja os programas ao uso de certos tipos de terminal ou à saída de arquivos. Ou exija que a saída tenha os espaços necessários que precedem o texto em novas linhas.
Mbomb007

Respostas:

6

Carvão , 10 bytes

UTFθ«ι≡ι⸿↑

Experimente online! Link é a versão detalhada do código. Explicação:

UT

Desative o preenchimento direito.

Fθ«

Loop sobre a entrada.

ι

Imprimir o caractere atual. Ele lida automaticamente \n(que o Charcoal trata como \vneste contexto), mas o Charcoal se traduz \rem \r\n, então ...

≡ι⸿

... verifique se há \r...

... e se sim, volte para uma linha.

Neil
fonte
Você não deve remover a lbandeira do seu link do TIO?
Adám
@ Adám O que me impede de colar qualquer bobagem na minha resposta e depois vincular a um programa abaixo do ideal?
Neil
Entendo. Talvez Charcoal deva enviar o link TIO para stderr (Debug)?
Adám
@ Adám, sugiro que apenas @ ASCII.
Neil
@ Neil corrigido, eu acho?
somente ASCII
5

Ruby , 24 17 bytes

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

Experimente online!

Ele não funciona no TIO, mas funciona no console do Linux.

GB
fonte
Você pode deixar o espaço entre tr "eu acho.
Kevin Cruijssen
Uh, eu não acho que desta solução, pode ser apenas obra para qualquer idioma para alterar todas as \ns em \vquando executado em um console Linux.
Adám
@ Adám E alguns idiomas não mudam nada e funcionam em um console do DOS?
tsh
Sinto muito por alterar o desafio no meio da especificação, mas para tornar o desafio mais interessante e menos sujeito a respostas triviais, agora exijo uma saída adequada no TIO .
Adám
5
Mudando as especificações: não acho justo. mas vou excluir minha resposta se for necessário.
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);}

Experimente online.

Explicação:

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

Resposta antiga antes da alteração do desafio 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;}

Explicação:

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

Não funciona no TIO, funciona no prompt de comando do Windows:

insira a descrição da imagem aqui

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

Experimente online!


Salvou:

  • -1 byte, graças a Lynn
TFeld
fonte
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]é apenas um pouco mais curto.
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);}

Assume a codificação ASCII ( '\r'==13, '\n'==10); ajuste para se adequar a outros sistemas.

Experimente online! (requer Javascript)

Versão legível

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é a posição atual da coluna; dé o número de espaços que devem ser inseridos antes de um caractere imprimível. Ambos são assumidos como zero na entrada para a função.

Programa de teste

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
fonte
chars são apenas ints pequenos , eles devem ser intercambiáveis ​​(em teoria). Talvez gccvai fazer uma conversão implícita
Stan Strum
91 bytes .
Jonathan Frech
A propósito, não acho que, de acordo com nosso consenso, você possa redefinir suas variáveis ​​globais c,d. Sua função deve - sem outro código de limpeza - poder executar várias vezes. Portanto, você provavelmente precisará adicionar a c=d=0.
Jonathan Frech
Para seu interesse, a meta post relevante .
Jonathan Frech
Agora é uma função reutilizável.
Toby Speight
2

Python 3 , 101 94 bytes

Com base na resposta do 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

Experimente 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
fonte
2

Limpo , 92 91 bytes

-1 graças a Laikoni!

Nota: \ in \ré omitido de bytecount, pois o CG do Linux manipula literal \re \ns.
Nota: O Windows CG requer \ne pode \rser escapado; portanto, +3 se precisar ser executado no Windows.

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

?0

Experimente online!

Uma aplicação parcial de ? :: Int [Char] -> [Char]com 0 como o primeiro argumento inicial. Isso desce através de cada caractere, mantendo o controle de quantos atravessados, a contagem é redefinida quando encontra um retorno de carro e, quando encontra uma nova linha, adiciona espaços iguais ao número de caracteres atravessados ​​nesse ponto.

Furioso
fonte
1
Eu acho que ?_[]=[]pode ser ?_ e=e.
Laikoni
@Laikoni Você está certo. Juro que já perdi exatamente a mesma coisa uma dúzia de vezes.
Ο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

Experimente online!


Solução bastante simples. # é uma função infix que cria recursivamente a saída, um caractere de cada vez, mantendo um contador de posição de caractere (n) e um sinalizador para quando adicionar espaços após uma nova linha (x).

aoemica
fonte
1
Você pode definir uma função infix em vez de c, usar em l$rvez de c 0 0re c _ _ e=e(ou melhor (_#_)e=e).
Laikoni
Todos juntos 87 bytes: Experimente online!
Laikoni
@Laikoni Obrigado, eu não sabia que você poderia usar esse truque infix com tantos parâmetros.
Aoemica