Programme le plus court pour diviser une chaîne en non-chiffres sans RegExps

16

EDIT: Si vous utilisez Lisp, j'ai donné quelques lignes directrices en bas pour compter les octets.

Objectif: créer la fonction la plus courte qui divise une chaîne en non-chiffres et renvoie un tableau composé uniquement de chiffres dans chaque chaîne, sans utiliser d'expressions régulières. Les zéros de tête doivent être inclus dans chaque chaîne.

Classement actuel (séparé en catégories):

  • C / C ++ / C # / Java: 68 (C) ....
  • GolfScript / APL / J: 13 (APL)
  • Tous les autres: 17 (Bash, utilisations tr), 24 (Ruby)

Règles:

(Je m'excuse pour la lenteur)

  1. Le format doit être une fonction avec un seul argument de chaîne. Jusqu'à deux arguments supplémentaires peuvent être ajoutés si nécessaire pour le bon retour du tableau (par exemple sh / csh / DOS Batch a besoin d'une référence de variable supplémentaire pour retourner, etc.).
  2. La déclaration de fonction principale ne compte pas, pas plus que l'importation d'autres bibliothèques standard. `# include`s,` import`s et `using`s ne comptent pas. Tout le reste fait. Cela inclut les fonctions `# define`s et helper. Désolé pour la confusion. Référez-vous à cela comme un guide utile sur ce qui compte / ne compte pas (écrit en syntaxe de style C)
    // ne compte pas dans le total, peut être omis sauf si
    // non évident, comme la moitié de la bibliothèque standard de Java.
    #include <stdio.h>
    
    importez some.builtin.Class // ne compte pas, voir ci-dessus
    
    #define printf p // compte pour le total
    
    / * Toute autre directive de préprocesseur, etc. compte. * /
    
    int i = 0; // compte
    
    someFunction (); // compte
    
    char [] [] myMainSplitFunction (char [] [] array) {// ne compte pas
      // Tout ici compte
      return returnArray; // Même cela compte.
    } // ne compte pas
    
    / * Tout ici compte, y compris la déclaration * /
    char [] [] someHelperFunction (char [] chaîne) {
      // des trucs
    } // même cela compte
    
  3. La sortie doit être un tableau de chaînes ou similaire (les listes de tableaux en Java et similaires sont acceptables). Des exemples de sortie acceptées: String[], char[][], Array, List, et Array(objet).
  4. Le tableau doit contenir uniquement des primitives de chaîne de longueur variable ou des objets chaîne. Aucune chaîne vide ne doit être présente dans le retour, à l'exception ci-dessous. Remarque: les chaînes doivent contenir une chaîne de correspondances consécutives, comme l'exemple d'entrée et de sortie ci-dessous.
  5. S'il n'y a pas de correspondance, le corps de la fonction doit renvoyer nullun tableau / liste vide ou un tableau / liste contenant une chaîne vide.
  6. Aucune bibliothèque externe autorisée.
  7. Les terminaisons de ligne DOS comptent comme un octet, pas deux (déjà couvertes en méta, mais les besoins sont soulignés)
  8. Et la plus grande règle ici: aucune expression régulière n'est autorisée.

C'est une question de , donc la plus petite taille gagne. Bonne chance!

Et voici quelques exemples d'entrées et de sorties (avec des échappements de style C):

Entrée: "abc123def456"
Sortie: ["123", "456"]

Entrée: "aitew034snk582: 3c"
Sortie: ["034", "582", "3"]

Entrée: "as5493tax54 \\ [email protected]"
Sortie: ["5493", "54", "430", "52", "9"]

Entrée: "sasprs] tore \" re \\ forz "
Sortie: null, [], [""] ou similaire

Veuillez mettre combien d'octets utilisés par vos réponses, et comme toujours, bon golf!


Lignes directrices pour Lisp

Voici ce qui compte et ne compte pas dans les dialectes lisp:

;;; Option 1

(defun extract-strings (ab); ne compte pas
  (des trucs) ;;; Tout ici compte
); Ne compte pas

;;; Option 2

(defun extract-strings (string & aux (start 0) (end 0)); ne compte pas
  (des trucs) ;;; Tout ici compte
); Ne compte pas.
Tous les autres lambdas comptent entièrement pour le nombre d'octets.

Isiah Meadows
la source
Cela n'a-t-il pas été demandé auparavant?
Ismael Miguel
1
Oui, mais je l'ai redemandé sur Meta et y ai apporté des modifications substantielles avant de le publier à nouveau ici. Pour cette raison, il ne doit pas être classé comme un doublon (l'autre connexe doit être fermé s'il ne l'est pas déjà).
Isiah Meadows
2
Votre «golf» ne devrait-il pas être affiché comme réponse?
MrWhite
4
Désolé, mais -1 pour avoir interdit GolfScript. Toutes les langues devraient être autorisées.
Poignée de porte
1
@ Doorknob C'est vrai, mais je comprends aussi les sentiments du PO. Les gens devraient avoir une chance de concourir même s'ils ne parlent pas GolfScript, J ou APL (et je suis coupable d'avoir lu ce dernier dans ces compétitions.) Pouvez-vous jeter un coup d'œil à ma proposition dans le fil auquel il est lié?
Tobia

Réponses:

10

APL, 13 caractères

(ou 28/30 octets, lire ci-dessous)

{⍵⊂⍨⍵∊∊⍕¨⍳10}

Je vois que vous avez banni GolfScript de votre question. Je comprends votre sentiment, mais j'espère que cette communauté n'interdira pas finalement APL, car c'est un langage de programmation vraiment remarquable avec une longue histoire, sans parler de beaucoup de plaisir à coder. Peut-être qu'il pourrait simplement être évalué différemment, si les gens estiment que la concurrence est injuste. Je publierai mes réflexions sur cette question dans le fil que vous avez lié.

Sur ce même jeton, j'ai toujours ajouté une note de bas de page à mes messages APL, affirmant que l'APL pouvait être marqué comme 1 char = 1 octet. Ma revendication repose sur le fait que quelques implémentations APL (principalement commerciales) prennent toujours en charge leur propre codage hérité sur un octet, avec les symboles APL mappés sur les valeurs supérieures de 128 octets. Mais c'est peut-être trop étiré, auquel cas vous voudrez peut-être marquer cette entrée comme 28 octets en UTF-16 ou 30 octets en UTF-8.

Explication

{        ⍳10}  make an array of naturals from 1 to 10
       ⍕¨      convert each number into a string
      ∊        concatenate the strings into one (it doesn't matter that there are two 1s)
    ⍵∊         test which chars from the argument are contained in the digit string
 ⍵⊂⍨           use it to perform a partitioned enclose, which splits the string as needed

Exemples

      {⍵⊂⍨⍵∊∊⍕¨⍳10} 'ab5c0x'
 5  0 
      {⍵⊂⍨⍵∊∊⍕¨⍳10}  'z526ks4f.;8]\p'
 526  4  8 

Le format de sortie par défaut d'un tableau de chaînes ne précise pas le nombre de chaînes présentes dans le tableau, ni le nombre de blancs. Mais une manipulation rapide pour ajouter des guillemets devrait être assez claire:

      {q,⍵,q←'"'}¨ {⍵⊂⍨⍵∊∊⍕¨⍳10} 'ab5c0x'
 "5"  "0" 
      {q,⍵,q←'"'}¨ {⍵⊂⍨⍵∊∊⍕¨⍳10}  'z526ks4f.;8]\p'
 "526"  "4"  "8" 
Tobia
la source
En ce qui concerne votre commentaire, je pense que pour les autres langues en concurrence équitable avec les "raccourcis", il faut compter chaque symbole dans les autres langues comme un caractère. Par exemple, ma solution Mathematica publiée ici devrait être comptée comme 7 (plus ou moins). Je pense que concevoir un langage avec des jetons compressés n'est pas du tout un mérite.
Dr belisarius
Pourriez-vous fournir un vidage hexadécimal de votre golf? Je ne peux pas lire certains des caractères.
Isiah Meadows
@impinball Comment l'hexdump vous aiderait-il? Ce n'est pas comme si vous voyiez ce qui se fait.
mniip
@impinball le code APL est {omega enclose commute omega epsilon epsilon format each iota 10}. Si vous avez besoin des valeurs Unicode, vous pouvez simplement les copier et les coller dans n'importe quel outil en ligne , même si vous ne pouvez pas voir les caractères (ce qui est étrange, car la plupart des polices Unicode modernes ont les symboles APL). {\ u2375 \ u2282 \ u2368 \ u2375 \ u220a \ u220a \ u2355 \ u00a8 \ u237310} (attention au dernier "10" qui ne fait pas partie de la séquence d'échappement)
Tobia
1
Au lieu de ∊⍕¨⍳10, ne pourriez-vous pas simplement utiliser ⎕D? Cela devrait être la constante '0123456789'. Dyalog APL le supporte à tout le moins, tout comme le NARS2000.
marinus
5

Python 47

la mise en oeuvre

f=lambda s:"".join([' ',e][e.isdigit()]for e in s).split()

Démo

>>> sample=["abc123def456","aitew034snk582:3c","as5493tax54\\[email protected]","sasprs]tore\"re\\forz"]
>>> [f(data) for data in sample]
[['123', '456'], ['034', '582', '3'], ['5493', '54', '430', '52', '9'], []]

Algorithme

Convertissez chaque caractère non numérique en espace, puis divisez la chaîne résultante. Une approche simple et claire.

Et une solution amusante avec itertools (71 caractères)

f1=lambda s:[''.join(v)for k,v in __import__("itertools").groupby(s,key=str.isdigit)][::2]
Abhijit
la source
4

Rubis, 70

f=->(s){s.chars.chunk{|c|c.to_i.to_s==c}.select{|e|e[0]}.transpose[1]}

Version en ligne pour les tests

Étant donné que la conversion de tout caractère non numérique en un entier renvoie 0 en Ruby (avec to_i), la conversion de chaque caractère en entier et de retour en caractère est la façon non rationnelle de rechercher un chiffre ...

David Herrmann
la source
Vous pouvez également faire un membre ('0' .. '9').? pour chaque char, mais ce que vous avez fait est déjà plus court
fgp
Vous avez certainement raison - j'aurais dû dire: "une" façon;)
David Herrmann
4

bash, 26 (contenu de la fonction: 22 + surcharge d'affectation de tableau 4)

Cela ne va pas battre l'autre bashréponse , mais c'est intéressant car cela pourrait vous faire double-prendre:

f()(echo ${1//+([!0-9])/ })

L'utilisation est:

$ a=(`f "ab5c0x"`); echo ${a[@]}
5 0
$ a=(`f "z526ks4f.;8]\p"`); echo ${a[@]}
526 4 8
$ 

Au premier coup d'œil, cela //+([!0-9])/ressemble beaucoup à une substitution d'expression rationnelle, mais ce n'est pas le cas. Il s'agit d'une expansion de paramètre bash , qui suit des règles de correspondance de modèles , au lieu de règles d'expression régulière.

Le retour des vrais types de tableaux bash à partir des fonctions bash est une douleur, j'ai donc choisi de renvoyer une liste délimitée par des espaces à la place, puis de convertir en tableau dans une affectation de tableau en dehors de l'appel de fonction. Donc, par souci d'équité, je pense que l' (` `)appel autour de la fonction devrait être inclus dans mon score.

Traumatisme numérique
la source
3

Mathematica 32

StringCases[#,DigitCharacter..]&

Usage

inps ={"abc123def456", "aitew034snk582:3c", "as5493tax54\\[email protected]", 
        "sasprs]tore\"re\\forz"}  
StringCases[#,DigitCharacter..]&/@inps

{{"123", "456"}, 
 {"034", "582", "3"}, 
 {"5493", "54", "430", "52", "9"}, 
 {}
}

L'équivalent utilisant des expressions régulières est beaucoup plus long!:

StringCases[#, RegularExpression["[0-9]+"]] &
Dr. belisarius
la source
Mathematica aspire à regex.
CalculatorFeline
3

Bash, 21 octets 17/21 octets (amélioré par DigitalTrauma )

Création d'une liste séparée par des espaces avec tr

function split() {
tr -c 0-9 \ <<E
$1
E
}

remplace tout non numérique par un espace

Usage

$ for N in $(split 'abc123def456'); do echo $N; done
123
456

Éditer

comme indiqué par les commentaires ci-dessous, le code peut être réduit à 17 octets:

function split() (tr -c 0-9 \ <<<$1)

et comme le résultat n'est pas à proprement parler un tableau Bash, l'utilisation doit être

a=(`split "abc123def456"`); echo ${a[@]}

et le supplément (``)doit être compté

Coaumdio
la source
1
Gah tu m'as battu dessus! Mais pourquoi ne pas utiliser une chaîne ici au lieu d'un document ici? Aussi , vous pouvez enregistrer une nouvelle ligne à la fin de la teneur en fonction que vous utilisez au (blah)lieu de {blah;}: split()(tr -c 0-9 \ <<<$1). De cette façon, votre corps de fonction ne comporte que 17 caractères.
Digital Trauma
1
Votre fonction renvoie une "liste séparée par des espaces" au lieu d'un tableau. Certes , le retour de véritables tableaux de la fonction bash est maladroit, mais vous pouvez au moins affecter le résultat de votre fonction à un tableau dans votre utilisation: a=($(split "12 3a bc123")); echo ${a[@]}. On pourrait faire valoir que "($ ())" doit être compté dans votre score
Digital Trauma
Avant d'explorer l' trapproche, j'ai essayé de le faire avec une expansion des paramètres . trest certainement la meilleure approche pour le golf.
Digital Trauma
Avez-vous essayé d'entourer le travec l'opérateur d'extension? Cela aboutirait à quelque chose comme ($(tr...)), et là où la déclaration de fonction ne compte pas, les parenthèses externes ne compteraient pas contre vous. Ce ne serait que la partie de substitution de commande.
Isiah Meadows
Je ne vois pas comment cela devrait fonctionner, mais je ne parle pas couramment les tableaux Bash. Quoi qu'il en soit, la (``)construction est de 1 caractère meilleure que ($())celle et doit être préférée.
Coaumdio
2

Smalltalk (Smalltalk / X), 81

f := [:s|s asCollectionOfSubCollectionsSeparatedByAnyForWhich:[:ch|ch isDigit not]]

valeur f: 'abc123def456' -> OrderedCollection ('123' '456')

Valeur f: 'aitew034snk582: 3c' -> OrderedCollection ('034' '582' '3')

valeur f: 'as5493tax54 \ [email protected]' -> OrderedCollection ('5493' '54' '430' '52' '9')

valeur f: 'sasprs] tore \ "re \ forz' -> OrderedCollection ()

soupir - Smalltalk a tendance à utiliser des noms de fonction longs veeeery ...

blabla999
la source
2
Est-ce un nom de fonction? o__O
Tobia
@tobia Apparemment ...
Isiah Meadows
asCollectionOfSubCollectionsSeparatedByAnyForWhichಠ_ಠ Ce nom est trop long
TuxCrafting
1

R, 81

f=function(x){
s=strsplit(x,"",T)[[1]]
i=s%in%0:9
split(s,c(0,cumsum(!!diff(i))))[c(i[1],!i[1])]
}

La fonction accepte une chaîne et renvoie une liste de chaînes.

Exemples:

> f("abc123def456")
$`1`
[1] "1" "2" "3"

$`3`
[1] "4" "5" "6"

-

> f("aitew034snk582:3c")
$`1`
[1] "0" "3" "4"

$`3`
[1] "5" "8" "2"

$`5`
[1] "3"

-

> f("as5493tax54\\[email protected]")
$`1`
[1] "5" "4" "9" "3"

$`3`
[1] "5" "4"

$`5`
[1] "4" "3" "0"

$`7`
[1] "5" "2"

$`9`
[1] "9"

-

> f("sasprs]tore\"re\\forz")
$<NA>
NULL

Remarque: $xest le nom de l'élément de liste.

Sven Hohenstein
la source
1

Perl, 53

Edit: sur aucune correspondance, sub retourne maintenant la liste avec une chaîne vide (au lieu de la liste vide) comme requis.

Il évite également le fractionnement sur un seul caractère d'espace, car il déclenche le fractionnement sur tout comportement d' espace blanc , ce qui viole probablement les règles. Je pourrais utiliser un / /délimiteur, qui se diviserait sur un seul espace, mais paradoxalement, cela ressemblerait à l'utilisation d'un modèle d'expression régulière. Je pourrais utiliser unpackau prix de quelques caractères supplémentaires et ainsi me débarrasser splitcomplètement de la controverse, mais je pense que, ce que je termine avec, se diviser sur un caractère littéral (autre que l'espace) est OK.

sub f{shift if(@_=split a,pop=~y/0-9/a/csr)[0]eq''and$#_;@_}

Et, non, l'opérateur de translittération de Perl ne fait pas d'expressions régulières. Je peux dérouler la plage 0-9 0123456789si c'est le problème.

user2846289
la source
Tant qu'il n'utilise pas d'expressions régulières, il est valide.
Isiah Meadows
Mon Perl n'est pas si fort. Si je comprends le code, vous remplacez les non-chiffres par un non-chiffre spécifique, puis vous fractionnez sur ce non-chiffre choisi, puis vous filtrez les chaînes vides. Est-ce une lecture correcte?
Tim Seguine
1
@TimSeguine: Pas exactement. Les non-chiffres sont remplacés et écrasés en un seul caractère, le fractionnement sur lequel produit une chaîne vide si ce délimiteur se trouve être au début. Il est ensuite déplacé si la liste contient d'autres entrées.
user2846289
La liste vide est correcte.
Isiah Meadows
1

C, 68 octets (uniquement le corps de la fonction)

void split (char *s, char **a) {
int c=1;for(;*s;s++)if(isdigit(*s))c?*a++=s:0,c=0;else*s=0,c=1;*a=0;
}

Le premier argument est la chaîne d'entrée, le second est le tableau de sortie, qui est un tableau de chaînes terminé par NULL. Une mémoire suffisante doit être réservée aavant d'appeler la fonction (pire cas:sizeof(char*)*((strlen(s)+1)/2) .

La chaîne d'entrée est modifiée par la fonction (chaque caractère non numérique est remplacé par '\0')

Exemple d'utilisation

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>

void split (char *s, char **a) {
int c=1;for(;*s;s++)if(isdigit(*s))c?*a++=s:0,c=0;else*s=0,c=1;*a=0;
}   

void dump(char **t) {
    printf("[ ");for(;*t;t++)printf("%s ", *t);printf("]\n");
}   

int main() {
    char **r = malloc(1024);
    char test1[] = "abc123def456";
    char test2[] = "aitew034snk582:3c";
    char test3[] = "as5493tax54\\[email protected]";
    char test4[] = "sasprs]tore\"re\\forz";
    split(test1,r); 
    dump(r);
    split(test2,r); 
    dump(r);
    split(test3,r); 
    dump(r);
    split(test4,r); 
    dump(r);
    return 0;
}

Production

[ 123 456 ]
[ 034 582 3 ]
[ 5493 54 430 52 9 ]
[ ]

Version sans golf:

void split (char *s, char **a) {
    int c=1; // boolean: the latest examined character is not a digit
    for(;*s;s++) {
        if(isdigit(*s)) {
            if(c) *a++ = s; // stores the address of the beginning of a digit sequence
            c=0;
        } else {
            *s=0; // NULL-terminate the digit sequence
            c=1;
        }   
    }   
    *a = 0; // NULL-terminate the result array
} 
Coaumdio
la source
1

VBScript, 190 (164 sans déclaration de fonction)

Function f(i)
For x=1 To Len(i)
c=Mid(i,x,1)
If Not IsNumeric(c) Then
Mid(i,x,1)=" "
End If
Next
Do
l=Len(i)
i=Replace(i,"  "," ")
l=l-Len(i)
Loop Until l=0
f=Split(Trim(i)," ")
End Function

Bien qu'il ne soit pas du tout compétitif, je suis surpris que VBScript soit aussi court sur ce sujet étant donné sa verbosité (13 octets pour les CR uniquement). Il parcourt la chaîne en remplaçant tous les caractères non numériques par des espaces, puis réduit tous les espaces en espaces simples, puis utilise un délimiteur d'espace pour le diviser.

Cas de test

Input: "ab5c0x"
Output: 5,0

Input: "z526ks4f.;8]\p"
Output: 526,4,8
Comintern
la source
Les fins de ligne DOS comptent comme un caractère pour autant que j'ai lu sur la méta.
Isiah Meadows du
Je vous ai suggéré une modification.
Isiah Meadows
Le décompte suppose déjà des fins de ligne de 1 octet de style Linux. Je reçois 190 caractères par mon décompte (juste vérifié à nouveau).
Comintern
D'accord. Je dois avoir mal compté.
Isiah Meadows
1

Lisp commun (1 selon la lettre; ≈173 selon l'esprit)

Voici une version lisible. Le nombre d'octets est assez élevé en raison des noms longs dans des choses commedigit-char-p et position-ifet vector-push-extend.

(defun extract-numeric-substrings (string &aux (start 0) (end 0) (result (make-array 0 :adjustable t :fill-pointer 0)))
  (loop 
     (unless (and end (setq start (position-if #'digit-char-p string :start end)))
       (return result))
     (setq end (position-if (complement #'digit-char-p) string :start (1+ start)))
     (vector-push-extend (subseq string start end) result)))
(extract-numeric-substrings "abc123def456")
#("123" "456")

(extract-numeric-substrings "aitew034snk582:3c")
#("034" "582" "3")

(extract-numeric-substrings "as5493tax54\\[email protected]")
#("5493" "54" "430" "52" "9")

(extract-numeric-substrings "sasprs]tore\"re\\forz")
#()

Le concept de "déclaration de fonction" est en quelque sorte vague. Voici une version qui n'a qu'un octet (le caractère xdans le corps de la fonction); tout le reste est regroupé dans les variables auxiliaires de la liste lamba de la fonction (partie de la déclaration de la fonction):

(defun extract-numeric-substrings (string 
                                   &aux (start 0) (end 0) 
                                   (result (make-array 0 :adjustable t :fill-pointer 0))
                                   (x (loop 
                                         (unless (and end (setq start (position-if #'digit-char-p string :start end)))
                                           (return result))
                                         (setq end (position-if (complement #'digit-char-p) string :start (1+ start)))
                                         (vector-push-extend (subseq string start end) result))))
  x)

Le nombre d'octets réel dépendra du nombre de déclarations auxiliaires qui devront être déplacées dans le corps pour que cela soit jugé acceptable. Un changement de nom de fonction locale serait également utile (par exemple, raccourcir position-ifcar il apparaît deux fois, utiliser des variables à lettre unique, etc.)

Ce rendu du programme comporte 220 caractères:

(LOOP(UNLESS(AND END(SETQ START(POSITION-IF #'DIGIT-CHAR-P STRING :START END)))(RETURN RESULT))(SETQ END(POSITION-IF(COMPLEMENT #'DIGIT-CHAR-P)STRING :START(1+ START)))(VECTOR-PUSH-EXTEND(SUBSEQ STRING START END)RESULT))

Si rien d'autre, cela devrait promouvoir les variables Common Lisp & aux .

Cela peut être écrit de manière plus concise avec loop , bien sûr:

(defun extract-numeric-substrings (s &aux (b 0) (e 0) (r (make-array 0 :fill-pointer 0)))
  (loop 
     with d = #'digit-char-p 
     while (and e (setq b (position-if d s :start e)))
     finally (return r)
     do 
       (setq e (position-if-not d s :start (1+ b)))
       (vector-push-extend (subseq s b e) r)))

Le loopformulaire, sans espace supplémentaire, contient 173 caractères:

(LOOP WITH D = #'DIGIT-CHAR-P WHILE(AND E(SETQ B(POSITION-IF D S :START E)))FINALLY(RETURN R)DO(SETQ E(POSITION-IF-NOT D S :START(1+ B)))(VECTOR-PUSH-EXTEND(SUBSEQ S B E)R))
Joshua Taylor
la source
Je compterais à partir (resultde la parenthèse finale pour être le corps. La partie qui définit le nom et les paramètres est la déclaration.
Isiah Meadows
Veuillez vous référer à la règle 2 sur mes règles modifiées pour voir de quoi je parle vraiment dans une déclaration de fonction (en gros, déclarer le nom de la fonction, les paramètres et si requis syntaxiquement, ce qui est rare parmi les langages interprétés, le type de retour).
Isiah Meadows
@impinball Oui, le compte "1" est en quelque sorte une blague, mais la partie importante ici est celle qui result est déclarée comme paramètre ici; il a juste une forme d'initialisation très simple. C'est la même chose, en principe, qu'un argument facultatif avec une valeur par défaut calculée par une expression complexe. (Dans des cas plus simples, il est facile d'imaginer quelque chose comme char* substring( char *str, int begin, int end(0) )dans un langage avec une syntaxe de type C pour spécifier qui endest facultatif et que s'il n'est pas fourni, alors sa valeur est 0. Je souligne simplement le fait que certains de ces termes
Joshua Taylor
@impinball n'est pas assez concret et le langage n'est pas assez agnostique pour empêcher un certain nombre d'octets trollish. :)
Joshua Taylor
La première partie qui ne spécifie pas de paramètres est l'endroit où je voudrais compter les statistiques (par exemple (defun fn (string &aux (start 0) (end 0), ne compterait pas, mais tout ce qui reste dans le lambda le ferait).
Isiah Meadows
0

JavaScript, 240 octets

Et pour ceux d'entre vous qui sont curieux, voici mon golf probablement énorme:

function split(a) { // begin function
function f(c){for(var a=-1,d=9;d--;){var e=c.indexOf(d+"");0
>e||e<a&&(a=e)}return 0<a?a:null}var c=f(a);if(null==c)retur
n null;var d=[];for(i=0;;){a=a.substring(c);d[i]||(d[i]="");
c=f(a);if(null==c)break;d[i]+=a.charAt(c);0<c&&i++}return d;
} // end function

Ci-dessus en joli imprimé:

function split(a) {
    function f(c) {
        for (var a = -1, d = 9;d--;) {
            var e = c.indexOf(d + "");
            0 > e || e < a && (a = e);
        }
        return 0 < a ? a : null;
    }
    var c = f(a);
    if (null == c) return null;
    var d = [];
    for (i = 0;;) {
        a = a.substring(c);
        d[i] || (d[i] = "");
        c = f(a);
        if (null == c) break;
        d[i] += a.charAt(c);
        0 < c && i++;
    }
    return d;
}

Ci-dessus dans le code descriptif normal

function split(a) {
    function findLoop(string) {
        var lowest = -1;
        var i = 9;
        while (i--) {
            var index = string.indexOf(i + '');
            if (index < 0) continue;
            if (index < lowest) lowest = index;
        }
        return (lowest > 0) ? lowest : null;
    }
    var index = findLoop(a);
    if (index == null) return null;
    var ret = [];
    i = 0;
    for ( ; ; ) {
        a = a.substring(index);
        if (!ret[i]) ret[i] = '';
        index = findLoop(a);
        if (index == null) break;
        ret[i] += a.charAt(index);
        if (index > 0) i++;
    }
    return ret;
}
Isiah Meadows
la source
0

PHP 134

function f($a){
$i=0;while($i<strlen($a)){!is_numeric($a[$i])&&$a[$i]='-';$i++;}return array_filter(explode('-',$a),function($v){return!empty($v);});
}
Einacio
la source
Vous pouvez le raccourcir en omettant le rappel à array_filter. Cela supprimera automatiquement toutes les entrées qui sont falselorsqu'elles sont castées en booléens.
kelunik
@kelunik qui filtrerait également les 0
Einacio
0

C, 158

#define p printf
char s[100],c;int z,i;int main(){while(c=getchar())s[z++]=(c>47&&c<58)*c;p("[");for(;i<z;i++)if(s[i]){p("\"");while(s[i])p("%c",s[i++]);p("\",");}p("]");}

Étant donné que C n'a pas de fonctions d'impression de tableau intégrées, j'ai dû faire ce travail par moi-même, donc je m'excuse qu'il y ait une virgule finale dans chaque sortie. Essentiellement, ce code fait qu'il lit la chaîne s'il ne s'agit pas d'un chiffre, il le remplace par '\ 0', puis je passe en revue le code et j'imprime toutes les chaînes de chiffres. (EOF = 0)

Entrée: ab5c0x
Sortie: ["5", "0",]

Entrée: z526ks4f.; 8] \ p
Sortie: ["526", "4", "8",]

DEMANDER
la source
Selon les règles de la question (règle 2), il suffit de compter les caractères dans le corps de la fonction. Votre solution serait donc en réalité inférieure à 170 octets. Je ne sais pas si le nombre inclut des prototypes variables en dehors du corps de la fonction.
grovesNL
Je vais modifier les règles à ce sujet: #defines, les déclarations de variables, etc. compteront, mais la déclaration de fonction ne le sera pas.
Isiah Meadows
De plus, la dernière fois que j'ai vérifié, il y avait un type en C noté comme char[][]légal. Si vous revenez comme ça (ou char**), tout ira bien.
Isiah Meadows, le
Il ne doit pas être une sortie texte? Je pensais que le programme était censé produire le tableau dans un format de chaîne
ASKASK
0

C #, 98

static string[] SplitAtNonDigits(string s)
{
    return new string(s.Select(c=>47<c&c<58?c:',').ToArray()).Split(new[]{','},(StringSplitOptions)1);
}

Tout d'abord, cela utilise la .Select()méthode d'extension LINQ pour transformer tous les non-chiffres en virgules. string.Replace()serait préférable, car il renvoie un stringplutôt qu'un IEnumerable<char>, mais string.Replace()ne peut prendre qu'un seul caractère ou chaîne et ne peut pas utiliser un prédicat comme char.IsDigit()ou47<c&c<58 .

Comme mentionné, .Select()appliqué à une chaîne renvoie un IEnumerable<char>, nous devons donc le reconvertir en chaîne en le transformant en tableau et en passant le tableau dans lestring constructeur.

Enfin, nous avons divisé la chaîne à l'aide de virgules string.Split(). (StringSplitOptions)1est une façon plus courte de dire StringSplitOptions.RemoveEmptyEntries, qui prendra automatiquement en charge plusieurs virgules consécutives et virgules au début / fin de la chaîne.

BenM
la source
1
Au lieu de char.IsDigit(c), vous pouvez utiliser'/'<c&&c<':'
grovesNL
1
Bon point ... ou mieux encore, 47<c&&c<58. (Franchement, je suis surpris que cela fonctionne avec des chiffres, mais apparemment c'est le cas).
BenM
1
Et je peux enregistrer un caractère très précieux en utilisant un simple «&» au lieu d'un double «&&». En C #, cet ET toujours logique lorsque les deux opérandes sont des booléens - il ne fait qu'un ET au niveau du bit quand ils sont des entiers.
BenM
Joli. Je ne savais pas qu'il était capable de faire ça.
grovesNL
Une variante légèrement plus courte consiste à diviser l'espace blanc au lieu de ,, puis à supprimer manuellement les éléments videsreturn new string(s.Select(c=>47<c&c<58?c:' ').ToArray()).Split().Where(a=>a!="").ToArray();
VisualMelon
0

JS / Noeud: 168 162 147 138 Chars

function n(s){
var r=[];s.split('').reduce(function(p,c){if(!isNaN(parseInt(c))){if(p)r.push([]);r[r.length-1].push(c);return 0;}return 1;},1);return r;
}

Version embellie:

function n(s) {
  var r = [];
  s.split('').reduce(function (p, c) {
    if (!isNaN(parseInt(c))) {
      if (p) {
        r.push([]);
      }
      r[r.length - 1].push(c);
      return 0;
    }
    return 1;
  }, 1);
  return r;
}
palanik
la source
Cette question ne veut que le tableau retourné, vous pouvez donc supprimer console.log(r)et d'autres choses
Pas que Charles
La déclaration de fonction ne compte pas dans le score (la raison est d'aider à égaliser les chances)
Isiah Meadows
D'accord. Ajustement du score selon le commentaire de @ impinball. (En fait, il y a deux fonctions déclarées ici. Le nombre de caractères inclut la fonction anonyme)
palanik
Cela devrait. J'ai mis à jour les règles pour mieux l'expliquer.
Isiah Meadows
Pendant ce temps, nous
avons trouvé
0

Rubis, 24

f=->s{s.tr("
-/:-~",' ').split}

Définit les chiffres en utilisant un espace négatif dans la plage ascii imprimable.

histocrate
la source
La déclaration de fonction ne compte pas.
Isiah Meadows
0

php , 204

function s($x){$a=str_split($x);$c=-1;$o=array();
for($i= 0;$i<count($a);$i++){if(ord($a[$i])>=48&&ord($a[$i])<=57)
{$c++;$o[$c]=array();}while(ord($a[$i])>=48&&ord($a[$i])<=57)
{array_push($o[$c],$a[$i]);$i++;}}return $o;}

Code descriptif:

function splitdigits($input){

    $arr = str_split($input);
    $count = -1;
    $output = array();
    for($i = 0; $i < count($arr); $i++){


    if(ord($arr[$i]) >= 48 && ord($arr[$i]) <= 57){
        $count++;
        $output[$count] = array();
    }

    while(ord($arr[$i]) >= 48 && ord($arr[$i]) <= 57){
        array_push($output[$count], $arr[$i]);
        $i++;
    } 

}

return $output;
}

C'est un code assez long et je suis sûr qu'il y aura une version php beaucoup plus courte pour ce code golf. C'est ce que je pourrais trouver en php.

palerdot
la source
il y a quelques améliorations: vous pouvez remplacer array()par [], array_push($output[$count], $arr[$i]);avec $output[$count][]=$arr[$i];et les ord()chèques avec is_numeric(). et vous n'avez même pas besoin de diviser la chaîne pour parcourir ses caractères. aussi, seul le code interne de la fonction compte, donc comme c'est votre nombre de caractères est 204.
Einacio
La déclaration de fonction ne compte pas. Référez-vous à la règle 2 comme guide sur ce qui compte et ce qui ne l'est pas.
Isiah Meadows
0

Python

def find_digits(_input_):
    a,b = [], ""
    for i in list(_input_):
        if i.isdigit(): b += i
        else:
            if b != "": a.append(b)
            b = ""
    if b != "": a.append(b)
    return a
J'ai quitté StackExchange
la source
0

Python 104 83

def f(s, o=[], c=""):
    for i in s:
        try:int(i);c+=i
        except:o+=[c];c=""
    return [i for i in o+[c] if i]

La réponse @Abhijit est beaucoup plus intelligente, ce n'est qu'une version "minifiée" de ce que j'avais en tête.

assert f("abc123def456") == ["123", "456"]
assert f("aitew034snk582:3c") == ["034", "582", "3"]
assert f("as5493tax54\\[email protected]") == ["5493", "54", "430", "52", "9"]
assert f("sasprs]tore\"re\\forz") == []

Cela ne produit aucune sortie, donc le code fonctionne, s'il est exécuté un par un, car certaines variables sont définies lors de la déclaration.

gcq
la source
Vous n'avez pas à compter la déclaration de fonction, si vous l'avez fait. Juste comme un avertissement
Isiah Meadows
0

PHP 98 89

Comme dans la réponse bash de DigitalTrauma, cela n'utilise pas d'expression régulière.

function f($x) {
// Only the following line counts:
for($h=$i=0;sscanf(substr("a$x",$h+=$i),"%[^0-9]%[0-9]%n",$j,$s,$i)>1;)$a[]=$s;return@$a;
}

Cas de test:

php > echo json_encode(f("abc123def456")), "\n";
["123","456"]
php > echo json_encode(f("aitew034snk582:3c")), "\n";
["034","582","3"]
php > echo json_encode(f("as5493tax54\\[email protected]")), "\n";
["5493","54","430","52","9"]
php > echo json_encode(f("sasprs]tore\"re\\forz")), "\n";
null
Veuillez vous lever
la source
0

Haskell 31

{-# LANGUAGE OverloadedStrings #-}
import Data.Char (isDigit)
import Data.Text (split)

f=filter(/="").split(not.isDigit)

Il fractionne la chaîne sur tous les caractères non numériques et supprime les chaînes vides générées par des délimiteurs consécutifs.

lortabac
la source
0

VBA 210, 181 sans déclaration de fonction

Function t(s)
Dim o()
For Each c In Split(StrConv(s,64),Chr(0))
d=IsNumeric(c)
If b And d Then
n=n&c
ElseIf d Then:ReDim Preserve o(l):b=1:n=c
ElseIf b Then:b=0:o(l)=n:l=l+1:End If:Next:t=o
End Function
Gaffi
la source
0

Rebol (66 caractères)

remove-each n s: split s complement charset"0123456789"[empty? n]s

Non golfé et enveloppé dans la déclaration de fonction:

f: func [s] [
    remove-each n s: split s complement charset "0123456789" [empty? n]
    s
]

Exemple de code dans la console Rebol:

>> f "abc123def456"
== ["123" "456"]

>> f "aitew035snk582:3c"
== ["035" "582" "3"]

>> f "as5493tax54\\[email protected]"
== ["5493" "54" "430" "52" "9"]

>> f {sasprs]torer"re\\forz}
== []
draegtun
la source
0

JavaScript, 104 97 89

Golfé:

Edit: Lorsque les boucles sortent de la fin du tableau, cestundefined , qui est faux et termine la boucle.

2/27: L' utilisation ?:sauve la verbosité de if/else.

function nums(s) {
s+=l='length';r=[''];for(k=i=0;c=s[i];i++)r[k]+=+c+1?c:r[k+=!!r[k][l]]='';
r[l]--;return r
}

Le retour chariot dans le corps est pour la lisibilité et ne fait pas partie de la solution.

Non golfé:

L'idée est d'ajouter chaque caractère à la dernière entrée du tableau s'il s'agit d'un chiffre et de s'assurer que la dernière entrée du tableau est une chaîne dans le cas contraire.

function nums(s) {
    var i, e, r, c, k;
    k = 0;
    s+='x'; // ensure the input does not end with a digit
    r=[''];
    for (i=0;i<s.length;i++) {
        c=s[i];
        if (+c+1) { // if the current character is a digit, append it to the last entry
            r[k] += c;
        }
        else { // otherwise, add a new entry if the last entry is not blank
            k+=!!r[k].length;
            r[k] = '';
        }
    }
    r.length--; // strip the last entry, known to be blank
    return r;
}
DocMax
la source
0

Javascript, 72

function f(a){
 a+=".",b="",c=[];for(i in a)b=+a[i]+1?b+a[i]:b?(c.push(b),""):b;return c
}

Non golfé

a+=".",b="",c=[];        //add '.' to input so we dont have to check if it ends in a digit
for(i in a)
    b=+a[i]+1?           //check if digit, add to string if it is
        b+a[i]:         
    b?                   //if it wasnt a digit and b contains digits push it
        (c.push(b),""):  //into the array c and clear b
    b;                   //else give me b back
return c

Exemple d'entrée / sortie

console.log(f("abc123def456"));
console.log(f("aitew034snk582:3c"));
console.log(f("as5493tax54\\[email protected]"));
console.log(f("sasprs]tore\"re\\forz"));

["123", "456"]
["034", "582", "3"]
["5493", "54", "430", "52", "9"]
[] 

JSFiddle

Danny
la source
1
Je l'aime! Beaucoup plus simple que le mien. Vous pouvez supprimer 8 autres caractères en les remplaçant if(+a[i]+1)b+=a[i];else if(b)c.push(b),b=""par b=+a[i]+1?b+a[i]:b?(c.push(b),""):b.
DocMax
@DocMax thx, j'ai modifié pour inclure votre suggestion :). Cela (c.push(b),"")semblait intelligent, jamais vu ça.
Danny
Je l'avais oublié jusqu'à ce que je le voie largement utilisé plus tôt dans la journée
DocMax
Ce n'est pas valide '', est confondu avec 0 et c'est une bizarrerie javascript difficile à gérer. Essayez '12 34 56 '
edc65
0

R 52

Cette fonction divise les chaînes par classe de caractères (ce n'est pas regex! :)) la classe est N - caractères numériques et P {N} signifie la négation de cette classe. o = T signifie omettre les sous-chaînes vides.

x
## [1] "wNEKbS0q7hAXRVCF6I4S" "DpqW50YfaDMURB8micYd" "gwSuYstMGi8H7gDAoHJu"
require(stringi)
stri_split_charclass(x,"\\P{N}",o=T)
## [[1]]
## [1] "0" "7" "6" "4"

## [[2]]
## [1] "50" "8" 

## [[3]]
## [1] "8" "7"
bartektartanus
la source
0

PHP 99

<?php

$a = function($s) {
foreach(str_split($s)as$c)$b[]=is_numeric($c)?$c:".";return array_filter(explode('.',implode($b)));
};

var_dump($a("abc123def456"));
var_dump($a("aitew034snk582:3c"));
var_dump($a("as5493tax54\\[email protected]"));
var_dump($a("sasprs]tore\"re\\forz"));


Production

array(2) {
  [3]=>
  string(3) "123"
  [6]=>
  string(3) "456"
}
array(3) {
  [5]=>
  string(3) "034"
  [8]=>
  string(3) "582"
  [9]=>
  string(1) "3"
}
array(5) {
  [2]=>
  string(4) "5493"
  [5]=>
  string(2) "54"
  [6]=>
  string(3) "430"
  [7]=>
  string(2) "52"
  [9]=>
  string(1) "9"
}
array(0) {
}
Kelunik
la source
0

JavaScript 88

88 caractères sans compter la fonction n (x) {}

function n(x){
y=[],i=0,z=t=''
while(z=x[i++])t=!isNaN(z)?t+z:t&&y.push(t)?'':t
if(t)y.push(t)
return y
}
marteau-de-loup
la source