Program terpendek untuk memisahkan string pada non-digit tanpa RegExps


16

EDIT: Jika Anda menggunakan Lisp, saya telah memberikan beberapa panduan di bagian bawah dalam menghitung byte.

Tujuan: Membuat fungsi terpendek yang memisahkan string pada non-digit dan mengembalikan array yang terdiri dari hanya digit di setiap string, tanpa menggunakan ekspresi reguler apa pun. Nol terkemuka harus dimasukkan dalam setiap string.

Peringkat saat ini (dipisahkan dalam kategori):

  • C / C ++ / C # / Java: 68 (C) ....
  • GolfScript / APL / J: 13 (APL)
  • Lainnya: 17 (Bash, penggunaan tr), 24 (Ruby)

Aturan:

(Saya minta maaf atas panjangnya)

  1. Format harus sebagai fungsi dengan argumen string tunggal. Hingga dua argumen tambahan dapat ditambahkan jika perlu untuk pengembalian array yang tepat (mis. Sh / csh / DOS Batch membutuhkan referensi variabel tambahan untuk dikembalikan, dll.).
  2. Deklarasi fungsi utama tidak masuk hitungan, dan juga tidak mengimpor perpustakaan standar lainnya. `# include`,` import`, dan `using` tidak dihitung. Yang lainnya tidak. Ini termasuk fungsi `# define` dan pembantu. Maaf bila membingungkan. Lihat ini sebagai panduan bermanfaat tentang apa yang tidak / tidak dihitung (ditulis dalam sintaks C-style)
    // tidak diperhitungkan total, dapat dihilangkan kecuali
    // tidak jelas, seperti setengah dari perpustakaan standar Java.
    #termasuk <stdio.h>
    
    impor some.builtin.Class // tidak masuk hitungan, lihat di atas
    
    #define printf p // menghitung total
    
    / * Arahan preprocessor lain, dll menghitung. * /
    
    int i = 0; // diperhitungkan
    
    someFunction (); // diperhitungkan
    
    char [] [] myMainSplitFunction (char [] [] array) {// tidak masuk hitungan
      // Semua yang ada di sini penting
      return returnArray; // Bahkan ini penting.
    } // tidak masuk hitungan
    
    / * Segala sesuatu di sini penting, termasuk deklarasi * /
    char [] [] someHelperFunction (char [] string) {
      // barang
    } // bahkan ini penting
    
  3. Output harus berupa array string atau sejenisnya (Daftar array di Java dan yang serupa dapat diterima). Contoh output yang diterima: String[], char[][], Array, List, dan Array(objek).
  4. Array harus berisi hanya berisi string-panjang primitif variabel atau objek string. Tidak boleh ada string kosong di kembalinya, dengan pengecualian di bawah ini. Catatan: string berisi string pertandingan yang berurutan, seperti contoh input dan output di bawah ini.
  5. Jika tidak ada kecocokan, maka badan fungsi harus kembali null, array / daftar kosong, atau array / daftar yang berisi string kosong.
  6. Tidak ada perpustakaan eksternal yang diizinkan.
  7. Akhir baris DOS dihitung sebagai satu byte, bukan dua (sudah dibahas dalam meta, tetapi perlu ditekankan)
  8. Dan aturan terbesar di sini: tidak ada ekspresi reguler yang diizinkan.

Ini adalah pertanyaan , sehingga ukuran terkecil menang. Semoga berhasil!

Dan berikut adalah beberapa contoh input dan output (dengan lolos C-style):

Input: "abc123def456"
Output: ["123", "456"]

Input: "aitew034snk582: 3c"
Output: ["034", "582", "3"]

Input: "as5493tax54 \\ 430-52@g9.fc"
Output: ["5493", "54", "430", "52", "9"]

Input: "sasprs] tore \" re \\ forz "
Output: null, [], [""], atau serupa

Harap cantumkan berapa byte yang digunakan oleh jawaban Anda, dan seperti biasa, bermain golf bahagia!


Pedoman untuk Lisp

Inilah yang dihitung dan tidak dihitung dalam dialek Lisp:

;;; Pilihan 1

(mencabut ekstrak-string (ab); Tidak masuk hitungan
  (barang) ;; Semua yang ada di sini penting
); Tidak masuk hitungan

;;; pilihan 2

(mencabut ekstrak-string (string & aux (mulai 0) (akhir 0)); Tidak dihitung
  (barang) ;; Semua yang ada di sini penting
); Tidak masuk hitungan.
Semua lambda lainnya sepenuhnya dihitung menuju jumlah byte.


Bukankah ini ditanyakan sebelumnya?
Ismael Miguel

1
Ya, tapi saya bertanya kembali di Meta dan melakukan pengeditan substansial sebelum mempostingnya lagi di sini. Karena itu, ini tidak boleh digolongkan sebagai duplikat (yang terkait lainnya harus ditutup jika belum).
Isiah Meadows

2
Bukankah "golf" Anda diposting sebagai jawaban?
MrWhite

4
Maaf, tetapi -1 karena tidak mengizinkan GolfScript. Semua bahasa harus diizinkan.
Gagang Pintu

1
@ Doorknob Itu benar, tapi saya juga mengerti perasaan OP. Orang-orang harus memiliki kesempatan untuk bersaing bahkan jika mereka tidak berbicara GolfScript, J, atau APL (dan saya bersalah membaca yang terakhir dalam kompetisi ini.) Dapatkah Anda melihat proposal saya di utas yang ditautkannya?
Tobia

Jawaban:


10

APL, 13 karakter

(atau 28/30 byte, baca di bawah)

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

Saya melihat Anda telah melarang GolfScript dari pertanyaan Anda. Saya mengerti sentimen Anda, tetapi saya harap komunitas ini tidak akan melarang APL, karena ini adalah bahasa pemrograman yang benar-benar luar biasa dengan sejarah panjang, belum lagi banyak hal yang menyenangkan untuk dikodekan. Mungkin bisa saja diberi skor berbeda, jika orang-orang merasa itu bersaing secara tidak adil. Saya akan memposting pemikiran saya tentang masalah ini ke utas yang telah Anda tautkan.

Pada token yang sama, saya selalu menambahkan catatan kaki ke posting APL saya, mengklaim bahwa APL dapat dinilai sebagai 1 char = 1 byte. Klaim saya bertumpu pada kenyataan bahwa beberapa (sebagian besar komersial) implementasi APL masih mendukung enkode byte tunggal warisan mereka sendiri, dengan simbol APL dipetakan ke nilai 128 byte atas. Tetapi mungkin ini terlalu berlebihan, dalam hal ini Anda mungkin ingin mencetak entri ini sebagai 28 byte di UTF-16 atau 30 byte di UTF-8.

Penjelasan

{        ⍳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

Contohnya

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

Format output default untuk array string tidak memperjelas berapa banyak string yang ada dalam array, atau berapa banyak kosong. Tetapi manipulasi cepat untuk menambahkan kutipan harus membuatnya cukup jelas:

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

Mengenai komentar Anda, saya pikir bahwa untuk bahasa lain bersaing secara adil dengan yang "singkatan" orang harus menghitung setiap simbol dalam bahasa lain sebagai satu karakter. Sebagai contoh, solusi Mathematica saya yang diposting di sini harus dihitung sebagai 7 (lebih atau kurang). Merancang bahasa dengan token terkompresi sama sekali tidak pantas, saya pikir.
Dr. belisarius

Bisakah Anda memberikan hex dump golf Anda? Saya tidak dapat membaca beberapa karakter.
Isiah Meadows

@impinball Bagaimana hexdump membantu Anda? Ini tidak seperti Anda akan melihat apa yang sedang dilakukan.
mniip

@impinball kode APL adalah {omega melampirkan komuter omega epsilon format epsilon setiap iota 10}. Jika Anda memerlukan nilai unicode, Anda cukup menyalin dan menempelkannya ke alat online apa pun , bahkan jika Anda tidak dapat melihat karakter (yang aneh, karena sebagian besar font Unicode modern memiliki simbol APL). Bagaimanapun, yang Anda dapatkan adalah ini {\ u2375 \ u2282 \ u2368 \ u2375 \ u220a \ u220a \ u2355 \ u00a8 \ u237310} (perhatikan "10" terakhir yang bukan bagian dari urutan pelarian)
Tobia

1
Alih-alih ∊⍕¨⍳10, tidak bisakah Anda menggunakan saja ⎕D? Itu harus konstan '0123456789'. Dyalog APL paling tidak mendukungnya, dan begitu pula NARS2000.
marinus

5

Python 47

Penerapan

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

Demo

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

Algoritma

Konversi setiap karakter non-digit ke spasi dan kemudian pisahkan string yang dihasilkan. Pendekatan yang sederhana dan jelas.

Dan solusi yang menyenangkan dengan itertools (71 karakter)

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

4

Ruby, 70

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

Versi online untuk pengujian

Karena mengonversi karakter non-digit ke int menghasilkan 0 di Ruby (dengan to_i), mengonversi setiap char ke int dan kembali ke char adalah cara non-regex untuk memeriksa ...


Anda juga dapat melakukan anggota ('0' .. '9').? untuk setiap karakter, tetapi yang Anda lakukan sudah lebih pendek
fgp

Anda pasti benar - saya seharusnya mengatakan: "a" way;)
David Herrmann

4

bash, 26 (isi fungsi: 22 + susunan tugas array 4)

Ini tidak akan mengalahkan jawaban yang lainbash , tetapi menarik karena mungkin membuat Anda mengambil dua kali lipat:

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

Penggunaannya adalah:

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

Pada pandangan cepat pertama, //+([!0-9])/tampak sangat mirip substitusi regexp, tetapi tidak. Ini adalah ekspansi parameter bash , yang mengikuti aturan pencocokan pola , alih-alih aturan ekspresi reguler.

Mengembalikan tipe array bash yang sebenarnya dari fungsi bash adalah hal yang menyebalkan, jadi saya memilih untuk mengembalikan daftar yang dibatasi oleh ruang, kemudian mengonversinya menjadi sebuah array dalam penugasan array di luar pemanggilan fungsi. Jadi untuk kepentingan keadilan, saya merasa (` `)bahwa fungsi panggilan harus dimasukkan dalam skor saya.


3

Mathematica 32

StringCases[#,DigitCharacter..]&

Pemakaian

inps ={"abc123def456", "aitew034snk582:3c", "as5493tax54\\430-52@g9.fc", 
        "sasprs]tore\"re\\forz"}  
StringCases[#,DigitCharacter..]&/@inps

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

Yang setara menggunakan regex jauh lebih lama !:

StringCases[#, RegularExpression["[0-9]+"]] &

Mathematica menyebalkan di regex.
CalculatorFeline

3

Bash, 21 byte 17/21 byte (ditingkatkan oleh DigitalTrauma )

Membangun daftar yang dipisahkan ruang tr

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

mengganti non digit dengan spasi

Pemakaian

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

Edit

seperti yang ditunjukkan oleh komentar di bawah ini, kode dapat dipreteli menjadi 17 byte:

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

dan karena hasilnya tidak berbicara deret Bash, penggunaannya harus

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

dan ekstra (``)harus dihitung


1
Gah Anda mengalahkan saya untuk itu! Tapi mengapa tidak menggunakan string di sini dan bukan dokumen di sini? Juga Anda dapat menyimpan baris baru pada akhir isi fungsi yang Anda gunakan (blah)bukan {blah;}: split()(tr -c 0-9 \ <<<$1). Dengan begitu fungsi tubuh Anda hanya 17 karakter.
Trauma Digital

1
Fungsi Anda mengembalikan "daftar yang dipisahkan oleh ruang" alih-alih sebuah array. Tentu saja kembali array benar dari fungsi bash canggung, tapi Anda bisa setidaknya menetapkan hasil fungsi Anda ke array dalam penggunaan Anda: a=($(split "12 3a bc123")); echo ${a[@]}. Dapat dikatakan bahwa "($ ())" dihitung dalam skor Anda
Digital Trauma

Sebelum menjelajahi trpendekatan, saya mencoba melakukan ini dengan ekspansi parameter . trjelas merupakan pendekatan yang lebih baik untuk tujuan golf.
Trauma Digital

Sudahkah Anda mencoba mengelilingi troperator ekspansi? Itu akan keluar untuk sesuatu seperti ($(tr...)), dan di mana deklarasi fungsi tidak dihitung, kurung luar tidak akan dihitung melawan Anda. Itu hanya akan menjadi bagian pengganti perintah.
Isiah Meadows

Saya tidak melihat bagaimana ini seharusnya bekerja, tapi saya tidak lancar dalam array Bash. Bagaimanapun, (``)konstruksinya adalah 1-char lebih baik daripada yang ($())dan akan lebih disukai.
Coaumdio

2

Smalltalk (Smalltalk / X), 81

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

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

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

nilai f: 'as5493tax54 \ 430-52@g9.fc' -> OrderedCollection ('5493' '54' '430' '52' '9')

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

sigh - Smalltalk memiliki kecenderungan untuk menggunakan nama fungsi panjang veeeery ...


2
Apakah itu nama fungsi? o__O
Tobia

@tobia Rupanya ...
Isiah Meadows

asCollectionOfSubCollectionsSeparatedByAnyForWhichಠ_ಠ Nama ini terlalu panjang
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])]
}

Fungsi menerima string dan mengembalikan daftar string.

Contoh:

> 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\\430-52@g9.fc")
$`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

Catatan: $xadalah nama elemen daftar.


1

Perl, 53

Edit: tanpa kecocokan, sub sekarang mengembalikan daftar dengan string kosong (bukan daftar kosong) seperti yang diperlukan.

Ini juga menghindari pemisahan pada karakter spasi tunggal, karena memicu perilaku 'pemisahan pada ruang putih' , yang mungkin melanggar aturan. Saya bisa menggunakan / /pembatas, yang akan terpecah pada satu ruang, tetapi secara paradoksal itu akan terlihat seperti menggunakan pola regexp. Saya bisa menggunakan unpackdengan mengorbankan beberapa karakter tambahan dan menyingkirkan splitkontroversi sama sekali, tapi saya pikir, apa yang saya selesaikan, membelah karakter literal (selain ruang) tidak apa-apa.

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

Dan, tidak, operator transliterasi Perl tidak melakukan ekspresi reguler. Saya dapat membuka gulungan rentang 0-9 0123456789jika itu masalahnya.


Selama tidak menggunakan ekspresi reguler, itu valid.
Isiah Meadows

Perl saya tidak begitu kuat. Jika saya mengerti kodenya, Anda mengganti non-digit dengan non-digit tertentu, lalu membaginya pada non-digit yang dipilih, kemudian memfilter string kosong. Apakah ini bacaan yang benar?
Tim Seguine

1
@ Timimeguine: Tidak juga. Non-digit diganti dan tergencet ke satu karakter, pemisahan yang menghasilkan string kosong jika pembatas itu terjadi pada awal. Itu kemudian bergeser jika daftar berisi entri lain.
user2846289

Daftar orang baik-baik saja.
Isiah Meadows

1

C, 68 byte (hanya badan fungsi)

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

Argumen pertama adalah string input, yang kedua adalah array output, yang merupakan array string yang diakhiri NULL. Memori yang memadai harus disediakan untuk asebelum memanggil fungsi (kasus terburuk:) sizeof(char*)*((strlen(s)+1)/2).

String input dimodifikasi oleh fungsi (setiap karakter non-digit digantikan oleh '\0')

Contoh penggunaan

#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\\430-52@g9.fc";
    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;
}

Keluaran

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

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

1

VBScript, 190 (164 tanpa deklarasi fungsi)

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

Meskipun tidak kompetitif sama sekali, saya terkejut bahwa VBScript keluar sesingkat ini mengingat betapa verbose itu (13 byte untuk CR saja). Itu loop melalui string, mengganti karakter non-numerik dengan spasi, kemudian mengurangi semua spasi putih menjadi spasi tunggal, dan kemudian menggunakan pembatas ruang untuk membaginya.

Uji kasus

Input: "ab5c0x"
Output: 5,0

Input: "z526ks4f.;8]\p"
Output: 526,4,8

Akhir baris DOS dihitung sebagai satu karakter sejauh yang saya baca di meta.
Isiah Meadows

Saya menyarankan edit untuk Anda.
Isiah Meadows

Hitungannya sudah mengasumsikan ujung garis 1 byte gaya Linux. Saya mendapatkan 190 karakter berdasarkan hitungan saya (baru diverifikasi lagi).
Comintern

Baik. Saya pasti salah hitung.
Isiah Meadows

1

Common Lisp (1 sesuai dengan surat; ≈173 sesuai dengan semangat)

Ini versi yang bisa dibaca. Jumlah byte cukup tinggi karena nama-nama panjang dalam hal-hal seperti digit-char-pdan position-ifdan 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\\430-52@g9.fc")
#("5493" "54" "430" "52" "9")

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

Konsep "deklarasi fungsi" agak kabur. Berikut adalah versi yang hanya memiliki satu byte (karakterx dalam fungsi tubuh); segala sesuatu yang lain dibundel ke variabel tambahan daftar lamba fungsi (bagian dari deklarasi fungsi):

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

Jumlah byte sebenarnya akan tergantung pada berapa banyak deklarasi bantu yang harus dipindahkan ke dalam tubuh agar ini dianggap dapat diterima. Beberapa penamaan fungsi lokal juga akan membantu (mis. Mempersingkatposition-if karena muncul dua kali, menggunakan variabel huruf tunggal, dll.).

Render program ini memiliki 220 karakter:

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

Jika tidak ada yang lain, ini harus dipromosikan variabel Common Lisp & aux .

Ini dapat ditulis dengan lebih ringkas loop, tentu saja:

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

The loopbentuk, dengan ruang ekstra dihapus, memiliki 173 karakter:

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

Saya akan menghitung mulai dari (resultpada kurung terakhir menjadi tubuh. Bagian yang mendefinisikan nama dan parameter adalah deklarasi.
Isiah Meadows

Silakan merujuk ke aturan 2 pada aturan saya yang diubah untuk melihat apa yang sebenarnya saya bicarakan dalam deklarasi fungsi (pada dasarnya, nyatakan nama fungsi, parameter, dan jika diperlukan secara sintaksis, yang jarang di antara bahasa yang ditafsirkan, tipe kembalinya).
Isiah Meadows

@impinball Ya, "1" count adalah semacam lelucon, tapi bagian penting di sini adalah bahwa result yang dinyatakan sebagai parameter di sini; itu hanya memiliki bentuk inisialisasi yang sangat sepele. Ini adalah hal yang sama, pada prinsipnya, sebagai argumen opsional dengan nilai default yang dihitung oleh beberapa ekspresi kompleks. (Dalam kasus yang lebih sederhana, mudah untuk membayangkan sesuatu seperti char* substring( char *str, int begin, int end(0) )dalam beberapa bahasa dengan sintaks mirip C untuk menentukan itu endopsional dan bahwa jika tidak disediakan, maka nilainya 0. Saya hanya menyoroti fakta bahwa beberapa istilah ini
Joshua Taylor

@impinball tidak cukup konkret dan cukup agnostik untuk mencegah jumlah byte trollish. :)
Joshua Taylor

Bagian pertama yang tidak menentukan parameter adalah di mana saya akan menghitung stat (misalnya (defun fn (string &aux (start 0) (end 0)tidak akan menghitung, tetapi semua yang tersisa di lambda akan).
Isiah Meadows

0

JavaScript, 240 byte

Dan bagi Anda yang penasaran, inilah mungkin golf besar saya:

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

Di atas dalam cetakan cantik:

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

Di atas dalam kode deskriptif 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;
}

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

Anda dapat mempersingkatnya dengan meninggalkan callback di array_filter. Ini secara otomatis akan menghapus semua entri yang falseketika mereka dilemparkan ke boolean.
kelunik

@kelunik yang akan menyaring 0s juga
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("]");}

Karena C tidak memiliki fungsi print array bawaan, saya harus melakukan itu sendiri, jadi saya minta maaf bahwa ada koma terakhir di setiap output. Pada dasarnya apa yang dilakukan kode itu adalah membaca string jika bukan digit yang menggantikannya dengan '\ 0' dan kemudian saya hanya mengulang-ulang kode dan mencetak semua rantai angka. (EOF = 0)

Input: ab5c0x
Output: ["5", "0",]

Input: z526ks4f.; 8] \ p
Output: ["526", "4", "8",]


Menurut aturan pertanyaan (aturan 2), Anda hanya perlu menghitung karakter di badan fungsi. Jadi solusi Anda sebenarnya akan kurang dari 170 byte. Saya tidak yakin apakah hitungannya menyertakan prototipe variabel di luar fungsi tubuh.
grovesNL

Saya akan mengubah aturan tentang ini: #defines, deklarasi variabel, dll akan dihitung, tetapi deklarasi fungsi tidak akan.
Isiah Meadows

Juga, terakhir kali saya memeriksa, ada tipe C yang dinotasikan sebagai char[][]legal. Jika Anda kembali seperti itu (atau char**), Anda akan baik-baik saja.
Isiah Meadows

Tidak harus Menjadi keluaran teks? Saya
pikir

0

C #, 98

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

Pertama, ini menggunakan .Select()metode ekstensi LINQ untuk mengubah semua non-digit menjadi koma. string.Replace()akan lebih disukai, karena ia mengembalikan a stringdaripada IEnumerable<char>, tetapi string.Replace()hanya dapat mengambil satu karakter atau string dan tidak dapat menggunakan predikat seperti char.IsDigit()atau 47<c&c<58.

Seperti disebutkan, .Select()diterapkan ke string mengembalikan sebuah IEnumerable<char>, jadi kita perlu mengubahnya kembali menjadi string dengan mengubahnya menjadi sebuah array dan meneruskan array ke dalam stringkonstruktor.

Akhirnya, kami membagi string menggunakan koma string.Split(). (StringSplitOptions)1adalah cara yang lebih singkat untuk mengatakan StringSplitOptions.RemoveEmptyEntries, yang akan secara otomatis menangani beberapa koma dan koma berturut-turut pada awal / akhir string.


1
Alih-alih char.IsDigit(c), Anda dapat menggunakan'/'<c&&c<':'
grovesNL

1
Poin bagus ... atau bahkan lebih baik 47<c&&c<58,. (Terus terang, saya terkejut itu bekerja dengan angka, tetapi ternyata itu berhasil).
BenM

1
Dan saya dapat menyimpan karakter ekstra berharga dengan menggunakan satu '&' daripada double '&&'. Dalam C #, ini masih logis DAN ketika kedua operan adalah boolean - itu hanya sedikit DAN ketika mereka bilangan bulat.
BenM

Bagus Saya tidak tahu itu bisa melakukan itu.
grovesNL

Varian yang sedikit lebih pendek adalah dengan membagi pada ruang putih alih-alih ,, dan kemudian secara manual menghapus item kosongreturn new string(s.Select(c=>47<c&c<58?c:' ').ToArray()).Split().Where(a=>a!="").ToArray();
VisualMelon

0

JS / Simpul: 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;
}

Versi dipercantik:

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

Pertanyaan ini hanya ingin array dikembalikan, sehingga Anda dapat menghapus console.log(r)dan beberapa hal lainnya
Bukan karena Charles

Deklarasi fungsi tidak diperhitungkan dalam skor (alasannya adalah untuk membantu menyamakan kedudukan)
Isiah Meadows

Baik. Menyesuaikan skor sesuai komentar @ impinball. (Sebenarnya ada dua fungsi yang dideklarasikan di sini. Hitungan Char mencakup fungsi anonim)
palanik

Itu harus. Saya memperbarui aturan untuk membantu menjelaskannya dengan lebih baik.
Isiah Meadows

Sementara itu, muncul dengan sesuatu yang lebih baik ...
palanik

0

Ruby, 24

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

Menentukan digit menggunakan ruang negatif dalam rentang ascii yang dapat dicetak.


Deklarasi fungsi tidak masuk hitungan.
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;}

Kode Deskriptif:

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

Ini adalah kode yang cukup panjang dan saya yakin akan ada versi php yang jauh lebih pendek untuk kode golf ini. Inilah yang bisa saya temukan di php.


ada beberapa peningkatan: Anda dapat mengganti array()dengan [], array_push($output[$count], $arr[$i]);dengan $output[$count][]=$arr[$i];, dan ord()memeriksa dengan is_numeric(). dan Anda bahkan tidak perlu membagi string untuk beralih ke karakternya. juga, hanya kode bagian dalam dari fungsi yang diperhitungkan, sehingga Anda menghitung char adalah 204.
Einacio

Deklarasi fungsi tidak masuk hitungan. Rujuk ke aturan 2 sebagai panduan tentang apa yang diperhitungkan dan apa yang tidak.
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

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]

@Abhijit jawabannya jauh pintar, ini hanya versi "diperkecil" dari apa yang ada dalam pikiran saya.

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

Ini tidak menghasilkan output, jadi kode berfungsi, jika dijalankan satu per satu, karena beberapa variabel didefinisikan pada deklarasi.


Anda tidak harus menghitung deklarasi fungsi, jika Anda melakukannya. Sama seperti seorang kepala
Isiah Meadows

0

PHP 98 89

Seperti dalam jawaban bash DigitalTrauma, ini tidak menggunakan regex.

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

Kasus uji:

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\\430-52@g9.fc")), "\n";
["5493","54","430","52","9"]
php > echo json_encode(f("sasprs]tore\"re\\forz")), "\n";
null

0

Haskell 31

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

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

Ini membagi string pada semua karakter non-numerik dan menghilangkan string kosong yang dihasilkan oleh pembatas berurutan.


0

VBA 210, 181 tanpa deklarasi fungsi

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

0

Rebol (66 karakter)

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

Tidak disatukan dan dibungkus dengan deklarasi fungsi:

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

Kode contoh di konsol Rebol:

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

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

>> f "as5493tax54\\430-52@g9.fc"
== ["5493" "54" "430" "52" "9"]

>> f {sasprs]torer"re\\forz}
== []

0

JavaScript, 104 97 89

Golf:

Sunting: Ketika loop berjalan dari ujung array, cadalahundefined , yang palsu dan mengakhiri loop.

2/27: Menggunakan ?:menghemat wordiness dari 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
}

Pengembalian carriage di bodi adalah untuk keterbacaan dan bukan bagian dari solusi.

Tidak Terkumpul:

Idenya adalah untuk menambahkan setiap karakter ke entri terakhir dalam array jika itu adalah digit dan untuk memastikan entri array terakhir adalah string sebaliknya.

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

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
}

Tidak disatukan

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

Contoh input / output

console.log(f("abc123def456"));
console.log(f("aitew034snk582:3c"));
console.log(f("as5493tax54\\430-52@g9.fc"));
console.log(f("sasprs]tore\"re\\forz"));

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

JSFiddle


1
Saya suka itu! Jauh lebih sederhana dari milik saya. Anda dapat menjatuhkan 8 karakter lainnya dengan mengganti if(+a[i]+1)b+=a[i];else if(b)c.push(b),b=""dengan b=+a[i]+1?b+a[i]:b?(c.push(b),""):b.
DocMax

@DocMax thx, saya diedit untuk memasukkan saran Anda :). Itu (c.push(b),"")tampak pintar, tidak pernah melihatnya.
Danny

Saya telah melupakannya sampai saya melihatnya digunakan secara luas sebelumnya hari ini di codegolf.stackexchange.com/questions/22268#22279
DocMax

Itu tidak valid, '' keliru untuk 0 dan ini merupakan javascript yang sulit untuk dikelola. Coba '12 34 56 '
edc65

0

R 52

Fungsi ini membagi string dengan kelas karakter (ini bukan regex! :)) kelas adalah karakter N - numerik dan P {N} berarti negasi dari kelas ini. o = T berarti menghilangkan substring kosong.

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"

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\\430-52@g9.fc"));
var_dump($a("sasprs]tore\"re\\forz"));


Keluaran

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

0

JavaScript 88

88 karakter saat tidak menghitung fungsi 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
}
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.