Meu Deus, está coberto de abas!


26

Usuários de recuo do espaço, uni-vos ! Devemos lutar contra todos os usuários da aba humilde !

Sua missão (se você optar por aceitá-la) é escrever um programa ou função que aceite dois argumentos:

  • Uma sequência: esta é a entrada.
  • Um número inteiro positivo: esse é o número de espaços por guia.

Você deve percorrer todas as linhas da string e substituir todas as guias usadas para indentação pelo número de espaços especificado e todas as guias não usadas para indentação (por exemplo, no meio de uma linha) por um espaço.

Observe que linhas como \t \tabccomportamento indefinido; eles foram inseridos pelos usuários da guia Evil para complicar seus programas.

De acordo com a sociedade Tabs Must Die, seu programa deve ser o mais curto possível para evitar a detecção pelos usuários maus da guia.

Exemplo

\t é usado para representar guias aqui.

String de entrada:

a
\t\tb\tc
d

Número de entrada:

4

Saída:

a
        b c
d

A linha do meio foi recuada por 8 espaços, 4 por guia (já que o número fornecido era 4).

String de entrada:

\ta\t\tb

Número de entrada:

4

Saída:

    a  b

NOTA: Essa não é uma duplicata do desafio de expansão da guia ; requer um formato de entrada muito diferente e requisitos ligeiramente diferentes.


1
Sim , desde que a pergunta não solicite explicitamente números decimais (o que não é verdade).
Martin Ender


1
Podemos assumir que a entrada contém apenas ASCII, guias e novas linhas imprimíveis?
Dennis

2
Caso de teste proposto: \ta\t\tb, 4(minha revisão anterior estava falhando aquele)
Dennis

2
Precisamos de uma resposta no espaço em branco.
Kaz Wolfe

Respostas:


7

CJam, 30 24 23 bytes

q{_9=NA=Seasi*' ?@?:N}/

Normalmente me recuso a postar código malicioso na internet ...

Este é um programa completo que lê a seqüência de caracteres de STDIN e o número como um argumento da linha de comando.

Experimente on-line no intérprete CJam .

Como funciona

q                        Read all input from STDIN.
 {                   }/  For each character C in the input:
  _9=                      Push 1 if C is a tab and 0 otherwise.
     NA=                   See below.
        Seasi*             Push a string of W spaces, where W is the integer from
                           the command-line arguments.
              '            Push a spaces character.
                ?          Select the string if NA= pushed a truthy value, the
                           single space otherwise.
                 @         Rotate C on top of the stack.
                  ?        Select the string of spaces or the single space if _9=
                           pushed 1, the character C otherwise.
                   :N      Save the result in N.

O que NA=faz:

  • Para o primeiro caractere, Nele conterá seu valor padrão, ou seja, a string "\n".

    Para todos os caracteres subsequentes, Nconterá o resultado da última iteração, ou seja, o último caractere da entrada, um caractere de espaço ou uma sequência de um ou mais espaços.

  • Se Nfor uma sequência, NA=selecione o elemento no índice 10 de N (contornando). O resultado será um espaço ou um caractere de avanço de linha. Ambos são verdadeiros.

    Se N for um caractere, NA=pressione 1 para avanço de linha e 0 caso contrário.

  • Por causa do acima, NA=empurrará um valor verdadeiro para o primeiro caractere, um caractere precedido por um avanço de linha ou um caractere precedido por uma sequência de espaços (recuo que já foi substituído).

    Em todos os outros casos (incluindo um tabulador que foi substituído por um caractere de espaço ), NA=enviará um valor falso.


6
Ainda bem que você está prestando um serviço à Internet removendo guias maliciosas. ;)
Alex A.

19

K5, 53 45 bytes

{{,/(b+a&~b:x*&\a:9=y){$[x;x#" ";y]}'y}[x]'y}

Em ação:

  {{,/(b+a&~b:x*&\a:9=y){$[x;x#" ";y]}'y}[x]'y}[4;(,"a";"\t\tb\tc";,"d")]
(,"a"
 "        b c"
 ,"d")

Eu só quero que o registro mostre que esta questão é moralmente repreensível.


11
-21346106841 para... this question is morally reprehensible.
TheNumberOne

3
Isso precisa acabar com a resposta mais votada, simplesmente para que as pessoas vejam a nota de rodapé.
Geobits 9/09/15

Você pode retornar o resultado em vez de imprimi-lo por 3 bytes.
Kirbyfan64sos

1
@ kirbyfan64sos: estou imprimindo o resultado para evitar a necessidade de juntar as linhas. Se eu puder aceitar e retornar o resultado como uma lista de strings, uma para cada linha, eu poderia salvar `0:e `" \ n "\`.
Johne

@ JohnE eu não coloquei uma regra dizendo que você não pode, então acho que você pode. :)
kirbyfan64sos

8

Perl, 23 bytes

Código de 22 bytes + linha de comando de 1 bytes

Espero que não seja muito atrevido assumir que a entrada numérica pode ser fornecida através do parâmetro -i! Certifique-se de substituir \ t no código abaixo pelo caractere de tabulação real.

s/\G\t/$"x$^I/ge;y/\t/ /

Exemplo de uso:

printf "a\n\t\tb\tc\nd" | perl -p entry.pl -i4

Ou por conveniência:

printf "a\n\t\tb\tc\nd" | perl -pe 's/\G\t/$"x$^I/ge;y/\t/ /' -i4

Explicação:

O uso do -pargumento executará o programa para todas as linhas da entrada e imprimirá o resultado no final.

No exemplo acima, a substituição do regex substitui \G\tpor " "x4(um espaço repetido quatro vezes). \Gé uma construção de expressão regular pouco conhecida que corresponde à posição da primeira correspondência se a primeira iteração ou da posição da correspondência anterior se não à primeira iteração, o que significa que substituirá apenas todas as guias no início da string e faça-o um por um. O y/\t/ /simplesmente substitui todas as guias restantes por espaços.


2

Julia, 69 59 bytes

f(s,n)=(r=replace)(r(s,r"^\t*"m,i->" "^endof(i)n),"\t"," ")

Ungolfed:

function f(s::String, n::Int)
    # Replace the leading indentation tabs
    r1 = replace(s, r"^\t*"m, i -> " "^endof(i)n)

    # Replace any remaining tabs between words
    r2 = replace(r1, r"\t", " ")

    # Return
    r2
end

Economizou 10 bytes e corrigiu um problema graças ao Glen O!


Existe algum benefício em substituir as guias de recuo principais separadamente? Parece-me que deve ser tratado diretamente pela parte "guias restantes". Além disso, sua parte "substituir as guias entre texto" corresponderá apenas a uma única guia, e se você tiver "hello\t\t1"?
Glen O

Se assumirmos que todo o recuo é feito com guias (sem "\t \t"situações), você pode fazer o seguinte f(s,n)=(r=replace)(r(s,r"^\t*"m,i->" "^endof(i)n),"\t"," "):, que usa uma função de substituição e captura todas as guias de recuo em uma ocorrência.
Glen O

@ GlenO Uau, isso é realmente genial. Muito obrigado!
Alex A.

Percebi que minha resposta foi reduzida. Há algo que eu fiz de errado? Ficaria feliz em resolver qualquer problema.
Alex A.

Não vejo nenhum problema. Talvez seja apenas um daqueles tipos vingativos que votam negativamente porque não gostam de um idioma ou coisas assim? Não vejo falhas.
Glen O


2

Mathematica, 42 37 bytes

Obrigado a @ LegionMammal978 por várias sugestões de economia de código. O primeiro parâmetro #é para o texto de entrada, o segundo parâmetro #2, para o número de espaços por guia.

StringReplace[#,"\t"->" "~Table~{#2}]&

Além disso, você pode mudar Table[" ",{#2}]para " "~Table~{#2}salvar um byte. Por que você está StringJoininserindo a corda vazia?
LegionMammal978

1

Ruby 49 bytes

def r s,t;s.gsub! /^\t/,' '*t;s.gsub!"\t",' ';end

2
Isso não funciona se houver duas guias no início de uma linha.
Não que Charles,

1

JavaScript (ES6), 70

Usando cadeias de modelo, a nova linha é significativa e contada

(s,n,r=n)=>[...s].map(c=>c<`
`?` `.repeat(r):(r=c<` `?n:1,c)).join``

Teste a execução do snippet abaixo no Firefox.

F=(s,n,r=n)=>[...s].map(c=>c<`
`?` `.repeat(r):(r=c<` `?n:1,c)).join``

// TEST
out=x=>O.innerHTML+=x+'\n\n'

out('Input: "A\\n\\t\\tB\\tC\\nD" 4\nOutput:\n'+F('A\n\t\tB\tC\nD',4))

out('Input: "\\tA\\t\\tB" 4\nOutput:\n'+F('\tA\t\tB', 4))
<pre id=O></pre>


1
Uau, um voto negativo! Poderia ser alguém que não consegue ler ou entender 'Teste no Firefox'?
edc65

Suspeito de viés de linguagem. Julia e CJam também receberam votos negativos.
Dennis

1

CoffeeScript, 72 bytes

(s,n)->s.replace(/^\t+/mg,(m)->" ".repeat(m.length*n)).replace /\t/g," "

(Tentando jogar golfe pelo menos mais duas mordidas, para vencer a solução ES6 ... Ajuda apreciada: D)

Uso:

f=(s,n)->s.replace(/^\t+/mg,(m)->" ".repeat(m.length*n)).replace /\t/g," "
str="""
My nice\tString
\tIndent <--
\t\tDouble
""" #\t is recognized as tab by CS
alert(f(str,4))

1

Retina, 42 bytes

Todas as ocorrências de .são espaços, todas \tsão guias literais (1 byte) e <empty>representam um arquivo em branco. É apenas para facilitar a leitura. Também não tenho certeza absoluta de que estou fazendo o loop corretamente, mas acho que sim. Cada linha deve ser colocada em seu próprio arquivo. Adicionei 1 byte para cada arquivo adicional.

A entrada é assumida como Unária em sua própria linha no final da entrada.

(1*)$
_$1
m+`(?<!^|\t)\t
.
(`1$
<empty>
)`\t
\t.
\t|_
<empty>

Explicação

Eu adiciono uma _entrada antes da Unary para delimitá-la durante a substituição, para que eu não remova nenhuma da seqüência de entrada. Em seguida, substituo todas as guias que não estão no início de uma linha por um único espaço. Em seguida, faço um loop, removendo um único 1e adicionando um único espaço após cada guia, até ficar sem entrada. Finalmente, eu limpo, removendo as guias e o sublinhado.


1

Python, 72 68 bytes

Guias são guias literais (1 byte), portanto, r'...'não é necessário. Infelizmente, o Python requer look-behinds / look-aheads de "largura fixa", então não posso usá-lo (?<!^|\t). Usa praticamente o mesmo método da minha solução Retina.

import re
lambda s,n:re.sub('\t',' '*n,re.sub('(?<!^)(?<!\t)\t',' ',s))




0

Haskell , 75 bytes

s#m|let('\t':r)#n=(' '<$[1..n])++r#n;(x:r)#n=x:r#(m^sum[1|x<' ']);e#_=e=s#m

Experimente online! Isso pressupõe que a entrada contenha apenas caracteres imprimíveis, além de guias e novas linhas, conforme permitido pelo OP nos comentários.

Explicação:

A #função externa pega uma string se um número me chama a #função interna definida localmente com os mesmos argumentos. Isso é feito para acompanhar o mvalor original , pois a #função interna altera o número:

  • ('\t':r)#n=(' '<$[1..n])++r#nSe você encontrar uma guia, substitua-a por nespaços e deixe ninalterada.
  • (x:r)#n=x:r#(m^sum[1|x<' '])Se alguma parte xque não for uma guia for encontrada, mantenha-a como está, mas defina no número original, mse xfor uma nova linha, e 1caso contrário. Isso é feito por m^sum[1|x<' ']: mé levado ao poder de sum[1|x<' ']avaliar 1quando xé menor que um espaço (ou seja, uma nova linha), então obtemos m^1 = m. Caso contrário, é 0e nós temos m^0 = 1.

0

Java 11, 134 bytes

n->s->{var r="";for(var p:s.split("\n")){for(;p.charAt(0)==9;p=p.substring(1))r+=" ".repeat(n);r+=p+"\n";}return r.replace('\t',' ');}

Experimente online.
NOTA: O Java 11 ainda não está no TIO, portanto " ".repeat(n)foi emulado repeat(" ",n)(com a mesma contagem de bytes).

Explicação:

n->s->{                 // Method with integer & String parameters and String return-type
  var r="";             //  Result-String, starting empty
  for(var p:s.split("\n")){
                        //  Loop over the rows (split by new-lines)
    for(;p.charAt(0)==9;//   Inner loop as long as the current row starts with a tab
       p=p.substring(1))//     After every iteration: remove the first character (tab)
      r+=" ".repeat(n); //    Append `n` amount of spaces to the result-String
    r+=p+"\n";}         //   Append the rest of the row with a newline to the result
  return r.replace('\t',' ');} 
                        //   Replace any remaining tabs with a space, and return the result
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.