Signifikantes Leerzeichen


55

Wir definieren Whitespace als eines der drei Zeichen, Tabulator (0x09), Zeilenvorschub (0x0A) oder Leerzeichen (0x20).

Für diese Herausforderung müssen Sie zwei Programme oder Funktionen in derselben Programmiersprache schreiben, die die folgenden Aufgaben ausführen:

  1. Zählen Sie die Leerzeichen in einer bestimmten Zeichenfolge. Zum Beispiel die Eingabe

      123 -_-   abc
    def
    

    würde 7 zurückgeben (vorausgesetzt, es gibt keinen nachgestellten Zeilenumbruch).

  2. Teilen Sie eine bestimmte Zeichenfolge bei aufeinanderfolgenden Leerzeichenfolgen. Wenn die Zeichenfolge mit Leerzeichen beginnt oder endet, sollten an den Enden keine leeren Zeichenfolgen zurückgegeben werden. Zum Beispiel die gleiche Eingabe

      123 -_-   abc
    def
    

    würde zurückkehren ["123", "-_-", "abc", "def"].

In beiden Fällen können Sie eine Eingabe über STDIN, ein Befehlszeilenargument oder ein Funktionsargument vornehmen und das Ergebnis zurückgeben oder es STDOUT ausgeben. Wenn Sie für das zweite Programm auf STDOUT drucken möchten, drucken Sie bitte jede Zeichenfolge in einer eigenen Zeile ohne umgebende Anführungszeichen.

Bei beiden Programmen können Sie davon ausgehen, dass die Eingabe nur druckbares ASCII (0x20 bis 0x7E) und Leerzeichen enthält.

Hier ist der Haken:

  • Wenn alle Leerzeichen aus beiden Programmen / Funktionen entfernt werden, müssen die resultierenden Zeichenfolgen identisch sein. Das heißt, Ihre beiden Einreichungen unterscheiden sich möglicherweise nur in der Anzahl und der Platzierung von Leerzeichen.
  • Weder Programm noch Funktion dürfen Zeichenfolgen- oder Regex-Literale enthalten (Zeichenliterale sind in Ordnung, vorausgesetzt, Ihre Sprache verfügt über einen bestimmten Zeichentyp).
  • Weder Programm noch Funktion dürfen Kommentare enthalten.
  • Sie dürfen den Quellcode des Programms weder direkt noch indirekt lesen.

Das ist Code Golf. Ihre Punktzahl ist die Summe der Größen beider Lösungen (in Bytes). Die niedrigste Punktzahl gewinnt.

Bestenlisten

Das folgende Stack-Snippet generiert sowohl eine reguläre Rangliste als auch eine Übersicht der Gewinner nach Sprache. Also, auch wenn Sie mit der Sprache Ihrer Wahl nicht die gesamte Herausforderung gewinnen können, warum nicht versuchen, einen Platz auf der zweiten Liste zu ergattern? Es würde mich sehr interessieren, wie die Leute diese Herausforderung in einer Vielzahl von Sprachen angehen!

Um sicherzustellen, dass Ihre Antwort angezeigt wird, beginnen Sie Ihre Antwort mit einer Überschrift. Verwenden Sie dazu die folgende Markdown-Vorlage:

# Language Name, N bytes

wo Nist die Gesamtgröße Ihrer Vorlage. Wenn Sie Ihren Score zu verbessern, Sie können alte Rechnungen in der Überschrift halten, indem man sich durch das Anschlagen. Zum Beispiel:

# Ruby, <s>104</s> <s>101</s> 96 bytes

Sie können auch die einzelnen Zählungen vor der Gesamtzählung angeben, z

# Python 2, 35 + 41 = 76 bytes

Die letzte Nummer, die nicht durchgestrichen ist, wird vom Snippet verwendet.

<script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script><script>site = 'meta.codegolf',postID = 5314,isAnswer = true,QUESTION_ID = 42253;jQuery(function(){var u='https://api.stackexchange.com/2.2/';if(isAnswer)u+='answers/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJeRCD';else u+='questions/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJO6t)';jQuery.get(u,function(b){function d(s){return jQuery('<textarea>').html(s).text()};function r(l){return new RegExp('<pre class="snippet-code-'+l+'\\b[^>]*><code>([\\s\\S]*?)<\\/code><\/pre>')};b=b.items[0].body;var j=r('js').exec(b),c=r('css').exec(b),h=r('html').exec(b);if(c!==null)jQuery('head').append(jQuery('<style>').text(d(c[1])));if (h!==null)jQuery('body').append(d(h[1]));if(j!==null)jQuery('body').append(jQuery('<script>').text(d(j[1])))})})</script>


26
Diese Rangliste ist cool!
Digital Trauma

5
Klingt so, als würde eine Whitespace-Antwort Regel 1 entsprechen.;)
nyuszika7h

1
@ nyuszika7h Wäre zwar so, aber es wird sowieso nicht besonders kurz.
Martin Ender

7
Signifikantes Leerzeichen, also kein Leerzeichen mit Vorteilen oder
Ähnlichem

Antworten:


15

Pyth, 16 + 15 = 31 Bytes

Probieren Sie es hier aus .

Zähler:

L@,cb)sm!cd)b1 0

Splitter:

L@,cb)sm!cd)b10

Diese definieren jeweils eine Funktion, ydie eine Zeichenketteneingabe zur Lösung der gewünschten Aufgabe benötigt.

Vielen Dank an @FryAmTheEggman für die Idee, Pyths Funktion der modularen Indizierung in Listen zu nutzen, um einen Charakter zu rasieren.

Testfälle:

L@,cb)sm!cd)b1 0y++"abc def"b"gh ij k"
L@,cb)sm!cd)b10y++"abc def"b"gh ij k"

Erläuterung:

L                  define a function, y, which takes one input, b.
 @                 Index into
  ,                2-tuple of
   cb)             b.split()                          (solution to splitter)
   s               sum over                           (solution to counter)
    m              map, with input d, to
     !cd)          logical negation of d.split()      (empty list is falsy)
     b             over b.
                   Index is either:
   10
   1
                   Indexing is modulo the length of the list in Pyth.
 0                 In one case, a 0 with a leading space is outside the function.
                   Leading space suppresses print, so the 0 is invisible.

52

Python, 54 + 56 = 110 Bytes

Zähler:

m=lambda x:sum(y.isspace()for y in x)
+1
0<9or x.split()

Splitter:

m=lambda x:sum(y.isspace()for y in x)+10<9or x.split()

Für den Zähler verwenden wir die Tatsache, dass es in Python in Ordnung ist, nur einen Ausdruck in einer Zeile zu haben. Es ist notwendig, eine zu trennen +1und 0<9or x.split()zu verhindern , dass NameErrorsie geworfen wird, da 0<9dies Truedie x.split()Auswertung aufgrund eines Kurzschlusses verhindert.

Für den Splitter ist, da die Anzahl der Whitespaces immer nicht negativ sum(y.isspace()for y in x)+10<9ist, immer Falseund die Splitting-Funktion kommt ins Spiel.


Alternative 1, 59 + 60 = 119 Bytes

Zähler:

m=lambda x:[x.split(),sum(y.isspace()for y in x)][min([1])]

Splitter:

m=lambda x:[x.split(),sum(y.isspace()for y in x)][m in([1])]

Die Ergebnisse der Zählung und Aufteilung werden in einer Liste mit zwei Elementen gespeichert. Die Liste wird indiziert, indem entweder min([1])das Minimum der Liste mit einem Element zurückgegeben wird 1, oder m in([1])das False(äquivalent zu 0) zurückgegeben wird, wie mes nicht in enthalten ist [1].


Alternative 2, 67 + 69 = 136 Bytes

Zähler:

ted=1;s=lambda x:[x.split(),sum(y.isspace()for y in x)][not s or ted]

Splitter:

ted=1;s=lambda x:[x.split(),sum(y.isspace()for y in x)][not sorted]

Wie oben werden die Ergebnisse der Zählung und Aufteilung in einer Liste mit zwei Elementen gespeichert. sortedist eine eingebaute Funktion, die ein wahrer Wert ist, also gibt sie not sortedzurück False(äquivalent zu 0). Denn not s or tedda seine Funktion und auch Wahrheit ist, not sist Falseund ted = 1wird zurückgegeben.


Alternative 3, 59 + 60 = 119 Bytes

Zähler:

def f(s):a=s.split();a1=len(s)-len((s*0).join(a));return a1

Splitter:

def f(s):a=s.split();a1=len(s)-len((s*0).join(a));return a
1

Dies ist eine Funktion, bei der das Ergebnis des Splitters in der Variablen aund das Ergebnis des Zählers in der Variablen gespeichert werden a1. In diesem Fall kann Python nach wie vor nur einen Ausdruck in einer Zeile verwenden 1. Durch Aufteilen wird a1festgelegt, was von der Funktion zurückgegeben werden soll.


22
Ich würde nochmal +1 für geben not sorted.
Martin Ender

Ist der Zeilenumbruch zwischen +1und 0<9or x.split()erforderlich?
isaacg

1
@isaacg Wenn Sie Ausnahmen interessieren, dann ja
Sp3000

Sie können 3 Bytes mit m=lambda x:sum(y.isspace()for y in x)+00and x.split()und m=lambda x:sum(y.isspace()for y in x)+0;0and x.split()abschneiden (wobei das Semikolon natürlich eine neue Zeile ist)
cjfaure

@ CJFAURE Ich glaube nicht, dass der erste als Splitter funktioniert, wenn es kein Leerzeichen gibt
Sp3000

16

Java 8, 239 + 240 = 479

Zähle das Leerzeichen (gibt Integer zurück)

Object f(String s){String r=new String(new char[]{92,'s'}),e=new String();int intx=0;intx=1;return intx>0?s.chars().filter(c->c==9|c==10|c==32).count():java.util.Arrays.stream(s.split(r)).map(t->t.replaceAll(r,e)).filter(t->t.length()>0);}

Auf das Leerzeichen aufteilen (gibt Stream <String> zurück)

Object f(String s){String r=new String(new char[]{92,'s'}),e=new String();int intx=0;int x=1;return intx>0?s.chars().filter(c->c==9|c==10|c==32).count():java.util.Arrays.stream(s.split(r)).map(t->t.replaceAll(r,e)).filter(t->t.length()>0);}

Erläuterung:

Object f(String s){
    String r=new String(new char[]{92,'s'}),e=new String();  // init regex'es

    int intx=0;     // critical variable

    intx=1;         // change intx to 1
              OR
    int x=1;        // new, unused variable

    return intx>0 ? // test variable to decide what to do
      s.chars().filter(c->c==9|c==10|c==32).count() :
      java.util.Arrays.stream(s.split(r)).map(t->t.replaceAll(r,e)).filter(t->t.length()>0);
}

Für mich sieht das großartig aus. +1
Rodolfo Dias

Ziemlich gut, wenn man bedenkt, dass Java die schlechteste Sprache für Code-Golf ist.
13.

13

Leerzeichen, 75 + 153 = 228

Leerzeichen, Tabulatoren und Zeilenumbrüche werden durch STL ersetzt und der Lesbarkeit halber gefaltet. Konvertieren Sie in eine richtige Whitespace-Datei mit tr -d \\n | sed 'y/STL/ \t\n/'.

Zähler

SSSLLSSLSSSTSSSSSLSLSSLSTLTSTTTSLSLTSSLTSSTLTTLSSSTLTSSSLSLLLSSSLS
LLSLLTLST

Splitter

SSSTLSSSLTTSLSSTLSSSLSLSTLTSTTTSLSSLSLTSLSSSTSSSSTLTSSTLTTTTLSSSTL
SLSTTSLSLSLLSSTTLSSSTSTSLSSSTLTTTLTSTSLTLSSSSSTLSSSLTTSLSSTSLLSLTL
LSSSLTLSSLSLTLLSSLLLL

2
Ich habe mich gefragt, wie lange es dauern würde ...;)
Martin Ender

4
Mit Leerzeichen wird dies zu zwei separaten Code-Golf-Herausforderungen.
13.

13

Marbelous, 103 + 92 = 195

Zähler:

@0      @200@1@3
]]&1]]3W
  \\!!?001
        &0  >W@1
>W    @2/\  /\@3+A
00&0      &1
          Dp
@0//

Splitter:

@0  @200@1    @3
]]&1]]  3W    \\
  !!    ?001&0
>W@1>W@2
/\  /\@3+A00&0
          &1Dp@0
//

Testen Sie diese Programme hier. Zylindrische Karten, Include-Bibliotheken und Leerzeichen für leere Zellen müssen alle überprüft werden.

Eingabe und Ausgabe erfolgen über STDIN / STDOUT.

Erläuterung

Zähler:

Gegenquelle

Der blaue Pfad empfängt Eingaben. Wenn das Zeichen ein Leerzeichen ist (ASCII-Wert kleiner als 0x21), wird der schwarze Pfad verwendet, der mit dem violetten Pfad synchronisiert wird.

Der violette Pfad erhöht einfach &1jedes Mal, wenn der schwarze Pfad genommen wird, einen im Synchronizer gespeicherten Marmor .

Sobald keine Eingabe mehr erfolgt, wird der rote Pfad genommen, die Anzahl der Whitespace-Zeichen gedruckt und beendet.

Splitter:

Splitterquelle

Das Programm beginnt mit dem blauen Pfad, der so lange wiederholt wird, bis ein Nicht-Leerzeichen gefunden wurde.

Sobald ein Nicht-Whitespace-Zeichen abgerufen wurde, wird der schwarze Pfad verwendet, der dieses Zeichen druckt und die Ausführung auf den grünen Pfad verschiebt, der wiederholt und gedruckt wird, bis ein Whitespace-Zeichen empfangen wird. Die Ausführung fährt dann mit dem violetten Pfad fort, der 3Weinen Drei-Wege-Splitter enthält.

Der linke Zweig verschiebt die Ausführung in den blauen Pfad (und Leerzeichen werden verworfen, bis ein Nicht-Leerzeichen-Zeichen gefunden wird).

Der mittlere Zweig setzt die Kopie der Eingabe auf 0 mit ?0(generiere eine Zufallszahl zwischen 0und 0) und addiert 10 ( 0x0A= Newline), die dann ausgegeben wird.

Der richtige Weg wird verworfen.


Es scheint, als ob der Splitter nicht terminiert, wenn Leerzeichen nachgestellt sind.
Martin Ender

12

CJam, 26 + 27 = 53 59 61 73 77 Bytes

Zähler

'!q_,\SN9c++SerS%:Qs,-QN*?

Splitter

' !q_,\SN9c++SerS%:Qs,-QN*?

Wie es funktioniert

Die Idee ist einfach: Berechnen Sie beide Leerzeichen und teilen Sie die Zeichenfolge bei aufeinanderfolgenden Leerzeichenfolgen auf. Dann wählen Sie eine von ihnen auf der Grundlage der folgenden Tatsache, die ' !bedeutet, not of space characterwas falsch ist, während '!der !Charakter, der wahr ist.

Erweiterter Code:

'! / ' !                              "Get truthy or falsy value";
        q_                            "Read the input, make a copy";
          ,\                          "Take the length of the copy and swap";
            SN9c++                    "Get a string comprised of all Whitespaces";
                  Ser                 "Replace any occurrence of any character of"
                                      "the above string with space";
                     S%               "Split on one or more runs of space";
                       :Qs,           "Store this in Q, flatten to a string and take length";
                           -          "Subtract from total length to get count";
                            QN*       "Put the splitted array on stack and join newline";
                               ?      "Base on the truthy or falsy value, pick one to print";

Die Eingabe erfolgt über STDIN und die Ausgabe über STDOUT

Probieren Sie es hier online aus


10

Mathematica, 44 + 43 = 87 - 97 Bytes

Ich dachte, ich würde der Mischung eine weitere Sprache hinzufügen.

Zähler:

StringCount[#,Whitespace]+0 1StringSpli t@#&

Splitter:

String Count[#,Whitespace]+01StringSplit@#&

Dies nutzt die Eigenschaft von Mathematica, dass Raumtrennung die gleiche ist wie Multiplikation. Und das Multiplizieren von etwas mit 0 ist immer 0, und das Hinzufügen von 0 zu etwas ist immer idempotent.

Für den Zähler zählen wir zuerst das Leerzeichen und addieren es 0*1*StringSpli*t@#. StringSpliund tsind nicht definiert, aber Mathematica verwendet symbolische Berechnungen, so dass diese nur als unbekannte Variable und Funktion behandelt werden. Das 1*ist (genauso wie 0+) idempotent , das 0*macht es zu einer Null. Es ist notwendig, die StringSplitVariablen in zwei Variablen zu trennen , da 0eine Liste manchmal als Skalar-Vektor-Multiplikation behandelt wird, die einen Vektor (Liste) von Nullen ergibt.

Für den Splitter verwende ich die Tatsache, dass es Countauch gibt, aber ich sehe nicht in Strings. Es wird versucht, alle Unterausdrücke zu zählen , die mit dem Muster übereinstimmen, es handelt sich jedoch Whitespaceum ein Muster, das nur für den Inhalt von Zeichenfolgen gilt. Also Countwerde immer wiederkommen 0, was das Stringverschwinden lässt. Die Multiplikation des geteilten Arrays mit 01 = 1ist wiederum idempotent.


10

Ruby, 107 91 Bytes

Splitter (46 Bytes)

p
p=gets(p).split
puts p||$_.size-pp.join.size

Zähler (45 Bytes)

pp=gets(p).split
puts p||$_.size-pp.join.size

pist eine vordefinierte Methode, die ohne Argumente nur zurückgibt nil. Wir verwenden dies auf verschiedene Arten. Im Splitter ptut die Initiale nichts. gets(p)Liest alles von der Standardeingabe ein, da der Begrenzer null ist. Wir bezeichnen dies als integrierte Split-Methode und weisen das Ergebnis zu p. Wenn also keine Argumente angegeben werden, wird es als Variable analysiert. puts p||...schließt jedes Element der pVariablen kurz und druckt es in eine eigene Zeile.

Im Zähler löschen wir die erste neue Zeile, damit ppstattdessen das geteilte Array zugewiesen wird. Da wir es nicht zugewiesen haben, pist es immer noch die Methode ohne Rückgabe, sodass der zweite Teil von ||ausgewertet und an übergeben wird puts. $_ist eine magische Variable, die das Ergebnis von enthält. Die getsGesamtmenge an Leerzeichen entspricht also der Größe abzüglich der Nicht-Leerzeichen-Zeichen, die enthalten sind pp. Ich habe das Gefühl, dass es eine kürzere Art des Zählens geben sollte, aber ich kann keine finden, und auf jeden Fall macht es Spaß, das geteilte Array im Zähler zu verwenden.


7

Python, 169

In Python ist das fast zu einfach!

Zähler:

def x(s):
 def y(s):
  return sum(map(str.isspace,s))
  return s.split()
 return y(s)

Splitter:

def x(s):
 def y(s):
  return sum(map(str.isspace,s))
 return s.split()
 return y(s)

Sie unterscheiden sich in nur einem Leerzeichen und ich mache keine Tricks wie das Teilen einer Zahl oder eines Variablennamens in zwei Hälften :)


6

C 138 + 136 = 274

In jedem Fall ist der Code ein Programm, das genau ein Befehlszeilenargument akzeptiert und das Ergebnis an stdout ausgibt. \tsollte durch ein Tabulatorzeichen ersetzt werden. Wenn Sie ein Argument mit Tabulatoren und Zeilenumbrüchen übergeben möchten, müssen Sie herausfinden, wie;).

Zählen

#define strtok strpbrk
h=' \t\n';main(c,v,n)char**v;{for(n=- -c-1;v[n]=strtok(1[v],&h);n[v]++)v[!n]=0,puts(*v),c++;n*='d%';printf(&n,c-2);}

Aufteilen

#define strtokstrpbrk
h=' \t\n';main(c,v,n)char**v;{for(n=--c-1;v[n]=strtok(1[v],&h);n[v]++)v[!n]=0,puts(*v),c++;n*='d%';printf(&n,c-2);}

6

JavaScript, 95 + 96 = 191 Bytes

Zähler:

c=(a,v)=>{v
v=a=a.split(RegExp(String.fromCharCode(92,115)));return v?a.length-1:a.filter(j=>j)}

Splitter:

s=(a,v)=>{vv=a=a.split(RegExp(String.fromCharCode(92,115)));return v?a.length-1:a.filter(j=>!!j)}

Ungolfed:

s=(a,v)=>{

    v  // this `v` is ignored, or combined with the next line to make `vv`

    // split array and store it in `a` and `v` (or alternatively `vv`)
    v = a = a.split(RegExp(String.fromCharCode(92,115)));

    return v?
            a.length-1        // return number of whitespace chars
            :
            a.filter(j=>j)    // return array without empty strings
    }

Die RegExp(String.fromCharCode(92,115)Zeile erstellt den mit Leerzeichen übereinstimmenden regulären Ausdruck /\s/ohne reguläre Ausdrücke oder Zeichenfolgenliterale.

In jedem Programm verwenden wir die Variable voder vv. Wir speichern das aufgeteilte Array in dieser Variablen ( voder vv) und verzweigen dann unser Verhalten auf den Wert von v(wird in der Zwischenzeit vvignoriert). In der Theke vhat ein wahrer Wert; Im Splitter hat es einen falschen Wert (weil er vvstattdessen den Wert hat).


Alternative: JavaScript, 250 Byte

Ich habe eine andere Lösung, die aus Gründen der Kürze keine Preise gewinnt, aber ich fand es eine interessante Herausforderung, das automatische Semikolon-Einfügeverhalten von JavaScript zu missbrauchen.

Zähler:

c=a=>{a=a.split(RegExp(String.fromCharCode(92,115)));x:for(i=2;i--;)for(o=i?a.length-1:a.filter(j=>j);1;){break x}return o}

Splitter:

s=a=>{a=a.split(RegExp(String.fromCharCode(92,115)));x:for(i=2;i--;)for(o=i?a.length-1:a.filter(j=>j);1;){break
x}return o}

Ungolfed Zähler:

s=a=>{
    a = a.split(
            RegExp(String.fromCharCode(92,115))   // split input on whitespace regex /\s/
        );  
    x:                             // x is a label for the outer loop
    for(i=2;i--;)                  // run this outer loop twice
        for(o=i?                   // if this is the first outer loop pass, 
               a.length-1          //    set `o` to number of whitespaces
               :                   // else, on second outer loop pass,
               a.filter(j=>j);     //    set `o` to split input (w/o empty strings)
            1;                     // 1 is truthy; run inner loop forever
            ) {
                break x;           // break out of outer loop
            }
    return o;                      // return `o`
}

Der Splitter ist bis auf die Leitung genau derselbe:

break x;

ist jetzt

break
x;

JavaScript automatische Semikolon Einfügung normalerweise nicht beendet mehrzeiligen Aussagen früh , wenn sie ohne Zeilenumbruch verstanden werden kann, aber es duldet keine Linie nach bricht return, continueoder break. Daher wird die Zeile einfach als gelesen break, was nur aus der inneren Schleife herausbricht, anstatt aus der äußeren Schleife herauszubrechen. Das "Second-Pass" -Verhalten o = a.filter(j=>j)wird dann ausgeführt (anstatt im Zähler übersprungen zu werden), da der äußeren Schleife ein zweiter Durchgang gegeben wird.


Ist das !!xanders als beim Autokonvertieren Bool?
14 m²,

@ l4m2 Ist es nicht! Ich habe es entfernt, da filterauto-bools seinen Rückruf nach den gleichen Regeln wie zurückgibt !!. Vielen Dank!
Apsillers

5

Python, 228 198 182 166 146 145 Bytes

Zähler ( 72 Bytes ):

ior1=0
w=lambda i:i.split()if ior1 else sum(ord(c)in(9,10,32)for c in i)

Splitter ( 73 Bytes ):

ior1=0
w=lambda i:i.split()if i or 1else sum(ord(c)in(9,10,32)for c in i)

ior1ist eine Falsey-Variable, aber i or 1wahr. Das ist der Haupttrick.


Bricht dies nicht, wenn idie leere Zeichenfolge für den Splitter ist? Könnte durch Ändern von iorbin behoben werden ior1, wodurch Sie auch das Zeichen zwischen 1und speichern können else.
Isaacg

@isaacg Ich habe total vergessen, dass du Zahlen in Variablennamen haben könntest! Vielen Dank <3
undergroundmonorail

5

Befunge 98, 61 + 59 = 120

Zähler:

~:'!-0`#v_ >$1+#@ #. #
 @#,#$ #<_v#`0-!':~ # .#
  ,#$ #+55<v

Splitter:

~:'!-0`#v_ >$1+#@ #.#
 @#, #$#<_v#`0-!':~ #.#
  , #$#+55<v

4

Bash, 75 + 79 = 154 Bytes

Dies setzt voraus, dass bash die Ausführung fortsetzen kann, auch wenn einige Zeilen oder Teile einer Skriptzeile (unter bestimmten Umständen) fehlerhaft sind. Whitespace wird verwendet, um die Escape-Zeichen für einige enge Klammern zu deaktivieren und eine Pipe zu brechen, indem sie in eine neue Zeile eingefügt wird.

Splitter:

echo $((`echo $1|wc -w`+${#1}-$(\)\)\)
for a in $1;do echo $a;done|wc -c)))

Zähler:

echo $((`echo $1|wc -w`+${#1}-$(\ )\ )\ )
for a in $1;do echo $a;done
|wc -c)))

Die Eingabe erfolgt über ein Kommandozeilenargument, die Ausgabe erfolgt über stdout.

Da dies vom Bash-Fehlerverhalten abhängt, wird vom Benutzer erwartet, dass er stderr ignoriert.

Beispiellauf (Eingabe mit einer neuen Zeile und mehreren zusammenhängenden Leerzeichen):

# bash counter.sh "abc def
gh   ij k" 2>/dev/null
6
# bash splitter.sh "abc def
gh   ij k" 2>/dev/null
abc
def
gh
ij
k

4

Ruby, 114 + 116 107 + 109 = 216 Bytes

Dies kann nicht mit der Rubinlösung von Histokraten mithalten, aber ich dachte, es wäre es wert, es trotzdem zu ertragen.

Ich habe $zfür nilund nil.to_sfürString.new

Das zusätzliche Leerzeichen, das ich am Ende der Eingabe hinzufüge, erzwingt das Hinzufügen des letzten Wortes zum Array ( r) - ein Wort wird nur am Ende des Arrays hinzugefügt, wenn ein Leerzeichen auf ein Nicht-Leerzeichen folgt. Die Alternative war das Hinzufügen eines weiteren r<<w if wnach dem each_byteBlock.

Zählen

->s{r=[]
n=-1
w=$z
(s+9.chr).each_byte{|b|if b<33
r<<w if w
w=$z
n+=1
else
w=w.to_s+b.chr
end}
$zorr ?r:n}

Aufteilen

->s{r=[]
n=-1
w=$z
(s+9.chr).each_byte{|b|if b<33
r<<w if w
w=$z
n+=1
else
w=w.to_s+b.chr
end}
$z or r ?r:n}

Ah, ich war mir nicht sicher, was das angeht. Ich habe es geändert, um if-else anstelle des ternären Operators zu verwenden - keine String-Literale mehr.
Alexanderbird

3

Haskell , 53 + 55 = 108, 36 + 38 = 74 Bytes

Zähler

f=do
 pure(length.filter(<'!'))words

Splitter

f=do
 pure(length.filter(<'!'))
 words

Diese Lösung nutzt die Tatsache, dass in Haskell Funktionen eine Instanz der Monad-Typklasse sind und somit als monadische Aktionen in Do-Notation verwendet werden können.

Im ersten Fall ist die resultierende Funktion des do-Blocks das erste Argument von pure(was im Wesentlichen constfür den Funktionstyp gilt), wodurch der Zähler zum Endergebnis wird und der Splitter verworfen wird.

Im zweiten Fall purewird nur auf ein einzelnes Argument angewendet, wodurch es zu einer Funktion wird, die eine andere Funktion (den Zähler) zurückgibt. Das Ergebnis wird jedoch niemals verwendet und somit verworfen. Das Endergebnis ist die zweite Zeile des do-Blocks, der Splitter.


Netter Ansatz! [' ','\t','\n']kann auf gekürzt werden " \t\n".
Laikoni

@ Laikoni Die Beschreibung erlaubt nur Zeichen Literale, keine Zeichenfolge oder Regex Literale
Siracusa

2
Da Sie bei dieser Herausforderung nicht mit den meisten Steuerzeichen umgehen müssen, können Sie diese verkürzen, indem Sie (<'!')zum Testen auf Leerzeichen verwenden.
Ørjan Johansen

2

Java 8, 187 + 188 = 375

Zunächst möchte ich sagen, dass diese Antwort stark auf @ Ypnypn basiert. Grundsätzlich habe ich einige Teile durch kürzere ersetzt (einschließlich des Whitespace-abhängigen Teils, den IMO bei dieser Herausforderung am wichtigsten macht), aber der Funktionscode ist größtenteils derselbe.

Zähle das Leerzeichen , 187 (kehrt zurück int):

Object f(String s){String r=new String(new char[]{92,115});int a=0;return a--+a>0?s.chars().filter(c->c>8&c<11|c==32).count():java.util.Arrays.stream(s.split(r)).filter(t->t.length()>0);}

Auf den Whitespace aufteilen , 188 (Rückgabe Stream<String>):

Object f(String s){String r=new String(new char[]{92,115});int a=0;return a- -+a>0?s.chars().filter(c->c>8&c<11|c==32).count():java.util.Arrays.stream(s.split(r)).filter(t->t.length()>0);}

2

J, 48 + 49 = 97 Zeichen

Zwei Funktionen, die ein einziges Argument annehmen und zurückgeben. Verwendete die schlechteste Methode, die ich mir vorstellen konnte, um die Regel für das gleiche Leerzeichen zu übertreffen. Es gibt also wahrscheinlich Zeichen, die man retten kann, wenn man eine cleverere Route findet.

(aa[aa=.+/@a=.a:-.~(e.u:)&9 10 32 :(<;._1~1,}.))      NB. count
(a a[aa=.+/@a=.a:-.~(e.u:)&9 10 32 :(<;._1~1,}.))     NB. split

Wir definieren das Verb so a, dass es zwei verschiedene Aktionen hat, abhängig davon, ob es mit einem Argument oder mit zwei verwendet wird. Mit einem Argument wird (e.u:)&9 10 32geprüft, ob jedes Zeichen ein Leerzeichen ist oder nicht. Mit zwei Argumenten ist es a:-.~(<;._1~1,}.), das einen booleschen Vektor rechts nimmt und das linke Argument an diesen Positionen abschneidet, wobei alle leeren Schnitte mit weggeworfen werden a:-.~.

Dann definieren wir aaals Anzahl der wahren Werte im Ergebnis von a, was nur mit einem Argument Sinn macht. Schließlich verwenden wir aaoder a aabhängig davon, ob wir das Leerzeichen der Zeichenfolge zählen oder teilen möchten. aafunktioniert wie erwartet.

Der Grund dafür a aist, dass wenn J sieht (f g)y, es (f g)einen Haken betrachtet und ihn wie auswertet y f (g y). In diesem Fall fist die dyadische aoberhalb der das Schneid der Fall ist, und gist a[aa, der die Summe aus berechnet aa, führt es aus und berechnet (monadischen) awieder.

Auf der REPL:

   (aa[aa=.+/@a=.a:-.~e.&(u:9 10 32) :(<;._1~1,}.))   '  123',TAB,'-_-   abc',LF,'def'
7
   (a a[aa=.+/@a=.a:-.~e.&(u:9 10 32) :(<;._1~1,}.))  '  123',TAB,'-_-   abc',LF,'def'
+---+---+---+---+
|123|-_-|abc|def|
+---+---+---+---+

2

Bash, 54 + 50 = 104 Bytes

Zähler

a=$IFS
IFS=
cat()(tr -cd $a|wc -c)
printf %s \\n$1|cat

Splitter

a=$IFSIFS=ca
t()(tr-cd$a|wc-c)
printf %s\\n $1|cat

1

Perl, 37 + 38 = 75

Zähler :

sub f{($_)=@_;(y/   - //,[split])[0.1]}

Splitter :

sub f{($_)=@_;(y/   - //,[split])[0 .1]}

1

Perl 6, 31 + 32 = 63 Bytes

Zähler

{?^1??.words!!+grep 33>*,.ords}

Probieren Sie es online!

?^1wird so analysiert, ?^ 1dass der Boolesche Negationsoperator auf 1 angewendet wird , was zu führt False.

Splitter

{? ^1??.words!!+grep 33>*,.ords}

Probieren Sie es online!

? ^1konvertiert den Bereich 0..0 in Bool, was zur Folge hat True.


0

Python 2, 98

Teilen (49)

Gibt die Token in einer Liste zurück.

f=lambda s:[sum(map(str.isspace,s))]and s.split()

Zählen (49)

Gibt eine Liste mit der Länge eins zurück, die die Anzahl der Leerzeichen enthält. Es wird höchstwahrscheinlich einen Laufzeitfehler verursachen, aber die Funktion fkann nach dem Ausführen des Codes verwendet werden.

f=lambda s:[sum(map(str.isspace,s))]
ands.split()

0

C (gcc) , 88 + 89 = 177 Bytes

Splitter

i,n,x,c;f(char*s){x=n=i=0;for(x+++n;c=*s++;c*x&&putchar(c))i=c<33?n++,c=i*10,0:1;x=n-1;}

Splitter

Zähler

i,n,x,c;f(char*s){x=n=i=0;for(x+ ++n;c=*s++;c*x&&putchar(c))i=c<33?n++,c=i*10,0:1;x=n-1;}

Zähler

Heruntergewirtschaftet

Nimmt Eingaben als Funktionsargument. Die Zählfunktion gibt die Anzahl der Leerzeichen zurück. Die Aufteilungsfunktion verwendet STDOUT für ihre Ausgabe (gibt jedoch im Übrigen auch die Anzahl der Leerzeichen minus eins zurück).

i,                      Flag signalling whether we are inside a word.
n,                      Number of whitespace encountered.
x,                      Flag signalling whether or not we should output the words.
c;                      Current character.
f(char*s){              Take input string as an argument.
x=n=i=0;for(            Initialise everything and start loop.
x+++n;                  SPLITTER ONLY: Interpreted as x++ +n, meaning x is set to 1 and n stays 0.
x+ ++n;                 COUNTER ONLY: Inverse of the above. Sets n to 1, and x stays 0.
c=*s++;                 Sets c to current char and increment string pointer, end loop if end of string.
c*x&&putchar(c))        Only output c if x is 1 and c is non-zero, which only happens if we left a word.
i=c<33?                 Since input contains only printable ASCII or whitespace, anything below 33 is whitespace.
       n++,             ...if that is the case, increment the whitespace counter (n)
           c=i*10,      ...and set c to newline (10), but only if we just left a word (if i is 1)
                  0:    ...and set i to 0.
                    1;  If not a whitespace, set i to 1, signalling we are inside a word.
x=n-1;}                 Implicitly returns n-1, which is the number of whitespaces if we are in the counter function.

0

Zsh , 35 + 35 = 70 Bytes

  • Weder Programm noch Funktion dürfen Zeichenketten- oder Regex-Literale enthalten

Ich bin mir nicht sicher, ob ich qualifiziert bin [^$IFS], da es beim Pattern Matching verwendet wird. Hier ist eine 45 + 45-Lösung für den Fall, dass es verboten ist.


Teilt:

:<<<${#1//[^$IFS]} 
:
<<<${(F)${=1}}

Anzahl:

:
<<<${#1//[^$IFS]}
:<<<${(F)${=1}}

Der :eingebaute ist gleichwertig zutrue , wir verwenden es als etwas zwischen einem Kommentar und / dev / null (da Kommentare nicht wir die unerwünschte Erweiterung .

Zsh hat eine eingebaute Funktion zum Teilen von Whitespace ${=var}. Dies macht es schwierig, eine andere logische Kombination zu erstellen, als nur beide auszuführen und die nicht gewünschte zu verwerfen.

Probieren Sie es online!

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.