2倍にして再配置することでこの数に到達できますか?


34

Math.SEに関するこの質問に触発されました

以降では1、繰り返し次の二つのいずれかの操作を行うことができます:

  • 数を2倍にします。

    または

  • 先行ゼロがないことを除いて、任意の方法で数字を並べ替えます。

リンクされたMath.SE投稿から例を挙げると1000、次の手順でアクセスできます。

1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 125, 250, 500, 1000

このプロセスでどの数値に到達できますか、最も短い解決策は何ですか?

チャレンジ

正の整数Nを指定すると、可能であればN、上記のプロセスで到達する整数の最短のシーケンスを決定します。最適なソリューションが複数ある場合は、いずれかを出力します。そのようなシーケンスが存在しない場合は、空のリストを出力する必要があります。

シーケンスは、便利で曖昧さのない任意の文字列またはリスト形式にすることができます。

プログラムまたは関数を作成し、STDIN(または最も近い代替)、コマンドライン引数または関数引数を介して入力を取得し、STDOUT(または最も近い代替)、関数の戻り値または関数(out)パラメーターを介して結果を出力できます。

これはコードゴルフなので、最短の回答(バイト単位)が勝ちです。

テストケース

256までのすべての到達可能数のリストを次に示します。最初の列は数値(入力)、2番目の列は最適なステップ数(ソリューションの有効性を確認するために使用できます)、3番目は列は、そこに到達するための最適なシーケンスの1つです。

1       1       {1}
2       2       {1,2}
4       3       {1,2,4}
8       4       {1,2,4,8}
16      5       {1,2,4,8,16}
23      7       {1,2,4,8,16,32,23}
29      10      {1,2,4,8,16,32,23,46,92,29}
32      6       {1,2,4,8,16,32}
46      8       {1,2,4,8,16,32,23,46}
58      11      {1,2,4,8,16,32,23,46,92,29,58}
61      6       {1,2,4,8,16,61}
64      7       {1,2,4,8,16,32,64}
85      12      {1,2,4,8,16,32,23,46,92,29,58,85}
92      9       {1,2,4,8,16,32,23,46,92}
104     15      {1,2,4,8,16,32,64,128,256,512,125,250,205,410,104}
106     14      {1,2,4,8,16,32,64,128,256,265,530,305,610,106}
107     14      {1,2,4,8,16,32,23,46,92,29,58,85,170,107}
109     18      {1,2,4,8,16,32,23,46,92,184,368,386,772,277,554,455,910,109}
116     12      {1,2,4,8,16,32,23,46,92,29,58,116}
122     7       {1,2,4,8,16,61,122}
124     16      {1,2,4,8,16,32,23,46,92,29,58,85,170,107,214,124}
125     11      {1,2,4,8,16,32,64,128,256,512,125}
128     8       {1,2,4,8,16,32,64,128}
136     18      {1,2,4,8,16,32,23,46,92,184,148,296,592,259,518,158,316,136}
140     15      {1,2,4,8,16,32,64,128,256,512,125,250,205,410,140}
142     16      {1,2,4,8,16,32,23,46,92,29,58,85,170,107,214,142}
145     17      {1,2,4,8,16,32,23,46,92,184,368,736,376,752,257,514,145}
146     18      {1,2,4,8,16,32,64,128,256,512,125,250,205,410,104,208,416,146}
148     11      {1,2,4,8,16,32,23,46,92,184,148}
149     16      {1,2,4,8,16,32,64,128,182,364,728,287,574,457,914,149}
152     11      {1,2,4,8,16,32,64,128,256,512,152}
154     17      {1,2,4,8,16,32,23,46,92,184,368,736,376,752,257,514,154}
158     16      {1,2,4,8,16,32,23,46,92,184,148,296,592,259,518,158}
160     14      {1,2,4,8,16,32,64,128,256,265,530,305,610,160}
161     13      {1,2,4,8,16,32,23,46,92,29,58,116,161}
163     18      {1,2,4,8,16,32,23,46,92,184,148,296,592,259,518,158,316,163}
164     18      {1,2,4,8,16,32,64,128,256,512,125,250,205,410,104,208,416,164}
166     20      {1,2,4,8,16,32,23,46,92,184,368,736,376,752,257,514,154,308,616,166}
167     17      {1,2,4,8,16,32,23,46,92,184,148,296,269,538,358,716,167}
169     23      {1,2,4,8,16,32,64,128,256,512,125,250,205,410,104,208,416,461,922,229,458,916,169}
170     13      {1,2,4,8,16,32,23,46,92,29,58,85,170}
176     17      {1,2,4,8,16,32,23,46,92,184,148,296,269,538,358,716,176}
182     9       {1,2,4,8,16,32,64,128,182}
184     10      {1,2,4,8,16,32,23,46,92,184}
185     16      {1,2,4,8,16,32,23,46,92,184,148,296,592,259,518,185}
188     23      {1,2,4,8,16,32,23,46,92,184,148,296,592,259,518,185,370,740,470,940,409,818,188}
190     18      {1,2,4,8,16,32,23,46,92,184,368,386,772,277,554,455,910,190}
194     16      {1,2,4,8,16,32,64,128,182,364,728,287,574,457,914,194}
196     23      {1,2,4,8,16,32,64,128,256,512,125,250,205,410,104,208,416,461,922,229,458,916,196}
203     16      {1,2,4,8,16,32,64,128,256,265,530,305,610,160,320,203}
205     13      {1,2,4,8,16,32,64,128,256,512,125,250,205}
208     16      {1,2,4,8,16,32,64,128,256,512,125,250,205,410,104,208}
209     19      {1,2,4,8,16,32,23,46,92,184,368,736,376,752,257,514,145,290,209}
212     8       {1,2,4,8,16,61,122,212}
214     15      {1,2,4,8,16,32,23,46,92,29,58,85,170,107,214}
215     11      {1,2,4,8,16,32,64,128,256,512,215}
218     9       {1,2,4,8,16,32,64,128,218}
221     8       {1,2,4,8,16,61,122,221}
223     14      {1,2,4,8,16,32,23,46,92,29,58,116,232,223}
227     20      {1,2,4,8,16,32,23,46,92,184,148,296,592,259,518,158,316,361,722,227}
229     20      {1,2,4,8,16,32,64,128,256,512,125,250,205,410,104,208,416,461,922,229}
230     16      {1,2,4,8,16,32,64,128,256,265,530,305,610,160,320,230}
232     13      {1,2,4,8,16,32,23,46,92,29,58,116,232}
233     22      {1,2,4,8,16,32,23,46,92,184,368,736,376,752,257,514,154,308,616,166,332,233}
235     19      {1,2,4,8,16,32,23,46,92,184,148,296,269,538,358,716,176,352,235}
236     19      {1,2,4,8,16,32,23,46,92,184,148,296,592,259,518,158,316,632,236}
238     19      {1,2,4,8,16,32,64,128,256,512,125,250,205,410,104,208,416,832,238}
239     25      {1,2,4,8,16,32,23,46,92,184,368,736,376,752,257,514,154,308,616,166,332,233,466,932,239}
241     16      {1,2,4,8,16,32,23,46,92,29,58,85,170,107,214,241}
244     8       {1,2,4,8,16,61,122,244}
247     21      {1,2,4,8,16,32,23,46,92,184,148,296,592,259,518,158,316,632,362,724,247}
248     17      {1,2,4,8,16,32,23,46,92,29,58,85,170,107,214,124,248}
250     12      {1,2,4,8,16,32,64,128,256,512,125,250}
251     11      {1,2,4,8,16,32,64,128,256,512,251}
253     19      {1,2,4,8,16,32,23,46,92,184,148,296,269,538,358,716,176,352,253}
256     9       {1,2,4,8,16,32,64,128,256}

さらに多くのテストデータが必要な場合は、1,000までの同じテーブルがあります

これらのテーブルに表示されていない数値は、空のリストを生成する必要があります(数値がテーブルの範囲内にある場合)。


実行時間に制限はありますか?
9

2
@Fatalizeいいえ、夢中になります。
マーティンエンダー

しかし、潜在的に無限の実行時間は許容できないと思いますか?理論的に終了する必要がありますか?
15


結果が複数ある場合はどうでしょうか:[1、2、4、8、16、32、64、46、92、29] [1、2、4、8、16、32、23、46、92、 29]
dbramwell

回答:


18

Pyth、43バイト

?}QKhu?Jf}QTGJsm+Ld+yedsMfnhT\0.p`edGQ]]1KY

デモンストレーション。

これは、可能なすべてのダブルまたは再配列シーケンスを生成することから始まります。ただし、実際にそれが終了するのを見たかったので、短絡を追加しました。

解決策が見つかるまで実行されるか、入力に等しい反復回数だけ実行され、その時点でgivesめて戻ります[]


これにより、十分な反復が保証されます。まず、結果の例のおかげで、この多くの反復ですべてのn <= 1000に十分であることがわかります。数値が大きい場合、次の引数が成り立ちます。

まず、プロセスの各ステップで桁数を維持または増加する必要があります。

第二に、最初から最後まで単一の再配置を行う方が迅速だったため、すべてが互いに再配置された3つの数値がすべて最短順序で表示されることはありません。

第三に、3の倍数はすべて到達不能です。これは、2倍も再配置も3の非倍数から3の倍数を生成できないためです。

したがって、指定された数で終わる可能な最長のシーケンスは、入力と同じ桁数以下の数字のセットの数の2倍の合計に等しく、数字は3の倍数になりません。

各桁数に対するそのような桁セットの数:

4 - 474
5 - 1332
6 - 3330

さらに、例から、3桁の数字で終わる最短シーケンスの長さが26を超えないことがわかります。したがって、シーケンスの長さの上限は次のとおりです。

4: 474 * 2 + 26 = 974
5: 974 * 2 + 1332 = 3638
6: 3330 * 2 + 3638 = 10298

いずれの場合も、上限は桁数のある数値よりも低くなります

新しい数字は最後の数字でグループに分けることができるため、数字セットの数は10倍以上増加することはできません。桁。

したがって、上限は、4以上のすべての可能な桁数に対して、その数の桁を持つ任意の数よりも低くなります。これにより、入力に等しい反復回数で常に十分であるという証明が完成します。


入力に等しい反復回数で十分ですか?理論的には、上限は次に大きい10のべき乗ではありません(シーケンスは頻繁に任意に減少する可能性があるため)。
マーティンエンダー

@MartinBüttner良い点。入力が常に十分であるという証拠があるはずだと思いますが、今のところ編集します。
isaacg

@MartinBüttner入力に等しい反復が常に十分に追加されるという証拠。
isaacg

ああ、とてもいい。:)(興味深いことに、100,000まででも26ステップ以上は必要ありません。)
マーティンエンダー

入力より長くないすべてのステップを列挙する方が速いと思いますか?
ジョンドヴォルザーク

7

SWI-Prolog、252バイト

a(N,Z):-findall(X,b(N,[1],X),R),sort(R,[Z|_]);Z=[].
b(N,[A|T],Z):-n(A,C),n(N,M),length(C,L),length(M,O),L=<O,((A=N,reverse([A|T],Z));(A\=N,(B is A*2;permutation(C,D),\+ nth0(0,D,48),n(B,D),\+member(B,[A|T])),b(N,[B,A|T],Z))).
n(A,B):-number_codes(A,B).

例:a(92,Z).出力Z = [1, 2, 4, 8, 16, 32, 64, 46, 92]

時間がかかるため、N> 99で機能することをまだ確認していませんが、機能しない理由はわかりません。


2

ジュリア、306 245 218バイト

まだこれをゴルフに取り組んでいます。完了したら、未使用のバージョンを提供します。

s->(M=s=[s];while 1∉s C=0;for i=1:size(s,1) p=2;for j=permutations(dec(s[i])) j[1]>48&&j[end]%2<1&&(l=int(j);l=l÷p;l∉M&&(M=[M,l];S=[l s[i,:]];C==0?C=S:C=[C;S]));p=1end;end;C==0&&return [];s=C;end;sortrows(s)[1,:])

1

Haskell、246バイト

これが機能するかどうかは完全にはわかりませんが、最初に下に分岐するシーケンス(下にソートされるように)が常に短い場合、たとえば

[1,2,4,8,16,32,64,128,256,512,125,250,500,1000]

より短い

[1,2,4,8,16,32,64,128,256,512,251,502,250,500,1000]

私は1000まで真実であるとテストしました。

import Data.List
h l|mod(e l)2==0=l:h(div(e l)2:l)|0<1=[l]
s l=map((:l).read)(filter((/='0').e)(permutations$show$e l))
e=head
m=map e
n f=m.groupBy(\a b->e a==e b).sort.concatMap f
w l|e(e l)==1=[nub$e l]|m x/=m l=w x|0<1=[[]] where x=n h(n s l)

1

C#655バイト

List<int> C(int i,List<int> x,int a){x.Add(a);if(a==i)return x;List<int> o=null;string s=a.ToString(),m=i.ToString();var res=G(s,s.Length);foreach (var r in res)if (r.First()!='0'){var l=int.Parse(new String(r.ToArray()));if(!x.Contains(l)&&l.ToString().Length<=m.Length){var n=C(i,x.ToList(),l);if(n!=null&&(o==null||o.Count()>n.Count()))o=n;}}if ((a*2).ToString().Length>m.Length)return o;var p = C(i, x.ToList(), a * 2);if (p!=null&&(o==null||o.Count()>p.Count()))o=p;return o;}IEnumerable<IEnumerable<T>> G<T>(IEnumerable<T> l,int i){return i==1?l.Select(t =>new T[]{t}):G(l,i-1).SelectMany(t=>l.Where(e=>!t.Contains(e)),(a,b)=>a.Concat(new T[]{b}));}

(LinqPad)で呼び出します:

var i = 64;
C(i,new List<int>(),1).Dump();

99以上の数値はテストしていません。時間があれば->幸運を祈ります。

編集:ungolfedバージョン:

List<int> C(int i, List<int> x, int toAdd, bool removeLast)
{
    x.Add(toAdd);

    if ( toAdd == i )
    {
        return x;
    }
    else
    {
        List<int> shortest = null;
        if ( toAdd > 9 )
        {
            var res = G(toAdd.ToString(), toAdd.ToString().Length);

            foreach ( var r in res )
            {
                if ( r.First () != '0' )
                {
                    var resi = int.Parse(new String(r.ToArray()));

                    if ( !x.Contains(resi) && resi.ToString().Length <= i.ToString().Length )
                    {
                        var resPerm = C(i, x.ToList(), resi, false);
                        if ( resPerm != null )
                        {
                            if ( shortest == null || shortest.Count() > resPerm.Count() )
                            {
                                shortest = resPerm;
                            }
                        }
                    }
                }
            }
        }
        if ( (toAdd * 2).ToString().Length > i.ToString().Length )
        {
            return shortest;
        }
        var resDouble = C(i, x.ToList(), toAdd * 2, false);
        if ( resDouble != null )
        {
            if ( shortest == null || shortest.Count() > resDouble.Count() )
            {
                shortest = resDouble;
            }
            return shortest;
        }

        return shortest;
    }
}
IEnumerable<IEnumerable<T>> G<T>(IEnumerable<T> l,int i)
{
    return i==1?l.Select(t => new T[]{t}):G(l,i-1).SelectMany(t=>l.Where(e=>!t.Contains(e)),(a,b)=>a.Concat(new T[]{b}));
}

0

CJam、83

ri:N_1a:Xa:Y;{X,{XI=__se!{c~},:i^\2*|NA*,&X-_YI=f+Y\+:Y;X\+:X;}fI}*X#_){Y=W%}{;L}?p

オンラインで試す

私は長い間これに座っていました、それは非常に短くも速くもありません、そして私はそれを改善するためのエネルギー/モチベーションがあるかどうかわからないので、私はそれを投稿しています。

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