구분되지 않은 문자열에서 누락 된 숫자 찾기


19

문제는 무제한 정수 문자열에서 누락 된 숫자를 식별하는 것입니다.

숫자 문자열이 제공됩니다 (올바른 입력은 정규식과 일치합니다 ^[1-9][0-9]+$). 문자열은 정수 시퀀스를 나타냅니다. 예를 들면 다음과 같습니다 1234567891011. 순서의 모든 번호의 범위는 출신 12147483647포함.

순서는 각 숫자가 이전 숫자보다 하나 큰 일련의 숫자입니다. 그러나이 시퀀스 에는 시퀀스에서 누락 된 숫자가 하나만 포함될 있습니다. 주어진 문자열에 시퀀스에서 누락 된 숫자가 포함되어 있지 않을 수도 있습니다. 문자열은 항상 시퀀스에서 최소한 두 개의 숫자를 포함합니다.

누락 된 값을 찾을 수없는 경우 코드는 누락 된 값을 출력하거나 반환해야합니다 0(이는 0거짓 값이 아님).

다음은 유효한 입력과 출력 / 반환입니다.

input                         output    actual sequence (for refrence)
123467                        5         1 2 3 4 _ 6 7
911                           10        9 __ 11
123125126                     124       123 ___ 125 126
8632456863245786324598632460  8632458   8632456 8632457 _______ 8632459 8632460  
123                           0         1 2 3
8632456863245786324588632459  0         8632456 8632457 8632458 8632459  

이 모든 것이 입력으로 '문자열'로 설명되어 있지만 언어가 임의로 많은 수를 처리 할 수 ​​있다면 ( dc그리고 mathematica두 가지를보고 있습니다) 입력이 문자열 대신 임의로 큰 수 일 수 있습니다. 코드가 더 쉽습니다.

참고로, 이것은 프로그래머에 의해 영감을 얻었습니다 .SE 질문 : 문자열에서 누락 된 숫자 찾기


4
이것이 분명한가?
마틴 엔더

@ MartinBüttner 나는 그것에 대해 조금 생각하고 순서가 1 증가하는 (문제가 될 수 있음) 상황이 모호한 상황을 생각해 낼 수 없었습니다.

OEIS에 정확히 하나의 요소가 누락 된 연결된 시퀀스 인 정수 목록에 대한 항목이 있습니까?
mbomb007

@ mbomb007 나는 많은 다른 목록이 있기 때문에 그렇게 생각하지 않습니다. 그리고 이것은 단지 하나의 큰 ole string입니다. 어떻게 정의했는지 잘 모르겠습니다. 그 문제에 대해 흥미로운 CS 질문은 "이 문자열을 모두 받아들이는 언어는 무엇입니까"입니다. 확실히 규칙적이지 않습니다. CF가 의심 스럽다.

1
: 나는 순서 도전의 대상이 만든 codegolf.stackexchange.com/q/73513/34718
mbomb007

답변:


5

하스켈, 115112 바이트

g b|a<-[b!!0..last b]=last$0:[c|c<-a,b==filter(/=c)a]
maximum.map(g.map read.words.concat).mapM(\c->[[c],c:" "])

첫 번째 줄은 도우미 함수 정의이고 두 번째 줄은 기본 익명 함수입니다. 테스트 사례를 확인하십시오 (시간 제한으로 인해 더 짧은 테스트를 실행해야 함).

설명

이것은 무차별 대입 솔루션입니다. 가능한 모든 방법으로 문자열을 단어로 나누고, 단어를 정수로 구문 분석하고, 하나의 요소가 누락 된 범위 (해당 요소를 반환하는 등)가 있는지 확인 0하고 모든 분할에서 최대 값을 가져옵니다. 범위-와-없는 요소 검사는 도우미 함수에서 이루어집니다 g목록을 소요 b하고 범위 내에서 유일한 요소를 반환 [head of b..last of b]에없는 b, 또는 0하나 않는 경우 존재하지.

g b|                         -- Define g b
    a<-[b!!0..last b]=       -- (with a as the range [head of b..last of b]) as:
    last$0:[...]             --  the last element of this list, or 0 if it's empty:
            c|c<-a,          --   those elements c of a for which
            b==filter(/=c)a  --   removing c from a results in b.
mapM(\c->[[c],c:" "])        -- Main function: Replace each char c in input with "c" or "c "
map(...)                     -- For each resulting list of strings:
  g.map read.words.concat    --  concatenate, split at spaces, parse to list of ints, apply g
maximum                      -- Maximum of results (the missing element, if exists)

2

자바 스크립트 (ES6), 117 바이트

s=>eval(`for(i=l=0;s[i];)for(n=s.slice(x=i=m=0,++l);s[i]&&!x|!m;x=s.slice(x?i:i+=(n+"").length).search(++n))m=x?n:m`)

설명

상당히 효율적인 접근. 모든 테스트 사례에 대해 즉시 완료됩니다.

입력 문자열의 시작 부분에서 각 부분 문자열을 숫자로 가져 n오고 누락 된 숫자 m를로 초기화합니다 0. 그런 다음 n문자열의 시작 부분에서 반복적으로 제거 하고 증가 n하고 문자열을 검색합니다. 인 경우 index of n != 0확인합니다 m. 이면 m == 0설정 m = n하고 계속하고 그렇지 않은 경우 누락 된 숫자가 여러 개 있으므로이 하위 문자열에서 검사를 중지하십시오. 이 프로세스는 전체 문자열이 제거 될 때까지 계속됩니다.

var solution =

s=>
  eval(`                     // use eval to use for loops without writing {} or return
    for(
      i=                     // i = index of next substring the check
      l=0;                   // l = length of initial substring n
      s[i];                  // if it completed successfully i would equal s.length
    )
      for(
        n=s.slice(           // n = current number to search for, initialise to subtring l
          x=                 // x = index of n relative to the end of the previous n
          i=                 // set i to the beginning of the string
          m=0,               // m = missing number, initialise to 0
          ++l                // increment initial substring length
        );
        s[i]&&               // stop if we have successfully reached the end of the string
        !x|!m;               // stop if there are multiple missing numbers
        x=                   // get index of ++n
          s.slice(           // search a substring that starts from the end of the previous
                             //     number so that we avoid matching numbers before here
            x?i:             // if the previous n was missing, don't increment i
            i+=(n+"").length // move i to the end of the previous number
          )
          .search(++n)       // increment n and search the substring for it's index
      )
        m=x?n:m              // if the previous number was missing, set m to it
  `)                         // implicit: return m
<input type="text" id="input" value="8632456863245786324598632460" />
<button onclick="result.textContent=solution(input.value)">Go</button>
<pre id="result"></pre>


2

자바 스크립트 (ES6) 114

s=>eval("for(d=0,n=-9,z=s;z=z.slice((n+'').length);z.search(++n)?z.search(++n)?n=(z=s).slice(x=0,++d):x=n-1:0);x")  

덜 골프 와 설명

f=s=>{
  d = 0  // initial digit number, will be increased to 1 at first loop 
  n = -9 // initial value, can not be found
  z = s  // initializa z to the whole input string
  // at each iteration, remove the first chars of z that are 'n' 
  // 'd' instead of 'length' would be shorter, but the length can change passing from 9 to 10 
  for(; z=z.slice((n+'').length); ) 
  {
    ++n; // n is the next number expected in sequence
    if (z.search(n) != 0)
    {
      // number not found at position 0
      // this could be the hole
      // try to find the next number
      ++n;
      if (z.search(n) != 0)
      {
        // nope, this is not the correct sequence, start again
        z = s; // start to look at the whole string again
        x = 0; // maybe I had a candidate result in xm but now must forget it
        ++d;   // try a sequence starting with a number with 1 more digit
        n = z.slice(0,d) // first number of sequence
      }
      else
      {
        // I found a hole, store a result in x but check the rest of the string
        x = n-1
      }
    }
  }      
  return x // if no hole found x is 0
}

테스트

F=s=>eval("for(d=0,n=-9,z=s;z=z.slice((n+'').length);z.search(++n)?z.search(++n)?n=(z=s).slice(x=0,++d):x=n-1:0);x")

console.log=x=>O.textContent+=x+'\n'

elab=x=>console.log(x+' -> '+F(x))

function test(){ elab(I.value) }

;['123467','911','123125126','8632456863245786324598632460',
  '123','124125127','8632456863245786324588632459']
.forEach(t=>elab(t))
<input id=I><button  onclick='test()'>Try your sequence</button>
<pre id=O></pre>


2

C, 183 168 166 163 바이트

n,l,c,d,b[9];main(s,v,p)char**v,*p;{for(;s>1;)for(d=s=0,n=atoi(strncpy(b,p=v[1],++l)),p+=l;*p&&s<2;)p+=memcmp(p,b,c=sprintf(b,"%d",++n))?d=n,s++:c;printf("%d",d);}

언 골프

n,l,c,d,b[9];

main(s,v,p)char**v,*p;
{
    /* Start at length 1, counting upwards, while we haven't
       found a proper number of missing numbers (0 or 1) */
    for(;s>1;)
        /* Start at the beginning of the string, convert the
           first l chars to an integer... */
        for(d=s=0,n=atoi(strncpy(b,p=v[1],++l)),p+=l;*p&&s<2;)
            /* If the next number is missing, then skip, otherwise
               move forward in the string.... */
            p+=memcmp(p,b,c=sprintf(b,"%d",++n))?d=n,s++:c;

    printf("%d",d); /* print the missing number */
}

2
891112숫자의 길이가 다른 곳 과 같은 입력에서는 어떻게 작동 합니까?
Zgarb

@ Zgarb 그것은 잘 작동합니다. 이 sprintf호출은 이전보다 길거나 관계없이 누락 된 번호의 길이를 반환합니다.
Cole Cameron

알았어 고마워! +1하십시오.
Zgarb
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.