すべての異なるGozintaチェーンを検索


36

ゴジンタチェーン

Project Euler#606に触発)

nのgozintaチェーンは、{1,a,b,...,n}各要素が次を適切に分割するシーケンスです。たとえば、12には8つの異なるgozintaチェーンがあります。

{1,12}, {1,2,12}, {1,2,4,12}, {1,2,6,12}, {1,3,12}, {1,3,6,12}, {1,4,12} and {1,6,12}.

チャレンジ

正の整数(n > 1)を受け入れ、指定された数のすべての異なるgozintaチェーンを出力または返すプログラムまたは関数を作成します。

  1. チェーンの順序は重要です(昇順)。チェーンの順序は関係ありません。
  2. 偶然に、それは存在します、あなたは挑戦を解決するビルトインを使うことができません。
  3. これはです。

編集:1潜在的な入力としての削除。


4
PPCGへようこそ。素敵な最初の質問!
AdmBorkBork

5
「偶然に存在する[(あなたを見て、Mathematica!)]」
エリック・ザ・アウトゴルファー

3
AdmBorkBorkが言ったように、一般にエッジケースはチャレンジのコアにとって重要な場合にのみ追加されます-理由だけ[[1]]が必要な場合[1,1]は、1当時のgozintaである場合は現状の[1,1,12]gozintaで12あり[1,1,1,12]、今は可能ですもはや「すべてを返す...」
ジョナサンアラン

4
あなたはそれを知らない人のために質問でしゃれを明確にする必要があります。2|4「2つは4つになります」別名「2つのgozinta 4」と読みます
mbomb007

1
2時間半では、サンドボックスが機能するのに十分な時間ではありません。サンドボックスFAQを参照してください
ピーターテイラー

回答:


10

Pythonの368の 65バイト

編集:@notjaganのおかげで-3バイト

f=lambda x:[y+[x]for k in range(1,x)if x%k<1for y in f(k)]or[[x]]

オンラインでお試しください!

説明

gozintaチェーンx、チェーンの最後にある数字で構成され、その左側に少なくとも1つの除数があります。各除数のためkxチェーン[1,...,k,x]別個のものです。したがって、我々はそれぞれの除数のためにすることができk、その明確なのすべてを見つけるgozintaチェーン とAPPENDをxすべて明確な得るために、彼らの最後にgozintaチェーンをしてk、直接の左側にありますx。これは、すべてのgozintaチェーンが1から始まるため、再帰がボトムアウトしたことを意味するため、x = 1どこ[[1]]に返されるまで再帰的に行われます。

Pythonリストの内包表記によりコードが非常に短くなり、二重反復が可能になります。これは、にある値f(k)を、すべての異なる除数の同じリストに追加できることを意味しますk


遅すぎた今、これをしようとしていた= /
ロッド

3
この回答は、これまでの他の回答に比べて非常に高速です。
ajc2000

不要なリストのアンパックを削除して、-3バイト
-notjagan

7

、13バイト

ufo=ḣ⁰…ġ¦ΣṖḣ⁰

H.PWizのアプローチとはやや異なるアプローチですが、それでも総当たりです。オンラインでお試しください!

説明

基本的な考え方は、すべてのサブシーケンスを連結し[1,...,n]、各要素が次の要素を分割するサブリストに結果を分割することです。これらのうち、で始まり、1で終わり、n重複しないものを保持します。これは組み込みの「rangify」で行われます。その後、重複を破棄します。

ufo=ḣ⁰…ġ¦ΣṖḣ⁰  Input is n=12.
           ḣ⁰  Range from 1: [1,2,..,12]
          Ṗ    Powerset: [[],[1],[2],[1,2],[3],..,[1,2,..,12]]
         Σ     Concatenate: [1,2,1,2,3,..,1,2,..,12]
       ġ¦      Split into slices where each number divides next: [[1,2],[1,2],[3],..,[12]]
 fo            Filter by
      …        rangified
   =ḣ⁰         equals [1,...,n].
u              Remove duplicates.

私は、各数字が次を分割するパワーセット内の配列にフィルターをかけることは短くないと思いますか?
ETHproductions

@ETHproductionsいいえ、1バイト長くなります。
-Zgarb

5

ゼリー9 8バイト

ÆḌ߀Ẏ;€ȯ

オンラインでお試しください!

Japt answerと同様の手法を使用しているため、大規模なテストケースでは非常に高速に実行されます。

使い方

ÆḌ߀Ẏ;€ȯ    Main link. Argument: n (integer)
ÆḌ          Yield the proper divisors of n.
       ȯ    If there are no divisors, return n. Only happens when n is 1.
  ߀        Otherwise, run each divisor through this link again. Yields
            a list of lists of Gozinta chains.
    Ẏ       Tighten; bring each chain into the main list.
     ;€     Append n to each chain.

4

Mathematica、77バイト

FindPath[Graph@Cases[Divisors@#~Subsets~{2},{m_,n_}/;m∣n:>m->n],1,#,#,All]&

Graph頂点がDivisors入力のであるaを形成し#、エッジが適切な分割可能性を表しAll、頂点1から頂点までのパスを見つけます#


1
うわー、これはかなり賢いです!
ジョンファンミン

3

ゼリー、12 バイト

ŒPµḍ2\×ISµÐṀ

整数を受け入れ、整数のリストのリストを返す単項リンク。

オンラインでお試しください!

どうやって?

最初が1、最後がN、すべてのペアが分割されるように、1〜Nの一意の整数のすべてのソート済みリストが必要です。コードは、ペアワイズ除算基準が問題の範囲のべき乗セットを満たしていることを確認することでこのフィルターを実現しますが、増分差の最大合計を持つもののみを選択します(1で始まり、Nで終わるものは、 N-1の増分差の合計、その他の差は小さくなります)。

ŒPµḍ2\×ISµÐṀ - Link: number N
ŒP           - power-set (implicit range of input) = [[1],[2],...,[N],[1,2],[1,3],...,[1,N],[1,2,3],...]
          ÐṀ - filter keep those for which the result of the link to the left is maximal:
  µ      µ   - (a monadic chain)
    2\       -   pairwise overlapping reduce with:
   ḍ         -     divides? (1 if so, 0 otherwise)
       I     -   increments  e.g. for [1,2,4,12] -> [2-1,4-2,12-4] = [1,2,8]
      ×      -   multiply (vectorises) (no effect if all divide,
             -                          otherwise at least one gets set to 0)
        S    -   sum         e.g. for [1,2,4,12] -> 1+2+8 = 11 (=12-1)

n-wiseオーバーラップリデュースがありますか?:o:PIが<slice>2<divisible>\<each>:P を使用していたことをどうやって見なかったのか
-HyperNeutrino

Jelly's quicksの最新の変更を使用して、11バイトƝで `2`の代わりに使用できます
Xcoder氏18年

3

Japt、17バイト

⬣ßX m+S+UR÷ª'1

オンラインでテストしてください!

奇妙なことに、出力を文字列として生成することは、配列の配列として生成するよりもはるかに簡単でした...

説明

 ⬠£  ßX m+S+URà ·  ª '1
Uâq mX{ßX m+S+UR} qR ||'1   Ungolfed
                            Implicit: U = input number, R = newline, S = space
Uâ                          Find all divisors of U,
  q                           leaving out U itself.
    mX{         }           Map each divisor X to
       ßX                     The divisor chains of X (literally "run the program on X")
          m    R              with each chain mapped to
           +S+U                 the chain, plus a space, plus U.
                  qR        Join on newlines.
                     ||     If the result is empty (only happens when there are no factors, i.e. U == 1)
                       '1     return the string "1".
                            Otherwise, return the generated string.
                            Implicit: output result of last expression

それでは、他のアプローチと同様に、あなたのアプローチは無効なチェーンを生成してフィルタリングすることを避けていますか?

@Umbrellaいや、それはので、それもような場合に超高速に動作し、なぜ、時にのみ有効なもの、1つの除数を生成12000 :-)
ETHproductions

再帰の非常に良い使用:)そして、私はその¬トリックにニックを入れています!:p
シャギー

@Shaggy ¬は、基本的に「Xに引数を与えない、またはYに真実の引数を与える」関数を実装した理由の1つです
。P– ETHproductions

3

Mathematica、60バイト

Cases[Subsets@Divisors@#,x:{1,___,#}/;Divisible@@Reverse@{x}]&

文書化されていないマルチ引数形式のを使用しますDivisible。ここでif 、などをDivisible[n1,n2,...]返します。inputのリストをすべて取得し、dの約数列を与える形式のを返します。Truen2∣n1n3∣n2FalseSubsetsDivisors#Cases{1,___,#}DivisibleTrueReverse


それで、Divisible基本的にgozintaチェーンを検証するためのビルトインですか?

@Umbrella適切な分割可能性をチェックしません。
-ngenisis

3

Haskell、51バイト

f 1=[[1]]
f n=[g++[n]|k<-[1..n-1],n`mod`k<1,g<-f k]

適切な除数のgozintaチェーンを再帰的に見つけて追加しますn

オンラインでお試しください!


適切に処理するための余分な信用があるべきだと思う1。まとめて免除すると結論付けたので1、そのケースを削除して10バイト節約できますか?

@Umbrella 1はこのアルゴリズムの特殊なケースではなく、再帰の基本ケースとして必要です。2番目の定義式では、空のリストのみを返すことができます。
クリスチャンシーバーズ

そうですか。私のソリューション(まだ投稿さ[[1]]れていない)もベースとして使用しています。

3

Haskell(ラムダボット)、92 85バイト

x#y|x==y=[[x]]|1>0=(guard(mod x y<1)>>(y:).map(y*)<$>div x y#2)++x#(y+1)
map(1:).(#2)

インポートguardする必要Control.Monadがあるため、Lambdabot Haskellが必要です。メイン関数は匿名関数であり、許可されていると言われており、数バイト削減します。

7バイトを節約してくれたLaikoniに感謝します。

説明:

モナドはとても便利です。

x # y

これは、実際のすべての作業を行う再帰関数です。xは累積する数値(値に残っている除数の積)でありy、次の数値に分割する必要があります。

 | x == y = [[x]]

場合はx等号y我々は再帰を行っています。x現在のgozintaチェーンの終わりとして使用し、それを返します。

 | 1 > 0 =

Haskellの「真」のゴルフ主義。つまり、これがデフォルトのケースです。

(guard (mod x y < 1) >>

リストモナド内で動作しています。リストモナド内では、複数の選択を同時に行うことができます。これは、疲労によって何かの「可能な限り」を見つけるときに非常に役立ちます。guard声明は、「条件が真の場合のみ、次の選択肢を検討する」と言います。この場合、唯一の次の選択肢を検討するy除算x

(y:) . map (y *) <$> div x y#2)

y分割する場合、gozintaチェーンxに追加yする選択肢があります。この場合、チェーンに追加したばかりの「因数分解」を行いたいので、と等しい値(#)で最初から再帰的にを呼び出します。次に、この再帰呼び出しの結果が何であれ、その値を複数のファクターで除算し、公式にgozintaチェーンに追加します。y = 2xx / yyyy

++

次の選択も考慮してください。これは単に2つのリストを一緒に追加しますが、単刀直入に、「このことを行うか、この他のことを行うかを選択する」と考えることができます。

x # (y + 1)

もう1つのオプションは、値を使用せずに単に再帰を続行することですyy分割しない場合x、これが唯一のオプションです。y分割する場合x、このオプションは他のオプションと同様に使用され、結果が結合されます。

map (1 :) . (# 2)

これがgozintaの主要な機能です。(#)引数で呼び出して再帰を開始します。A 1は、すべてのgozintaチェーンの前に付加され(#)ます。これは、関数がチェーンに1を入れることはないためです。


1
素晴らしい説明!パターンガードをすべて1行に入れることで、いくつかのバイトを節約できます。mod x y==0に短縮できますmod x y<1。無名関数が許可されているため、メイン関数はとしてポイントフリーで記述できますmap(1:).(#2)
ライコニ

3

ハスケル、107の 100 95バイト

f n=until(all(<2).map head)(>>=h)[[n]]
h l@(x:_)|x<2=[l]|1<2=map(:l)$filter((<1).mod x)[1..x-1]

より良い終了条件があるかもしれません(のようなものを試しました

f n=i[[n]]
i x|g x==x=x|1<2=i$g x
g=(>>=h)

長いです)。1繰り返し1のスクラブまたは重複(nubinでPreludeはない)のスクラブはより多くのバイトであるため、のチェックは慎重に思えます。

オンラインでお試しください。


3
(>>=h)のため(concatMap h)
マイケルクライン


神聖ながらくた私は約愚かだu...
レイフ・Willerts

3

JavaScript(Firefox 30-57)、73バイト

f=n=>n>1?[for(i of Array(n).keys())if(n%i<1)for(j of f(i))[...j,n]]:[[1]]

便利なのn%0<1は偽です。


2

ゼリー、17バイト

ḊṖŒP1ppWF€ḍ2\Ạ$Ðf

オンラインでお試しください!


それは驚くほど速かった。1ただし、予想外の結果です。私は決定的な結果を見つけることができませんでしたが1、私はそれがあると思いました[[1]][1,1]他のすべての結果が増加するシーケンスであることを除いて、それが間違っているとは断言できません。考え?

@Umbrella 1の答えを何でもすることができます。
Xcoder氏17

@Umbrellaは、それが問題だ場合、私は(置き換える2のためにそれを修正することができます;€;Q¥€)。
エリックアウトゴルファー

2

Mathematica、104バイト

(S=Select)[Rest@S[Subsets@Divisors[t=#],FreeQ[#∣#2&@@@Partition[#,2,1],1>2]&],First@#==1&&Last@#==t&]&

FreeQ[...]になることができますAnd@@BlockMap[#∣#2&@@#&,#,2,1]
ジョンファンミン

非常に素晴らしい!しかし、追加のメッセージDeveloperPartitionMap :: nlen:が表示されます-メッセージテキストが見つかりません->> `なぜですか?
-J42161217

BlockMapDeveloper`PartitionMap内部で関数を使用しますが、開発者関数なので、エラーメッセージはありません。このエラーは、1または0の要素を持つリストが原因で発生し、2つのパーティションを作成することはできません。
ジョンファンミン

2

Mathematica、72バイト

Cases[Subsets@Divisors@#,{1,___,#}?(And@@BlockMap[#∣#2&@@#&,#,2,1]&)]&

説明

Divisors@#

入力のすべての約数を見つけます。

Subsets@ ...

そのリストのすべてのサブセットを生成します。

Cases[ ... ]

パターンに一致するすべてのケースを選択...

{1,___,#}

1で始まり、<input>... で終わる

?( ... )

そして条件を満たします...

And@@BlockMap[#∣#2&@@#&,#,2,1]&

左側の要素は、リストのすべての2つのパーティションの右側の要素をオフセット1で分割します。


2

TI-BASIC、76バイト

Input N
1→L1(1
Repeat Ans=2
While Ans<N
2Ans→L1(1+dim(L1
End
If Ans=N:Disp L1
dim(L1)-1→dim(L1
L1(Ans)+L1(Ans-(Ans>1→L1(Ans
End

説明

Input N                       Prompt user for N.
1→L1(1                        Initialize L1 to {1}, and also set Ans to 1.

Repeat Ans=2                  Loop until Ans is 2.
                              At this point in the loop, Ans holds the
                              last element of L1.

While Ans<N                   While the last element is less than N,
2Ans→L1(1+dim(L1              extend the list with twice that value.
End

If Ans=N:Disp L1              If the last element is N, display the list.

dim(L1)-1→dim(L1              Remove the last element, and place the new
                              list size in Ans.

L1(Ans)+L1(Ans-(Ans>1→L1(Ans  Add the second-to-last element to the last
                              element, thereby advancing to the next
                              multiple of the second-to-last element.
                              Avoid erroring when only one element remains
                              by adding the last element to itself.

End                           When the 1 is added to itself, stop looping.

Ans> 1チェックとループ条件を削除することにより、正常に終了する代わりにエラーで終了できる場合は、さらに5バイトを節約できます。しかし、私はそれが許可されているとは確信していません。


これを電卓に入力しましたか?それは予想外で、やや印象的だからです。

うん!TI-BASICのトリッキーな部分は、グローバル変数しかないため、リスト自体を再帰スタックとして効果的に使用する必要がありました。
calc84maniac

2

Mathematica 86 77バイト

Select[Subsets@Divisors@#~Cases~{1,___,#},And@@BlockMap[#∣#2&@@#&,#,2,1]&]&

定義によるブルートフォース。

リストのペアワイズシーケンシャル要素比較を行うより短い方法があればいいのに。

9バイトの節約を提案してくれた@Jenny_mathyと@JungHwanMinに感謝


1
FreeQ[#∣#2&@@@Partition[#,2,1],1>2]&](2番目の引数として)82バイトに移動するために使用できます
-J42161217

@Jenny_mathy以上、And@@BlockMap[#∣#2&@@#&,#,2,1]
JungHwan分

1

17 16バイト

-1バイト、Zgarbのおかげ

foEẊ¦m`Je1⁰Ṗthḣ⁰

オンラインでお試しください!


短いが、遅い。私は入れて50入力して、それがタイムアウトしました。アプローチの要点は何ですか?

基本的にすべての可能なチェーンを試行し、仕様に一致するチェーンを選択します
-H.PWiz

@Umbrella TIOには60秒のタイムアウトがありますが、これはプログラムのせいではありません。
エリックアウトゴルファー

o`:⁰:1することができ`Je1⁰
Zgarb

@Zgarbもう一度
...-H.PWiz

0

PHP 147 141

冗長テストを削除するために編集されました

function g($i){$r=[[1]];for($j=2;$j<=$i;$j++)foreach($r as$c)if($j%end($c)<1&&$c[]=$j)$r[]=$c;foreach($r as$c)end($c)<$i?0:$R[]=$c;return$R;}

説明:

function g($i) {

定型文の15文字:(

    $r = [[1]];

[[1]]すべてのチェーンが1で始まるように結果セットを初期化します。これにより、入力として1がサポートされます。

    for ($j = 2; $j <= $i; $j++) {
        foreach ($r as $c) {
            if ($j % end($c) < 1) {
                $c[] = $j;
                $r[] = $c;
            }
        }
    }

2までのすべての数のために$i、私たちは現在の数で私たちのセット内の各チェーンを延長するつもりならば、それはgozinta、そして、私たちの結果セットに拡張されたチェーンを追加します。

    foreach ($r as $c) {
        end($c) < $i ? 0 : $R[] = $c;
    }

到達しなかった中間チェーンを除外します $i

    return $R;
}

定型文の10文字:(


-1

Mathematica

f[1] = {{1}};
f[n_] := f[n] = Append[n] /@ Apply[Join, Map[f, Most@Divisors@n]]

追加の呼び出しのために回答がキャッシュされます。


1
サイトへようこそ!これはコードゴルフなので、バイトカウントを含め、さらに余分な空白をすべて削除する必要があります。
小麦ウィザード
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.