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 \\ [email protected]"
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.

Isiah Meadows
sumber
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" 
Tobia
sumber
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\\[email protected]","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]
Abhijit
sumber
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 ...

David Herrmann
sumber
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.

digital Trauma
sumber
3

Mathematica 32

StringCases[#,DigitCharacter..]&

Pemakaian

inps ={"abc123def456", "aitew034snk582:3c", "as5493tax54\\[email protected]", 
        "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]+"]] &
Belisarius
sumber
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

Coaumdio
sumber
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 \ [email protected]' -> OrderedCollection ('5493' '54' '430' '52' '9')

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

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

blabla999
sumber
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\\[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

Catatan: $xadalah nama elemen daftar.

Sven Hohenstein
sumber
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.

pengguna2846289
sumber
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\\[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;
}

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
} 
Coaumdio
sumber
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
Komintern
sumber
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\\[email protected]")
#("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))
Joshua Taylor
sumber
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;
}
Isiah Meadows
sumber
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
sumber
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",]

ASKASK
sumber
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.

BenM
sumber
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;
}
palanik
sumber
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.

histokrat
sumber
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.

palerdot
sumber
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
Saya meninggalkan StackExchange
sumber
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\\[email protected]") == ["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.

gcq
sumber
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\\[email protected]")), "\n";
["5493","54","430","52","9"]
php > echo json_encode(f("sasprs]tore\"re\\forz")), "\n";
null
Tolong berdiri
sumber
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.

lortabac
sumber
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
Gaffi
sumber
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\\[email protected]"
== ["5493" "54" "430" "52" "9"]

>> f {sasprs]torer"re\\forz}
== []
draegtun
sumber
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;
}
DocMax
sumber
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\\[email protected]"));
console.log(f("sasprs]tore\"re\\forz"));

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

JSFiddle

Danny
sumber
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"
bartektartanus
sumber
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"));


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) {
}
kelunik
sumber
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
}
wolfhammer
sumber