Bir sıra oluşturun


12

Bu dizideki ardışık iki sayı arasındaki fark -1 veya 1 ise ve ilk öğesi 0 ise, bir tamsayı dizisi bir dizidir.

Daha doğrusu: a1, a2, ..., an aşağıdaki durumlarda tek bir dizidir:

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

Giriş

  • n - dizideki eleman sayısı
  • s - dizideki elemanların toplamı

Çıktı

  • mümkünse nelemanların toplamıyla birlikte bir dizi dizi / liste / dizi / vb.s
  • mümkünse boş bir küme / liste / dizi / vb.

Örnekler

Giriş için 8 4çıkış [0 1 2 1 0 -1 0 1]veya olabilir [0 -1 0 1 0 1 2 1]. Başka olasılıklar da olabilir.

Giriş için 3 5çıkış boş []çünkü yapılamıyor.

kurallar

Bu bir kod golf, bayt kazanır en kısa cevap kazanır. Başvurular bir program veya işlev olmalıdır. Giriş / çıkış standart yollardan herhangi biri ile verilebilir .


Bu arada, bir uzunluk l dizisi olarak temsil edilebilen tüm sayıların, arasındaki (l-1)*l/2ve -(l-1)*l/2aynı pariteye sahip olan tüm sayılar olduğuna dair bir kanıtım var (l-1)*l/2.
gururlu haskeller

bu istenen bir dizi yapmak için verimli bir algoritma (O (n)) yapmak için kullanılabilir
gururlu haskeller

Yanıtlar:


7

CJam, 56 47 44 34 bayt

Burada iyileştirilmesi gereken çok şey var, ancak işte ilk denemede:

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

Rolü etkili bir şekilde yapması için Dennis'e verilen krediler { ... }%.

Mümkünse dizi temsilini yazdırır, aksi takdirde ""

Buradan çevrimiçi deneyin


Kafam karıştı: {}%Kodunuzun bir kısmı benimkine benzemiyor (sadece altyazılarla noktaların yerini @ @ PeterTaylor'un kodu). Kodunuza bir şey {}=
Dennis

Başlangıçta _{_W=)+}%\{_W=(+}%+ilk iki kopyasını yaptım , birinciye 1 ekleyin, diğerinden 1 çıkarın. Örneğiniz bana bunu tek bir { ... }%blokta nasıl yapacağımı anlamamı sağladı . { ... }=Bununla ilgili olarak , henüz yayınlanmamış olmasına rağmen, denememde bu kadar çok azaltmıştım.
Doktor

Ben girdi 3 5verilen çıktı olması gerektiği []ve olmamalı sorudan anlıyorum""
Peter Taylor

1
@PeterTaylor "boş bir küme / liste / dizi / vb mümkün değilse" - Bu yüzden ben sadece açıklığa kavuşturmak zorunda düşünüyorum ...
Optimizer

Artı, []pCJam sadece çıktı "". Böylece dil boş dizileri temsil eder.
Doktor

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

Bütün kapların kaba kuvvetine veya numaralandırmasına gerek yok.

Uzunlukta bir dizi bakınız n olarak N -1 adımları, her bir aşama olarak, artma veya azalma.
Unutmayın, bir artışı yalnızca bir azalma için değiştirebilirsiniz, toplam 2'ye göre değişir, bu nedenle belirli bir uzunluk için toplam her zaman eşit veya her zaman tek olur.
Tüm artışlara sahip olan dizi 0, 1, 2, 3, ..., n-1'dir ve toplamın (n-1) * n / 2 olduğunu biliyoruz
. Son adımı değiştirmek, toplam 2 ile değişir, böylece son adım 2 ağırlığındadır. Son adımın bir
sonraki adımının değiştirilmesi, toplamın 4 olarak değişmesi nedeniyle son adım 4'ün ağırlığındadır. Bunun nedeni, birbirini takip eden adımın kısmi toplamı temel almasıdır.
Önceki adımı değiştirdiğinizde, toplam 6 değişir, bu nedenle son adım 6 ağırlığındadır (8 değil, ikili sayılar değildir).
...
İlk adımın değiştirilmesi (n-1) * 2

Algoritma

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

Kod çözülmemiş kod

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
}

Firefox / FireBug konsolunda test et

F(8,4)

Çıktı

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

5

GolfScript ( 41 39 bayt)

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

Çevrimiçi demo

Dennis'e 41-> 39 için teşekkürler .


Sen kısaltabilir ,0=için ?. CJam'e açık bir liman 5 byte daha kısa olacaktır:L1,al~:S;({{_W=(+_)))+}%}*{:+S=}=p
Dennis

@Dennis oooh, bu iki {}% bloğa binmek için kullanışlı bir yol. Kullanmamın sakıncası var mı?
Doktor

@Optimizer: Yapmıyorum, ama bu gerçekten benim işim değil.
Dennis

{ ... }%Blok hakkında konuşuyordum . Kodumda iki tane vardı, onu 1'e indirmeye çalışıyordum. Gerçek algoritma olduğu gibi, hem Peter hem de ben aynı algoritmayı neredeyse aynı anda yayınladık.
Doktor

3

Mathematica, 73 bayt

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

Basit kaba kuvvet çözümü.

Tüm adım seçimlerini yapıyorum. Sonra tek dizileri elde etmek için bunları birikmiş listelere dönüştürüyorum. Ve sonra toplamı ikinci parametreye eşit olan ilkini arıyorum. Eğer olmayan varsa, varsayılan değer şudur {}.


Mathematica sadece matematik / kombinasyonla ilgili problemlerde parlıyor, değil mi? ;)
Doktor

@Optimizer Eminim CJam yine de yenecek. ;) Aslında aynı algoritmayı CJam'de yapmak zor olmamalı.
Martin Ender

1
Kesinlikle yenecek, ancak sadece kısa yöntem adları nedeniyle. Algoritma ileri doğru olmayacaktır.
Doktor

@Optimizer, ha? Basit bir döngü ve filtre ile bu fonksiyon kompozisyonundan daha basit olduğunu düşünüyorum.
Peter Taylor

3

Haskell, 56 bayt

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

Açıklama:

  • 1,-1N-1 izinleri ve uzunluğu ile bir liste oluşturun : replicateM n-1[-1,1]
    Örnek: replicateM 2 [-1,1]==[[-1,-1],[-1,1],[1,-1],[1,1]]
  • Bir sekansı buradan oluşturun. scanldüşük performansa sahiptir, ancak burada doğru işi yapar.
  • Uzunluğu mümkün olan tüm tek dizileri Filtre ntoplamı olduğus

1
basit bir iyileştirme, bir infix işlevini değiştirmek. daha sezgisel olmayan bir iyileştirme için bir ipucu: Control.Monadsadece replicateMçok uzun olan kullanmak için içe aktarma . simüle etmek için başka hangi monadik işlevi kullanabilirsiniz replicateM?
gururlu haskeller

Bu arada, sadece bir çözüm döndürmelisiniz, bu yüzden çözümünüze eklemelisiniz head$.
gururlu haskeller

head[]için geri dönmez [] :: [[a]]- ve hatalardan nefret ederim.
Johannes Kuhn

1
çünkü biraz zaman geçti, ne demek istediğimi anlatacağım. Sen kullanabilirsiniz mapM(\x->[1,-1])[2..n]yerine sequenceve replicate.
gururlu haskeller

İlginç. Daha da kısa: 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 bayt

Mathematica çözümümden çok daha kısa, ancak bu çoğunlukla CJam'ı düzgün kullanmama suçum:

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

Kelimenin tam anlamıyla aynı algoritma: get- n-1upuples {1, -1}. Birikimi ile aynı olan ilkini bulun sa 0. Hiçbiri bulunmazsa boş bir dizi yazdırın.


0

CJam, 40

CJam'de bir başka yaklaşım.

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

0

Yakut (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 karakter

Her diziyi diğer cevaplar gibi kontrol eder. Daha kısa bir O (n) çözeltisi yapmaya çalışacaktır.

   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*⍵),⊂⍬}

Misal:

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

Bu, diğer birçok kişi, her kombinasyonda, eşleşen bir tane bulmak için kaba kuvvetler bulur, eğer bulunmazsa hiçbir şey döndürmez. Aslında kodu kısaltmak için bazı kombinasyonları bir kereden fazla dener.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.