Espaces blancs significatifs


55

Nous définissons les espaces comme étant l'un des trois caractères, tabulation (0x09), nouvelle ligne (0x0A) ou espace (0x20).

Pour ce défi, vous devez écrire deux programmes ou fonctions dans le même langage de programmation, qui effectuent les tâches suivantes:

  1. Comptez les caractères d'espacement dans une chaîne donnée. Par exemple, l'entrée

      123 -_-   abc
    def
    

    retournerait 7 (à condition qu'il n'y ait pas de nouvelle ligne).

  2. Fractionner une chaîne donnée lors de passages consécutifs d'espaces. Si la chaîne commence ou se termine par un espace, aucune chaîne vide ne doit être renvoyée à la fin. Par exemple, la même entrée

      123 -_-   abc
    def
    

    reviendrait ["123", "-_-", "abc", "def"].

Dans les deux cas, vous pouvez prendre une entrée via STDIN, un argument de ligne de commande ou une fonction, renvoyer le résultat ou l’afficher STDOUT. Pour le second programme, si vous choisissez d’imprimer sur STDOUT, veuillez imprimer chaque chaîne sur sa propre ligne, sans les guillemets.

Pour les deux programmes, vous pouvez supposer que l’entrée ne contient que des fichiers ASCII imprimables (0x20 à 0x7E) et des espaces.

Maintenant voici le piège:

  • Si tous les espaces sont supprimés des deux programmes / fonctions, les chaînes résultantes doivent être identiques. En d'autres termes, vos deux soumissions peuvent uniquement différer par le nombre et l'emplacement des caractères d'espacement.
  • Aucun programme / fonction ne peut contenir de chaîne ou de littéral de regex (les littéraux de caractères conviennent, à condition que votre langue ait un type de caractère désigné).
  • Aucun programme / fonction ne peut contenir de commentaires.
  • Vous ne devez pas lire le code source du programme, directement ou indirectement.

C'est du code golf. Votre score est la somme des tailles des deux solutions (en octets). Le score le plus bas gagne.

Classements

L'extrait de pile ci-dessous génère à la fois un classement régulier et un aperçu des gagnants par langue. Donc, même si votre langue de choix ne vous permet pas de remporter l’ensemble du défi, pourquoi ne pas tenter de vous tailler une place sur la deuxième liste? Je serais très intéressé de voir comment les gens abordent ce défi dans diverses langues!

Pour vous assurer que votre réponse apparaît, commencez votre réponse par un titre, en utilisant le modèle Markdown suivant:

# Language Name, N bytes

Nest la taille totale de votre soumission. Si vous améliorez votre score, vous pouvez conserver les anciens scores en les effaçant. Par exemple:

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

Vous pouvez également inclure les comptes individuels avant le compte total, par exemple:

# Python 2, 35 + 41 = 76 bytes

Le dernier numéro qui n'est pas rayé sera utilisé par l'extrait de code.

<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
Ce classement est cool!
Digital Trauma

5
On dirait que toute réponse de Whitespace serait conforme à la règle 1.;)
nyuszika7h

1
@ nyuszika7h En effet, mais ce ne sera pas particulièrement court de toute façon.
Martin Ender

7
Espaces blancs significatifs, donc pas d'espaces avec avantages ou autres ...
corsiKa

Réponses:


15

Pyth, 16 + 15 = 31 octets

Essayez ici .

Compteur:

L@,cb)sm!cd)b1 0

Splitter:

L@,cb)sm!cd)b10

Ceux-ci définissent chacun une fonction, yqui prend une entrée de chaîne pour résoudre la tâche souhaitée.

Merci à @FryAmTheEggman pour l'idée d'utiliser la fonctionnalité d'indexation modulaire de Pyth dans des listes pour raser un caractère.

Cas de test:

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

Explication:

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 octets

Compteur:

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()

Pour le compteur, nous utilisons le fait que Python accepte simplement d'avoir une expression sur une ligne. Il est nécessaire de se séparer +1et 0<9or x.split()d'empêcher toute NameErrorprojection, car il 0<9est Trueimpossible x.split()de l'évaluer en raison d'un court-circuit.

Pour le séparateur, étant donné que le nombre d'espaces est toujours non négatif, il en sum(y.isspace()for y in x)+10<9est toujours ainsi Falseet la fonction de fractionnement entre en jeu.


Alternative 1, 59 + 60 = 119 octets

Compteur:

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])]

Les résultats du comptage et du fractionnement sont stockés dans une liste à deux éléments. La liste est indexée par l' une min([1]), renvoyant le minimum de la liste d' un élément contenant 1, ou m in([1])qui renvoie False(équivalent à 0) comme mne figure pas dans [1].


Alternative 2, 67 + 69 = 136 octets

Compteur:

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]

Comme ci-dessus, les résultats du comptage et du fractionnement sont stockés dans une liste à deux éléments. sortedest une fonction intégrée qui est une valeur de vérité, donc not sortedrenvoie False(équivalent à 0). Car not s or ted, puisque sest une fonction et aussi la vérité, not sest Falseet ted = 1est retourné.


Alternative 3, 59 + 60 = 119 octets

Compteur:

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

Il s'agit d'une fonction dans laquelle le résultat du séparateur est stocké dans la variable aet le résultat du compteur dans la variable a1. Comme avant, Python est bien d’avoir juste une expression sur une ligne, dans ce cas 1. La scission a1détermine ce qu’il faut renvoyer de la fonction.


22
Je ferais encore +1 pour not sorted.
Martin Ender

La nouvelle ligne entre +1et est-elle 0<9or x.split()nécessaire?
isaacg

1
@isaacg Si les exceptions vous importent, alors oui
Sp3000

Vous pouvez supprimer 3 octets avec m=lambda x:sum(y.isspace()for y in x)+00and x.split()et m=lambda x:sum(y.isspace()for y in x)+0;0and x.split()(faire de ce point-virgule une nouvelle ligne bien sûr)
cjfaure

@cjfaure Je ne pense pas que le premier fonctionne comme un séparateur s'il n'y a pas d'espace blanc
Sp3000

16

Java 8, 239 + 240 = 479

Compter les espaces (retourne Integer)

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

Fractionner sur les espaces (renvoie Stream <String>)

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

Explication:

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

Pour moi, cela semble brillant. +1
Rodolfo Dias

Assez bon, considérant que Java doit être la pire langue pour le golf de code.
mardi

13

Espaces blancs, 75 + 153 = 228

Les espaces, les onglets et les nouvelles lignes sont remplacés par STL, respectivement, et sont repliés pour plus de lisibilité. Convertir dans un fichier Whitespace approprié avec tr -d \\n | sed 'y/STL/ \t\n/'.

Compteur

SSSLLSSLSSSTSSSSSLSLSSLSTLTSTTTSLSLTSSLTSSTLTTLSSSTLTSSSLSLLLSSSLS
LLSLLTLST

Splitter

SSSTLSSSLTTSLSSTLSSSLSLSTLTSTTTSLSSLSLTSLSSSTSSSSTLTSSTLTTTTLSSSTL
SLSTTSLSLSLLSSTTLSSSTSTSLSSSTLTTTLTSTSLTLSSSSSTLSSSLTTSLSSTSLLSLTL
LSSSLTLSSLSLTLLSSLLLL

2
Je me demandais combien de temps cela prendrait ...;)
Martin Ender

4
Avec les espaces blancs, cela devient deux défis de golf distincts.
mardi

13

Marbelous, 103 + 92 = 195

Compteur:

@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
//

Testez ces programmes ici. Les panneaux cylindriques, les bibliothèques d'inclusion et les espaces pour les cellules vides doivent tous être cochés.

Les entrées et sorties se font via STDIN / STDOUT.

Explication

Compteur:

Contre Source

Le chemin bleu reçoit une entrée. Si le caractère est un caractère d'espacement (valeur ascii inférieure à 0x21), le chemin d'accès noir est pris, ce qui se synchronise avec le chemin d'accès violet.

Le chemin violet incrémente simplement une bille stockée dans le &1synchroniseur à chaque fois que le chemin noir est emprunté.

Une fois qu'il n'y a plus d'entrée, le chemin rouge est pris, en imprimant le nombre de caractères d'espacement et en sortant.

Splitter:

Splitter Source

Le programme commence par le chemin bleu, qui boucle jusqu'à ce qu'un caractère non-blanc soit trouvé.

Une fois qu'un caractère non-blanc est récupéré, le chemin noir est pris, lequel imprime ce caractère et déplace l'exécution vers le chemin vert, qui boucle et imprime jusqu'à la réception d'un caractère blanc. L'exécution continue ensuite vers le chemin violet, qui contient 3Wou un séparateur à trois voies.

La branche de gauche déplace l'exécution vers le chemin bleu (et les espaces blancs sont supprimés jusqu'à ce qu'un caractère non blanc soit trouvé).

La branche du milieu définit la copie de l'entrée sur 0 avec ?0(générer un nombre aléatoire entre 0et 0) et ajoute 10 ( 0x0A= nouvelle ligne), qui est ensuite sortie.

Le bon chemin est jeté.


Il semble que le séparateur ne se termine pas s'il reste des espaces.
Martin Ender

12

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

Compteur

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

Splitter

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

Comment ça fonctionne

L’idée est simple: calculez le nombre d’espaces blancs et divisez la chaîne sur des exécutions consécutives d’espaces blancs. Choisissez ensuite l' un d'entre eux repose sur le fait suivant celui des ' !moyens not of space characterqui est falsy, tout '!est le !caractère, qui est truthy.

Code développé:

'! / ' !                              "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";

L'entrée est de STDIN et la sortie est de STDOUT

Essayez-le en ligne ici


10

Mathematica, 44 + 43 = 87 97 octets

Je pensais ajouter une autre langue au mélange.

Compteur:

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

Splitter:

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

Ceci utilise la fonctionnalité de Mathematica selon laquelle la séparation de l’espace est identique à la multiplication. Et que multiplier quelque chose avec 0 soit toujours 0, et ajouter 0 à quelque chose est toujours idempotent.

Pour le compteur, nous comptons d’abord les espaces et nous les ajoutons 0*1*StringSpli*t@#. StringSpliet tne sont pas définis, mais Mathematica utilise le calcul symbolique et traite donc ceux-ci comme une variable et une fonction inconnues. Le 1*est idempotent (juste comme 0+), le le 0*transforme en un zéro. Il est nécessaire de séparer les StringSplitvariables en deux variables, car 0une liste est parfois traitée comme une multiplication scalaire-vecteur qui donne un vecteur (liste) de zéros.

Pour le séparateur, j'utilise le fait qu'il Countexiste aussi mais ne cherche pas dans les chaînes. Il essaie de compter toutes les sous- expressions correspondant au modèle, mais Whitespaceest un modèle qui s'applique uniquement au contenu de la chaîne. Ainsi Countreviendra toujours 0, ce qui fait Stringdisparaître. La multiplication du tableau divisé par 01 = 1est à nouveau idempotente.


10

Ruby, 107 91 octets

Splitter (46 bytes)

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

Compteur (45 octets)

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

pest une méthode prédéfinie qui, sans arguments, renvoie simplement nil. Nous l'utilisons de plusieurs manières. Dans le séparateur, l'initiale pne fait rien. gets(p)lit tout depuis l'entrée standard, puisque le délimiteur est nul. Nous appelons la méthode split intégrée et affectons le résultat à celui-ci p. Ainsi, lorsqu'il ne reçoit pas d'arguments, il est analysé comme une variable. puts p||...court-circuite et affiche chaque élément de la pvariable sur sa propre ligne.

Dans le compteur, nous supprimons la première nouvelle ligne afin que le tableau fractionné soit affecté à la ppplace. Comme nous n’avons pas assigné à p, c’est toujours la méthode sans renvoi, donc la deuxième partie ||est évaluée et transmise puts. $_est une variable magique contenant le résultat de gets, de sorte que la quantité totale d’espaces blancs est la taille de celle-ci moins les caractères non-blancs, qui sont ce qui ppcontient. Je pense qu’il devrait y avoir un moyen plus rapide de compter, mais je ne parviens pas à en trouver un, et de toute façon, l’utilisation du tableau divisé dans le compteur est amusante.


7

Python, 169

C'est presque trop facile de faire cela en Python!

Compteur:

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)

Ils diffèrent par un seul espace, et je ne fais pas de ruse comme diviser un nombre ou un nom de variable en deux :)


6

C, 138 + 136 = 274

Dans chaque cas, le code est un programme qui accepte exactement un argument de ligne de commande et affiche le résultat sur stdout. \tdevrait être remplacé par un caractère de tabulation. Si vous voulez passer un argument contenant des onglets et des nouvelles lignes, il vous appartient de déterminer comment;).

Compte

#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);}

Scission

#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 octets

Compteur:

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
    }

La RegExp(String.fromCharCode(92,115)ligne crée la regex correspondant à un espace, /\s/sans regex ni littéraux de chaîne.

Dans chaque programme, nous utilisons la variable vou vv. Nous stockons le tableau divisé dans cette variable ( vou vv), puis nous modifions notre comportement sur la valeur de v(en attendant, elle vvest ignorée). Dans le comptoir, va une valeur de vérité; dans le séparateur, il a une valeur falsy (parce vvque la valeur est obtenue à la place).


Autre: JavaScript, 250 octets

J'ai une autre solution qui ne gagne aucun prix pour la brièveté, mais j'ai pensé que c'était un défi intéressant d'abuser du comportement d'insertion automatique du point-virgule de JavaScript.

Compteur:

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}

Compteur non-golfé:

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`
}

Le séparateur est exactement le même, à l'exception de la ligne:

break x;

est maintenant

break
x;

L'insertion automatique de points-virgules par JavaScript ne termine normalement pas les instructions multilignes si elles peuvent être comprises sans saut de ligne, mais elle ne tolère pas les sauts de ligne après return, continueou break. Par conséquent, la ligne est simplement lue comme breakce qui sépare uniquement la boucle interne au lieu de sortir de la boucle externe. Le comportement "second-pass" o = a.filter(j=>j)est ensuite exécuté (par opposition à ignoré dans le compteur), car la boucle externe reçoit un second passage.


Est-ce !!xdifférent de la Boolconversion automatique ?
l4m2

@ l4m2 Ce n'est pas! Je l'ai enlevé, puisque filterson retour de rappel est auto-boolé par les mêmes règles que !!. Merci!
apsillers

5

Python, 228 198 182 166 166 146 145 octets

Compteur ( 72 octets ):

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

Splitter ( 73 octets ):

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

ior1est une variable de Falsey, mais i or 1est la vérité. C'est le truc principal.


Cela ne casse-t-il pas si ila chaîne est vide pour le séparateur? Pourrait être corrigé en passant iorbà ior1, ce qui vous permet également de sauvegarder le caractère entre 1et else.
isaacg

@isaacg J'ai totalement oublié que vous pourriez avoir des nombres avec des noms de variables! Merci <3
undergroundmonorail

5

Befunge 98, 61 + 59 = 120

Compteur:

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

Splitter:

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

4

Bash, 75 + 79 = 154 octets

Cela dépend de la capacité de bash à poursuivre l'exécution même si certaines lignes ou parties de ligne du script sont mal formées (dans certaines circonstances). Les espaces sont utilisés pour désactiver les échappements pour certains crochets rapprochés et pour casser un tuyau en le plaçant sur une nouvelle ligne.

Splitter:

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

Compteur:

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

L'entrée se fait via un argument en ligne de commande, la sortie se fait via stdout.

Comme cela repose sur le comportement d'erreur bash, l'utilisateur est censé ignorer stderr.

Exemple d'exécution (montrant une entrée avec une nouvelle ligne et plusieurs espaces contigus):

# 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 octets

Cela ne peut pas rivaliser avec la solution ruby ​​d'Histocrat, mais je pensais que cela valait la peine d'être présenté de toute façon.

J'ai utilisé $zpour nilet nil.to_spourString.new

Le caractère d'espacement supplémentaire que j'ajoute à la fin de l'entrée consiste à forcer le dernier mot à être ajouté à array ( r) - un mot n'est ajouté à la fin du tableau que lorsqu'un caractère d'espacement suit un caractère autre qu'un espace. L'alternative consistait à en ajouter une autre r<<w if waprès le each_bytebloc.

Compte

->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}

Scission

->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, je n'étais pas sûr de la décision à ce sujet. Je l'ai changé pour utiliser if-else au lieu de l'opérateur ternaire - plus de chaînes de caractères.
alexanderbird

3

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

Compteur

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

Splitter

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

Cette solution tire parti du fait que, dans Haskell, les fonctions sont une instance de la classe de type Monad et peuvent donc être utilisées comme actions monadiques dans la notation do.

Dans le premier cas, la fonction résultante du bloc do est le premier argument de pure(qui concerne essentiellement constle type de fonction), ce qui fait du compteur le résultat final et du séparateur en cours d'élimination.

Dans le second cas, il pures’applique uniquement à un seul argument, ce qui en fait une fonction qui renvoie une autre fonction (le compteur). Cependant, le résultat n'est jamais utilisé et donc jeté. Le résultat final est la deuxième ligne du bloc do, le séparateur.


Belle approche! [' ','\t','\n']peut être raccourci à " \t\n".
Laikoni

@Laikoni La description n'autorise que les littéraux de caractères, pas de littéraux de chaîne ou de regex
siracusa

2
Comme le défi ne nécessite pas de gérer la plupart des caractères de contrôle, vous pouvez le réduire en utilisant (<'!')pour tester les espaces.
Ørjan Johansen le

2

Java 8, 187 + 188 = 375

Tout d'abord, je voudrais dire que cette réponse est fortement basée sur celle de @ Ypnypn. J'ai essentiellement remplacé certaines parties par des parties plus courtes (y compris la partie dépendant des espaces, dont l'OMI est la plus importante dans ce défi), mais le code fonctionnel est essentiellement le même.

Comptez les espaces , 187 (renvoie 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);}

Fractionner sur les espaces , 188 (retourne 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 caractères

Deux fonctions prenant et retournant un seul argument. J'ai utilisé la méthode la plus dégoûtante que je puisse imaginer pour battre la règle des espaces identiques, mais les espaces sont donc préservés. Il faut donc probablement sauvegarder des personnages en trouvant un itinéraire plus astucieux pour contourner cela.

(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

Nous définissons le verbe acomme ayant deux actions différentes, selon qu'il soit utilisé avec un argument ou avec deux. Avec un argument, il (e.u:)&9 10 32vérifie si chaque caractère est un espace ou non. Avec deux arguments, c’est a:-.~(<;._1~1,}.), qui prend un vecteur booléen à droite et coupe l’argument de gauche à ces positions, en éliminant les coupes vides avec a:-.~.

Ensuite, nous définissons aale nombre de valeurs True dans le résultat de a, ce qui n'a de sens qu'avec un seul argument. Enfin, nous utilisons aaou a aselon que nous voulions compter ou fractionner les espaces de la chaîne. aafonctionne comme prévu.

La raison a afonctionne parce que quand J voit (f g)y, il considère (f g)un crochet et l'évalue comme y f (g y). Dans ce cas, fest le dyadique aau-dessus duquel se fait la coupe, et gest a[aa, qui calcule la somme de aa, la jette, et calcule (monadique) à anouveau.

Au 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 octets

Compteur

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

Compteur :

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

Splitter :

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

1

Perl 6, 31 + 32 = 63 octets

Compteur

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

Essayez-le en ligne!

?^1est analysé comme ?^ 1ce qui applique l'opérateur de négation booléenne à 1, résultant en False.

Splitter

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

Essayez-le en ligne!

? ^1convertit la plage 0..0 en Bool, résultant en True.


0

Python 2, 98

Fractionnement (49)

Renvoie les jetons dans une liste.

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

Comptage (49)

Retourne une liste de longueur un contenant le nombre de caractères d'espace. Cela entraînera probablement une erreur d'exécution, mais la fonction fpeut être utilisée après avoir exécuté le code.

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

0

C (gcc) , 88 + 89 = 177 octets

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

Compteur

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;}

Compteur

Fatigué

Prend l'entrée comme argument de fonction. La fonction de comptage renvoie le nombre d'espaces. La fonction de division utilise STDOUT pour sa sortie (mais elle renvoie également le nombre d'espaces moins un).

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 octets

  • Aucun programme / fonction ne peut contenir de chaîne ou de littéral de regex

Je ne suis pas sûr qu'il soit [^$IFS]qualifié, car il est utilisé dans la recherche de motifs. Voici une solution 45 + 45 en cas d’interdiction.


Divisé:

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

Compter:

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

L' :intégré est équivalent à true, nous l'utilisons comme un élément entre un commentaire et / dev / null (car les commentaires ne sont pas autorisés) en lui envoyant l'extension non souhaitée.

Zsh a une fonction intégrée pour la division sur les espaces blancs, cet être ${=var}. Cela rend difficile toute combinaison logique autre que l'exécution et la suppression de celle que nous ne voulons pas.

Essayez-le en ligne!

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.