Bontà, è coperto di schede!


26

Utenti di rientro dello spazio, unitevi ! Dobbiamo combattere contro tutti gli utenti modesti !

La tua missione (se scegli di accettarlo) è scrivere un programma o una funzione che contenga due argomenti:

  • Una stringa: questo è l'input.
  • Un numero intero positivo: questo è il numero di spazi per scheda.

È necessario passare attraverso ogni riga della stringa e sostituire ogni scheda utilizzata per il rientro con il numero dato di spazi e ogni scheda non utilizzata per il rientro (ad esempio nel mezzo di una riga) con uno spazio.

Si noti che linee come \t \tabc sono comportamento indefinito; sono stati inseriti dagli utenti della scheda male per complicare i tuoi programmi.

Secondo la Tabs Must Die Society, il tuo programma deve essere il più breve possibile per evitare il rilevamento da parte di utenti malvagi.

Esempio

\t è usato per rappresentare le schede qui.

Stringa di input:

a
\t\tb\tc
d

Numero di input:

4

Produzione:

a
        b c
d

La linea mediana è stata indentata da 8 spazi, 4 per scheda (dato che il numero dato era 4).

Stringa di input:

\ta\t\tb

Numero di input:

4

Produzione:

    a  b

NOTA: questo non è un duplicato della sfida di espansione delle schede ; richiede un formato di input molto diverso e requisiti leggermente diversi.


1
, purché la domanda non richieda esplicitamente numeri decimali (cosa che non fa).
Martin Ender,


1
Possiamo supporre che l'input contenga solo ASCII, tab e newline stampabili?
Dennis,

2
Banco di prova proposto: \ta\t\tb, 4(la mia precedente revisione stava venendo a mancare quella)
Dennis

2
Abbiamo bisogno di una risposta in Whitespace.
Kaz Wolfe,

Risposte:


7

CJam, 30 24 23 byte

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

Di solito mi rifiuto di pubblicare codice dannoso su Internet ...

Questo è un programma completo che legge la stringa da STDIN e il numero come argomento della riga di comando.

Provalo online nell'interprete CJam .

Come funziona

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.

Cosa NA=fa:

  • Per il primo carattere, Nconterrà il valore predefinito, ovvero la stringa"\n" .

    Per tutti i caratteri successivi, Nconterrà il risultato dell'ultima iterazione, ovvero l'ultimo carattere dell'input, un carattere spazio o una stringa di uno o più spazi.

  • Se Nè una stringa,NA= seleziona l'elemento sull'indice 10 di N (avvolgendo). Il risultato sarà uno spazio o un carattere di avanzamento riga. Entrambi sono veritieri.

    Se N è un carattere, NA=spinge 1 per un avanzamento riga e 0 altrimenti.

  • A causa di quanto sopra, NA=spingerà un valore di verità per il primo carattere, un carattere preceduto da un avanzamento di riga o un carattere preceduto da una stringa di spazi (rientro che è già stato sostituito).

    In tutti gli altri casi (incluso un tabulatore che è stato sostituito da un carattere spazio ), NA=verrà inviato un valore errato.


6
Per fortuna stai facendo un servizio a Internet rimuovendo le schede dannose. ;)
Alex A.

19

K5, 53 45 byte

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

In azione:

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

Voglio solo che la documentazione dimostri che questa domanda è moralmente riprovevole.


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

3
Questo deve finire con la risposta più votata, semplicemente così la gente vedrà la nota in calce.
Geobits,

È possibile restituire il risultato invece di stamparlo per 3 byte.
kirbyfan64sos,

1
@ kirbyfan64sos: sto stampando il risultato per evitare di dover unire le linee. Se posso accettare e restituire il risultato come un elenco di stringhe, una per ogni riga, potrei salvare `0:e `" \ n "\`.
Giovanni,

@JohnE Non ho messo una regola dicendo che non puoi, quindi immagino che tu possa. :)
kirbyfan64sos

8

Perl, 23 byte

Codice 22 byte + 1 byte riga comandi

Spero che non sia troppo sfacciato per supporre che l'input numerico possa essere dato tramite il parametro -i! Assicurarsi di sostituire \ t nel codice seguente con il carattere di tabulazione effettivo.

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

Esempio di utilizzo:

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

O per comodità:

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

Spiegazione:

L'uso -pdell'argomento eseguirà il programma per ogni riga nell'input, quindi stamperà il risultato alla fine.

Nell'esempio sopra, la sostituzione regex sostituisce \G\t con " "x4(uno spazio ripetuto quattro volte). \Gè un costrutto regex poco noto che corrisponde alla posizione della prima corrispondenza se la prima iterazione o dalla posizione della corrispondenza precedente se non alla prima iterazione, il che significa che sostituirà solo tutte le schede all'inizio della stringa e fallo uno per uno. La y/\t/ /sostituisce semplicemente tutte le schede rimanenti con spazi.


2

Julia, 69 59 byte

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

Salvato 10 byte e risolto un problema grazie a Glen O!


Ci sono dei vantaggi nel sostituire le schede di rientro principali separatamente? Mi sembra che dovrebbe essere gestito direttamente dalla parte "schede rimanenti". Inoltre, la parte "Sostituisci le schede tra il testo" corrisponderà solo a una singola scheda, cosa succede se hai "hello\t\t1"?
Glen O,

Se assumiamo che tutte le rientranze vengano eseguite con le schede (nessuna "\t \t"situazione), puoi farlo:, f(s,n)=(r=replace)(r(s,r"^\t*"m,i->" "^endof(i)n),"\t"," ")che utilizza una funzione di sostituzione e catturerà tutte le schede di indentazione in un solo colpo.
Glen O

@GlenO Wow, è davvero geniale. Grazie mille!
Alex A.

Ho notato che la mia risposta è stata sottovalutata. C'è qualcosa che ho fatto di sbagliato? Sarei felice di affrontare qualsiasi problema.
Alex A.

Non vedo alcun problema. Forse è solo uno di quei tipi vendicativi che votano perché non gli piace una lingua o cose del genere? Non riesco a vedere alcun difetto.
Glen O


2

Mathematica, 42 37 byte

Grazie a @ LegionMammal978 per più suggerimenti per il salvataggio del codice. Il primo parametro, #è per il testo di input, il secondo parametro #2, per il numero di spazi per scheda.

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

Inoltre, è possibile passare Table[" ",{#2}]a " "~Table~{#2}per salvare un byte. Perché stai StringJoininserendo la stringa vuota su di essa?
LegionMammal978,

1

Rubino 49 byte

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

2
Questo non funziona se ci sono due schede all'inizio di una riga.
Non che Charles, il

1

JavaScript (ES6), 70

Utilizzando le stringhe del modello, la nuova riga è significativa e conteggiata

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

Prova a eseguire lo snippet di seguito in 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
Caspita un voto negativo! Potrebbe essere qualcuno che non riesce a leggere o capire "Test in Firefox"?
edc65,

Ho il sospetto di una parzialità linguistica. Anche Julia e CJam hanno ottenuto voti negativi.
Dennis,

1

CoffeeScript, 72 byte

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

(Cercando di giocare a golf almeno altri 2 morsi, in modo da battere la soluzione ES6 ... Aiuto apprezzato: 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 byte

Tutte le occorrenze di .sono spazi, tutte \tsono schede letterali (1 byte) e <empty>rappresentano un file vuoto. È solo per leggibilità. Inoltre, non sono del tutto sicuro di fare il ciclo correttamente, ma penso di sì. Ogni riga deve essere inserita nel proprio file. Ho aggiunto 1 byte per ogni file aggiuntivo.

Si presume che l'input sia in Unario sulla propria riga alla fine dell'input.

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

Spiegazione

Aggiungo un _input prima dell'Unario per delimitarlo durante la sostituzione, in modo da non rimuovere quelli finali dalla stringa di input. Quindi, sostituisco tutte le schede non all'inizio di una riga con un singolo spazio. Quindi, eseguo il ciclo, rimuovendo un singolo 1e aggiungendo un singolo spazio dopo ogni scheda, fino a quando non esaurisco l'input. Infine, pulisco rimuovendo le schede e il trattino basso.


1

Python, 72 68 byte

Le schede sono letterali (1 byte), quindi r'...'non sono necessarie. Sfortunatamente, Python richiede look-behind / look-aheads "a larghezza fissa", quindi non posso usarli (?<!^|\t). Utilizza praticamente lo stesso metodo della mia soluzione Retina.

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




0

Haskell , 75 byte

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

Provalo online! Ciò presuppone che l'input contenga solo caratteri stampabili, nonché schede e nuove righe, come consentito da OP nei commenti.

Spiegazione:

La #funzione esterna accetta una stringa se un numero me chiama la funzione interna localmente definita #con gli stessi argomenti. Questo viene fatto per tenere traccia del mvalore originale , poiché la #funzione interna cambia il numero:

  • ('\t':r)#n=(' '<$[1..n])++r#nSe si incontra una scheda, sostituirla con nspazi e lasciare ninvariata.
  • (x:r)#n=x:r#(m^sum[1|x<' '])Se xviene rilevata una parte che non è una scheda, mantenerla così com'è ma impostata nsul numero originale mse xè una nuova riga e 1altrimenti. Questo viene fatto da m^sum[1|x<' ']: mè portato al potere di sum[1|x<' ']cui valuta 1quando xè più piccolo di uno spazio (cioè una nuova linea), quindi otteniamo m^1 = m. Altrimenti è 0e abbiamo m^0 = 1.

0

Java 11, 134 byte

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

Provalo online.
NOTA: Java 11 non è ancora su TIO, quindi " ".repeat(n)è stato emulato come repeat(" ",n)invece (con lo stesso conteggio byte).

Spiegazione:

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.