Suchen Sie die fehlende Zahl in einer nicht begrenzten Zeichenfolge

19

Die Herausforderung besteht darin, die fehlende Zahl in einer Folge von nicht begrenzten ganzen Zahlen zu identifizieren.

Sie erhalten eine Ziffernfolge (gültige Eingabe entspricht dem regulären Ausdruck ^[1-9][0-9]+$). Die Zeichenfolge repräsentiert eine Folge von ganzen Zahlen. Zum Beispiel 1234567891011. Alle Zahlen in der Sequenz liegen im Bereich von 1und 2147483647einschließlich.

Die Folge besteht aus einer Reihe von Zahlen, wobei jede Zahl eine Nummer größer ist als ihre Vorgängerin. Diese Sequenz kann jedoch eine und nur eine fehlende Nummer aus der Sequenz enthalten. Es ist möglich, dass eine bestimmte Zeichenfolge auch keine fehlenden Zahlen aus der Sequenz enthält. Die Zeichenfolge enthält immer mindestens zwei Zahlen aus der Sequenz.

Der Code muss den fehlenden Wert ausgeben oder zurückgeben 0(dies ist ein 0- kein falscher Wert), falls keine fehlenden Werte gefunden wurden.

Folgendes sind gültige Eingaben und deren Ausgabe / Rückgabe:

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  

Während all dies als 'Zeichenkette' als Eingabe beschrieben wird, kann die Eingabe, wenn die Sprache willkürlich große Zahlen verarbeiten kann ( dcund mathematicaich sehe euch beide), eine willkürlich große Zahl anstelle einer Zeichenkette sein, wenn dies der Fall ist der Code einfacher.

Als Referenz wurde dies von der Programmers.SE-Frage inspiriert: Finden Sie die fehlende Zahl in der Reihenfolge in der Zeichenfolge

Gemeinschaft
quelle
4
Sind Sie sicher, dass dies eindeutig ist?
Martin Ender
@ MartinBüttner Ich habe ein bisschen darüber nachgedacht und konnte mir keine Situation einfallen lassen, in der eine um 1 erhöhte Sequenz (das könnte das Problem sein) eine mehrdeutige Situation hat.
Gibt es in OEIS einen Eintrag für die Liste der Ganzzahlen, bei denen in einer verketteten Sequenz genau ein Element fehlt?
mbomb007
@ mbomb007 Ich glaube nicht, da es unendlich viele verschiedene Listen gibt. Und das ist nur eine große alte Saite. Nicht sicher, wie Sie es definieren würden. In diesem Fall wäre eine interessante CS-Frage "Welche Sprache akzeptiert all diese Zeichenfolgen?". Es ist sicherlich nicht regelmäßig. Ich bezweifle seine CF.
1
Ich habe die Sequenz zum Thema einer Herausforderung gemacht: codegolf.stackexchange.com/q/73513/34718
mbomb007

Antworten:

5

Haskell, 115 112 Bytes

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

Die erste Zeile ist eine Hilfsfunktionsdefinition, die zweite ist die anonyme Hauptfunktion. Überprüfen Sie die Testfälle (ich musste aus zeitlichen Gründen kürzere Tests durchführen).

Erläuterung

Dies ist eine Brute-Force-Lösung: Teilen Sie die Zeichenfolge auf alle möglichen Arten in Wörter auf, analysieren Sie die Wörter in Ganzzahlen, prüfen Sie, ob ein Bereich mit einem fehlenden Element vorliegt (und geben Sie dieses Element 0ansonsten zurück), und nehmen Sie das Maximum über alle Teilungen. Die Überprüfung des Bereichs mit fehlenden Elementen wird in der Hilfsfunktion durchgeführt g, die eine Liste erstellt bund das einzige Element in dem Bereich zurückgibt, in dem [head of b..last of b]es nicht boder 0nicht vorhanden ist.

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)
Zgarb
quelle
2

JavaScript (ES6), 117 Byte

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

Erläuterung

Ziemlich effizienter Ansatz. Beendet sofort alle Testfälle.

Ruft jede Teilzeichenfolge vom Anfang der Eingabezeichenfolge als Zahl ab nund initialisiert die fehlende Zahl mauf 0. Anschließend wird nder Anfang der Zeichenfolge wiederholt entfernt, die Zeichenfolge erhöht nund danach gesucht. Wenn index of n != 0ja, wird geprüft m. Wenn m == 0, setze m = nund fahre fort, wenn nicht, gibt es mehrere fehlende Zahlen, also hör auf, diese Teilzeichenfolge zu überprüfen. Dieser Vorgang wird fortgesetzt, bis die gesamte Zeichenfolge entfernt wurde.

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>

user81655
quelle
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")  

Weniger golfen und erklärt

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
}

Prüfung

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>

edc65
quelle
2

C 183 168 166 163 Bytes

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

Ungolfed

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 */
}
Cole Cameron
quelle
2
Wie funktioniert das bei Eingaben, bei 891112denen die Zahlen unterschiedlich lang sind?
Zgarb
@ Zgarb Es funktioniert gut. Der sprintfAnruf gibt die Länge der fehlenden Nummer zurück, unabhängig davon, ob sie länger als die vorherige ist oder nicht.
Cole Cameron
OK danke! Habe eine +1.
Zgarb