RegExps olmadan basamak olmayan bir dizeyi bölmek için en kısa program


16

EDIT: Lisp kullanıyorsanız, bayt sayma altta bazı yönergeler verdim.

Amaç: Basamaklı olmayan sayılara bir dize ayıran ve normal ifadeler kullanılmadan, her bir dize içindeki rakamlardan oluşan bir dizi döndüren en kısa işlevi yapın. Her dizede baştaki sıfırlar bulunmalıdır.

Mevcut Sıralamalar (kategorilere ayrılmış):

  • C / C ++ / C # / Java: 68 (C) ....
  • GolfScript / APL / J: 13 (APL)
  • Diğerleri: 17 (Bash, kullanımlar tr), 24 (Ruby)

Kurallar:

(Uzunluğu özür dilerim)

  1. Biçim, tek bir dize bağımsız değişkenine sahip bir işlev olarak olmalıdır. Dizinin düzgün döndürülmesi için gerekirse en fazla iki bağımsız değişken eklenebilir (örn. Sh / csh / DOS Batch öğesinin döndürülmesi için fazladan değişken başvurusu gerekir).
  2. Birincil işlev bildirimi sayılmaz ve diğer standart kitaplıkları içe aktarmaz. "# include`s," import`s ve "using`s sayılmaz. Geri kalan her şey. Buna `` define '' ve yardımcı fonksiyonlar dahildir. Karışıklık için özür dilerim. Neyi saymaz / saymaz (C stili sözdiziminde yazılmıştır) hakkında yararlı bir kılavuz olarak bakın
    // toplamı saymaz, aksi takdirde ihmal edilebilir
    // açık değil, Java'nın standart kütüphanesinin yarısı gibi.
    #include <stdio.h>
    
    import some.builtin.Class // sayılmaz, yukarıya bakın
    
    #define printf p // toplamı sayar
    
    / * Diğer önişlemci yönergeleri vb. Sayılır. * /
    
    int i = 0; // sayılır
    
    birFonksiyon (); // sayılır
    
    char [] [] myMainSplitFunction (char [] [] dizi) {// sayılmaz
      // Buradaki her şey önemlidir
      return returnArray; // Bu bile önemlidir.
    } // sayılmaz
    
    / * Buradaki her şey önemlidir, beyan dahil * /
    char [] [] someHelperFunction (char [] string) {
      // şey
    } // bu bile önemlidir
    
  3. Çıktı bir dize dizisi veya benzeri olmalıdır (Java ve benzerindeki dizi listeleri kabul edilebilir). Kabul edilen çıkış örnekler: String[], char[][], Array, List, ve Array(nesne).
  4. Dizi yalnızca değişken uzunlukta dize temel öğeleri veya dize nesneleri içermelidir. Aşağıdaki istisna dışında, dönüşte boş dizeler olmamalıdır. Not: Dizeler, aşağıdaki örnek girdi ve çıktı gibi ardışık eşleşmeler dizisini içermelidir.
  5. Eşleşme yoksa, işlev gövdesi null, boş bir dizi / liste veya boş bir dize içeren bir dizi / liste döndürmelidir .
  6. Harici kütüphaneye izin verilmez.
  7. DOS satır sonları iki değil, bir bayt olarak sayılır (zaten meta ile kaplıdır, ancak vurgulanması gerekir)
  8. Ve buradaki en büyük kural: düzenli ifadelere izin verilmiyor.

Bu bir sorusu, bu yüzden en küçük boyut kazanır. İyi şanslar!

Ve işte bazı örnek giriş ve çıkışlar (C stili kaçışlarla):

Giriş: "abc123def456"
Çıktı: ["123", "456"]

Girdi: "aitew034snk582: 3c"
Çıktı: ["034", "582", "3"]

Girdi: "as5493tax54 \\ 430-52@g9.fc"
Çıktı: ["5493", "54", "430", "52", "9"]

Girdi: "sasprs] \" re \\ forz "yendi
Çıktı: boş, [], [""] veya benzeri

Lütfen cevaplarınız tarafından kaç bayt kullanıldığını ve her zaman olduğu gibi mutlu golf oynayın!


Lisp Kuralları

Lisp lehçelerinde neyin sayıldığı ve sayılmadığı aşağıda açıklanmıştır:

;;; seçenek 1

(defun özü dizeleri (ab); sayılmaz
  (şey) ;;; Buradaki her şey önemlidir
); Sayılmaz

;;; seçenek 2

(defun özü dizeleri (string & aux (start 0) (end 0))); sayılmaz
  (şey) ;;; Buradaki her şey önemlidir
); Önemli değil.
Diğer tüm lambdaslar bayt sayısına tam olarak sayılır.


Bu daha önce sorulmamış mıydı?
Ismael Miguel

1
Evet, ancak Meta'da yeniden sordum ve burada tekrar göndermeden önce üzerinde önemli düzenlemeler yaptım. Bu nedenle, kopya olarak sınıflandırılmamalıdır (ilgili değilse, diğeri kapalı olmalıdır).
Isiah Meadows

2
"Golf" unuz cevap olarak yayınlanmamalı mı?
MrWhite

4
Maalesef, GolfScript'e izin vermemek için -1. Tüm dillere izin verilmelidir.
Kapı Tokmağı

1
@Doorknob Bu doğru, ama aynı zamanda OP'nin duygularını da anlıyorum. İnsanlar GolfScript, J veya APL bilmeyen bile rekabet şansına sahip olmalıdır (ve bu yarışmalarda ikincisi incelerken suçlu değilim.) Eğer bir göz verebilir önerimi o bağlantılı dizisindeki?
Tobia

Yanıtlar:


10

APL, 13 karakter

(veya 28/30 bayt, aşağıyı okuyun)

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

GolfScript'i sorunuzdan yasakladığınızı görüyorum. Duygunuzu anlıyorum, ama umarım bu topluluk APL'yi yasaklamaz, çünkü kodlamak için çok eğlenceden bahsetmemek için uzun bir geçmişi olan gerçekten dikkat çekici bir programlama dilidir. Belki insanlar farklı bir şekilde puanlanabilir haksız rekabet ettiğini hissediyorum. Bu konuyla ilgili düşüncelerimi bağladığınız konuya göndereceğim.

Aynı jetonda, APL gönderilerime her zaman APL'nin 1 char = 1 byte olarak puanlanabileceğini iddia eden bir dipnot ekledim. Benim iddiam, birkaç (çoğunlukla ticari) APL uygulamasının hala kendi eski tek bayt kodlamasını desteklediği ve APL sembolleri üst 128 bayt değerlerine eşlendiğine dayanıyor. Ama belki de bu çok fazla bir esnektir, bu durumda bu girişi UTF-16'da 28 bayt veya UTF-8'de 30 bayt olarak puanlamak isteyebilirsiniz.

açıklama

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

Örnekler

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

Bir dizi dizisinin varsayılan çıktı biçimi, dizide kaç tane dizenin olduğunu veya kaç boşluk olduğunu netleştirmez. Ancak tırnak eklemek için hızlı bir manipülasyon yeterince açık olmalıdır:

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

Yorumunuzla ilgili olarak, diğer diller için "steno" olanlarla adil bir şekilde rekabet etmenin, diğer dillerdeki her sembolü bir karakter olarak sayması gerektiğini düşünüyorum. Örneğin, burada yayınlanan Mathematica çözümüm 7 (daha fazla veya daha az) olarak sayılmalıdır. Sıkıştırılmış jetonlarla bir dil tasarlamak hiç de kolay değil bence.
Dr. belisarius

Golfünüzün onaltılık bir dökümünü sağlayabilir misiniz? Bazı karakterleri okuyamıyorum.
Isiah Meadows

@impinball Hexdump size nasıl yardımcı olur? Ne yapıldığını görecekmişsiniz gibi değil.
mniip

@impinball APL kodu {omega, her bir iota 10 için gidip gelme omega epsilon epsilon biçimidir}. Unicode değerlerine ihtiyacınız varsa, karakterleri göremeseniz bile kopyalayıp herhangi bir çevrimiçi araca yapıştırabilirsiniz (bu, çoğu modern Unicode yazı tipinin APL sembollerine sahip olduğu için gariptir) Her durumda, elde ettiğiniz şey budur {\ u2375 \ u2282 \ u2368 \ u2375 \ u220a \ u220a \ u2355 \ u00a8 \ u237310} (kaçış dizisinin bir parçası olmayan son "10" a dikkat edin)
Tobia

1
Bunun yerine, ∊⍕¨⍳10sadece kullanamaz mıydın ⎕D? Bu sabit olmalı '0123456789'. Dyalog APL en azından bunu destekliyor ve NARS2000 de destekliyor.
marinus

5

Python 47

uygulama

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

gösteri

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

Sayı olmayan her karakteri uzaya dönüştürün ve sonuçta oluşan dizeyi bölün. Basit ve açık bir yaklaşım.

Itertools ile eğlenceli bir çözüm (71 karakter)

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

4

Yakut, 70

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

Test için Çevrimiçi Sürüm

Sayısal olmayan herhangi bir karakteri int'e dönüştürdüğünden Ruby'de (to_i ile) 0 döndürdüğünden, her karakteri int'e ve char'a geri dönüştürmek, bir rakamı kontrol etmenin regex olmayan yoludur ...


Ayrıca ('0' .. '9'). Üye misiniz? her karakter için, ama yaptığın şey zaten daha kısa
fgp

Kesinlikle haklısın - şunu söylemeliydim: "bir" yol;)
David Herrmann

4

bash, 26 (işlev içeriği: 22 + dizi atama ek yükü 4)

Bu diğer bashcevabı yenmeyecek , ama ilginç çünkü sizi iki kez ele geçirebilir:

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

Kullanımı:

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

İlk hızlı bakışta, //+([!0-9])/normal ifade yerine koymaya çok benziyor, ama değil. Normal ifade kuralları yerine kalıp eşleme kurallarını izleyen bir bash parametresi genişletmesidir .

Bash işlevlerinden gerçek bash dizi türlerini döndürmek bir acıdır, bu yüzden bunun yerine boşlukla ayrılmış bir liste döndürmeyi seçtim, sonra işlev çağrısının dışındaki bir dizi atamasında bir diziye dönüştürmeyi seçtim. Bu nedenle, adalet yararına (` `), fonksiyon çağrısının etrafına puanımın dahil edilmesi gerektiğini hissediyorum .


3

Mathematica 32

StringCases[#,DigitCharacter..]&

kullanım

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"}, 
 {}
}

Normal ifadeler kullanan eşdeğeri çok daha uzundur !:

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

Mathematica normal ifade berbat.
CalculatorFeline

3

Bash, 21 bayt 17/21 bayt ( DigitalTrauma tarafından geliştirilmiştir )

İle boşlukla ayrılmış bir liste oluşturma tr

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

rakam olmayan herhangi bir yeri bir boşlukla değiştirir

kullanım

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

Düzenle

aşağıdaki yorumların işaret ettiği gibi, kod 17 bayta çıkarılabilir:

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

ve sonuç sıkıca bir Bash dizisi konuşmadığından,

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

ve ekstra (``)sayılmalıdır


1
Gah beni dövüyorsun! Ama neden burada-belge yerine burada-dize kullanmıyorsunuz? Ayrıca kullandığınız fonksiyon içerik sonunda bir yeni satır kaydedebilirsiniz (blah)yerine {blah;}: split()(tr -c 0-9 \ <<<$1). Bu şekilde işlev bedeniniz sadece 17 karakterdir.
Dijital Travma

1
İşleviniz dizi yerine "boşlukla ayrılmış liste" döndürür. Bash fonksiyon garip gelen Kesinlikle doğrudur diziler dönen, ancak en az sizin kullanımında bir dizi için fonksiyonun sonucunu atayabilir: a=($(split "12 3a bc123")); echo ${a[@]}. Skorunuzda "($ ())" sayılabilir
Digital Trauma

trYaklaşımı keşfetmeden önce bunu bir parametre genişletmesi ile yapmaya çalıştım . trkesinlikle golf için daha iyi bir yaklaşımdır.
Dijital Travma

trGenişletme operatörü ile çevreyi denediniz mi? Bu gibi bir şey ortaya çıkacaktı ($(tr...))ve işlev beyanının sayılmadığı durumlarda, dış parantezler size karşı sayılmayacaktı. Sadece komuta ikame kısmı olurdu.
Isiah Meadows

Bunun nasıl çalışması gerektiğini görmüyorum, ama Bash dizilerinde akıcı değilim. Her neyse,(``) yapı olandan 1-char daha iyidir ($())ve tercih edilecektir.
Coaumdio

2

Küçük konuşma (Küçük konuşma / X), 81

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

f değeri: 'abc123def456' -> OrderedCollection ('123' '456')

f değeri: 'aitew034snk582: 3c' -> OrderedCollection ('034' '582' '3')

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

f değeri: 'sasprs] \ "re \ forz' -> OrderedCollection ()

sigh - Smalltalk, veeeery uzun işlev adlarını kullanma eğilimindedir ...


2
Bu bir işlev adı mı? o__O
Tobia

@tobia Görünüşe göre ...
Isiah Meadows

asCollectionOfSubCollectionsSeparatedByAnyForWhich
Name_ಠ

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

İşlev bir dizeyi kabul eder ve bir dize listesi döndürür.

Örnekler:

> 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

Not: $xliste öğesinin adıdır.


1

Perl, 53

Düzenle: Eşleşmediklerinde, sub artık gerektiği gibi boş dize (boş liste yerine) içeren listeyi döndürür.

Ayrıca , büyük olasılıkla kuralları ihlal eden 'herhangi bir beyaz boşlukta bölünme' davranışını tetiklediğinden, tek boşluk karakteri üzerinde bölünmeyi de önler . kullanabilirim/ /Tek bir alana bölünecek sınırlayıcı , ama paradoksal olarak normal ifade deseni gibi görünecektir . unpackBazı ekstra karakterlerin pahasına kullanabilirim ve bu yüzden splittamamen tartışmalardan kurtulabilirim , ancak bitirdiğim şeyle (boşluk dışında) gerçek bir karaktere bölmenin sorun olmadığını düşünüyorum.

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

Ve hayır, Perl'in harf çevirisi operatörü düzenli ifadeler yapmıyor. 0123456789Eğer sorun bu ise 0-9 aralığını açabilirim .


Normal ifadeler kullanmadığı sürece geçerlidir.
Isiah Meadows

Perl'im o kadar güçlü değil. Kodu anlarsam, rakam olmayan rakamları belirli bir rakam olmayan ile değiştirirsiniz, ardından seçilen rakam olmayan sayıya böler ve ardından boş dizeleri filtrelersiniz. Bu doğru bir okuma mı?
Tim Seguine

1
@TimSeguine: Tam olarak değil. Rakam olmayanlar değiştirilir ve tek bir karakterle ezilir, bu ayırıcı başlangıçta boş dize oluşturur. Daha sonra liste başka girişler içeriyorsa kaydırılır.
user2846289

Enpty listesi tamam.
Isiah Meadows

1

C, 68 bayt (yalnızca işlevin gövdesi)

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

İlk argüman girdi dizesi, ikincisi NULL sonlu dize dizisi olan çıktı dizisidir. aİşlevi çağırmadan önce yeterli bellek ayrılmalıdır (en kötü durum:) sizeof(char*)*((strlen(s)+1)/2).

Giriş dizesi işlev tarafından değiştirilir (her rakam olmayan karakterin yerini alır '\0')

Kullanım örneği

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

Çıktı

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

Golfsiz sürüm:

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 işlev bildirimi olmadan)

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

Hiç rekabetçi olmasa da, VBScript'in ne kadar ayrıntılı olduğu göz önüne alındığında (bu sadece CR'ler için 13 bayt) bu kadar kısa bir sürede ortaya çıktığına şaşırdım. Sayısal olmayan karakterleri boşluklarla değiştirerek dizeden geçer, sonra tüm boşlukları tek boşluklara indirir ve sonra bölmek için boşluk ayırıcı kullanır.

Test senaryoları

Input: "ab5c0x"
Output: 5,0

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

DOS satır sonları metada okuduğum kadarıyla bir karakter olarak sayılır.
Isiah Meadows

Senin için bir düzenleme önerdim.
Isiah Meadows

Sayı zaten Linux stili 1 bayt satır sonlarını varsayar. Sayımla 190 karakter alıyorum (sadece tekrar doğrulandı).
Komintern

Tamam. Yanlış saymış olmalıydım.
Isiah Meadows

1

Ortak Lisp (mektuba göre 1; ruha göre ≈173)

İşte okunabilir bir versiyon. Bayt sayısı nedeniyle gibi şeyler uzun isimleri oldukça yüksektir digit-char-pve position-ifve 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")
#()

"İşlev beyanı" kavramı bir nevi belirsizdir. İşte sadece bir bayt ( xfonksiyon gövdesindeki karakter ) olan bir sürüm ; geri kalan her şey işlevin lamba listesinin yardımcı değişkenlerinde bulunur (işlevin bildiriminin bir parçası):

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

Gerçek bayt sayısı, kabul edilebilir sayılabilmesi için kaç tane yardımcı bildirimin vücuda taşınması gerektiğine bağlı olacaktır. Bazı yerel işlevlerin yeniden adlandırılması da yardımcı olacaktır (örneğin, position-ifiki kez göründüğü için kısaltın , tek harfli değişkenler kullanın, vb.).

Programın bu görüntüsünde 220 karakter vardır:

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

Başka bir şey yoksa, bu Common Lisp & aux değişkenlerini desteklemelidir .

Bu loopelbette daha kısaca yazılabilir :

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

loopKaldırıldı ekstra alan formu, 173 karakterden:

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

(resultBeden olarak son parantezden başlayarak sayacağım . Adı ve parametreleri tanımlayan kısım bildirimdir.
Isiah Meadows

Bir işlev bildiriminde gerçekte neden bahsettiğimi görmek için lütfen değiştirilmiş kurallarımdaki kural 2'ye bakın (temel olarak, işlev adını, parametrelerini belirtin ve sözdizimsel olarak gerekirse, yorumlanan diller arasında nadir olan dönüş türü).
Isiah Meadows

@impinball Evet, "1" sayısı çeşit şaka, ama burada önemli bir parçası olmasıdır result edilir burada bir parametre olarak ilan; sadece önemsiz olmayan bir başlatma formuna sahip. Prensipte, bazı karmaşık ifadelerle hesaplanan varsayılan bir değere sahip isteğe bağlı bir argüman olarak aynı şeydir. (Daha basit durumlarda, char* substring( char *str, int begin, int end(0) )C dilinde benzeyen bir sözdizimine sahip bazı dillerde olduğu gibi end, isteğe bağlı olduğunu ve sağlanmadıysa, değerinin olduğunu belirtmek kolaydır 0. Sadece bu terimlerin bazılarının
Joshua Taylor

@impinball, bazı trol bayt sayısını önlemek için yeterince somut ve dil agnostik değildir. :)
Joshua Taylor

Parametreleri belirtmeyen ilk bölüm saymayı stat olarak alacağım (örneğin (defun fn (string &aux (start 0) (end 0)sayılmaz, ancak lambdada kalan her şey).
Isiah Meadows

0

JavaScript, 240 bayt

Meraklı olanlar için, işte benim büyük dev golfüm:

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

Yukarıda güzel baskı:

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

Yukarıda normal açıklayıcı kod

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

Adresindeki geri aramayı bırakarak kısaltabilirsiniz array_filter. Bu, falseboole'lara döküldükleri zamanki tüm girdileri otomatik olarak kaldırır .
kelunik

@kelunik de 0'ları filtreleyecek
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("]");}

C yerleşik dizi yazdırma işlevleri olmadığından, bu çıktıyı kendi başıma yapmak zorunda kaldım, bu yüzden her çıktıda son bir virgül olduğu için özür dilerim. Aslında bu kodun yaptığı, '\ 0' ile değiştirdiği bir rakam değilse dizeyi okur ve sonra sadece kodun içinden geçer ve tüm basamak zincirlerini yazdırırım. (EOF = 0)

Giriş: ab5c0x
Çıkış: ["5", "0",]

Giriş: z526ks4f.; 8] \ p
Çıkış: ["526", "4", "8",]


Sorunun kurallarına göre (kural 2), yalnızca işlev gövdesindeki karakterleri saymanız gerekir. Yani çözümünüz aslında 170 bayttan az olacaktır. Sayının işlev gövdesi dışında değişken prototipler içerip içermediğinden emin değilim.
groves

Bu konuyla ilgili kuralları değiştireceğim: #defines, değişken bildirimler, vb. Sayılır, ancak işlev bildirimi kabul edilmez.
Isiah Meadows

Ayrıca, en son kontrol ettiğimde, C notunda char[][]yasal olan bir tür vardı . Eğer bu şekilde dönerseniz (ya da char**), iyi olacaksınız.
Isiah Meadows

Metin çıktısı olmak zorunda değil mi? Ben programın bir dize formatında dizi çıktı gerekiyordu
ASKASK

0

C #, 98

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

İlk olarak, .Select()tüm basamak olmayanları virgül haline getirmek için LINQ genişletme yöntemini kullanır . string.Replace()a stringyerine bir döndürdüğü için tercih edilir IEnumerable<char>, ancak string.Replace()yalnızca tek bir karakter veya dize alabilir ve benzeri bir yüklemden yararlanamazchar.IsDigit() veya47<c&c<58 .

Belirtildiği gibi, .Select()bir dizeye uygulanan bir döndürür IEnumerable<char>, bu yüzden diziye dönüştürüp diziyi diziye geçirerek dizeye geri döndürmemiz gerekir.string .

Son olarak, dizeyi virgüllerde kullanarak ayırıyoruz string.Split(). (StringSplitOptions)1, StringSplitOptions.RemoveEmptyEntriesdizenin başlangıcında / sonunda otomatik olarak birbirini izleyen birden çok virgül ve virgülle ilgilenir.


1
Bunun yerine, char.IsDigit(c)kullanabilirsiniz'/'<c&&c<':'
grovesNL

1
İyi bir nokta ... ya da daha iyisi 47<c&&c<58. (Açıkçası, sayılarla çalıştığına şaşırdım, ama görünüşe göre çalışıyor).
BenM

1
Ve bir çift '&&' yerine tek bir '&' kullanarak ekstra değerli bir karakter kaydedebilirim. C # 'da, bu hala mantıksal AND her iki işlenen de boolean olduğunda - sadece bitsel bir AND yapar ve tamsayılar.
BenM

Güzel. Bunu yapabildiğini bilmiyordum.
grovesNL

Biraz daha kısa bir varyant, beyaz boşluk yerine bölünmek ,ve daha sonra boş öğeleri manuel olarak kaldırmaktırreturn new string(s.Select(c=>47<c&c<58?c:' ').ToArray()).Split().Where(a=>a!="").ToArray();
VisualMelon

0

JS / Düğüm: 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;
}

Güzelleştirilmiş sürüm:

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

Bu soru sadece dizinin döndürülmesini istiyor, böylece kaldırabilirsiniz console.log(r)ve başka şeyler
Charles

İşlev beyanı skora doğru sayılmaz (nedeni oyun alanını düzleştirmeye yardımcı olmaktır)
Isiah Meadows

Tamam. Skoru @ impinball'un yorumuna göre düzeltildi. (Aslında burada bildirilen iki işlev vardır. Char sayısı anonim işlevi içerir)
palanik

Olması gerekiyor. Daha iyi açıklamak için kuralları güncelledim.
Isiah Meadows

Bu arada, daha iyi bir şey ile geldi ...
palanik

0

Yakut, 24

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

Yazdırılabilir ASCII aralığındaki negatif boşluk kullanarak rakamları tanımlar.


İşlev bildirimi sayılmaz.
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;}

Açıklayıcı Kod:

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

Bu oldukça uzun bir kod ve bu kod golf için çok daha kısa bir php sürümü olacak eminim. Ben php ile gelip budur.


Eğer değiştirebilirsiniz: bazı gelişmeler vardır array()ile [], array_push($output[$count], $arr[$i]);birlikte $output[$count][]=$arr[$i];ve ord()çekler is_numeric(). ve karakterleri yinelemek için dizeyi bölmeniz bile gerekmez. Ayrıca, işlevin yalnızca iç kodu sayılır, bu nedenle char sayımı
204'tür.

İşlev bildirimi sayılmaz. Neyin önemli olduğu ve neyin önemli olmadığı konusunda kılavuz olarak kural 2'ye bakın.
Isiah Meadows

0

piton

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 cevap çok zekidir, bu sadece aklımdakilerin "küçültülmüş" bir versiyonudur.

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") == []

Bu çıktı vermez, bu nedenle bazı değişkenler bildirimde tanımlandığı için kod tek tek çalıştırılırsa çalışır.


Eğer öyleyse, işlev bildirimini saymanız gerekmez. Tıpkı bir kafa gibi
Isiah Meadows

0

PHP 98 89

DigitalTrauma'nın bash cevabında olduğu gibi, bu normal ifade kullanmaz.

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

Test senaryoları:

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)

Dizeyi sayısal olmayan tüm karakterlere ayırır ve ardışık sınırlayıcılar tarafından oluşturulan boş dizeleri kaldırır.


0

VBA 210, 181 işlev bildirimi olmadan

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

Açıklanmamış ve işlev bildiriminde sarılmış:

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

Rebol konsolundaki örnek kod:

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

golfed:

Düzenleme: Döngüler dizinin sonuna geldiğinde c,undefined falsy olan ve döngü sona erer.

2/27: Kullanmak ?:kelimesini kurtarır 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
}

Gövdedeki taşıyıcı dönüşü okunabilirlik içindir ve çözümün bir parçası değildir.

Ungolfed:

Buradaki fikir, bir rakamsa dizideki son girişe her karakteri eklemek ve son dizi girişinin bir dize olmasını sağlamaktır.

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
}

Ungolfed

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

Örnek giriş / çıkış

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
Bunu sevdim! Benimkinden çok daha basit. Sen değiştirerek başka 8 karakterden bırakın if(+a[i]+1)b+=a[i];else if(b)c.push(b),b=""ile b=+a[i]+1?b+a[i]:b?(c.push(b),""):b.
DocMax

@DocMax thx, önerinizi eklemek için düzenledim :). Bu (c.push(b),"")zekice görünüyordu, hiç görmedim.
Danny


Bu geçerli değil, '' 0 ile karıştırıldı ve yönetilmesi zor bir javascript tuhaflığı. '12 34 56 'deneyin
edc65

0

R 52

Bu işlev dizeleri karakter sınıfına göre böler (bu normal ifade! :) değildir) sınıf N - sayısal karakterlerdir ve P {N} bu sınıfın reddedilmesi anlamına gelir. o = T boş alt dizelerin çıkarılması anlamına gelir.

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


Çıktı

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

N (x) işlevi sayılmadığında 88 karakter {}

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
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.