Trova quello strano in una sequenza


20

La sfida:

Considera la funzione in F(N) = 2^N + 1cui Nun numero intero positivo è inferiore a 31. La sequenza definita da questa funzione è:

3, 5, 9, 17, 33, 65, 129, 257, 513, 1025, 2049, 4097, 8193, 16385, 32769, 65537, 131073, 262145, 524289, 1048577, 2097153, 4194305, 8388609, 16777217, 33554433, 67108865, 134217729, 268435457, 536870913, 1073741825

Un input verrà generato come segue:

  • Prendi 5 numeri interi contigui dalla sequenza sopra.
  • Sostituisci uno di essi con un numero intero diverso e positivo (che può o meno far parte della sequenza sopra).
  • Facoltativamente riordinare i 5 numeri risultanti.

Dato un tale elenco di 5 numeri interi, trova quello che è stato scambiato e quindi non fa parte dei 5 numeri interi contigui originali.

Esempio:

  • Sottolista originale: 5, 9, 17, 33, 65.
  • Sostituire uno: 5, 7, 17, 33, 65.
  • Riordina: 33, 17, 5, 7, 65.

L'output previsto sarebbe 7.

I 5 valori nell'input saranno sempre distinti e ci sarà sempre una soluzione unica. (Ad esempio, non dovrai occuparti di input come 3, 9, 17, 33, 129dove uno 3o 129potrebbe essere stato scambiato.)

Casi test:

5,9,17,33,829
o/p: 829

9,5,17,829,33
o/p: 829

33, 17, 5, 7, 65
o/p: 7

5,9,177,33,65
o/p: 177

65,129,259,513,1025
o/p: 259

129,259,513,1025,65
o/p: 259

63,129,257,513,1025
o/p: 63

65,129,257,513,4097
o/p: 4097

5, 9, 2, 17, 33
o/p: 2

536870913, 67108865, 1073741825, 1, 268435457
o/p: 1

4
Per riferimento futuro, confusione e incomprensioni come questa possono spesso essere evitate pubblicando prima idee di sfida nella sandbox , dove è possibile ottenere feedback dalla comunità prima che le persone inizino a risolvere la sfida.
Martin Ender,

@Ajay Dato che c'era ancora un po 'di confusione sulle specifiche, ho modificato la sfida ancora una volta con quello che penso fosse il tuo intento dietro questa sfida. Spero di non averlo frainteso, ma fatemi sapere se ho sbagliato qualcosa.
Martin Ender,

@MartinEnder dovrebbe essere il nuovo caso di test536870913,67108865,134217729,1,268435457
Jörg Hülsermann,

@ JörgHülsermann Sentiti libero di aggiungere anche quello, ma la mia intenzione era quella di aggiungere un caso di prova che copra N = 30come uno dei valori di input.
Martin Ender,

1
Una sfida interessante perché è così facile elaborare algoritmi sbagliati. E in effetti non ho mai visto così tante risposte errate pubblicate. Sarebbe stato anche peggio se i duplicati fossero stati autorizzati (molti metodi basati su set (incluso il mio) avrebbero fallito)
Ton Hospel,

Risposte:


6

Gelatina, 15 byte

⁹R2*‘ṡ5ḟ@€µEÐfQ

TryItOnline
Tutti i casi di test anche su TryItOnline

Restituisce un elenco contenente un elenco contenente quello dispari.

Come?

⁹R2*‘ṡ5ḟ@€µEÐfQ - Main link, a (list)
⁹               - literal 256 (saving a byte over literal 30)
 R              - range, [1,2,3,...]
  2*            - 2 ** x, [2,4,8,...]
    ‘           - increment, [3,5,9,...]
     ṡ5         - all contiguous slices of length 5
       ḟ@€      - filter with reversed arguments for each
          µ     - monadic chain separation
            Ðf  - filter on condition:
           E    - all equal (those previously filtered lists with only one value)
              Q - unique (there can be two, but both will have the same odd-one-out)

5

JavaScript (ES6), 62 byte

a=>a.find(n=>--n&--n|!n)||a.sort((a,b)=>a-b)[a[0]*16>a[3]?4:0]

Algoritmo completamente nuovo, poiché come sottolineato da @ edc65 il precedente era rotto. Spiegazione: Per prima cosa ci occupiamo del caso facile cercando un 2 o un numero che non sia uno maggiore di una potenza di 2. Se non ne è stato trovato nessuno, allora ci sono due casi possibili, a seconda che il valore aggiuntivo fosse inferiore o superiore al esecuzione originale di cinque, quindi controlliamo se il valore più piccolo e il secondo più grande appartengono alla stessa esecuzione di cinque e, in tal caso, incolpiamo il valore più grande, altrimenti il ​​valore più piccolo.


Quasi ok ma prova n-1&n-2con il valore2
edc65,

@ edc65 Non funziona per [3, 17, 33, 65, 257].
Neil,

@ edc65 Sembra --n&--n|!nbuono per il 2caso?
Neil,

Sembra davvero buono
edc65,

4

Python, 84 byte

def f(a,i=0):s=set(a)-{2**j+1for j in range(i,i+5)};return len(s)<2and s or f(a,i+1)

Tutti i casi di test sono su ideone

Per input validi restituisce un set contenente solo il dispari-one-out.
Per input non validi verrà raggiunto il limite di ricorsione e verrà generato un errore.


4

Mathematica, 65 byte

f[a___,x_,b___]/;NestList[2#-1&,a~Min~b/. 2->0,4]~SubsetQ~{a,b}=x

Questo definisce una funzione fche dovrebbe essere chiamata con 5 argomenti, ad es

f[5, 9, 17, 33, 829]

In linea di principio la funzione può essere chiamata con qualsiasi numero (diverso da zero) di argomenti, ma potresti ottenere risultati imprevisti ...

Penso che questa sia la prima volta, che sono riuscito a mettere l'intera soluzione a una sfida non banale nella parte sinistra di a =.

Spiegazione

Questa soluzione mette davvero le funzionalità di abbinamento dei modelli di Mathematica al servizio per noi. La caratteristica di base che stiamo usando è che Mathematica non può semplicemente definire funzioni semplici come, f[x_] := (* some expression in x *)ma possiamo usare schemi arbitrariamente complessi sul lato sinistro, ad esempio f[{a_, b_}, x_?OddQ] := ...aggiungerebbe una definizione alla fquale viene utilizzata solo quando viene chiamata con un elemento a due elementi elenco e un numero intero dispari. Convenientemente, possiamo già dare nomi ad elementi arbitrariamente in fondo all'espressione sul lato sinistro (ad es. Nell'ultimo esempio, potremmo fare immediatamente riferimento ai due elementi dell'elenco come ae b).

Lo schema che stiamo usando in questa sfida è f[a___,x_,b___]. Ecco a___e b___sono sequenze di zero o più argomenti ed xè un singolo argomento. Poiché il lato destro della definizione è semplicemente x, ciò che vogliamo è un po 'di magia che assicuri che xvenga utilizzata per l'input che stiamo cercando e a___che b___siano semplicemente caratteri jolly che coprono gli elementi rimanenti.

Questo viene fatto collegando una condizione al modello con /;. Il lato destro di /;(tutto fino a =) deve tornare Trueper far corrispondere questo schema. Il bello è che modello di abbinamento di Mathematica cercherà ogni singola assegnazione di a, xe bagli ingressi per noi, così la ricerca per l'elemento corretto è fatto per noi. Questa è essenzialmente una soluzione dichiarativa al problema.

Per quanto riguarda la condizione stessa:

NestList[2#-1&,a~Min~b/. 2->0,4]~SubsetQ~{a,b}

Si noti che questo non dipende xaffatto. Invece, questa condizione dipende solo dai restanti quattro elementi. Questa è un'altra comoda funzionalità della soluzione di corrispondenza dei motivi: grazie ai motivi di sequenza, ae binsieme contengono tutti gli altri input.

Quindi questa condizione deve verificare se i restanti quattro elementi sono elementi contigui della nostra sequenza con al massimo un gap. L'idea di base per verificare questo è che generiamo i successivi quattro elementi dal minimo (via ) e controlliamo se i quattro elementi sono un sottoinsieme di questo. Gli unici input in cui ciò può causare problemi sono quelli che contengono a , poiché ciò genera anche elementi di sequenza validi, quindi è necessario gestirli separatamente.xi+1 = 2xi - 12

Ultima parte: esaminiamo l'espressione reale, perché qui c'è un po 'di zucchero sintattico più divertente.

...a~Min~b...

Questa notazione infissa è l'abbreviazione di Min[a,b]. Ma ricordalo ae bsono sequenze, quindi questo in realtà si espande ai quattro elementi Min[i1, i2, i3, i4]e ci dà il più piccolo elemento rimanente nell'input.

.../. 2->0

Se questo si traduce in un 2, lo sostituiamo con uno 0 (che genererà valori che non sono nella sequenza). Lo spazio è necessario perché altrimenti Mathematica analizza il float letterale .2.

NestList[...&,...,4]

Applichiamo la funzione senza nome a sinistra 4 volte a questo valore e raccogliamo i risultati in un elenco.

2#-1&

Questo semplicemente moltiplica il suo input per 2 e lo decrementa.

...~SubsetQ~{a,b}

E infine, controlliamo che l'elenco contenente tutti gli elementi da ae bsia un sottoinsieme di questo.


Non sapevo che Mathematica potesse farlo!
DanTheMan,

4

Racchetta 198 byte

(λ(m)(let((l(for/list((i(range 1 31)))(+ 1(expt 2 i))))(r 1)(n(length m)))(for((i(-(length l)n)))(let
((o(for/list((j m)#:unless(member j(take(drop l i)n)))j)))(when(eq?(length o)1)(set! r o))))r))

Versione non golfata:

(define f
  (λ(m)
    (let ((l (for/list ((i (range 1 31))) 
               (+ 1 (expt 2 i))))
          (res 1)
          (n (length m)))
      (for ((i (- (length l) n)))
        (let ((o (for/list ((j m) 
                             #:unless (member j 
                                             (take (drop l i) n))) 
                    j)))
          (when (eq? (length o) 1)
            (set! res o))))
      res)))

test:

(f '(5 9 17 33 829))
(f '(9 5 17 829 33))
(f '(5 9 177 33 65))
(f '(65 129 259 513 1025))
(f '(129 259 513 1025 65))
(f '(63 129 257 513 1025))
(f '(65 129 257 513 4097))

Produzione:

'(829)
'(829)
'(177)
'(259)
'(259)
'(63)
'(4097)

2

05AB1E , 32 30 26 24 20 byte

30Lo>Œ5ùv¹yvyK}Dgi`q

Spiegazione

30Lo>    # list containing the sequence [3 .. 1073741825]
Œ5ù      # all sequence sublists of length 5
v        # for each such list
 ¹yvyK}  # remove it's elements from input
 Dgi     # if the remaining list has length 1
    `q   # end the program and print the final list flattened

Provalo online!


2

R, 97 byte

Questo si è rivelato più difficile di quanto pensassi. Sono sicuro che questo può essere giocato a golf in modo significativo però.

m=match(x<-sort(scan()),2^(1:31)+1);l=diff(m);ifelse(NA%in%m,x[is.na(m)],x[ifelse(l[4]>1,5,l>1)])

Ungolfed e spiegato

x<-sort(scan())                  # read input from stdin and sort, store as vector
m=match(x, 2^(1:31)+1)           # generate a vector of indices for which input matches the sequence
l=diff(m)                        # vector of the difference of indices (will only contain 4 elements)
ifelse(NA%in%m,                  # if m contains NA do:
       x[is.na(m)],              # return x where no match has been found, else:
       x[ifelse(l[4]>1,5,l>1)])  # return x by index where diff>1 unless it's the last object, then return x[5]

La match()funzione tornerà NAse qualsiasi elemento del vettore di input non è nella sequenza e di conseguenza possiamo semplicemente trovare l'indice dove NAesiste nell'input e restituirlo:x[is.na(m)]

Diventa un po 'più complicato se l'input fa parte della sequenza ma è fuori luogo. Poiché l'input è stato ordinato, la distanza tra ogni coppia di indici dovrebbe essere 1. Possiamo quindi trovare l'elemento fuori posto studiando la 1stdifferenza degli indici corrispondenti l=diff(m)e selezionare l'indice per il quale l>1. Questo sarebbe sufficiente se non fosse per il fatto che lcontiene 4elementi piuttosto che 5. Questo è un problema solo se l'ultimo elemento nell'input ordinato è un membro della sequenza MA non una parte della sottosequenza (come nel caso di test finale). Di conseguenza, se l' 4thelemento >1recupera la 5thvoce nell'input ordinato altrimenti cerca l'indice nel 4vettore -length:x[ifelse(l[4]>1,5,l>1)]


1
nelle recenti versioni di R esiste una funzione anyNAequivalente aany(is.na(x))
JDL,

2

Haskell, 66 64 byte

g x=[s|n<-[1..],[s]<-[filter(`notElem`[2^m+1|m<-[n..n+4]])x]]!!0

Esempio di utilizzo: g [65,129,257,513,4097]-> 4097.

Passa attraverso tutte le liste secondarie contigue di lunghezza 5 di F(N), mantiene gli elementi che non sono nell'elenco di input xe il modello corrisponde a quelli della lunghezza 1 (-> [s]).

Modifica: @xnor ha salvato due byte rimuovendo il limite superiore del ciclo esterno. Poiché una soluzione è garantita, la pigrizia di Haskell si ferma al primo numero trovato.


Hai davvero bisogno del limite superiore di 26?
xnor,

1

Perl, 64 59 byte

Include +2 per -an

Fornisci un elenco di input su STDIN:

perl -M5.010 oddout.pl <<< "5 9 2 17 33"

oddout.pl:

#!/usr/bin/perl -an
@a=grep$_,@a{@F,map{2**$_+++1}($.++)x5}=@F while$#a;say@a

Se non ti dispiace una quantità variabile di spazio attorno al risultato, questo verson 58 byte funziona:

#!/usr/bin/perl -ap
$_=join$",@a{@F,map{2**$_+++1}($.++)x5}=@F while/\b +\b/

Entrambe le versioni eseguono il ciclo per sempre se l'input non ha soluzione.

Questo è un codice molto malato, ma non riesco a pensare a niente di elegante ...

Il modo in cui io (ab) uso %aè un nuovo trucco perlgolf, per quanto ne so.


1

Python 2, 73 byte

s=set(input());i,=d={1}
while~-len(s-d):i*=2;d=d-{i/32+1}|{i+1}
print s-d

Scorre i set ddi cinque elementi di sequenza consecutivi fino a quando non trova uno che contiene tutti gli elementi di input tranne uno, quindi stampa la differenza, ovvero l'output in un set singleton.

Le serie ddi cinque elementi consecutivi sono costruite dal nulla aggiungendo ripetutamente un nuovo elemento i+1ed eliminando qualsiasi elemento precedente i/32+1che precede la finestra corrente di 5. Ecco come si presentano i suoi progressi.

{1}
{3}
{3, 5}
{3, 5, 9}
{3, 5, 9, 17}
{3, 5, 9, 17, 33}
{5, 9, 17, 33, 65}
{9, 17, 33, 65, 129}
{17, 33, 65, 129, 257}
{33, 65, 129, 257, 513}

C'è un 1 randagio all'inizio dell'inizializzazione, ma è innocuo perché viene immediatamente rimosso. Anche i set più piccoli in quanto costruiscono fino a 5 elementi sono innocui.


1

PHP, 87 76 75 byte

for(;count($b=array_diff($argv,$a?:[]))-2;)$a[$n%5]=1<<++$n|1;echo end($b);

Corri con php -r '<code>' <value1> <value2> <value3> <value4> <value5>


'a = [] `non è necessario
Jörg Hülsermann,

@ JörgHülsermann: è necessario per array_diff. Ma posso salvare un byte lì.
Tito,

Il risultato è un avviso array_diff (): l'argomento n. 2 non è un array. Bel modo di riempire l'array con il mod 5. Mi farà risparmiare array_map e range nella mia proposta
Jörg Hülsermann

1
endinvece di maxe la tua nota non è più importante
Jörg Hülsermann,


0

Java 7,85 byte

int f(int[]a,int l){int i=1;for(;i<l;)if(a[i++-1]*2-1!=a[i])return a[i];return a[0];}

Ungolfed

int f(int[]a,int l){
    int i=1;
    for(;i<l;)
    if(a[i++-1]*2-1!=a[i])
    return a[i];
   return a[0];

}

Hmm, sei sicuro che funzioni correttamente? Perché sto ottenendo un output errato per i casi di test 1, 5, 6 e 7 (solo il secondo, il terzo e il quarto output sono corretti). Inoltre, è il parametro l31? Nella domanda vedo solo un int-array come input, ma non un int aggiuntivo? : S
Kevin Cruijssen,

Non fallirà se il valore dispari è il secondo (all'indice 1)?
Ton Hospel,

Scusate ragazzi, ho frainteso la domanda .. In realtà ora sono in ospedale .. La cambierò in un breve lasso di tempo.
Numberknot,

0

PHP, 76 byte

ha implementato l'idea di Titus con la mod 5

<?for(;count($x=array_diff($_GET[a],$r))-1;$r[++$i%5]=2**$i+1);echo end($x);

126 byte prima

<?for(;$x=array_diff($_GET[a],array_map(function($z){return 2**$z+1;},range(++$i,$i+4)));)if(count($x)<2){echo end($x);break;}

funzione anonima: array_map(function($z){return 2**$z+1;},range($i,$i+4)). $x[key($x)]->end($x)
Tito

Mettendo 1-count($x=...)alla condizione ti libererai della pausa: for(;1-count($x=...););echo end($x);(-13)
Tito

0

Pyth, 18 byte

hhlD-LQ.:mh^2dSCd5

Forma la sequenza, prendi le liste di lunghezza 5, rimuovi ogni lista da Q, prendi il risultato più breve, emette il suo unico elemento.


Non funziona per[5, 9, 2, 17, 33]
Emigna,

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.