Sihirli uzunluk dizileri n


11

Sihirli bir dizi x[0..n-1], tam olarak x[i]örnekleri olacak şekilde negatif olmayan tamsayıların bir dizisidir .i

Örneğin 6,2,1,0,0,0,1,0,0,0 sihirli bir dizidir çünkü 6 0, 2 1 vb. Vardır.

N verildiğinde n uzunluğundaki tüm sihirli dizileri çıktılayan bir fonksiyon yazın


10 saniye içinde en yüksek n değeri için doğru çıktıyı üretebilen program kazanır. (Yine de tüm programlar açıktır)

Örneğin, Alice'in programı 10 saniye içinde n = 15 ile başa çıkabilirken Bob'lar aynı zamanda n = 20 ile başa çıkabilir. Bob kazanır.

Platform: Linux 2,7 GHz @ 4 CPU


5
PPCG'ye Hoşgeldiniz! Bu büyük bir zorluk, ancak kazanan bir kritere ihtiyacınız var. Örneğin, kazananın en kısa program olduğunu söyleyebilirsiniz.
Ypnypn


2
Lütfen cevaplar gönderildikten sonra kazanan kriteri değiştirmeyin. Ayrıca, bu bir kod golf en hızlı kod, en azından bence çok daha iyi oldu.
Alex A.

2
@xnor, n'nin tamsayı bölümlerini oluşturarak ve kendilerinin açıklayıcı olup olmadığını kontrol ederek başlayabilirsiniz.
Martin Ender

2
n>5Formda olmayan bir çözümü olan en küçük şey nedir [n-4, 2, 1, ..., 0, 0, 1, 0, 0, 0]? Aradım n=20ve bir tane bulamadım ve bir hata yapıp yapmadığımı merak ettim.
xnor

Yanıtlar:


19

Python, n≈10 8

def magic_sequences(n):
    if n==4:
        return (1, 2, 1, 0),(2, 0, 2, 0) 
    elif n==5:
        return (2, 1, 2, 0, 0),
    elif n>=7:
        return (n-4,2,1)+(0,)*(n-7)+(1,0,0,0),
    else:
        return ()

Bu, uzunluğun tek Sihirli dizilerinin olduğunu kanıtlayacağım gerçeğini kullanır n:

  • [1, 2, 1, 0]ve [2, 0, 2, 0]içinn=4
  • [2, 1, 2, 0, 0] için n=5
  • [n-4, 2, 1, 0, 0, ..., 0, 0, 1, 0, 0, 0] için n>=7

Bu nedenle, n>=7sadece büyük bir demet geri dönmek gerekiyor. Bunu kabaca n=10^8dizüstü bilgisayarımda yapabilirim, ki bu muhtemelen bellekle sınırlı; artık donuyor. (Listeler yerine tuples kullanma fikri için trichoplax sayesinde.) Ya da bunun yerine sıfır olmayan girişlerin bir sözlüğünü yazdırabilirseniz {0:n-4, 1:2, 2:1, (n-4):1}, bunu çok büyük için yapabilirsiniz n.

Ben benzersizliğini kanıtlıyorum n>=7; Diğeri kaba kuvvet veya vakalarla kontrol edilebilir.

Girişlerinin toplamı l, listenin tüm sayılarının toplam sayısıdır, uzunluğu n. Listede l[0]sıfırlar ve n-l[0]sıfır olmayan girişler var. Ancak tanım l[0]gereği sıfırdan farklı olmalıdır veya bir çelişki elde ederiz ve diğer sıfır olmayan girişlerin her biri en az 1'dir. Bu zaten toplamın toplamının bir l[0] + (n-l[0]-1)*1 = n-1toplamını oluşturur n. Bu nedenle l[0], en fazla bir 2 olabilir ve 2'den büyük bir giriş olamaz.

Ancak bu l[0], l[1], l[2], and l[l[0]], değerleri sıfırdan büyük olan l[0]ve bir permütasyon olan 1,1,2, maksimum toplamı veren tek olmayan girişler anlamına gelir l[0]+4. Bu toplamıdır yana n, elimizdeki en az 7 olan l[0]>=3ve bu yüzden l[l[0]]=1. Şimdi, en azından bir tane var 1, araçlar l[1]>=1, ama eğer l[1]==1bu başka 1, bu nedenle l[1]>=2, ima l[1]yalnız olduğunu 2. Bu l[2]=1, kalan tüm girişleri verir ve 0böylece l[0]=n-4çözümü tamamlar.


Ve dil ...?
edc65

@ edc65 Python gibi görünüyor. Ama emin değilim.
Ismael Miguel

4

Python 3, n≈40

def plausible_suffix(l,N):
    if sum(l)>N:
        return False

    pairs = [(N-1-i,l[i]) for i in range(len(l))]

    if sum(i*x for i,x in pairs)>N:
        return False

    num_remaining = N - len(l)

    for index, desired_count in pairs:
        count = l.count(index)
        more_needed = desired_count - count
        if more_needed<0: 
            return False
        num_remaining -= more_needed
        if num_remaining<0:
            return False
    return True

plausible_func = plausible_suffix

def generate_magic(N):
    l=[0]
    while l:
        extend = False
        if plausible_func(l,N):
            if len(l)==N:
                yield l[::-1]
            else:
                extend = True
        if extend:
            l.append(0)
        else:
            while l[-1]>=N-2:
                l.pop(-1)
                if not l:raise StopIteration
            l[-1]+=1

n=40 #test parameter

if n>0:
    for x in generate_magic(n):
        print(n,x)

Sağdan sola girişleri doldurarak, makul değilse, bir son ekte aramayı durdurarak olası listelerin genişliğinde ilk aramasını yapar, bu şu durumlarda gerçekleşebilir:

  • Soneki girişlerin toplamı aşıyor n(tüm listenin toplamı olmalıdır n)
  • i*l[i]Soneki ağırlıklı toplamı aşıyor n(tüm listenin toplamı olmalıdır n)
  • Herhangi bir sayı sonekte, son ekin yapması gerektiğini söylediklerinden daha fazla görünür
  • Doldurulmamış kalan nokta sayısı, daha fazla görünmesi gereken tüm sayıları dikkate almak için çok az.

Soldan sağa test edilmiş orijinal önekler vardı, ama bu daha yavaş gitti.

Çıkışlar n=30şu şekildedir:

4 [1, 2, 1, 0]
4 [2, 0, 2, 0]
5 [2, 1, 2, 0, 0]
7 [3, 2, 1, 1, 0, 0, 0]
8 [4, 2, 1, 0, 1, 0, 0, 0]
9 [5, 2, 1, 0, 0, 1, 0, 0, 0]
10 [6, 2, 1, 0, 0, 0, 1, 0, 0, 0]
11 [7, 2, 1, 0, 0, 0, 0, 1, 0, 0, 0]
12 [8, 2, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0]
13 [9, 2, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
14 [10, 2, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
15 [11, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
16 [12, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
17 [13, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
18 [14, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
19 [15, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
20 [16, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
21 [17, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
22 [18, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
23 [19, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
24 [20, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
25 [21, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
26 [22, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
27 [23, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
28 [24, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
29 [25, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]
30 [26, 2, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0]

İlk üç liste dışında [1, 2, 1, 0], [2, 0, 2, 0], [2, 1, 2, 0, 0], her bir uzunluk için tam olarak bir liste n>6vardır ve bu forma sahiptir [n-4, 2, 1, ..., 0, 0, 1, 0, 0, 0]. Bu örüntü en azından devam eder n=50. Sonsuza kadar beklediğinden şüpheleniyorum, bu durumda bunların çok sayıda çıktısını almak önemsiz. Olmasa bile, olası çözümlerle ilgili matematiksel bir anlayış, aramayı büyük ölçüde hızlandıracaktır.


@Ypnypn Özel kasam var n=0. Bence tek sonucunu dönen olduğunuzu kaçırmıştı nyukarı sayma değil, n's. Bu beni yukarı çıkarıyor n=40.
xnor

0

Pyth - 15 bayt

Len nve sonra filtrelerin olası tüm dizileri tarafından kaba kuvvet kullanır .

f.A.eq/TkYT^UQQ

Tam açıklama yakında.

Burada çevrimiçi deneyin .


2
FYI, OP kazanan kriteri en hızlı koda çevirdi.
Alex A.

2
Kazanan ölçüt ne olursa olsun, 3 baytlık bir golf: `` fqm / TdQT ^ UQQ`
Jakube

0

K, 26 bayt

{f@&{x~(+/x=)'!#x}'f:!x#x}

Maltysen'in yaklaşımı gibi kaba kuvvet. Programın kalbi, belirli bir vektörün "büyü" olup olmadığını test eden bir yüklemdir:

{x~(+/x=)'!#x}

Giriş vektörü ( !#x) olduğu sürece bir iota vektörü oluşturun , her bir basamağın ( (+/x=)') oluşumlarını sayın ve sonucu giriş vektörü ( x~) ile karşılaştırın. Bir eşleşme varsa, sihirli bir diziniz var.

Ne yazık ki, bu ilk bıçak oldukça yavaş görünüyor. Dizüstü bilgisayarımda Kona kullanarak test yapmak n = 7 ile başa çıkmak yaklaşık 12 saniye sürer. Bunu biraz daha düşünmem gerek.

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.