Catalogo dei prodotti


17

Questo problema riguarda la separazione di una stringa che rappresenta un identificatore del prodotto in tre componenti.

  • La prima parte è composta da lettere superiori e inferiori di lunghezza arbitraria che rappresentano il magazzino.
  • La seconda parte è costituita da cifre che rappresentano il numero del prodotto. Anche questa parte ha una lunghezza arbitraria.
  • L'ultima parte è qualificatori come dimensioni e colori e questa parte continua fino alla fine della stringa. Le qualificazioni sono garantite per iniziare con una lettera maiuscola e consistono in caratteri alfanumerici.

Ogni parte deve essere stampata chiaramente separata. È garantito che ogni parte non sia vuota.

Il vincitore è colui che utilizza meno byte per risolvere questo problema.

Esempio:
input: UK7898S14

output:
UK
7898
S14

Qui il Regno Unito è il Regno Unito, 7898 è il codice prodotto e S14 è la taglia 14.

Esempio 2:
Ingresso: cphDK1234CYELLOWS14QGOOD

Uscita:
cphDK
1234
CYELLOWS14QGOOD

Qui cphDK è Copenhagen, Danimarca, 1234 è il codice prodotto, CYELLOWS14QGOOD rappresenta il colore giallo, la taglia 14 e la buona qualità.


2
Ogni parte non è vuota?
Karl Napf,

@KarlNapf Sì. Ogni parte non è vuota.
Highace2,

@Emigna È stato ora incluso un esempio aggiuntivo.
Highace2,

"La prima parte è composta da lettere maiuscole e minuscole" - Forse uno degli esempi potrebbe contenere una tale combinazione di lettere maiuscole e minuscole. E forse anche un prefisso internazionale di 2 caratteri. Inoltre, il qualificatore potrebbe contenere caratteri non alfanumerici, come "Qualità ★★★ ☆☆"?
arte

Benvenuti in PPCG!
Erik the Outgolfer,

Risposte:


10

Perl, 12 byte

11 byte di codice + 1 byte per -pflag.

s/\d+/
$&
/

Per eseguirlo:

perl -pe 's/\d+/
$&
/' <<< "CYELLOWS14QGOOD"

2
Adoro la semplicità! :)
Dom Hastings

4

APL, 18

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

Funziona cercando i primi 2 punti in cui c'è un passaggio da carattere a cifra o viceversa, e usando quelli per dividere la stringa.


4

Retina , 28 14 10 8 byte

Salvato 4 byte grazie a Dom Hastings .
Salvato 2 byte grazie a Martin Ender .

S1`(\d+)

Provalo online!


Usando lo stesso meccanismo della risposta di @Dada, puoi salvare altri 4 byte: retina.tryitonline.net/… (tbh, probabilmente anche di più, ma è tutto ciò che ho potuto salvare! :))
Dom Hastings

@DomHastings. Aah, bella idea andare con il sostituto!
Emigna

3

Haskell, 36 byte (senza regex)

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

Questo dà il risultato nel formato ("UK",("7898","S14")). L'idea è quella di dividere alla prima cifra, quindi dividere il resto alla prima non cifra. Provalo su Ideone .


Buon uso di fmap su una tupla.
xnor

3

JavaScript, 38 36 byte

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

Esempio


@Arnauld Buona cattura.
Florent,

3

JavaScript (ES6), 28 26 byte

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

Salvato 2 byte grazie a @Grax

Esempi


Puoi ridurre altri 2 caratteri usando $ & nella tua sostituzione e rimuovendo le parentesi. s=>s.replace(/\d+/,` $& `)
Grax32

2

Gema, 17 12 personaggi

(Il trucco di non gestire il codice del paese in modo esplicito spudoratamente preso in prestito da Dada s' Perl soluzione . Apprezzamento va espresso lì.)

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

Esecuzione di esempio:

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

bash-4.3$ gema '<D>*=\n$1\n*' <<< 'cphDK1234CYELLOWS14QGOOD'
cphDK
1234
CYELLOWS14QGOOD

2

Python 2, 40 byte

Non conosco molto Regex, ma per fortuna questo problema è abbastanza semplice :) Separa la stringa di input in un elenco di lunghezza 3 che contiene ogni parte.

import re
lambda k:re.split('(\d+)',k,1)

2

05AB1E ,39 37 16 byte

Salvataggio di molti byte grazie a Emigna.

Utilizza la codifica 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

Provalo online!

(Questo è il mio primo post qui!)


È possibile salvare almeno 14 byte controllando le cifre anziché le lettere . E questo può probabilmente essere giocato a golf di più.
Emigna

Inoltre, benvenuto in PPCG :)
Emigna

Grazie! E hai ragione, in realtà sono andato tutto ingenuo su questo, letteralmente da sinistra a destra. Ho anche cercato di scavare .páà¬per ottenere la prima parte, ma non sembra aiutare per il resto a prima vista.
Osable

Sentiti libero di aggiornare la tua risposta con il mio codice (e giocaci ancora un po 'se puoi). Non credo che sia abbastanza diverso da giustificare la propria risposta.
Emigna

Ok lo farò allora come ho trovato un modo per metterlo in loop. Niente di troppo sofisticato, ma almeno scende a 16 byte. Grazie ancora! (Ora devo aggiornare le spiegazioni ... ma ci sono meno byte da spiegare)
Osable

1

JavaScript (ES6), 36 byte

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

Esempi


1

Java 7, 200 185 174 167 byte

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

Codice non testato e test:

Provalo qui.

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

Produzione:

UK 7898 S14 
cphDK 1234 CYELLOWS14QGOOD 

1

C #, 191 177 byte

golfed:

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

Ungolfed:

    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 ha salvato 14 byte.


Non è necessario ToCharArray (). la stringa è già IEnumerable <char>
Collegamento

Certo, non posso credere di non averlo notato.
paldir,

1

PHP, 48 byte

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

Con il suo $limitparametro, e straordinariamente utile \K, preg_split()è perfetto per questa sfida.


1

MATLAB, 81 73 byte

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

Funzione che accetta una stringa e restituisce una matrice di celle di tre stringhe. Testato nella versione R20105b.

Esempio di utilizzo:

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

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

Spiegazione

L'espressione regolare (?<=^\D+)\d+')corrisponde a un gruppo di cifre precedute da non cifre dall'inizio della stringa; questi ultimi non fanno parte della partita.

Il quarto output di regexpè il 'match'; e il settimo output sono le 'split'due parti della stringa prima e dopo la corrispondenza.


1

Rubino, 28 byte

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

Questo circonda il primo gruppo di cifre con nuove righe.


0

jq, 47 caratteri

(43 caratteri di codice + 4 caratteri opzioni della riga di comando.)

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

(Ancora una volta la vecchia storia: abbastanza elegante all'inizio, poi diventa dolorosamente dettagliata.)

Esecuzione di esempio:

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 online (il passaggio -rtramite URL non è supportato: controlla tu stesso l'output non elaborato).


0

PHP, 61 59 56 55 byte

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

Questo genera anche il codice iniziale:

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

modificare

Grazie a @manatwork per avermi salvato alcuni byte
Grazie a @ RomanGräf per altri pochi byte salvati


1
[\d]? : o \dè abbastanza.
arte

@manatwork Grazie. Non uso abbastanza regex (probabilmente una buona cosa) e ho iniziato il percorso [0-9] + prima di ricordare di \ d
gabe3886

1
Perché non sostituirlo [a-z]con \D?
Roman Gräf,

1
Ora che non hai [a-z], la ibandiera non è nemmeno necessaria.
arte

Ho davvero bisogno di dedicare più tempo a lavorare sulle espressioni regolari.
gabe3886,

0

JavaScript senza regex, 84 81 79 byte

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


2
Si potrebbe mettere alcuna inizializzazione in un unico luogo: o=n=i=''.
arte

E spostare il compito di c per il suo primo utilizzo: isNaN(c=p[i++]).
arte

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'inizializzazione dovrebbe rimanere ''perché la o, a cui verrà concatenato il risultato. Ma purtroppo il tuo codice non funziona per me, n deve essere incrementato condizionatamente.
arte

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 byte

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

Funzione anonima. Accetta una stringa come input e restituisce un elenco di stringhe come output.


0

Racchetta 274 byte

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

Ungolfed:

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

test:

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

Produzione:

'("UK" "7898" "S14")
'("cphDK" "1234" "CYELLOWS14QGOOD")

0

R, 63 52 byte

Modifica: salvato un sacco di byte grazie a @JDL

Prende input da stdin e stampa su stdout:

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

Esempio di output:

[1] "UK 7898 S1"
[1] "cphDK 1234 CYELLOWS14QGOOD"

Non gsub (...,"\\1 \\2 \\3")sarebbe più efficiente?
JDL

@JDL Non sono sicuro di seguire. Ti interessa elaborare o fare un esempio?
Billywob,

qualcosa del genere gsub("([A-Za-z]+)([0-9]+)(.+)","\\1 \\2 \\3",scan()), sebbene il primo argomento possa probabilmente essere espresso come qualcosa di più piccolo di quello ...
JDL

@JDL Molto intelligente ma non ho idea di come funzioni la "\\1 \\2 \\3"sostituzione. Anche aggiornato il pattern regex un po 'e usare ignore.case = TRUE.
Billywob,

Significano solo "output di tutto ciò che è stato catturato nella prima / seconda / terza coppia di ()parentesi.
JDL

0

Gelatina , 14 byte

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

TryItOnline!

Come?

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

0

C, 107 byte

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

Chiama con:

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

0

Python 2, 103 94 88 byte

Soluzione senza usare 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

Semplicemente estrae i numeri dal centro, quindi suddivide l'input usando il numero come indice. Richiede virgolette intorno all'input ma non ho visto da nessuna parte che le virgolette non sono consentite.

-9 dividendo a sul numero centrale, quindi stampare i componenti con b al centro

-6 Grazie a @Shebang

Casi test

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

D:\>python codes.py
"cphDK1234CYELLOWS14QGOOD"
cphDK 1234 CYELLOWS14QGOOD

b!="" -> b>""e c=a.split(b) -> c,d=a.split(b) ... print c[0],b,c[1] -> print c,b,dsalva 5 byte.
Kade,

Suggerimenti molto belli @Shebang. Grazie
ElPedro

Ah, ho dimenticato che le stringhe vuote sono false. Puoi salvare altri 3 byte semplicemente facendolo elif b:;)
Kade

0

C #, 74 byte

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

Sostituisci la prima serie di cifre con ritorno a capo, serie di cifre e un altro ritorno a capo, come ha fatto Johan Karlsson per JavaScript.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.