区切りのない文字列で不足している番号を見つける


19

課題は、区切りのない整数の文字列で欠落している数を識別することです。

数字の文字列が与えられます(有効な入力は正規表現に一致します^[1-9][0-9]+$)。文字列は整数のシーケンスを表します。たとえば、1234567891011。シーケンスのすべての数字は、範囲内にあるから12147483647包括的。

シーケンスは一連の数字で、各数字はその前の数字よりも1つ大きくなっています。ただし、このシーケンスに、シーケンスから欠落している番号が1つだけ含まれている場合があります。指定された文字列には、シーケンスから欠落している数値が含まれていない可能性もあります。文字列には、シーケンスから少なくとも2つの数字が常に含まれます。

コードは、欠損値を出力または返す必要があります。欠損値が見つからなかった場合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、私はあなたを見ています)、入力はコードを簡単に。

参考までに、これはProgrammers.SEの質問に触発されました:文字列の順序に欠落している番号を探します


4
これは明確ですよね?
マーティンエンダー

@MartinBüttner私はそれについて少し考えましたが、1ずつ増加するシーケンス(これが問題になる可能性があります)があいまいな状況に陥る状況を思い付くことができませんでした。

OEISに、正確に1つの要素が欠落した連結シーケンスである整数のリストのエントリがありますか?
mbomb007

@ mbomb007無限に多くの異なるリストがあるので、私はそうは思いません。そして、これは1つの大きなOLE文字列にすぎないこと。どのように定義するかわかりません。さらに言えば、CSに関する興味深い質問は、「これらの文字列をすべて受け入れる言語は何か」です。確かに定期的ではありません。私はそのCFを疑います。

1
シーケンスをチャレンジの対象にしました:codegolf.stackexchange.com/q/73513/34718
mbomb007

回答:


5

Haskell、115 112バイト

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:" "])

1行目はヘルパー関数の定義、2行目はメインの匿名関数です。 テストケースを確認します(時間制限のため、短いテストを実行する必要がありました)。

説明

これはブルートフォースソリューションです。あらゆる方法で文字列を単語に分割し、単語を整数に解析し、1つの要素が欠けている範囲(その要素を0返すなど)であるかどうかを確認し、すべての分割で最大値を取得します。range-with-missing-elementチェックはヘルパー関数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

JavaScript(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、不足している数値をに初期化m0ます。次に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

JavaScript(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それはうまく動作します。sprintfそれは長いより以前だかどうコールにかかわらず、不足している番号の長さを返します。
コールキャメロン

わかった、ありがとう!+1します。
-Zgarb
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.