Meine Güte, es ist in Registerkarten bedeckt!


26

Benutzer von Leerzeicheneinrückungen, vereinigt euch ! Wir müssen gegen alle Benutzer mit niedrigen Tabs kämpfen !

Ihre Mission (sollten Sie diese akzeptieren) ist es, ein Programm oder eine Funktion zu schreiben, die zwei Argumente enthält:

  • Eine Zeichenfolge: Dies ist die Eingabe.
  • Eine positive Ganzzahl: Dies ist die Anzahl der Leerzeichen pro Tabulator.

Sie müssen jede Zeile der Zeichenfolge durchgehen und jeden Tabulator, der zum Einrücken verwendet wird, durch die angegebene Anzahl von Leerzeichen und jeden Tabulator, der nicht zum Einrücken verwendet wird (z. B. in der Mitte einer Zeile), durch ein Leerzeichen ersetzen .

Beachten Sie, dass Zeilen wie \t \tabcundefiniertes Verhalten sind. Sie wurden von den Benutzern der bösen Registerkarte eingefügt, um Ihre Programme zu komplizieren.

Laut der Tabs Must Die Society muss Ihr Programm so kurz wie möglich sein, um eine Erkennung durch die bösen Tab-Benutzer zu vermeiden.

Beispiel

\t wird verwendet, um hier Registerkarten darzustellen.

Eingabezeichenfolge:

a
\t\tb\tc
d

Eingabenummer:

4

Ausgabe:

a
        b c
d

Die mittlere Zeile wurde um 8 Leerzeichen eingerückt, 4 pro Tab (da die angegebene Nummer 4 war).

Eingabezeichenfolge:

\ta\t\tb

Eingabenummer:

4

Ausgabe:

    a  b

HINWEIS: Dies ist kein Duplikat der Tab-Erweiterungsaufforderung . Es erfordert ein ganz anderes Eingabeformat und etwas andere Anforderungen.


1
Ja , solange die Frage nicht explizit nach Dezimalzahlen fragt (was nicht der Fall ist).
Martin Ender


1
Können wir davon ausgehen, dass die Eingabe nur druckbare ASCII-Zeichen, Tabulatoren und Zeilenumbrüche enthält?
Dennis

2
Vorgeschlagene Testfall: \ta\t\tb, 4(meine frühere Revision versagt , dass man)
Dennis

2
Wir brauchen eine Antwort in Whitespace.
Kaz Wolfe

Antworten:


7

CJam, 30 24 23 Bytes

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

Normalerweise weigere ich mich, bösartigen Code ins Internet zu stellen.

Dies ist ein vollständiges Programm, das die Zeichenfolge von STDIN und die Zahl als Befehlszeilenargument liest.

Probieren Sie es online im CJam-Interpreter aus .

Wie es funktioniert

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.

Was NA=macht:

  • Enthält für das erste Zeichen Nseinen Standardwert, dh die Zeichenfolge "\n".

    Enthält für alle nachfolgenden Zeichen Ndas Ergebnis der letzten Iteration, dh das letzte eingegebene Zeichen, ein Leerzeichen oder eine Zeichenfolge aus einem oder mehreren Leerzeichen.

  • Wenn Nes sich um eine Zeichenfolge handelt, NA=wird das Element am Index 10 von N ausgewählt (umlaufend). Das Ergebnis ist ein Leerzeichen oder ein Zeilenumbruch. Beide sind wahr.

    Wenn N ein Zeichen ist, NA=drücken Sie 1 für einen Zeilenumbruch und 0 ansonsten.

  • Aus diesem Grund NA=wird ein wahrer Wert für das erste Zeichen, ein Zeichen mit vorangestelltem Zeilenvorschub oder ein Zeichen mit vorangestellter Leerzeichenfolge (Einrückung, die bereits ersetzt wurde), übertragen.

    In allen anderen Fällen (einschließlich Tabulatoren , die durch ein Leerzeichen ersetzt wurde Charakter ), NA=drückt einen falsy Wert.


6
Gut, dass Sie dem Internet einen Dienst anbieten, indem Sie böswillige Tabs entfernen. ;)
Alex A.

19

K5, 53 45 Bytes

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

In Aktion:

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

Ich möchte nur, dass die Akte zeigt, dass diese Frage moralisch verwerflich ist.


11
-21346106841 für... this question is morally reprehensible.
TheNumberOne

3
Dies muss die am häufigsten gewählte Antwort sein, damit die Leute die Fußnote sehen können.
Geobits

Sie können das Ergebnis zurückgeben, anstatt es für 3 Bytes zu drucken.
kirbyfan64sos

1
@ kirbyfan64sos: Ich drucke das Ergebnis, um zu vermeiden, dass die Zeilen verbunden werden müssen. Wenn ich das Ergebnis als Liste von Zeichenfolgen akzeptieren und zurückgeben kann, eine für jede Zeile, könnte ich speichern `0:und "\ n".
JohnE

@JohnE Ich habe keine Regel aufgestellt, die besagt, dass du nicht kannst, also schätze ich, dass du kannst. :)
kirbyfan64sos

8

Perl, 23 Bytes

22 Byte Code + 1 Byte Befehlszeile

Hoffentlich nicht zu frech, um anzunehmen, dass die numerische Eingabe über den Parameter -i erfolgen kann! Stellen Sie sicher, dass \ t im folgenden Code durch das tatsächliche Tabulatorzeichen ersetzt wird.

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

Anwendungsbeispiel:

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

Oder der Einfachheit halber:

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

Erläuterung:

Die Verwendung des -pArguments führt das Programm für jede Zeile in der Eingabe aus und gibt das Ergebnis am Ende aus.

Im obigen Beispiel wird die Regex-Ersetzung \G\tdurch " "x4(ein Leerzeichen, das viermal wiederholt wird) ersetzt. \Gist ein wenig bekanntes Regex-Konstrukt, das entweder mit der Position der ersten Übereinstimmung bei der ersten Iteration oder mit der Position der vorherigen Übereinstimmung bei der ersten Iteration übereinstimmt. Dies bedeutet, dass nur alle Tabulatoren am Anfang der Zeichenfolge ersetzt werden und mach das eins nach dem anderen. Das y/\t/ /ersetzt einfach alle verbleibenden Tabulatoren durch Leerzeichen.


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

10 Bytes gespart und ein Problem dank Glen O behoben!


Hat es einen Vorteil, die führenden Einrückungslaschen separat zu ersetzen? Es scheint mir, dass es direkt von den "verbleibenden Registerkarten" Teil behandelt werden sollte. Außerdem stimmt Ihr Teil "Tabulatoren zwischen Text ersetzen" nur mit einer einzelnen Registerkarte überein. Was ist, wenn Sie eine haben "hello\t\t1"?
Glen O

Wenn wir davon ausgehen, dass alle Einrückungen mit Tabulatoren erfolgen (keine "\t \t"Situationen), können Sie Folgendes tun:, f(s,n)=(r=replace)(r(s,r"^\t*"m,i->" "^endof(i)n),"\t"," ")das eine Ersetzungsfunktion verwendet und alle Einrückungs-Tabulatoren mit einem Treffer erfasst.
Glen O

@ GlenO Wow, das ist wirklich genial. Vielen Dank!
Alex A.

Ich bemerkte, dass meine Antwort abgelehnt wurde. Gibt es etwas, was ich falsch gemacht habe? Für weitere Fragen stehe ich gerne zur Verfügung.
Alex A.

Ich sehe kein Problem. Vielleicht ist es nur einer dieser rachsüchtigen Typen, die abstimmen, weil sie keine Sprache mögen, oder solche Dinge? Ich kann keine Mängel sehen.
Glen O


2

Mathematica, 42 37 Bytes

Vielen Dank an @ LegionMammal978 für mehrere Vorschläge zum Speichern von Code. Der erste Parameter #steht für den Eingabetext, der zweite #2für die Anzahl der Leerzeichen pro Tabulator.

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

Außerdem können Sie ändern , Table[" ",{#2}]um " "~Table~{#2}ein Byte zu speichern. Warum StringJoinlegst du den leeren String drauf?
LegionMammal978

1

Ruby 49 Bytes

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

2
Dies funktioniert nicht, wenn sich am Anfang einer Zeile zwei Tabulatoren befinden.
Nicht dass Charles

1

JavaScript (ES6), 70

Mit Hilfe von Template-Strings wird der Zeilenumbruch signifikant und gezählt

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

Testen Sie das folgende Snippet 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
Wow eine Gegenstimme! Könnte jemand sein, der "Test in Firefox" nicht lesen oder verstehen kann?
edc65

Ich vermute eine sprachliche Voreingenommenheit. Julia und CJam bekamen auch Abstimmungen.
Dennis

1

CoffeeScript, 72 Bytes

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

(Beim Versuch, mindestens zwei weitere Bisse zu golfen, schlägt es die ES6-Lösung ... Hilfe geschätzt: D)

Verwendung:

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

Netzhaut, 42 Bytes

Alle Vorkommen von .sind Leerzeichen, alle \tsind wörtliche Tabulatoren (1 Byte) und <empty>stellen eine leere Datei dar. Es dient nur der Lesbarkeit. Ich bin mir auch nicht ganz sicher, ob ich die Schleife richtig mache, aber ich denke schon. Jede Zeile sollte in einer eigenen Datei platziert werden. Ich habe 1 Byte für jede weitere Datei hinzugefügt.

Es wird davon ausgegangen, dass sich die Eingabe am Ende der Eingabe in einer eigenen Zeile in Unary befindet.

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

Erläuterung

Ich füge _vor der Unary-Eingabe ein hinzu, um sie beim Ersetzen abzugrenzen, damit ich keine nachgestellten aus der Eingabezeichenfolge entferne. Dann ersetze ich alle Tabulatoren, die nicht am Anfang einer Zeile stehen, durch ein einzelnes Leerzeichen. Dann schleife ich, entferne ein einzelnes 1und füge nach jedem Tab ein einzelnes Leerzeichen hinzu, bis mir die Eingabe ausgeht. Zum Schluss entferne ich die Tabs und den Unterstrich.


1

Python, 72 68 Bytes

Tabulatoren sind wörtliche Tabulatoren (1 Byte) und werden daher r'...'nicht benötigt. Leider erfordert Python Look-Behinds / Look-Aheads mit "fester Breite", sodass ich sie nicht verwenden kann (?<!^|\t). Verwendet fast die gleiche Methode wie meine Retina-Lösung.

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

Probieren Sie es online! Dies setzt voraus, dass die Eingabe nur druckbare Zeichen sowie Tabulatoren und Zeilenumbrüche enthält, wie dies durch OP in den Kommentaren zulässig ist.

Erläuterung:

Die äußere #Funktion nimmt eine Zeichenfolge sund eine Zahl mund ruft die innere lokal definierte #Funktion mit denselben Argumenten auf. Dies geschieht, um den ursprünglichen mWert zu verfolgen , da die innere #Funktion die Zahl ändert:

  • ('\t':r)#n=(' '<$[1..n])++r#nWenn Sie auf einen Tabulator stoßen, ersetzen Sie ihn durch nLeerzeichen und lassen Sie ihn nunverändert.
  • (x:r)#n=x:r#(m^sum[1|x<' '])Wenn xein Tabulator nicht gefunden wird, behalten Sie diesen bei, setzen Sie ihn jedoch nauf die ursprüngliche Nummer, mwenn xes sich um einen Zeilenumbruch handelt, und auf eine 1andere Nummer . Dies wird gemacht durch m^sum[1|x<' ']: Wird mzur Potenz von sum[1|x<' ']ausgewertet, 1wenn xkleiner als ein Leerzeichen (dh eine neue Zeile) ist, so dass wir erhalten m^1 = m. Ansonsten ist es 0und wir haben 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',' ');}

Probieren Sie es online aus.
HINWEIS: Java 11 ist noch nicht in TIO, wurde also " ".repeat(n)als emuliert repeat(" ",n)(mit derselben Byteanzahl).

Erläuterung:

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
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.