Trova il numero mancante in una stringa non delimitata


19

La sfida è identificare il numero mancante in una stringa di numeri interi non delimitati.

Ti viene data una stringa di cifre (l'input valido corrisponderà all'espressione regolare ^[1-9][0-9]+$). La stringa rappresenta una sequenza di numeri interi. Ad esempio 1234567891011,. Tutti i numeri nella sequenza sono compresi nell'intervallo da 1e 2147483647compreso.

La sequenza è una serie di numeri in cui ogni numero è uno maggiore del suo predecessore. Tuttavia, questa sequenza può contenere uno e un solo numero mancante dalla sequenza. È possibile che una determinata stringa non contenga anche numeri mancanti dalla sequenza. La stringa conterrà sempre almeno due numeri dalla sequenza.

Il codice deve generare o restituire il valore mancante o 0(questo è un 0valore non falso) nel caso in cui non siano stati trovati valori mancanti.

Di seguito sono riportati gli input validi e il loro output / return:

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  

Mentre tutto ciò è descritto come una 'stringa' come input, se la lingua è in grado di gestire numeri arbitrariamente grandi ( dce mathematica, sto guardando voi due), l'input potrebbe essere un numero arbitrariamente grande invece di una stringa se ciò rende il codice più semplice.

Per riferimento, questo è stato ispirato dalla domanda Programmers.SE: trova il numero mancante nella sequenza nella stringa


4
Sei sicuro che non sia ambiguo?
Martin Ender,

@ MartinBüttner Ci ho pensato un po 'e non sono riuscito a trovare una situazione in cui una sequenza che aumenta di 1 (che potrebbe essere il problema) presenta una situazione ambigua.

Esiste una voce in OEIS per l'elenco di numeri interi che sono una sequenza concatenata mancante esattamente di un elemento?
mbomb007,

@ mbomb007 Non credo, dato che ci sono infiniti elenchi diversi. E che questa è solo una grande stringa oleosa. Non sono sicuro di come lo definiresti. Del resto, un'interessante domanda CS sarebbe "qual è il linguaggio che accetta tutte queste stringhe". Non è certo regolare. Dubito che sia CF.

1
Ho reso la sequenza oggetto di una sfida: codegolf.stackexchange.com/q/73513/34718
mbomb007,

Risposte:


5

Haskell, 115 112 byte

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

La prima riga è una definizione della funzione di supporto, la seconda è la principale funzione anonima. Verifica casi di test (ho dovuto eseguire test più brevi a causa delle restrizioni temporali).

Spiegazione

Questa è una soluzione di forza bruta: dividi la stringa in parole in tutti i modi possibili, analizza le parole in numeri interi, vedi se è un intervallo con un elemento mancante (restituendo quell'elemento e 0altrimenti) e prendi il massimo su tutte le suddivisioni. Il controllo range-with-missing-element viene eseguito nella funzione helper g, che accetta un elenco be restituisce l'unico elemento nell'intervallo [head of b..last of b]non presente bo 0se non esiste.

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

Spiegazione

Approccio abbastanza efficiente. Finisce istantaneamente per tutti i casi di test.

Ottiene ogni sottostringa dall'inizio della stringa di input come numero ne inizializza il numero mancante msu 0. Quindi rimuove ripetutamente ndall'inizio della stringa, incrementa ne cerca la stringa per essa. Se index of n != 0, controlla m. In caso contrario m == 0, impostare m = ne continuare, in caso contrario, sono presenti più numeri mancanti, quindi interrompere il controllo da questa sottostringa. Questo processo continua fino a quando l'intera stringa non è stata rimossa.

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

Meno golfato e spiegato

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
}

Test

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 byte

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 */
}

2
Come funziona per input come 891112dove i numeri hanno lunghezze diverse?
Zgarb,

@Zgarb Funziona bene. La sprintfchiamata restituisce la lunghezza del numero mancante, indipendentemente dal fatto che sia più lunga della precedente o meno.
Cole Cameron,

Ok grazie! Prendi un +1.
Zgarb,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.