長さnのマジックシーケンス


11

マジックシーケンスとは、負ではない整数のシーケンスでx[0..n-1]ありx[i]i

たとえば、6,2,1,0,0,0,1,0,0,0は、6個の0、2個の1などがあるため、マジックシーケンスです。

nを指定すると、長さnのすべてのマジックシーケンスを出力する関数を作成します


10秒以内に最高値nの正しい出力を生成できるプログラムが勝ちます。(ただし、すべてのプログラムは大歓迎です)

たとえば、Aliceのプログラムは10秒以内にn = 15まで処理できますが、Bobのプログラムは同じ時間内にn = 20まで処理できます。ボブが勝ちます。

プラットフォーム:Linux 2.7GHz @ 4 CPU


5
PPCGへようこそ!これは大きな挑戦ですが、勝利の基準が必要です。たとえば、勝者は最短のプログラムであると言えます。
Ypnypn


2
回答が投稿された後、勝利基準を変更しないでください。また、少なくとも私の意見では、これは最速のコードよりもコードゴルフとしてはるかに優れていました。
アレックスA.

2
@xnor nの整数パーティションを生成し、それらが自己記述的であるかどうかをチェックすることから開始できます。
マーティンエンダー

2
n>5形式ではないソリューションで最小のものは何 [n-4, 2, 1, ..., 0, 0, 1, 0, 0, 0]ですか?私はn=20それを見つけましたが見当たりませんでした。
xnor

回答:


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

これは、長さのマジックシーケンスのみが以下であるということを証明しますn

  • [1, 2, 1, 0]そして、 [2, 0, 2, 0]のためにn=4
  • [2, 1, 2, 0, 0] にとって n=5
  • [n-4, 2, 1, 0, 0, ..., 0, 0, 1, 0, 0, 0] にとって n>=7

したがって、のためにn>=7、巨大なタプルを返すだけで済みます。私はこれをn=10^8ラップトップで大体まで行うことができますが、これはおそらくメモリによって制限されます。それ以上とフリーズします。(リストではなくタプルを使用するというアイデアについては、trichoplaxに感謝します。)または、代わりにゼロ以外のエントリの辞書を印刷できる場合{0:n-4, 1:2, 2:1, (n-4):1}は、ginormousに対してこれを行うことができますn

の一意性を証明しn>=7ます。他のものはブルートフォースまたはケースワークによって確認できます。

のエントリのl合計は、リストのすべての数の合計数、つまりその長さnです。リストにはl[0]ゼロがあるため、n-l[0]ゼロ以外のエントリがあります。ただし、定義上l[0]、非ゼロでなければなりません。そうでない場合、矛盾が発生し、他の非ゼロエントリはそれぞれ少なくとも1 l[0] + (n-l[0]-1)*1 = n-1ですn。したがって、数えないl[0]で、最大1つの2があり、2より大きいエントリはありません。

しかし、それは、ゼロ以外のエントリのみがl[0], l[1], l[2], and l[l[0]]であり、その値は最大l[0]での順列で1,1,2あり、最大の合計がであることを意味しますl[0]+4。この合計はnであるl[0]>=3ため、少なくとも7 l[l[0]]=1です。現在、少なくとも1つ1がありますl[1]>=1が、これはを意味しますが、それがl[1]==1別の場合は、孤独を意味します。これによりが得られ、残りのすべてのエントリはであるため、ソリューションが完成します。1l[1]>=2l[1]2l[2]=10l[0]=n-4


そして、言語は...?
edc65

@ edc65 Pythonのように見えます。確信はないけど。
イスマエルミゲル

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)

可能性のあるリストの幅優先検索を行い、エントリを右から左に入力し、妥当でない場合はサフィックスで検索を停止します。

  • 接尾辞のエントリの合計が超えていますn(リスト全体の合計はでなければなりませんn
  • i*l[i]接尾辞のの加重合計が超えていますn(リスト全体の合計はでなければなりませんn
  • 接尾辞には、接尾辞が示すべき数よりも多くの数字が表示されます
  • 残りの塗りつぶされていないスポットの数が少なすぎるため、さらに表示する必要があるすべての数を説明できません。

オリジナルのテスト済みプレフィックスを左から右に持っていましたが、それはもっとゆっくりでした。

出力n=30は次のとおりです。

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]

最初の3つのリストを除いて、[1, 2, 1, 0], [2, 0, 2, 0], [2, 1, 2, 0, 0]正確に各長さの1つのリストがありますn>6、そして、それはフォームを持っています[n-4, 2, 1, ..., 0, 0, 1, 0, 0, 0]。このパターンは少なくとも持続しn=50ます。私はそれが永遠に続くと思います。その場合、これらの膨大な数を出力するのは簡単です。そうでなくても、可能な解決策を数学的に理解すると、検索が大幅に高速化されます。


@Ypnypn私は特別なケースを作りましたn=0nカウントアップせずに、単一の結果を返すことを逃していましたn。これは私を迎え入れますn=40
xnor

0

Pyth-15バイト

lenのすべての可能なシーケンスによるブルートフォースを使用してnからフィルターします。

f.A.eq/TkYT^UQQ

完全な説明はすぐに来ます。

こちらからオンラインでお試しください


2
参考までに、OPは勝利基準を最速のコードに変更しました。
アレックスA.

2
勝利基準に関係なく、3バイトのゴルフがあります: `fqm / TdQT ^ UQQ`
ジャクベ

0

K、26バイト

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

マルティセンのアプローチのように、総当たり。プログラムの中心は、与えられたベクトルが「魔法」であるかどうかをテストする述語です:

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

入力ベクトル(!#x)限りイオタベクトルを作成し、各桁の出現回数をカウント((+/x=)')して、結果を入力ベクトル(x~)と比較します。一致する場合、マジックシーケンスがあります。

残念ながら、この最初の突き刺しはかなり遅いようです。私のラップトップでKonaを使用してテストすると、n = 7を処理するのに約12秒かかります。これについてもう少し考える必要があります。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.