Katalog Produk


17

Masalah ini adalah tentang memisahkan string yang mewakili pengidentifikasi produk menjadi tiga komponen.

  • Bagian pertama terdiri dari huruf atas dan bawah dengan panjang sewenang-wenang yang mewakili gudang.
  • Bagian kedua adalah digit yang mewakili nomor produk. Bagian ini juga panjangnya sewenang-wenang.
  • Bagian terakhir adalah kualifikasi sebagai ukuran dan warna, dan bagian ini berlanjut hingga akhir string. Kualifikasi dijamin dimulai dengan huruf kapital dan terdiri dari karakter alfanumerik.

Setiap bagian harus dicetak dengan jelas dipisahkan. Dijamin setiap bagian tidak kosong.

Pemenangnya adalah orang yang menggunakan paling sedikit byte untuk menyelesaikan masalah ini.

Contoh:
Input: UK7898S14

Output:
UK
7898
S14

Di sini Inggris adalah Inggris, 7898 adalah kode produk, dan S14 adalah ukuran 14.

Contoh 2:
Input: cphDK1234CYELLOWS14QGOOD

Output:
cphDK
1234
CYELLOWS14QGOOD

Di sini cphDK adalah Copenhagen, Denmark, 1234 adalah kode produk, CYELLOWS14QGOOD mewakili warna kuning, ukuran 14, dan kualitas yang baik.


2
Apakah setiap bagian tidak kosong?
Karl Napf

@KarlNapf Ya. Setiap bagian tidak kosong.
Highace2

@Emigna Contoh tambahan sekarang telah disertakan.
Highace2

"Bagian pertama terdiri dari huruf besar dan kecil" - Mungkin salah satu contohnya bisa berisi campuran huruf besar dan kecil. Dan mungkin juga kode negara yang panjangnya tidak 2 karakter. Juga, dapatkah kualifikasi berisi karakter non-alfanumerik, seperti "Kualitas ★★★ ☆☆"?
manatwork

Selamat datang di PPCG!
Erik the Outgolfer

Jawaban:


10

Perl, 12 byte

11 byte kode + 1 byte untuk -pflag.

s/\d+/
$&
/

Untuk menjalankannya:

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

2
Cintai kesederhanaannya! :)
Dom Hastings

4

APL, 18

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

Bekerja dengan mencari 2 poin pertama di mana ada perubahan dari karakter ke digit atau sebaliknya, dan menggunakannya untuk membagi string.


4

Retina , 28 14 10 8 byte

Disimpan 4 byte berkat Dom Hastings .
Disimpan 2 byte berkat Martin Ender .

S1`(\d+)

Cobalah online!


Menggunakan mekanisme yang sama dengan jawaban @ Dada, Anda dapat menyimpan 4 byte lagi: retina.tryitonline.net/… (tbh, mungkin bahkan lebih, tapi hanya itu yang bisa saya selamatkan! :))
Dom Hastings

@HomHastings. Aah, ide bagus untuk menggantikannya!
Emigna

3

Haskell, 36 byte (tanpa regex)

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

Ini memberikan hasil dalam format ("UK",("7898","S14")). Idenya adalah untuk membagi di digit pertama, dan kemudian membagi sisanya di non-digit pertama. Cobalah di Ideone .


Penggunaan fmap yang bagus pada tuple.
xnor

3

JavaScript, 38 36 byte

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

Contoh


@Arnauld Tangkapan yang bagus.
Florent

3

JavaScript (ES6), 28 26 byte

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

Disimpan 2 byte berkat @Grax

Contohnya


Anda dapat mengurangi 2 karakter lagi dengan menggunakan $ & di pengganti dan menghapus tanda kurung. s=>s.replace(/\d+/,` $& `)
Grax32

2

Gema, 17 12 karakter

(Trik dari tidak menangani kode negara secara eksplisit tanpa malu-malu meminjam dari Dada 's Perl solusi . Apresiasi harus dinyatakan di sana.)

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

Contoh dijalankan:

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 Bytes

Saya tidak tahu banyak Regex, tapi untungnya masalah ini cukup sederhana :) Memisahkan string input menjadi daftar panjang 3 yang berisi setiap bagian.

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

2

05AB1E ,39 37 16 byte

Menyimpan banyak byte berkat Emigna.

Ini menggunakan pengkodean 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

Cobalah online!

(Ini posting pertama saya di sini!)


Anda dapat menyimpan setidaknya 14 byte dengan memeriksa angka alih-alih huruf . Dan ini kemungkinan bisa lebih banyak golf.
Emigna

Juga, selamat datang di PPCG :)
Emigna

Terima kasih! Dan Anda benar, sebenarnya saya terlalu naif dalam hal ini, secara harfiah dari kiri ke kanan. Saya juga mencoba menggali .páà¬untuk mendapatkan bagian pertama, tetapi tampaknya tidak membantu untuk sisanya pada pandangan pertama.
Osable

Jangan ragu untuk memperbarui jawaban Anda dengan kode saya (dan golf lagi jika Anda bisa). Saya tidak merasa bahwa itu cukup berbeda untuk menjamin jawabannya sendiri.
Emigna

Ok saya akan melakukannya saat saya menemukan cara untuk meletakkannya dalam satu lingkaran. Tidak ada yang terlalu canggih, tapi setidaknya turun ke 16 byte. Terima kasih lagi! (Sekarang saya harus memperbarui penjelasan ... tetapi ada lebih sedikit byte untuk menjelaskan)
Osable

1

JavaScript (ES6), 36 byte

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

Contohnya


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

Tidak digabungkan & kode uji:

Coba di sini.

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

Keluaran:

UK 7898 S14 
cphDK 1234 CYELLOWS14QGOOD 

1

C #, 191 177 byte

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

Tidak Disatukan:

    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 menyimpan 14 byte.


Anda tidak perlu ToCharArray (). string sudah IEnumerable <char>
Tautan Ng

Tentu saja, saya tidak percaya saya tidak memperhatikan ini.
paldir

1

PHP, 48 byte

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

Dengan $limitparameternya, dan yang sangat berguna \K, preg_split()sangat cocok untuk tantangan ini.


1

MATLAB, 81 73 byte

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

Fungsi yang menerima string dan mengembalikan array sel tiga string. Diuji dalam versi R20105b.

Contoh penggunaan:

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

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

Penjelasan

Ekspresi reguler (?<=^\D+)\d+')cocok dengan sekelompok digit yang diawali oleh non-digit dari awal string; yang terakhir bukan bagian dari pertandingan.

Output keempat regexpadalah 'match'; dan output ketujuh adalah 'split', yaitu, dua bagian dari string sebelum dan sesudah pertandingan.


1

Ruby, 28 byte

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

Ini mengelilingi cluster digit pertama dengan baris baru.


0

jq, 47 karakter

(43 karakter kode + 4 opsi opsi baris perintah.)

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

(Lagi-lagi kisah lama: cukup anggun di awal, lalu menjadi sangat menyakitkan.)

Contoh dijalankan:

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

Tes online (Melewati -rURL tidak didukung - periksa sendiri Output Raw.)


0

PHP, 61 59 56 55 byte

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

Ini menghasilkan kode awal juga:

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

Edit

Terima kasih kepada @manatwork karena telah menyimpan beberapa byte untuk saya.
Terima kasih kepada @ RomanGräf untuk beberapa byte lainnya yang disimpan


1
[\d]? : o \dsudah cukup.
manatwork

@manatwork Terima kasih. Saya tidak menggunakan cukup regex (bisa dibilang hal yang baik) dan mulai menyusuri rute [0-9] + sebelum mengingat tentang \ d
gabe3886

1
Kenapa tidak ganti [a-z]dengan \D?
Roman Gräf

1
Sekarang Anda tidak punya [a-z], ibendera juga tidak diperlukan.
manatwork

Saya benar-benar perlu menunggu lebih banyak waktu untuk mengerjakan ekspresi reguler.
gabe3886

0

JavaScript tanpa 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
Anda bisa meletakkan semua inisialisasi dalam satu tempat: o=n=i=''.
manatwork

Dan pindah tugas ke c untuk penggunaan pertama: 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, inisialisasi harus tetap ''karena o, yang hasilnya akan digabungkan. Tetapi sayangnya kode Anda tidak berfungsi untuk saya, dan perlu ditambahkan secara kondisional.
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 byte

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

Fungsi anonim. Mengambil string sebagai input, dan mengembalikan daftar string sebagai output.


0

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

Tidak Disatukan:

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

Pengujian:

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

Keluaran:

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

0

R, 63 52 byte

Sunting: Menyimpan banyak byte berkat @JDL

Membawa input dari stdin dan mencetak ke stdout:

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

Contoh output:

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

Bukankah gsub (...,"\\1 \\2 \\3")lebih efisien?
JDL

@ JDL Tidak yakin saya ikuti. Mau menguraikan atau memberi contoh?
Billywob

sesuatu seperti gsub("([A-Za-z]+)([0-9]+)(.+)","\\1 \\2 \\3",scan()), meskipun argumen pertama mungkin dapat dinyatakan sebagai sesuatu yang lebih kecil dari itu ...
JDL

@JDL Sangat pintar tapi saya tidak tahu bagaimana "\\1 \\2 \\3"penggantian bekerja. Juga memperbarui sedikit pola regex dan gunakan ignore.case = TRUE.
Billywob

Mereka hanya berarti "output apa pun yang ditangkap dalam ()kurung pertama / kedua / ketiga .
JDL

0

Jelly , 14 byte

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

TryItOnline!

Bagaimana?

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

Telepon dengan:

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

0

Python 2, 103 94 88 byte

Solusi tanpa menggunakan 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

Cukup mengekstrak angka dari tengah lalu mengiris input menggunakan angka sebagai indeks. Membutuhkan tanda kutip di sekitar input tetapi saya tidak melihat di mana pun bahwa tanda kutip tidak diizinkan.

-9 dengan memisahkan a di nomor tengah lalu cetak komponen dengan b di tengah

-6 Terima kasih kepada @Shebang

Uji Kasus

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

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

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

Petunjuk yang sangat bagus @ Shebang. Terima kasih
ElPedro

Ah, aku lupa senar kosong itu palsu. Anda dapat menyimpan 3 byte lagi hanya dengan membuatnya elif b:;)
Kade

0

C #, 74 byte

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

Ganti set angka pertama dengan carriage return, set digit, dan carriage return lainnya, seperti yang dilakukan Johan Karlsson untuk JavaScript.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.