Catalogue des produits

17

Ce problème concerne la séparation d'une chaîne représentant un identifiant de produit en trois composants.

  • La première partie se compose de lettres supérieures et inférieures de longueur arbitraire qui représentent l'entrepôt.
  • La deuxième partie est constituée de chiffres qui représentent le numéro de produit. Cette partie est également de longueur arbitraire.
  • La dernière partie est qualificative en termes de taille et de couleurs, et cette partie continue jusqu'à la fin de la chaîne. Les qualificatifs sont garantis pour commencer par une majuscule et se composent de caractères alphanumériques.

Chaque partie doit être imprimée clairement séparée. Il est garanti que chaque pièce n'est pas vide.

Le gagnant est celui qui utilise le moins d'octets pour résoudre ce problème.

Exemple:
Entrée: UK7898S14

Sortie:
UK
7898
S14

Ici, le Royaume-Uni est le Royaume-Uni, 7898 est le code produit et S14 est la taille 14.

Exemple 2:
Entrée: cphDK1234CYELLOWS14QGOOD

Sortie:
cphDK
1234
CYELLOWS14QGOOD

Ici cphDK est Copenhague, Danemark, 1234 est le code produit, CYELLOWS14QGOOD représente la couleur jaune, la taille 14 et la bonne qualité.

Highace2
la source
2
Chaque partie n'est-elle pas vide?
Karl Napf
@KarlNapf Oui. Chaque partie n'est pas vide.
Highace2
@Emigna Un exemple d'ajout a maintenant été inclus.
Highace2
«La première partie se compose de lettres majuscules et minuscules» - Peut-être qu'un des exemples pourrait contenir un tel mélange de lettres majuscules et minuscules. Et peut-être aussi un code de pays qui ne comporte pas 2 caractères. De plus, le qualificatif peut-il contenir des caractères non alphanumériques, comme «Qualité ★★★ ☆☆»?
manatwork
Bienvenue chez PPCG!
Erik the Outgolfer

Réponses:

10

Perl, 12 octets

11 octets de code + 1 octet pour l' -pindicateur.

s/\d+/
$&
/

Pour l'exécuter:

perl -pe 's/\d+/
$&
/' <<< "CYELLOWS14QGOOD"
Dada
la source
2
J'adore la simplicité! :)
Dom Hastings
4

APL, 18

{⍵⊂⍨3⌊+\1,2≠/⍵∊⎕D}'UK7898S14'
UK  7898  S14 

Fonctionne en recherchant les 2 premiers points où il y a un changement de caractère en chiffre ou vice-versa, et en les utilisant pour diviser la chaîne.

Moris Zucca
la source
4

Rétine , 28 14 10 8 octets

4 octets enregistrés grâce à Dom Hastings .
Enregistré 2 octets grâce à Martin Ender .

S1`(\d+)

Essayez-le en ligne!

Emigna
la source
En utilisant le même mécanisme que la réponse de @ Dada, vous pouvez enregistrer 4 autres octets: retina.tryitonline.net/… (tbh, probablement encore plus, mais c'est tout ce que j'ai pu économiser! :))
Dom Hastings
@DomHastings. Aah, belle idée avec le remplacement!
Emigna
3

Haskell, 36 octets (pas d'expression régulière)

d c='/'<c&&c<':'
(span d<$>).break d

Cela donne le résultat dans le format ("UK",("7898","S14")). L'idée est de diviser au premier chiffre, puis de diviser le reste au premier non-chiffre. Essayez-le sur Ideone .

Zgarb
la source
Belle utilisation de fmap sur un tuple.
xnor
3

JavaScript, 38 36 octets

s=>/(\D+)(\d+)(.+)/.exec(s).slice(1)

Exemple

Florent
la source
@Arnauld Bonne prise.
Florent
3

JavaScript (ES6), 28 26 octets

s=>s.replace(/\d+/,`
$&
`)

Sauvegardé 2 octets grâce à @Grax

Exemples

Johan Karlsson
la source
Vous pouvez réduire 2 caractères supplémentaires en utilisant $ & dans votre remplacement et en supprimant les parenthèses. s=>s.replace(/\d+/,` $& `)
Grax32
2

Gema, 17 12 caractères

(L'astuce de ne pas manipuler le code pays explicitement emprunté sans vergogne à la solution Perl de Dada . Une appréciation doit y être exprimée.)

<D>*=\n$1\n*

Exemple d'exécution:

bash-4.3$ gema '<D>*=\n$1\n*' <<< 'UK7898S14'
UK
7898
S14

bash-4.3$ gema '<D>*=\n$1\n*' <<< 'cphDK1234CYELLOWS14QGOOD'
cphDK
1234
CYELLOWS14QGOOD
homme au travail
la source
2

Python 2, 40 octets

Je ne connais pas beaucoup Regex, mais heureusement, ce problème est assez simple :) Sépare la chaîne d'entrée dans une liste de longueur 3 qui contient chaque partie.

import re
lambda k:re.split('(\d+)',k,1)
Kade
la source
2

05AB1E ,39 37 16 octets

Beaucoup d'octets enregistrés grâce à Emigna.

Il utilise l'encodage CP-1252.

TvDSdykF¬?¦}¶?}?

T                push "10"
 v               for each element (i.e., 1 and 0). Element is stored in 'y'
  DS             split string (input during the first iteration)
    d            for each character, 1 if digit or 0 otherwise
     yk          get index of the first occurrence of 'y'
       F         for 0 <= i < string.firstIndexOf(y)
        ¬?       print the first character of the string
          ¦      remove it from the string
           }     end inner for
            ¶?   display a newline
              }  end outer for
               ? display the remaining string

Essayez-le en ligne!

(Ceci est mon premier post ici!)

Osable
la source
Vous pouvez enregistrer au moins 14 octets en vérifiant les chiffres au lieu des lettres . Et cela peut probablement être joué davantage.
Emigna
Aussi, bienvenue au PPCG :)
Emigna
Merci! Et vous avez raison, en fait je suis devenu tout naïf sur celui-ci, littéralement de gauche à droite. J'ai également essayé de creuser .páà¬pour obtenir la première partie, mais cela ne semble pas aider pour le reste à première vue.
Osable
N'hésitez pas à mettre à jour votre réponse avec mon code (et jouez-en plus si vous le pouvez). Je ne pense pas que ce soit suffisamment différent pour justifier sa propre réponse.
Emigna
Ok je vais le faire alors que j'ai trouvé un moyen de le mettre en boucle. Rien de trop sophistiqué, mais au moins ça descend à 16 octets. Merci encore! (Maintenant, je dois mettre à jour les explications ... mais il y a moins d'octets à expliquer)
Osable
1

JavaScript (ES6), 36 octets

s=>/(.+?)(\d+)(.*)/.exec(s).slice(1)

Exemples

Arnauld
la source
1

Java 7, 200 185 174 174 167 octets

import java.util.regex.*;String c(String s){Matcher m=Pattern.compile("(.*?)(\\d+)(.*)").matcher(s);s="";for(int i=0;i<3;)if(m.matches())s+=m.group(++i)+" ";return s;}

Code non testé et testé:

Essayez-le ici.

import java.util.regex.*;
class M{
  static String c(String s){
    Matcher m = Pattern.compile("(.*?)(\\d+)(.*)").matcher(s);
    s = "";
    for(int i = 0; i < 3;){
      if(m.matches()){
        s += m.group(++i) + " ";
      }
    }
    return s;
  }

  public static void main(String[] a){
    System.out.println(c("UK7898S14"));
    System.out.println(c("cphDK1234CYELLOWS14QGOOD"));
  }
}

Production:

UK 7898 S14 
cphDK 1234 CYELLOWS14QGOOD 
Kevin Cruijssen
la source
1

C #, 191 177 octets

Golfé:

void F(string s){var a=s.ToList();int i=a.FindIndex(char.IsDigit);int n=a.FindIndex(i,char.IsUpper);Console.Write($"{s.Substring(0,i)}\n{s.Substring(i,n-i)}\n{s.Substring(n)}");

Non golfé:

    void F(string s)
    {
        var a = s.ToList();
        int i = a.FindIndex(char.IsDigit);
        int n = a.FindIndex(i, char.IsUpper);

        Console.Write($"{s.Substring(0, i)}\n{s.Substring(i, n - i)}\n{s.Substring(n)}");
    }

EDIT1: @Link Ng a enregistré 14 octets.

paldir
la source
Vous n'avez pas besoin de ToCharArray (). la chaîne est déjà IEnumerable <char>
Link Ng
Bien sûr, je ne peux pas croire que je n'ai pas remarqué cela.
paldir
1

PHP, 48 octets

print_r(preg_split('/(\D+|\d+)\K/',$argv[1],3));

Avec son $limitparamètre et son utilité fantastique \K, il preg_split()est parfait pour ce défi.

user59178
la source
1

MATLAB, 81 73 octets

function y=f(x)
[~,~,~,m,~,~,s]=regexp(x,'(?<=^\D+)\d+');y=[s(1) m s(2)];

Fonction qui accepte une chaîne et renvoie un tableau de cellules de trois chaînes. Testé dans la version R20105b.

Exemple d'utilisation:

>> f('UK7898S14')
ans = 
    'UK'    '7898'    'S14'

>> f('cphDK1234CYELLOWS14QGOOD')
ans = 
    'cphDK'    '1234'    'CYELLOWS14QGOOD'

Explication

L'expression régulière (?<=^\D+)\d+')correspond à un groupe de chiffres précédé de non-chiffres depuis le début de la chaîne; ces derniers ne font pas partie du match.

La quatrième sortie de regexpest le 'match'; et la septième sortie correspond aux 'split'deux parties de la chaîne avant et après la correspondance.

Luis Mendo
la source
1

Rubis, 28 octets

->s{puts s.sub(/\d+/,"\n\\&\n")}

Cela entoure le premier groupe de chiffres avec des retours à la ligne.

Lee W
la source
0

jq, 47 caractères

(Code de 43 caractères + options de ligne de commande de 4 caractères.)

match("(\\D+)(\\d+)(.+)").captures[].string

(Encore une fois, la vieille histoire: assez élégante au début, puis devient douloureusement verbeuse.)

Exemple d'exécution:

bash-4.3$ jq -Rr 'match("(\\D+)(\\d+)(.+)").captures[].string' <<< 'UK7898S14'
UK
7898
S14

bash-4.3$ jq -Rr 'match("(\\D+)(\\d+)(.+)").captures[].string' <<< 'cphDK1234CYELLOWS14QGOOD'
cphDK
1234
CYELLOWS14QGOOD

Test en ligne (le passage -rpar l'URL n'est pas pris en charge - vérifiez vous-même la sortie brute.)

homme au travail
la source
0

PHP, 61 59 56 55 octets

preg_match('/(\D+)(\d+)(.+)/',$argv[1],$a);print_r($a);

Cela génère également le code initial:

Array
(
    [0] => cphDK1234CYELLOWS14QGOOD
    [1] => cphDK
    [2] => 1234
    [3] => CYELLOWS14QGOOD
)

Éditer

Merci à @manatwork d'avoir enregistré quelques octets pour moi
Merci à @ RomanGräf pour encore quelques octets enregistrés

gabe3886
la source
1
[\d]? : o \dest suffisant.
manatwork
@manatwork Merci. Je n'utilise pas assez l'expression régulière (sans doute une bonne chose) et j'ai commencé la route [0-9] + avant de me souvenir de \ d
gabe3886
1
Pourquoi ne pas remplacer [a-z]par \D?
Roman Gräf
1
Maintenant que vous n'avez pas [a-z], le idrapeau n'est plus nécessaire non plus.
manatwork
J'ai vraiment besoin de passer plus de temps à travailler sur les expressions régulières.
gabe3886
0

JavaScript sans regex, 84 81 79 octets

p=>{for(i=n=o='';i<p.length;){if(n==isNaN(c=p[i++])){o+=' ';n++}o+=c}return o}

Philipp Flenker
la source
2
Vous pouvez mettre tous les initialisations en un seul endroit: o=n=i=''.
manatwork
Et déplacer l'affectation à c à sa première utilisation: isNaN(c=p[i++]).
manatwork
p=>{for(i=n=o=0;i<p.length;){c=p[i++];if(n++==c<59){o+=' '}o+=c}return o}
Roman Gräf
@ RomanGräf, l'initialisation doit rester ''car le o, auquel le résultat sera concaténé. Mais malheureusement, votre code ne fonctionne pas pour moi, n doit être incrémenté conditionnellement.
manatwork
p=>{for(i=n=0,o='';i<p.length;){c=p[i++];if(n==c<59){o+=' ';n++}o+=c}return o}
Roman Gräf
0

Mathematica, 39 octets

StringSplit[#,a:DigitCharacter..:>a,2]&

Fonction anonyme. Prend une chaîne en entrée et renvoie une liste de chaînes en sortie.

LegionMammal978
la source
0

Raquette 274 octets

(let((g 0)(j'())(k'())(l'())(m list->string)(r reverse)(n char-numeric?)(c cons))(for((i(string->list s)))
(when(and(= g 0)(n i))(set! g 1))(when(and(= g 1)(not(n i)))(set! g 2))(match g[0(set! j(c i j))]
[1(set! k(c i k))][2(set! l(c i l))]))(list(m(r j))(m(r k))(m(r l))))

Non golfé:

(define (f s)
  (let ((g 0)
        (j '())
        (k '())
        (l '())
        (m list->string)
        (r reverse)
        (n char-numeric?)
        (c cons))
    (for ((i (string->list s)))
      (when (and (= g 0) (n i)) (set! g 1)  )
      (when (and (= g 1) (not (n i))) (set! g 2) )
      (match g
        [0 (set! j (c i j))]
        [1 (set! k (c i k))]
        [2 (set! l (c i l))]))
    (list (m (r j)) (m (r k)) (m (r l)))))

Essai:

(f "UK7898S14")
(f "cphDK1234CYELLOWS14QGOOD")

Production:

'("UK" "7898" "S14")
'("cphDK" "1234" "CYELLOWS14QGOOD")
rnso
la source
0

R, 63 52 octets

Edit: sauvé un tas d'octets grâce à @JDL

Prend l'entrée de stdin et imprime vers stdout:

gsub("([a-z]+)(\\d+)(.+)","\\1 \\2 \\3",scan(,""),T)

Exemple de sortie:

[1] "UK 7898 S1"
[1] "cphDK 1234 CYELLOWS14QGOOD"
Billywob
la source
Ne serait pas gsub (...,"\\1 \\2 \\3")plus efficace?
JDL
@JDL Je ne suis pas sûr de suivre. Voulez-vous élaborer ou donner un exemple?
Billywob
quelque chose comme gsub("([A-Za-z]+)([0-9]+)(.+)","\\1 \\2 \\3",scan()), bien que le premier argument puisse probablement être exprimé comme quelque chose de plus petit que cela ...
JDL
@JDL Très intelligent mais je n'ai aucune idée du fonctionnement du "\\1 \\2 \\3"remplacement. A également mis à jour un peu le modèle d'expression régulière et l'utiliser ignore.case = TRUE.
Billywob
Ils signifient simplement "sortie tout ce qui a été capturé dans la première / deuxième / troisième paire de ()supports.
JDL
0

Gelée , 14 octets

O<65ITḣ2‘ṬœṗµY

TryItOnline!

Comment?

O<65ITḣ2‘ṬœṗµY - Main link: productIdentifier   e.g. "UK7898S14"
O              - cast to ordinals               e.g. [85,75,55,56,57,56,83,49,52]
 <65           - less than 65?                  e.g. [ 0, 0, 1, 1, 1, 1, 0, 1, 1]
    I          - incremental difference         e.g. [ 0, 1, 0, 0, 0,-1, 1, 0]
     T         - truthy indexes                 e.g. [2, 6, 7]
      ḣ2       - head to 2                      e.g. [2, 6]
        ‘      - increment                      e.g. [3, 7]
         Ṭ     - set truthy indexes             e.g. [0, 0, 1, 0, 0, 0, 1]
          œṗ   - split y at truthy indexes of x e.g. ["UK", "7898", "S14"]
            µ  - monadic chain separation
             Y - join with line feeds
Jonathan Allan
la source
0

C, 107 octets

#define p(x) printf("%c",x);
f(char*s){for(;*s>64;s++)p(*s)p(10)for(;*s<58;s++)p(*s)p(10)for(;*s;s++)p(*s)}

Appeler avec:

int main()
{
   f("UK7898S14");
   return 0;
}
Steadybox
la source
0

Python 2, 103 94 88 octets

Solution sans utiliser regex

a,b=input(),""
for f in a:
 if ord(f)<58:b+=f
 elif b"":c,d=a.split(b);print c,b,d;break

Extrait simplement les nombres du milieu, puis tranche l'entrée en utilisant le nombre comme index. Nécessite des guillemets autour de l'entrée mais je n'ai vu nulle part que les guillemets sont interdits.

-9 en divisant a sur le nombre du milieu, puis imprimez les composants avec b au milieu

-6 Merci à @Shebang

Cas de test

D:\>python codes.py
"UK7898S14"
UK 7898 S14

D:\>python codes.py
"cphDK1234CYELLOWS14QGOOD"
cphDK 1234 CYELLOWS14QGOOD
ElPedro
la source
b!="" -> b>""et c=a.split(b) -> c,d=a.split(b) ... print c[0],b,c[1] -> print c,b,denregistre 5 octets.
Kade
Très belles notes @Shebang. Merci
ElPedro
Ah, j'ai oublié que les chaînes vides sont fausses. Vous pouvez économiser encore 3 octets en le faisant simplement elif b:;)
Kade
0

C #, 74 octets

v=>new System.Text.RegularExpressions.Regex("\\d+").Replace(v,"\n$&\n",1);

Remplacez le premier ensemble de chiffres par un retour chariot, un ensemble de chiffres et un autre retour chariot, comme Johan Karlsson l'a fait pour JavaScript.

Grax32
la source