Crea una sequenza


12

Una sequenza di numeri interi è una sequenza se la differenza tra due numeri consecutivi in ​​questa sequenza è -1 o 1 e il suo primo elemento è 0.

Più precisamente: a1, a2, ..., an è una sequenza se:

For any k (1 ≤  k < n): |a[k] - a[k+1]|=1, 
a[1]=0

Ingresso

  • n - numero di elementi nella sequenza
  • s - somma degli elementi nella sequenza

Produzione

  • un set / list / array / etc di una sequenza di lunghezza ncon somma di elementi s, se possibile
  • un set / list / array / etc vuoto se non possibile

Esempi

Per input 8 4, output potrebbe essere [0 1 2 1 0 -1 0 1]o [0 -1 0 1 0 1 2 1]. Potrebbero esserci altre possibilità.

Per l'input 3 5, l'output è vuoto [], poiché non può essere eseguito.

Regole

Questo è un codice golf, vince la risposta più breve in byte. Le presentazioni devono essere un programma o una funzione. Input / output possono essere forniti in uno dei modi standard .


A proposito, ho una prova che tutti i numeri rappresentabili come una sequenza di lunghezza l sono tutti i numeri tra (l-1)*l/2e -(l-1)*l/2che hanno la stessa parità di (l-1)*l/2.
orgoglioso haskeller il

questo può essere usato per creare un algoritmo efficiente (O (n)) per creare una sequenza desiderata
haskeller orgoglioso

Risposte:


7

CJam, 56 47 44 34 byte

Un sacco di possibilità di miglioramento qui, ma ecco il primo tentativo di questo:

L0aa{{[~_(]_)2++}%}l~:N;(*{:+N=}=p

Ringraziamo Dennis per il modo efficiente di fare la { ... }%parte.

Stampa la rappresentazione dell'array, se possibile, altrimenti ""

Provalo online qui


Sono confuso: la {}%parte del tuo codice non assomiglia al mio (che è solo il codice di @ PeterTaylor, che sostituisce i punti con caratteri di sottolineatura). Se ho contribuito al tuo codice, è l' {}=operatore ...
Dennis,

Inizialmente avevo il _{_W=)+}%\{_W=(+}%+primo che faceva due copie, aggiungevo 1 alla prima, sottraendo 1 dall'altra. Il tuo esempio mi ha fatto capire come farlo in un { ... }%blocco. Per quanto riguarda { ... }=, l'avevo già ridotto così tanto nella mia sperimentazione, anche se non ancora pubblicato.
Ottimizzatore

Capisco dalla domanda che dato input 3 5dovrebbe essere l'output []e non""
Peter Taylor,

1
@PeterTaylor "un set / list / array / etc vuoto se non possibile" - Quindi penso che devo solo chiarire ...
Ottimizzatore

Inoltre, []pin CJam è appena uscito "". Quindi è come la lingua rappresenta array vuoti.
Ottimizzatore

6

JavaScript (E6) 79 82

F=(n,t,
  d=n+n*~-n/4-t/2,
  l=1,
  q=[for(x of Array(n))d<n--?++l:(d+=~n,--l)]
)=>d?[]:q

Non c'è bisogno di forza bruta o di enumerazione di tutte le tuple.

Vedi una sequenza di lunghezza n come n -1 passi, ogni passo è incrementale o decrescente.
Nota, puoi solo scambiare un incremento con un decremento, la somma varia di 2, quindi per ogni data lunghezza la somma è sempre pari o sempre dispari.
Avendo tutti gli incrementi, la sequenza è 0, 1, 2, 3, ..., n-1 e sappiamo che la somma è (n-1) * n / 2
Cambiando l'ultimo passaggio, la somma cambia di 2, quindi il l'ultimo passo pesa 2.
Cambiando il prossimo all'ultimo passo, la somma cambia di 4, quindi l'ultimo passo pesa 4. Questo perché il passo successivo si basa sulla somma parziale finora.
Cambiando il passaggio precedente, la somma cambia di 6, quindi l'ultimo passo pesa 6 (non 8, non sono numeri binari).
... La
modifica del primo passo pesa (n-1) * 2

Algoritmo

Find the max sum (all increments)  
Find the difference with the target sum (if it's not even, no solution)  
Seq[0] is 0  
For each step  
  Compare current difference with the step weight
  if is less 
     we have an increment here, seq[i] = seq[i-1]+1 
  else 
     we have a decrement here, seq[i] = seq[i-1]-1.  
     Subtract we current weight from the current diff.
If remaining diff == 0, solution is Seq[]. Else no solution

Codice Ungolfed

F=(len,target)=>{
  max=(len-1)*len/2
  delta = max-target
  seq = [last=0]
  sum = 0
  weight=(len-1)*2
  while (--len > 0)
  {
    if (delta >= weight)
    {
      --last
      delta -= weight;
    }
    else
    {
      ++last
    }  
    sum += last
    seq.push(last);
    weight -= 2;
  }  
  if (delta) return [];
  console.log(sum) // to verify

  return seq
}

Test nella console Firefox / FireBug

F(8,4)

Produzione

[0, -1, 0, -1, 0, 1, 2, 3]

5

GolfScript ( 41 39 byte)

[][1,]@~:^;({{.-1=(+.)))+}%}*{{+}*^=}?`

Demo online

Grazie a Dennis per 41-> 39.


È possibile ridurre ,0=a ?. Un porto diretto per CJam sarebbe più corto di 5 byte:L1,al~:S;({{_W=(+_)))+}%}*{:+S=}=p
Dennis

@Dennis oooh, è un modo pratico di cavalcare due blocchi {}%. Ti dispiace se lo uso?
Ottimizzatore

@Optimizer: io no, ma non è davvero il mio lavoro.
Dennis,

Stavo parlando del { ... }%blocco. Nel mio codice, ne avevo due, cercavo di ridurlo a 1. Come accade per l'algoritmo reale, penso che sia Peter che io abbiamo pubblicato lo stesso algoritmo quasi contemporaneamente.
Ottimizzatore

3

Mathematica, 73 byte

f=FirstCase[{0}~Join~Accumulate@#&/@Tuples[{-1,1},#-1],l_/;Tr@l==#2,{}]&;

Semplice soluzione di forza bruta.

Sto generando tutte le scelte di passaggi. Poi li trasformo in elenchi accumulati per ottenere le one-sequences. E poi sto cercando il primo la cui somma è uguale al secondo parametro. In caso contrario, il valore predefinito è {}.


Mathematica si fa strada su problemi di matematica / combinazione, no? ;)
Ottimizzatore

@Optimizer Sono sicuro che CJam lo batterà comunque. ;) In realtà questo stesso algoritmo non dovrebbe essere difficile da fare in CJam.
Martin Ender,

1
Lo batterà sicuramente, ma solo per i nomi brevi dei metodi. L'algoritmo non sarà così semplice.
Ottimizzatore

@Optimizer, eh? Penso che sia più semplice con un semplice ciclo e filtro rispetto a questa composizione di funzioni.
Peter Taylor,

3

Haskell, 56 byte

n%s=[x|x<-scanl(+)0`map`mapM(\_->[1,-1])[2..n],s==sum x]

Spiegazione:

  • Costruire un elenco con le permutazioni 1,-1e la lunghezza n-1: replicateM n-1[-1,1]
    Esempio: replicateM 2 [-1,1]==[[-1,-1],[-1,1],[1,-1],[1,1]]
  • Costruisci la sequenza singola da esso. scanlha prestazioni scadenti, ma fa il lavoro giusto qui.
  • Filtra tutte le possibili sequenze singole con la lunghezza in ncui si trova la sommas

1
un semplice miglioramento consiste nel cambiare la funzione da a a infisso. ecco un suggerimento per un miglioramento più non intuitivo: l'importazione Control.Monadsolo per l'utilizzo replicateMche è già troppo lungo. quale altra funzione monadica puoi usare per simulare replicateM?
orgoglioso haskeller il

a proposito, dovresti restituire solo una soluzione, quindi dovresti aggiungere head$alla tua soluzione.
orgoglioso haskeller il

headnon ritorna []per [] :: [[a]]- e odio gli errori.
Johannes Kuhn,

1
perché è passato del tempo, ti dirò cosa intendevo dire. È possibile utilizzare al mapM(\x->[1,-1])[2..n]posto di sequencee replicate.
orgoglioso haskeller il

Interessante. Ciò è ancora più breve: P
Johannes Kuhn,

2

Python, 138

from itertools import*
def f(n,s):
 for i in[list(accumulate(x))for x in product([-1,1],repeat=n-1)]:
  if sum(i)==s:return[0]+i
 return[]

0

CJam, 65 58 54 byte

A malapena più breve della mia soluzione Mathematica, ma è principalmente colpa mia se non uso ancora CJam correttamente:

0]]l~:S;({{_1+\W+}%}*{0\{+_}%);}%_{:+S=}#_@\i=\0>\[]?p

È letteralmente lo stesso algoritmo: get all n-1-tuples of {1, -1}. Trova il primo con accumulo uguale a s, anteponi a 0. Stampa un array vuoto se non ne viene trovato nessuno.


0

CJam, 40

Un altro approccio in CJam.

ri,W%)\_:+ri-\{2*:T1$>1{T-W}?2$+\}/])!*p

0

Rubino (136)

def one_sequences(n)
  n.to_s.chars.map(&:to_i).each_cons(2).to_a.select{|x|x[0] == 0 && (x[1] == 1 || x[1]
  == -1)}.count
end

0

J, 47 caratteri

Controlla ogni sequenza come molte altre risposte. Proverà a creare una soluzione O (n) più corta.

   f=.4 :'(<:@#}.])(|:#~y=+/)+/\0,|:<:2*#:i.2^<:x'

   8 f 4
0 1 2 1 0 1 0 _1

   3 f 5
[nothing]

0

APL 38

{⊃(↓a⌿⍨⍺=+/a←+\0,⍉1↓¯1*(⍵⍴2)⊤⍳2*⍵),⊂⍬}

Esempio:

     4 {⊃(↓a⌿⍨⍺=+/a←+\0,⍉1↓¯1*(⍵⍴2)⊤⍳2*⍵),⊂⍬}8
0 1 2 1 0 1 0 ¯1

Questo come tanti altri bruta solo attraverso ogni combinazione per trovare uno che corrisponde, se non trovato non restituisce nulla. In realtà prova alcune combinazioni più di una volta per rendere il codice più breve.

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.