Najkrótszy program do dzielenia ciągów znaków bez cyfr bez RegExps

16

EDYCJA: Jeśli używasz Lisp, podałem kilka wskazówek na dole liczenia bajtów.

Cel: Wykonaj najkrótszą funkcję, która dzieli ciąg na niecyfrowe i zwraca tablicę składającą się tylko z cyfr w każdym ciągu, bez użycia żadnych wyrażeń regularnych. Zera wiodące należy zawrzeć w każdym ciągu.

Aktualne tabele (podzielone na kategorie):

  • C / C ++ / C # / Java: 68 (C) ....
  • GolfScript / APL / J: 13 (APL)
  • Wszystkie pozostałe: 17 (Bash, używa tr), 24 (Ruby)

Zasady:

(Przepraszam za długość)

  1. Format musi być funkcją z pojedynczym argumentem łańcuchowym. W razie potrzeby do poprawnego zwrócenia tablicy można dodać maksymalnie dwa dodatkowe argumenty (np. Sh / csh / DOS Batch wymaga dodatkowej zmiennej odniesienia do zwrócenia itp.).
  2. Deklaracja funkcji podstawowej nie ma znaczenia, podobnie jak import innych standardowych bibliotek. `# include`s,` import`s i `using`s nie liczą się. Wszystko inne robi. Obejmuje to funkcje `# defin` i pomocnicze. Przepraszam za zamieszanie. Odwołaj się do tego jako pomocnego przewodnika po tym, co się nie liczy (napisane w stylu C)
    // nie wlicza się do sumy, można ją pominąć, chyba że
    // nieoczywiste, jak połowa standardowej biblioteki Java.
    #include <stdio.h>
    
    import some.builtin.Class // się nie liczy, patrz wyżej
    
    # zdefiniować printf p // liczy się do sumy
    
    / * Liczą się wszelkie inne dyrektywy preprocesora itp. * /
    
    int i = 0; // liczy się
    
    someFunction (); // liczy się
    
    char [] [] myMainSplitFunction (tablica char [] []) {// się nie liczy
      // Wszystko tutaj się liczy
      return returnArray; // Nawet to się liczy.
    } // się nie liczy
    
    / * Wszystko tutaj się liczy, łącznie z deklaracją * /
    char [] [] someHelperFunction (ciąg char []) {
      // rzeczy
    } // nawet to się liczy
    
  3. Dane wyjściowe muszą być tablicą łańcuchową lub podobną (dopuszczalne są listy tablic w Javie i podobnych). Przykłady wyjścia przyjętych: String[], char[][], Array, List, i Array(object).
  4. Tablica musi zawierać tylko prymitywy łańcuchowe o zmiennej długości lub obiekty łańcuchowe. Zwroty nie powinny zawierać pustych ciągów, z wyjątkiem wyjątku poniżej. Uwaga: ciągi powinny zawierać ciąg kolejnych dopasowań, takich jak przykładowe dane wejściowe i wyjściowe poniżej.
  5. Jeśli nie ma żadnych dopasowań, zwróci treść funkcji null, pustą tablicę / listę lub tablicę / listę zawierającą pusty ciąg.
  6. Niedozwolone są biblioteki zewnętrzne.
  7. Zakończenia linii DOS liczą się jako jeden bajt, a nie dwa (już pokryte meta, ale należy podkreślić)
  8. I największa reguła tutaj: niedozwolone są wyrażenia regularne.

To jest pytanie do , więc wygrywa najmniejszy rozmiar. Powodzenia!

A oto kilka przykładowych danych wejściowych i wyjściowych (ze znakami zmiany znaczenia w stylu C):

Dane wejściowe: „abc123def456”
Wyjście: [„123”, „456”]

Dane wejściowe: „aitew034snk582: 3c”
Wyjście: [„034”, „582”, „3”]

Dane wejściowe: „as5493tax54 \\ [email protected]”
Wyjście: [„5493”, „54”, „430”, „52”, „9”]

Dane wejściowe: „sasprs] tore \" re \\ forz "
Dane wyjściowe: null, [], [""] lub podobny

Podaj, ile bajtów wykorzystałeś w swoich odpowiedziach i, jak zawsze, życzymy udanej gry w golfa!


Wytyczne dla Lisp

Oto, co robi i nie liczy się w dialektach Lisp:

;;; opcja 1

(defun extract-strings (ab); Nie liczy się
  (rzeczy) ;;; Wszystko tutaj się liczy
); Nie liczy się

;;; Opcja 2

(defun extract-strings (string & aux (start 0) (end 0)); Nie liczy się
  (rzeczy) ;;; Wszystko tutaj się liczy
); Nie liczy się
Wszystkie pozostałe lambdy w pełni liczą się do liczby bajtów.

Isiah Meadows
źródło
Czy nie pytano o to wcześniej?
Ismael Miguel
1
Tak, ale ponownie poprosiłem o to w Meta i wprowadziłem znaczące zmiany przed opublikowaniem go tutaj. Z tego powodu nie należy go klasyfikować jako duplikatu (drugi powiązany powinien zostać zamknięty, jeśli jeszcze nie jest).
Isiah Meadows
2
Czy twoje „golf” nie powinno być zamieszczane jako odpowiedź?
MrWhite
4
Przepraszamy, ale -1 za niedozwolenie GolfScript. Wszystkie języki powinny być dozwolone.
Klamka
1
@Doorknob To prawda, ale rozumiem również odczucia OP. Ludzie powinni mieć szansę konkurować, nawet jeśli nie mówią w golfowym, J lub APL (i jestem winny przejrzenia tych ostatnich w tych zawodach.) Czy możesz rzucić okiem na moją propozycję w wątku, z którym się łączy?
Tobia

Odpowiedzi:

10

APL, 13 znaków

(lub 28/30 bajtów, czytaj poniżej)

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

Widzę, że zablokowałeś GolfScript od pytania. Rozumiem twoje zdanie, ale mam nadzieję, że ta społeczność ostatecznie nie zbanuje APL, ponieważ jest to naprawdę niezwykły język programowania z długą historią, nie wspominając o dobrej zabawie w kodowaniu. Może mógłby być inaczej oceniony, jeśli ludzie czuję, że konkuruje niesprawiedliwie. Prześlę swoje przemyślenia na ten temat do wątku, który podłączyłeś.

Na tym samym tokenie zawsze dodawałem przypis do moich postów APL, twierdząc, że APL może zostać oceniony jako 1 znak = 1 bajt. Moje twierdzenie opiera się na fakcie, że kilka (głównie komercyjnych) implementacji APL nadal obsługuje własne starsze kodowanie jednobajtowe, z symbolami APL odwzorowanymi na górne 128 bajtów. Ale może jest to zbyt duży odcinek, w którym to przypadku możesz chcieć zapisać ten wpis jako 28 bajtów w UTF-16 lub 30 bajtów w UTF-8.

Wyjaśnienie

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

Przykłady

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

Domyślny format wyjściowy tablicy ciągów nie wyjaśnia, ile ciągów jest w tablicy ani ile spacji. Ale szybka manipulacja dodawaniem cudzysłowów powinna dać wystarczająco jasne:

      {q,⍵,q←'"'}¨ {⍵⊂⍨⍵∊∊⍕¨⍳10} 'ab5c0x'
 "5"  "0" 
      {q,⍵,q←'"'}¨ {⍵⊂⍨⍵∊∊⍕¨⍳10}  'z526ks4f.;8]\p'
 "526"  "4"  "8" 
Tobia
źródło
Jeśli chodzi o twój komentarz, myślę, że w przypadku innych języków konkuruj uczciwie z tymi „krótszymi”, każdy symbol w innych językach należy liczyć jako jeden znak. Na przykład moje zamieszczone tutaj rozwiązanie Mathematica powinno być liczone jako 7 (mniej więcej). Wydaje mi się, że projektowanie języka przy użyciu skompresowanych tokenów wcale nie ma znaczenia.
Dr Belisarius
Czy możesz podać zrzut heksa swojego golfa? Nie mogę odczytać niektórych postaci.
Isiah Meadows
@impinball W jaki sposób zrzut heksowy mógłby ci pomóc? To nie tak, że zobaczysz, co się dzieje.
mniip
@impinball kod APL to {omega załącz dojazdy omega epsilon epsilon format każdy iota 10}. Jeśli potrzebujesz wartości Unicode, możesz po prostu skopiować i wkleić je do dowolnego narzędzia online , nawet jeśli nie widzisz znaków (co jest dziwne, ponieważ większość współczesnych czcionek Unicode ma symbole APL) W każdym razie otrzymujesz to {\ u2375 \ u2282 \ u2368 \ u2375 \ u220a \ u220a \ u2355 \ u00a8 \ u237310} (Pamiętaj o ostatniej „10”, która nie jest częścią sekwencji ucieczki)
Tobia
1
Zamiast tego ∊⍕¨⍳10nie możesz po prostu użyć ⎕D? To powinno być stałe '0123456789'. Dyalog APL przynajmniej go obsługuje, podobnie jak NARS2000.
marinus
5

Python 47

Realizacja

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

Próbny

>>> 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'], []]

Algorytm

Konwertuj każdy znak inny niż cyfrowy na spację, a następnie podziel wynikowy ciąg. Proste i jasne podejście.

I zabawne rozwiązanie z itertools (71 znaków)

f1=lambda s:[''.join(v)for k,v in __import__("itertools").groupby(s,key=str.isdigit)][::2]
Abhijit
źródło
4

Ruby, 70

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

Wersja online do testowania

Ponieważ konwersja dowolnego znaku nie będącego cyfrą na liczbę int zwraca 0 w Ruby (z to_i), konwersja każdego znaku na int i powrót na znak jest nieregexowym sposobem sprawdzenia cyfry ...

David Herrmann
źródło
Możesz także zrobić członka („0” .. „9”). dla każdego znaku, ale to, co zrobiłeś, jest już krótsze
fgp
Masz zdecydowanie rację - powinienem powiedzieć: „a” way;)
David Herrmann
4

bash, 26 (zawartość funkcji: 22 + narzut przypisania tablicy 4)

To nie przebije drugiej bashodpowiedzi , ale jest interesujące, ponieważ może sprawić, że podwoisz:

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

Zastosowanie to:

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

Na pierwszy rzut oka //+([!0-9])/wygląda jak podstawienie wyrażenia regularnego, ale tak nie jest. Jest to rozszerzenie parametrów bash , które jest zgodne z regułami dopasowywania wzorców zamiast reguł wyrażeń regularnych.

Zwracanie prawdziwych typów tablic bash z funkcji bash jest kłopotliwe, więc postanowiłem zamiast tego zwrócić listę rozdzielaną spacjami, a następnie przekonwertować na tablicę w przypisaniu tablicy poza wywołaniem funkcji. Dlatego w trosce o sprawiedliwość uważam, że (` `)wywołanie funkcji powinno być uwzględnione w moim wyniku.

Cyfrowa trauma
źródło
3

Mathematica 32

StringCases[#,DigitCharacter..]&

Stosowanie

inps ={"abc123def456", "aitew034snk582:3c", "as5493tax54\\[email protected]", 
        "sasprs]tore\"re\\forz"}  
StringCases[#,DigitCharacter..]&/@inps

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

Odpowiednik używania wyrażeń regularnych jest znacznie dłuższy !:

StringCases[#, RegularExpression["[0-9]+"]] &
Dr Belizariusz
źródło
Mathematica jest do bani w wyrażeniu regularnym.
CalculatorFeline
3

Bash, 21 bajtów 17/21 bajtów (poprawiony przez DigitalTrauma )

Budowanie listy oddzielonej spacjami za pomocą tr

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

zastępuje każdą cyfrę spacją

Stosowanie

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

Edytować

jak wskazano w komentarzach poniżej, kod można zmniejszyć do 17 bajtów:

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

a ponieważ wynik nie mówi ściśle o tablicy Bash, użycie powinno być

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

i dodatkowe (``)należy policzyć

Coaumdio
źródło
1
O tak, pobiłeś mnie! Ale dlaczego nie użyć tutaj ciągu zamiast dokumentu tutaj? Ponadto można zapisać nowej linii na końcu treści funkcji użyć (blah)zamiast {blah;}: split()(tr -c 0-9 \ <<<$1). W ten sposób twoje ciało funkcyjne ma tylko 17 znaków.
Cyfrowa trauma
1
Twoja funkcja zwraca „listę rozdzieloną spacjami” zamiast tablicy. Z pewnością powrocie prawdziwych tablic z funkcja bash jest niewygodne, ale można przynajmniej przypisać wynik swojej funkcji do tablicy w trakcie pracy: a=($(split "12 3a bc123")); echo ${a[@]}. Można argumentować, że „($ ())” wlicza się do twojego wyniku
Digital Trauma
Przed zbadaniem tego trpodejścia próbowałem zrobić to z rozszerzeniem parametrów . trjest zdecydowanie lepszym podejściem do gry w golfa.
Cyfrowa trauma
Czy próbowałeś otaczać się troperatorem ekspansji? Wychodzi na coś takiego ($(tr...)), a gdy deklaracja funkcji się nie liczy, zewnętrzne nawiasy nie liczą się przeciwko tobie. Będzie to tylko część zastępowania poleceń.
Isiah Meadows
Nie wiem, jak to powinno działać, ale nie jestem biegły w tablicach Bash. W każdym razie (``)konstrukt jest 1-znakowy lepszy od tego ($())i powinien być preferowany.
Coaumdio,
2

Smalltalk (Smalltalk / X), 81

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

wartość f: „abc123def456” -> OrDERCollection („123” „456”)

wartość f: „aitew034snk582: 3c” -> OrDERCollection („034” „582” „3”)

wartość f: „as5493tax54 \ [email protected]” -> Uporządkowana kolekcja („5493” „54” ​​„430” „52” „9”)

wartość f: 'sasprs] tore \ "re \ forz' -> OrdersCollection ()

westchnienie - Smalltalk ma tendencję do używania bardzo długich nazw funkcji ...

blabla999
źródło
2
Czy to nazwa funkcji? o__O
Tobia,
@Tobia Najwyraźniej ...
Isiah Meadows
asCollectionOfSubCollectionsSeparatedByAnyForWhichಠ_ಠ Ta nazwa jest za długa
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])]
}

Funkcja przyjmuje ciąg i zwraca listę ciągów.

Przykłady:

> 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

Uwaga: $xto nazwa elementu listy.

Sven Hohenstein
źródło
1

Perl, 53

Edytować: w przypadku braku dopasowań sub zwraca teraz listę z pustym łańcuchem (zamiast pustej listy) zgodnie z wymaganiami.

Unika także podziału na pojedynczą spację, ponieważ powoduje zachowanie „podziału na dowolne białe spacje” , co prawdopodobnie narusza reguły. Mógłbym użyć / /separatora, który podzieliłby się na pojedynczą spację, ale paradoksalnie wyglądałoby to jak użycie wzorca wyrażenia regularnego. Mógłbym użyć unpackkosztem dodatkowych postaci, więc splitcałkowicie pozbyć się kontrowersji, ale myślę, że to, co kończę, dzielenie na literalną postać (inną niż spacja) jest w porządku.

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

I nie, operator transliteracji Perla nie robi wyrażeń regularnych. Mogę rozwinąć zakres 0–9, 0123456789jeśli to jest problem.

użytkownik 2846289
źródło
Dopóki nie używa wyrażeń regularnych, jest poprawny.
Isiah Meadows
Mój Perl nie jest tak silny. Jeśli rozumiem kod, zamieniasz cyfry na inną niż cyfra, a następnie dzielisz na wybraną cyfrę, a następnie odfiltrowujesz puste ciągi. Czy to poprawny odczyt?
Tim Seguine
1
@TimSeguine: Niezupełnie. Nie-cyfry są zamieniane i zgniatane do pojedynczego znaku, dzieląc się, co powoduje powstanie pustego łańcucha, jeśli ten ogranicznik znajduje się na początku. Następnie jest przesuwany, jeśli lista zawiera inne wpisy.
user2846289
Pusta lista jest w porządku.
Isiah Meadows
1

C, 68 bajtów (tylko ciało funkcji)

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

Pierwszy argument to ciąg wejściowy, drugi to tablica wyjściowa, która jest tablicą zakończoną znakiem NULL. aPrzed wywołaniem funkcji należy zarezerwować wystarczającą ilość pamięci (w najgorszym przypadku:sizeof(char*)*((strlen(s)+1)/2) .

Łańcuch wejściowy jest modyfikowany przez funkcję (każdy znak nie będący cyfrą jest zastępowany przez '\0' )

Przykład użycia

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

Wynik

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

Wersja bez gry w golfa:

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
źródło
1

VBScript, 190 (164 bez deklaracji funkcji)

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

Chociaż wcale nie jestem konkurencyjny, jestem zaskoczony, że VBScript wypowiada się tak krótko, biorąc pod uwagę jego szczegółowość (13 bajtów dla samych CR). Pętla przechodzi przez ciąg, zastępując wszelkie znaki nienumeryczne spacjami, a następnie redukuje wszystkie białe spacje do pojedynczych spacji, a następnie używa separatora spacji, aby go podzielić.

Przypadki testowe

Input: "ab5c0x"
Output: 5,0

Input: "z526ks4f.;8]\p"
Output: 526,4,8
Komintern
źródło
Zakończenia linii DOS liczą się jako jeden znak, o ile czytałem o meta.
Isiah Meadows
Zaproponowałem ci edycję.
Isiah Meadows
Liczba już zakłada 1-bajtowe zakończenia linii w stylu Linux. Otrzymuję 190 znaków według mojej liczby (właśnie zweryfikowałem ponownie).
Comintern
Dobrze. Musiałem się przeliczyć.
Isiah Meadows
1

Common Lisp (1 zgodnie z literą; ≈173 zgodnie z duchem)

Oto czytelna wersja. Liczba bajtów jest dość wysokie, ponieważ długich nazw w rzeczy, jak digit-char-pi position-ifi 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")
#()

Pojęcie „deklaracji funkcji” jest niejasne. Oto wersja, która ma tylko jeden bajt (znak xw treści funkcji); wszystko inne jest zawarte w zmiennych pomocniczych listy lamba funkcji (część deklaracji funkcji):

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

Rzeczywista liczba bajtów będzie zależeć od liczby deklaracji pomocniczych, które musiałyby zostać przeniesione do ciała, aby uznać to za dopuszczalne. Pomocna byłaby także zmiana nazwy funkcji lokalnej (np. Skrócenie, position-ifponieważ pojawia się dwa razy, użycie zmiennych jednoliterowych itp.).

To renderowanie programu ma 220 znaków:

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

Jeśli nic więcej, powinno to promować wspólne zmienne Lisp i zmienne Aux .

Można to napisać bardziej zwięźle loop, oczywiście:

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

loopTworzą z dodatkową przestrzeń usunięte, ma 173 znaków:

(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
źródło
Liczę od początku (resultdo ostatniego nawiasu, by być ciałem. Część, która definiuje nazwę i parametry, to deklaracja.
Isiah Meadows
Zapoznaj się z regułą 2 moich zmienionych reguł, aby zobaczyć, o czym tak naprawdę mówię w deklaracji funkcji (w zasadzie zadeklaruj nazwę funkcji, parametry oraz, jeśli jest to wymagane składniowo, co jest rzadkie wśród języków interpretowanych, typ zwracany).
Isiah Meadows
@impinball Tak, licznik „1” jest trochę żartem, ale ważną częścią result jest zadeklarowanie tutaj jako parametru; po prostu ma bardzo nietrywialną formę inicjalizacji. Zasadniczo jest to to samo, co opcjonalny argument o wartości domyślnej obliczanej przez złożone wyrażenie. (W prostszych przypadkach łatwo sobie wyobrazić coś takiegochar* substring( char *str, int begin, int end(0) ) w jakimś języku ze składnią podobną do C, aby określić, że endjest opcjonalna, a jeśli nie jest podana, to jej wartość jest 0. Podkreślam tylko fakt, że niektóre z tych terminów
Joshua Taylor
@impinball nie są dość konkretne i wystarczająco agresywne językowo, aby zapobiec liczeniu bajtów trollish. :)
Joshua Taylor
Pierwsza część, która nie określa parametrów, polega na tym, że zliczam statystyki (np. (defun fn (string &aux (start 0) (end 0)Nie liczyłbym, ale wszystko, co pozostało w lambda, by to zrobiło).
Isiah Meadows
0

JavaScript, 240 bajtów

A dla tych z was, którzy są ciekawi, oto mój prawdopodobnie ogromny golf:

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

Powyżej w ładnym druku:

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

Powyżej w normalnym kodzie opisowym

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
źródło
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
źródło
Możesz go skrócić, pomijając oddzwonienie na array_filter. Spowoduje to automatyczne usunięcie wszystkich wpisów, które zostaną przesłane falsedo boolean.
kelunik
@kelunik, który odfiltrowałby również zera
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("]");}

Ponieważ C nie ma wbudowanych funkcji drukowania tablic, musiałem wykonać tę pracę sam, więc przepraszam, że na każdym wyjściu znajduje się końcowy przecinek. Zasadniczo to, co robi ten kod, to czyta ciąg znaków, jeśli nie jest cyfrą, zastępuje go „\ 0”, a następnie po prostu przeglądam kod i wypisuję wszystkie łańcuchy cyfr. (EOF = 0)

Wejście: ab5c0x
Wyjście: [„5”, „0”,]

Wejście: z526ks4f.; 8] \ p
Wyjście: [„526”, „4”, „8”,]

ZAPYTAJ
źródło
Zgodnie z regułami pytania (reguła 2) wystarczy policzyć znaki w ciele funkcji. Tak więc twoje rozwiązanie miałoby mniej niż 170 bajtów. Nie jestem jednak pewien, czy liczba obejmuje zmienne prototypy poza ciałem funkcji.
gajeNL
Zmienię zasady dotyczące tego: #defines, deklaracje zmiennych itp. Będą się liczyć, ale deklaracja funkcji nie.
Isiah Meadows
Ponadto, kiedy ostatnio sprawdzałem, w języku C pojawił się typ oznaczony jako zgodny z char[][]prawem. Jeśli wrócisz tak (lub char**), nic ci nie będzie.
Isiah Meadows
Nie musi to być tekst? Myślałem, że program powinien
wypisać
0

C #, 98

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

Po pierwsze, wykorzystuje LINQ .Select() metody rozszerzenia , aby zamienić wszystkie cyfry w przecinki. string.Replace()byłoby lepiej, ponieważ zwraca stringraczej niż a IEnumerable<char>, ale string.Replace()może wziąć tylko jeden znak lub ciąg i nie może użyć predykatu takiego jak char.IsDigit()lub 47<c&c<58.

Jak wspomniano, .Select()zastosowane do łańcucha zwraca an IEnumerable<char>, więc musimy go przekształcić z powrotem w łańcuch, przekształcając go w tablicę i przekazując tablicę do stringkonstruktora.

Wreszcie, rozdzielamy ciąg przecinkami za pomocą string.Split(). (StringSplitOptions)1jest krótszym sposobem powiedzeniaStringSplitOptions.RemoveEmptyEntries , który automatycznie zajmie się wieloma kolejnymi przecinkami i przecinkami na początku / końcu łańcucha.

BenM
źródło
1
Zamiast tego char.IsDigit(c)możesz użyć'/'<c&&c<':'
govesNL
1
Dobra uwaga ... lub nawet lepiej 47<c&&c<58. (Szczerze mówiąc, jestem zaskoczony, że działa z liczbami, ale najwyraźniej działa).
BenM
1
I mogę uratować dodatkową cenną postać, używając pojedynczego „&” zamiast podwójnego „&&”. W języku C # jest to nadal logiczne ORAZ, gdy oba operandy są logiczne - robi to tylko trochę ORAZ, gdy są liczbami całkowitymi.
BenM
Niezłe. Nie wiedziałem, że to potrafi.
gajeNL
Nieco krótszym wariantem jest podzielenie na białe pola zamiast ,, a następnie ręczne usunięcie pustych elementówreturn new string(s.Select(c=>47<c&c<58?c:' ').ToArray()).Split().Where(a=>a!="").ToArray();
VisualMelon
0

JS / Węzeł: 168 162 147 138 znaków

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

Wersja upiększona:

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
źródło
To pytanie chce tylko zwrócić tablicę, więc możesz usunąć console.log(r)i kilka innych rzeczy
Nie to, że Charles
Deklaracja funkcji nie wlicza się do wyniku (powodem jest wyrównanie pola gry)
Isiah Meadows
Dobrze. Skorygowano wynik zgodnie z komentarzem @ impinball. (W rzeczywistości deklarowane są tutaj dwie funkcje. Liczba
znaków
Powinno. Zaktualizowałem zasady, aby lepiej to wytłumaczyć.
Isiah Meadows
Tymczasem wymyśliłem coś lepszego ...
palanik
0

Ruby, 24

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

Definiuje cyfry za pomocą ujemnej spacji w drukowanym zakresie ascii.

histocrat
źródło
Deklaracja funkcji się nie liczy.
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;}

Kod opisowy:

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

To jest dość długi kod i jestem pewien, że będzie dużo krótsza wersja php dla tego kodu golfa. To właśnie mogłem wymyślić w php.

palerdot
źródło
istnieją pewne ulepszenia: można zastąpić array()z [], array_push($output[$count], $arr[$i]);z $output[$count][]=$arr[$i];, i ord()sprawdza z is_numeric(). i nie musisz nawet rozdzielać łańcucha, aby iterować jego znaki. liczy się tylko wewnętrzny kod funkcji, więc liczba
znaków
Deklaracja funkcji się nie liczy. Odwołaj się do reguły 2 jako przewodnika po tym, co się liczy, a co nie.
Isiah Meadows
0

Pyton

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
Opuściłem StackExchange
źródło
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 odpowiedź jest zdecydowanie sprytna, to tylko „zminimalizowana” wersja tego, co miałem na myśli.

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

Nie daje to żadnych wyników, więc kod działa, jeśli jest uruchamiany jeden po drugim, ponieważ niektóre zmienne są zdefiniowane w deklaracji.

gcq
źródło
Jeśli tak, nie musisz liczyć deklaracji funkcji. Tak jak heads-up
Isiah Meadows
0

PHP 98 89

Tak jak w odpowiedzi na bash DigitalTrauma, nie używa to wyrażenia regularnego.

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

Przypadki testowe:

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
Proszę wstać
źródło
0

Haskell 31

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

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

Dzieli ciąg na wszystkie znaki nienumeryczne i usuwa puste ciągi wygenerowane przez kolejne separatory.

lortabak
źródło
0

VBA 210, 181 bez deklaracji funkcji

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
źródło
0

Rebol (66 znaków)

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

Nieoznakowane i zapakowane w deklarację funkcji:

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

Przykładowy kod w konsoli 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
źródło
0

JavaScript, 104 97 89

Gra w golfa:

Edycja: Gdy pętle schodzą z końca tablicy, cjestundefined schodzą , co jest fałszem i kończy pętlę.

2/27: Używanie ?:ratuje słowoif/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
}

Powrót karetki w nadwoziu służy do czytelności i nie stanowi części rozwiązania.

Nie golfowany:

Chodzi o to, aby dołączyć każdy znak do ostatniego wpisu w tablicy, jeśli jest on cyfrą i upewnić się, że ostatni wpis w tablicy jest ciągiem znaków.

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
źródło
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
}

Nie golfił

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

Przykładowe wejście / wyjście

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
źródło
1
Lubię to! O wiele prostsze niż moje. Możesz upuścić kolejne 8 znaków, zastępując if(+a[i]+1)b+=a[i];else if(b)c.push(b),b=""je b=+a[i]+1?b+a[i]:b?(c.push(b),""):b.
DocMax
@DocMax thx, edytowałem, aby uwzględnić Twoją sugestię :). To (c.push(b),"")wydawało się sprytne, nigdy tego nie widziałem.
Danny
Zapomniałem o tym, dopóki nie zobaczyłem, że jest dziś powszechnie używany w codegolf.stackexchange.com/questions/22268#22279
DocMax
To nie jest poprawne ”, jest mylone z 0 i jest to dziwactwo javascript trudne do zarządzania. Spróbuj „12 34 56”
edc65
0

R 52

Ta funkcja dzieli łańcuchy znaków na klasy znaków (to nie jest wyrażenie regularne! :)) klasa to N - cyfry, a P {N} oznacza negację tej klasy. o = T oznacza pominięcie pustych podciągów.

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
źródło
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"));


Wynik

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
źródło
0

JavaScript 88

88 znaków, gdy nie zlicza się funkcji 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
źródło