RegExps없이 문자열을 숫자가 아닌 숫자로 나누는 가장 짧은 프로그램


16

편집 : Lisp를 사용하는 경우 맨 아래에 바이트 수를 세는 지침을 제공했습니다.

목표 : 문자열을 숫자가 아닌 숫자로 나누고 정규 표현식을 사용하지 않고 각 문자열의 숫자만으로 구성된 배열을 반환하는 가장 짧은 함수를 만듭니다. 각 문자열에는 선행 0이 포함됩니다.

현재 순위 (카테고리로 구분) :

  • C / C ++ / C # / Java : 68 (C) ....
  • GolfScript / APL / J : 13 (APL)
  • 다른 모든 것 : 17 (Bash, uses tr), 24 (Ruby)

규칙 :

(긴장에 대해 사과드립니다)

  1. 형식은 단일 문자열 인수를 가진 함수 여야합니다. 배열의 올바른 리턴에 필요한 경우 최대 두 개의 추가 인수가 추가 될 수 있습니다 (예 : sh / csh / DOS Batch는 리턴 할 추가 변수 참조가 필요함).
  2. 기본 함수 선언은 계산되지 않으며 다른 표준 라이브러리를 가져 오지 않습니다. `# include`,`import`s 및`using`은 포함되지 않습니다. 그 밖의 모든 것. 여기에는`# define`과 도우미 함수가 포함됩니다. 혼란을 드려 죄송합니다. 계산하지 않는 것 / 무시하는 것에 대한 유용한 안내서로 이것을 참조하십시오 (C 스타일 구문으로 작성 됨)
    // 총계에 포함되지 않으며, 그렇지 않으면 생략 될 수 있습니다
    // Java 표준 라이브러리의 절반과 같이 명백합니다.
    #include <stdio.h>
    
    import some.builtin.Class // 계산에 포함되지 않습니다. 위 참조
    
    #define printf p // 총계로 계산
    
    / * 다른 전 처리기 지시어 등이 포함됩니다. * /
    
    int i = 0; // 카운트
    
    someFunction (); // 카운트
    
    char [] [] myMainSplitFunction (char [] [] array) {// 계산하지 않습니다
      // 여기에있는 모든 것이 중요
      return returnArray; // 이것도 중요합니다.
    } // 계산에 포함되지 않습니다
    
    / * 선언을 포함하여 여기에있는 모든 것이 중요합니다 * /
    char [] [] someHelperFunction (char [] 문자열) {
      // 물건
    } // 이것도 중요하다
    
  3. 출력은 문자열 배열이거나 이와 유사해야합니다 (Java 및 유사한 배열 목록이 허용됨). 받아 출력의 예 : String[], char[][], Array, List, 및 Array(객체).
  4. 배열에는 가변 길이 문자열 기본 요소 또는 문자열 오브젝트 만 포함해야합니다. 아래에 예외를 제외하고는 빈 문자열이 반환되지 않아야합니다. 참고 : 문자열은 아래의 입력 및 출력 예제와 같이 연속적으로 일치하는 문자열을 포함해야합니다.
  5. 일치하는 것이 없으면 함수 본문은 null빈 배열 / 목록 또는 빈 문자열을 포함하는 배열 / 목록을 반환해야 합니다.
  6. 외부 라이브러리는 허용되지 않습니다.
  7. DOS 줄 끝은 2 바이트가 아닌 1 바이트로 계산됩니다 (이미 메타로 덮여 있지만 강조해야 함)
  8. 그리고 가장 큰 규칙은 정규식을 사용할 수 없다는 것입니다.

이것은 질문이므로 가장 작은 크기가 이깁니다. 행운을 빕니다!

다음은 입력 및 출력의 예입니다 (C 스타일 이스케이프 포함).

입력 : "abc123def456"
출력 : [ "123", "456"]

입력 : "aitew034snk582 : 3c"
출력 : [ "034", "582", "3"]

입력 : "as5493tax54 \\ 430-52@g9.fc"
출력 : [ "5493", "54", "430", "52", "9"]

입력 : "sasprs] tore \"re \\ forz "
출력 : null, [], [ ""] 또는 유사

귀하의 답변에 사용 된 바이트 수와 항상 행복한 골프를 넣으십시오!


Lisp에 대한 지침

Lisp 방언에서 무엇을하고 계산하지 않습니까?

;;; 옵션 1

(defun extract-strings (ab); 계산에 포함되지 않음)
  (물건) ;;; 여기에있는 모든 것이 중요합니다
); 계산하지 않습니다

;;; 옵션 2

(defun extract-strings (문자열 & aux (시작 0) (끝 0)); 계산에 포함되지 않습니다)
  (물건) ;;; 여기에있는 모든 것이 중요합니다
); 계산하지 않습니다.
다른 모든 람다는 바이트 수를 완전히 계산합니다.


이게 전에 묻지 않았습니까?
Ismael Miguel

1
예, 그러나 메타에 다시 질문하고 여기에 다시 게시하기 전에 메타를 크게 수정했습니다. 이 때문에 중복으로 분류되어서는 안됩니다 (다른 관련 항목은 아직 닫히지 않은 경우 닫아야 함).
Isiah Meadows

2
"골프"를 답변으로 게시해서는 안됩니까?
MrWhite

4
죄송하지만 GolfScript를 허용하지 않는 경우 -1입니다. 모든 언어가 허용되어야합니다.
Doorknob

1
@Doorknob 사실이지만 OP의 감정도 이해합니다. 사람들은 GolfScript, J 또는 APL을 구사하지 않더라도 경쟁 할 수있는 기회를 가져야합니다 (이 대회에서 후자를 유죄 판결을받은 죄책감이 있습니다). 연결된 스레드 에서 내 제안 을 살펴볼 수 있습니까 ?
Tobia

답변:


10

APL, 13 자

(또는 28/30 바이트, 아래 읽기)

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

귀하의 질문에서 GolfScript를 금지했습니다. 나는 당신의 감정을 이해하지만,이 커뮤니티가 APL을 금지하지 않기를 바랍니다. 왜냐하면 APL은 오랜 역사를 가진 진정으로 놀라운 프로그래밍 언어이기 때문입니다. 코드를 작성하는 데 많은 즐거움을 언급하지는 않았을 것입니다. 불공평 한 경쟁을 느낀다. 이 문제에 대한 내 생각을 연결 한 스레드에 게시하겠습니다.

같은 토큰에서 항상 APL 게시물에 각주를 추가하여 APL을 1 문자 = 1 바이트로 채점 할 수 있다고 주장했습니다. 필자의 주장은 APL 기호가 상위 128 바이트 값에 매핑되어 일부 (대부분 상업적인) APL 구현이 여전히 자체 레거시 단일 바이트 인코딩을 지원한다는 사실에 근거합니다. 그러나 이것은 너무 많은 확장 일 수 있습니다.이 경우이 항목을 UTF-16에서 28 바이트로 또는 UTF-8에서 30 바이트로 점수를 매길 수 있습니다.

설명

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

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

문자열 배열의 기본 출력 형식으로 인해 배열에 몇 개의 문자열이 있는지 또는 공백이 몇 개인 지 명확하지 않습니다. 그러나 따옴표를 추가하는 빠른 조작은 충분히 명확해야합니다.

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

귀하의 의견에 관해서는, 다른 언어의 경우 "속기"와 공정하게 경쟁한다고 생각합니다. 다른 언어의 각 기호는 한 문자로 간주해야합니다. 예를 들어, 여기에 게시 된 Mathematica 솔루션은 7로 계산되어야합니다. 압축 토큰으로 언어를 디자인하는 것은 전혀 가치가 없다고 생각합니다.
Dr. belisarius

당신은 당신의 골프의 16 진수 덤프를 제공 할 수 있습니까? 일부 문자를 읽을 수 없습니다.
Isiah Meadows

@impinball 16 진수 덤프가 어떻게 도움이 되나요? 당신이 무엇을하고 있는지 보는 것과는 다릅니다.
nini

@impinball APL 코드는 {오메가는 출퇴근 오메가 엡실론 엡실론 형식으로 각 iota 10}입니다. 유니 코드 값이 필요한 경우 문자를 볼 수없는 경우에도 복사하여 온라인 도구에 붙여 넣을 수 있습니다 (대부분의 최신 유니 코드 글꼴에는 APL 기호가 있으므로 이상합니다). {\ u2375 \ u2282 \ u2368 \ u2375 \ u220a \ u220a \ u2355 \ u00a8 \ u237310} (이스케이프 시퀀스의 일부가 아닌 마지막 "10"에주의)
Tobia

1
대신에 ∊⍕¨⍳10, 당신은 단지 사용할 수 없습니다⎕D 습니까? 그것은 상수 여야합니다 '0123456789'. Dyalog APL은 최소한이를 지원하며 NARS2000도 지원합니다.
marinus

5

파이썬 47

이행

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

데모

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

연산

숫자가 아닌 각 문자를 공백으로 변환 한 다음 결과 문자열을 분할하십시오. 간단하고 명확한 접근법.

itertools를 사용한 재미있는 솔루션 (71 자)

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

4

루비, 70

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

온라인 버전테스트를위한

숫자가 아닌 문자를 int로 변환하면 Ruby에서 (to_i로) 0을 반환하므로 모든 문자를 int로, 다시 char로 변환하는 것은 숫자를 확인하는 정규식이 아닌 방법입니다 ...


( '0'.. '9'). member도 할 수 있습니까? 모든 문자에 대해, 그러나 당신이 한 것은 이미 짧습니다
fgp

;) "는"방법 : 내가 말한해야 - 당신은 확실히 맞다
데이비드 헤르만

4

bash, 26 (기능 내용 : 22 + 배열 할당 오버 헤드 4)

이것은 다른 bash답변 을 이길 수 없지만 두 번 걸릴 수 있기 때문에 흥미 롭습니다.

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

사용법은 :

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

언뜻보기 //+([!0-9])/에는 정규 표현식 대체와 비슷하지만 그렇지 않습니다. 그것은 인 배시 파라미터 확장 다음, 패턴 매칭 규칙 대신 정규식 규칙.

bash 함수에서 진정한 bash 배열 유형을 반환하는 것은 쉽지 않으므로 대신 공백으로 구분 된 목록을 반환 한 다음 함수 호출 외부의 배열 할당에서 배열로 변환하기로 선택했습니다. 따라서 공정성 (` `)을 위해 함수 호출이 내 점수에 포함되어야한다고 생각합니다 .


3

매스 매 티카 32

StringCases[#,DigitCharacter..]&

용법

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

정규 표현식을 사용하는 것이 훨씬 더 깁니다! :

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

Mathematica는 정규식에서 짜증을냅니다.
CalculatorFeline

3

배쉬, 21 바이트 17/21 바이트 ( DigitalTrauma에 의해 개선됨) )

공백으로 구분 된 목록 작성 tr

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

숫자가 아닌 숫자를 공백으로 바꿉니다.

용법

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

편집하다

아래 주석에서 알 수 있듯이 코드를 17 바이트로 제거 할 수 있습니다.

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

결과가 Bash 배열을 엄격하게 말하지 않기 때문에 사용법은

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

그리고 여분 (``)은 계산되어야합니다


1
넌 날 이겼어! 그러나 here-document 대신 here-string을 사용하지 않는 이유는 무엇입니까? 또한 당신은 당신이 사용하는 함수 내용의 끝에서 줄 바꿈을 절약 할 수 있습니다 (blah)대신 {blah;}: split()(tr -c 0-9 \ <<<$1). 그렇게하면 함수 본문은 17 자입니다.
Digital Trauma

1
함수는 배열 대신 "공백으로 구분 된 목록"을 반환합니다. bash 함수에서 실제 배열을 반환하는 것은 어색하지만 적어도 함수 결과를 배열에서 배열에 할당 할 수 있습니다 : a=($(split "12 3a bc123")); echo ${a[@]}. "($ ())"는 당신의 점수에 포함된다고 주장 될 수 있습니다
Digital Trauma

Before exploring the tr approach, I tried doing this with a parameter expansion. tr is definitely the better approach for golfing purposes.
Digital Trauma

tr확장 연산자로 주변 환경을 사용해 보셨습니까 ? 그것은 같은 것으로 나올 것이고 ($(tr...))함수 선언이 계산되지 않으면 외부 괄호는 당신에게 계산되지 않습니다. 명령 대체 부분 일뿐입니다.
Isiah Meadows

이것이 어떻게 작동 해야하는지 알지 못하지만 Bash 배열에는 유창하지 않습니다. 어쨌든, (``)구성은 1보다 낫고 ($())선호됩니다.
Coaumdio

2

스몰 토크 (Smalltalk / X), 81

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

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

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

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

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

sigh - Smalltalk has a tendency to use veeeery long function names...


2
Is that a function name? o__O
Tobia

@tobia Apparently...
Isiah Meadows

asCollectionOfSubCollectionsSeparatedByAnyForWhich ಠ_ಠ This name is too long
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])]
}

The function accepts a string and returns a list of strings.

Examples:

> 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

Note: $x is the name of the list element.


1

Perl, 53

Edit: on no matches, sub now returns list with empty string (instead of empty list) as required.

It also avoids splitting on single space character, as it triggers 'split on any white-space' behavior, which probably violates the rules. I could use / / delimiter, which would split on single space, but paradoxically it would look like using regexp pattern. I could use unpack at the cost of some extra characters and so get rid of split controversy altogether, but I think that, what I finish with, splitting on a literal character (other than space) is OK.

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

And, no, Perl's transliteration operator doesn't do regular expressions. I can unroll 0-9 range to 0123456789 if that's the problem.


As long as it doesn't use regular expressions, it's valid.
Isiah Meadows

My Perl is not so strong. If I understand the code, you are replacing non-digits with a specific non-digit, then splitting on that chosen non-digit, then filtering out empty strings. Is this a correct reading?
Tim Seguine

1
@TimSeguine: Not exactly. Non-digits are replaced and squashed to a single character, splitting on which produces empty string if that delimiter happens to be at the beginning. It is then shifted away if list contains other entries.
user2846289

Enpty list is okay.
Isiah Meadows

1

C, 68 bytes (only the function's body)

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

The first argument is the input string, the second one is the output array, which is a NULL-terminated string array. Sufficient memory must be reserved for a before calling the function (worst case: sizeof(char*)*((strlen(s)+1)/2)).

The input string is modified by the function (every non-digit character is replaced by '\0')

Usage example

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

Output

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

Un-golfed version:

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 without function declaration)

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

While not competitive at all, I'm surprised that VBScript comes out this short on this given how verbose it is (13 bytes for the CRs alone). It loops through the string, replacing any non-numeric characters with spaces, then reduces all the whitespace to single spaces, and then uses a space delimiter to divide it.

Test cases

Input: "ab5c0x"
Output: 5,0

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

DOS line endings count as one character as far as I've read on meta.
Isiah Meadows

I suggested an edit for you.
Isiah Meadows

The count already assumes Linux style 1 byte line endings. I get 190 characters by my count (just verified again).
Comintern

Ok. I must have miscounted.
Isiah Meadows

1

Common Lisp (1 according to the letter; ≈173 according to the spirit)

Here's a readable version. The byte count is fairly high because of the long names in things like digit-char-p and position-if and 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")
#()

The concept of "function declaration" is sort of vague. Here's a version that only has one byte (the character x in the function body); everything else is bundled in to the auxiliary variables of the function's lamba list (part of the function's declaration):

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

The actual byte count will depend on how many of auxiliary declarations would have to be moved into the body for this to be deemed acceptable. Some local function renaming would help, too (e.g., shorten position-if since it appears twice, use single letter variables, etc.).

This rendering of the program has 220 characters:

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

If nothing else, this should promote Common Lisp's &aux variables.

This can be written more concisely with loop, of course:

(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 loop form, with extra space removed, has 173 characters:

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

I would count starting from (result on to the final parenthesis to be the body. The part that defines the name and parameters are the declaration.
Isiah Meadows

Please refer to rule 2 on my amended rules to see what I'm really talking about in a function declaration (basically, declare function name, parameters, and if syntactically required, which is rare among interpreted languages, the return type).
Isiah Meadows

@impinball Yeah, the "1" count is sort of a joke, but the important part here is that result is declared as a parameter here; it just has a very non-trivial initialization form. It's the same thing, in principle, as an optional argument with a default value that's computed by some complex expression. (In simpler cases, it's easy to imagine something like char* substring( char *str, int begin, int end(0) ) in some language with a C-like syntax to specify that end is optional and that if it's not provided, then its value is 0. I'm just highlighting the fact that some of these terms
Joshua Taylor

@impinball aren't quite concrete and language agnostic enough to prevent some trollish byte counts. :)
Joshua Taylor

The first part that isn't specifying parameters is where I would stat counting (e.g. (defun fn (string &aux (start 0) (end 0) wouldn't count, but everything remaining in the lambda would).
Isiah Meadows

0

JavaScript, 240 bytes

And for those of you who are curious, here's my probably huge 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

Above in pretty print:

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

Above in normal descriptive code

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

You can shorten it by leaving out the callback at array_filter. This will automatically remove all entries which are false when they're casted to booleans.
kelunik

@kelunik that would filter out 0s as well
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("]");}

Since C doesnt have array print functions built-in I had to do that work on my own so I apologive that there is a final comma in every output. Essentially what that code does is it reads the string if it is not a digit it replaces it with '\0' and then I just loop through the code and print out all of the chains of digits.(EOF=0)

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

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


According to the question's rules (rule 2), you only have to count the characters in the function body. So your solution would actually be less than 170 bytes. I'm not sure if the count includes variable prototypes outside the function body, though.
grovesNL

I will amend the rules on this: #defines, variable declarations, etc. will count, but the function declaration will not.
Isiah Meadows

Also, last time I checked, there was a type in C notated as char[][] which is legal. If you return as that (or char**), you will be fine.
Isiah Meadows

It doesn't have To be text output? I though the program was supposed to output the array in a string format
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);
}

First, this uses the LINQ .Select() extension method to turn all non-digits into commas. string.Replace() would be preferable, since it returns a string rather than a IEnumerable<char>, but string.Replace() can only take a single char or string and can't make use of a predicate like char.IsDigit() or 47<c&c<58.

As mentioned, .Select() applied to a string returns an IEnumerable<char>, so we need to turn it back into a string by turning it into an array and passing the array into the string constructor.

Finally, we split the string at commas using string.Split(). (StringSplitOptions)1 is a shorter way of saying StringSplitOptions.RemoveEmptyEntries, which will automatically takes care of multiple consecutive commas and commas at the start/end of the string.


1
Instead of char.IsDigit(c), you can use '/'<c&&c<':'
grovesNL

1
Good point...or even better, 47<c&&c<58. (Frankly, I'm surprised it works with numbers, but apparently it does).
BenM

1
And I can save an extra valuable character by using a single '&' instead of a double '&&'. In C#, this still logical AND when both operands are booleans -- it only does a bitwise AND when they're integers.
BenM

Nice one. I didn't know it was able to do that.
grovesNL

A slightly shorter variant is to split on white space instead of ,, and then manually remove the empty items return new string(s.Select(c=>47<c&c<58?c:' ').ToArray()).Split().Where(a=>a!="").ToArray();
VisualMelon

0

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

Beautified version:

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

This question only wants the array returned, so you can remove console.log(r) and some other things
Not that Charles

The function declaration doesn't count toward the score (reason is to help level the playing field)
Isiah Meadows

Ok. Adjusted the score as per @impinball's comment. (Actually there are two functions declared here. Char count includes the anonymous function)
palanik

It should. I updated the rules to help explain it better.
Isiah Meadows

Meanwhile, came up with something better...
palanik

0

Ruby, 24

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

Defines digits using negative space within the printable ascii range.


Function declaration doesn't count.
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;}

Descriptive Code:

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

This is pretty long code and I'm sure there will be a much shorter php version for this code golf. This is what I could come up with in php.


there are some improvements: you can replace array() with [], array_push($output[$count], $arr[$i]); with $output[$count][]=$arr[$i];, and the ord() checks with is_numeric(). and you don't even need to split the string to iterate over its characters. also, only the inner code of the function counts, so as it is you char count is 204.
Einacio

The function declaration doesn't count. Refer to rule 2 as a guide on what counts and what doesn't.
Isiah Meadows

0

Python

def find_digits(_input_):
    a,b = [], ""
    for i in list(_input_):
        if i.isdigit(): b += i
        else:
            if b != "": a.append(b)
            b = ""
    if b != "": a.append(b)
    return a

0

Python 104 83

def f(s, o=[], c=""):
    for i in s:
        try:int(i);c+=i
        except:o+=[c];c=""
    return [i for i in o+[c] if i]

@Abhijit answer is far clever, this is just a "minified" version of what i had in mind.

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

This yields no output, so the code is working, if ran one by one, as some variables are defined at the declaration.


You don't have to count the function declaration, if you did. Just as a heads up
Isiah Meadows

0

PHP 98 89

As in DigitalTrauma's bash answer, this doesn't use a 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;
}

Test cases:

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)

It splits the string on all non-numeric characters and removes the empty strings generated by consecutive delimiters.


0

VBA 210, 181 without function declaration

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

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

Ungolfed and wrapped in function declaration:

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

Example code in Rebol console:

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

Edit: When the loops walks off the end of the array, c is undefined, which is falsy and terminates the loop.

2/27: Using ?: saves the wordiness of 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
}

The carriage return in the body is for readability and is not part of the solution.

Ungolfed:

The idea is to append each character to the last entry in the array if it is a digit and to ensure the last array entry is a string otherwise.

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

Sample input/output

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

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

JSFiddle


1
I like it! Much simpler than my own. You can drop another 8 characters by replacing if(+a[i]+1)b+=a[i];else if(b)c.push(b),b="" with b=+a[i]+1?b+a[i]:b?(c.push(b),""):b.
DocMax

@DocMax thx, I edited to include your suggestion :). That (c.push(b),"") seemed clever, never seen that.
Danny

I had forgotten about it until I saw it used extensively earlier today in codegolf.stackexchange.com/questions/22268#22279
DocMax

That's not valid, ' ' is mistaken for 0 and it's a javascript quirk difficult to manage. Try '12 34 56'
edc65

0

R 52

This function splits strings by character class (this is not regex! :)) class is N - numeric characters and P{N} means negation of this class. o=T means omit empty substrings.

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


Output

array(2) {
  [3]=>
  string(3) "123"
  [6]=>
  string(3) "456"
}
array(3) {
  [5]=>
  string(3) "034"
  [8]=>
  string(3) "582"
  [9]=>
  string(1) "3"
}
array(5) {
  [2]=>
  string(4) "5493"
  [5]=>
  string(2) "54"
  [6]=>
  string(3) "430"
  [7]=>
  string(2) "52"
  [9]=>
  string(1) "9"
}
array(0) {
}

0

JavaScript 88

88 chars when not counting function 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
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.