最大数と最小数を作る


13

Puzzlingに関するこの投稿に触発されました。そのパズルのネタバレは以下にあります。

入力として3つの正の整数が与えられた場合(x, y, z)、包括的範囲を構築し、その範囲[x, y]を連結してから、z不必要に連続した数字を削除して、可能な最大および最小の正の整数を生成します。先行ゼロは許可されません(つまり、数字はで始まる必要があります[1-9])。これらの2つの数値をいずれかの順序で出力します。

Puzzling投稿の例では、入力に対して(1, 100, 100)、可能な最大数は99999785960616263646566676869707172737475767778798081828384858687888990919293949596979899100
あり、最小数はで10000012340616263646566676869707172737475767778798081828384858687888990919293949596979899100、そこに投稿されたjafeの回答
からの以下のロジックに従います。

  • 数値の長さに影響を与えることはできません(固定の桁数があります)。したがって、値を最大化するには、最初の最大桁、次に2番目の桁などを取ります。
  • 84の最初の9以外を削除します(16桁を削除します): 999995051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  • 次の17桁内の最大数は7であるため、ここから、答えの次の桁は最大で7になります(16桁を超える数字は削除できません)。したがって、15個の非7を削除します(削除するために残っている1桁):999997585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  • ここから、次の数字は最大8になるため、中央から8以外を1つ削除します。 99999785960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  • 同様のロジックですが、最小数では逆になります(つまり、先行1sではなく先行sが必要です9)。

以下に小さな例を示します(1, 10, 5)

範囲を構築し、可能な最大数を残して削除できる桁を12345678910決定し5ます。明らかに、これは出力の長さに影響を与えることができないため、先行桁を最大化することを意味します。したがって、削除する場合12345、が残り、678910これが作成できる最大のサイズになります。代わりに中央から数字を抜き取り、123410可能な限り小さいままにしておくことができるため、最小にするのは少し複雑です。

にとって (20, 25, 11)、これはかなりのように、退屈さ51

最後に、先行ゼロを試みる回答を除外するに(9, 11, 3)は、91011たターン利回り9110最大値と最小など。

I / Oとルール

  • 簡単/短い場合は、2つのプログラム/関数をコーディングできます。1つは最大のもの、もう1つは最小のものです。この場合、スコアは両方の部分の合計になります。
  • 入力と出力は任意の便利な方法で与えることができます
  • ただし、入力は言語のネイティブの数値型に適合すると想定できますが、、連結数や出力のいずれもがそうすると仮定することができます。
  • 完全なプログラムまたは機能のいずれかが受け入れられます。関数の場合、出力する代わりに出力を返すことができます。
  • 標準抜け穴は禁止されています。
  • これはので、通常のゴルフルールがすべて適用され、最短のコード(バイト単位)が勝ちます。

数字のリストは出力として受け入れられますか?
ロッド

先行ゼロを持つものを評価するときに偽の最小値を生成するテストケースは価値があるかもしれません-私はそう9, 11, 3するだろうと思います。
ジョナサンアラン

@Rodはい、数字のリストは出力に適しています。
AdmBorkBork

@Rod私はあなたが何を言っているのかわからない、私は明らかに「出力」を上に入力した。;-)
AdmBorkBork

@JonathanAllan良い電話。追加。
AdmBorkBork

回答:


5

Haskell、162バイト

l=length
((m,f)%n)s|n>=l s=[]|n>0,(p,c:r)<-span(/=m(f$take(n+1)s))s=c:((m,id)%(n-l p)$r)|1>0=s
(x#y)z=[p%z$show=<<[x..y]|p<-[(maximum,id),(minimum,filter(>'0'))]]

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

jafeによって記述されたアルゴリズムを使用します。効率の悪いメソッドを使用するには短くなるかもしれませんが、これは書くのがもっと楽しかったです:)

%操作は、4つの引数(実際には3が、何を)取る:m「最適」リストからメンバー(どちらかを選択する関数であるmaximumminimum、我々が望むものに依存します)。fこれは「フィルター」機能です。nドロップする残りの桁数。そしてs文字列。最初に、nが文字列の残りの桁数と等しいかどうかを確認し(>=安全のために使用しました)、sそうであれば残りを削除します。それ以外の場合は、まだ数字(n>0)をドロップする必要があるかどうかをチェックしspan、文字列を3つの部分に分割するために使用します。pドロップする数字c、最適な到達可能な数字、r残りの文字列。これを行うには、最適な数字と等しいかどうかをチェックする述語をspanに渡します。その数字を見つけるため最初のを取得これは、最初の反復にのみ関連する場合にです。その後、フィルターは不要になります。n+1文字列の数字をフィルタリングし、「chooser」関数に渡します。ここで、最適な桁を生成して再帰し、の長さp(ドロップされた桁数)を減算しnます。フィルタリング関数を再帰呼び出しに渡さず、代わりにに置き換えていることに注意してくださいid。これは、フィルタが先頭の0を選択しないようにするためだけにあるためですminimum

%本当にのためだけのヘルパー関数で#取って、私たちの「本当の」関数であるxyz。リストの内包表記は、ちょっとした繰り返しを避けるために使用します。関数タプルを繰り返し処理し、連結された文字列%とともにそれらを渡しzます。この文字列は(=<<)、このコンテキストではのように機能するマジックモナド演算子を使用して作成されますconcatMap


3

ゼリー、17バイト

r/VDœcL_¥¥ḷ/ƇVṢ.ị

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

すべての可能性を計算し、最大値と最小値を保持します。

左引数:x,y範囲を構築します。正しい引数:z削除する数字。

r/VDœcL_¥¥ḷ/ƇVṢ.ị
r/                 Inclusive range from x to y
  V                Concatenate the digits together
   D               Get the resulting digits
         ¥         Dyad:
        ¥            Dyad:
      L                Length of the list of digits in the concatenated number.
       _               Subtract the number of digits to be removed.
    œc               Combinations without replacement. (remove z digits)
            Ƈ      Keep lists of digits that:
          ḷ/       have a positive first element (no leading zeros).
             V     Combine digits into integers. (vectorizes to ldepth 1)
              Ṣ    Sort the numbers
               .ị  Indexes at value 0.5 which yields the first and last elements.

2

Python 2、143バイト

import itertools
s,e,r=input()
l=''.join(map(str,range(s,e+1)))
L=[i for i in itertools.combinations(l,len(l)-r)if'0'<i[0]]
print min(L),max(L)

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

これは、ターゲットサイズのすべての組み合わせを計算し(要素の順序は保持されます)、それから最小/最大数を取得することで機能します


ああ...私はそれが笑うと思う。私はそれを実際に決定論的に計算するプログラムを作るために本当に一生懸命努力していた。
ドンサウザンド

@RushabhMehtaブルートフォースの計算はまだ決定論的で、遅いだけです。
ディルナン

2

木炭、56バイトまたは21 + 46 35 = 67 56バイト

≔⪫…·NNωθFN≔⌈EθΦθ⁻λνθθ

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

≔⪫…·NNωθ

とを入力xyて、包括的な範囲を作成し、数字を文字列に結合します。

FN

削除する数字ごとに1回ループします。

≔⌈EθΦθ⁻λνθ

現在の文字列から可能な各文字を削除して形成された文字列のリストを作成し、最大値を取得します。

θ

結果を印刷します。

≔⪫…·NNωθF⊕N⊞υωΦθ∧⁼ι⌊Φ✂θκLυ¹∨κIλ⊞Oυω

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

≔⪫…·NNωθ

とを入力xyて、包括的な範囲を作成し、数字を文字列に結合します。

F⊕N⊞υω

入力zしてインクリメントします。次に、その長さのリストを作成しますz。次のフィルター内でインクリメントできるようにする必要がありますが、変数のみをインクリメントできるのはコマンドのみです。PushOperatorリストの長さを増加させる抜け穴があります。

 θ                      String of digits
Φ                       Filter over characters
         κ              Current index
          Lυ            Length of list i.e. current `z` value
            ¹           Literal 1
       ✂θ               Slice string of digits
      Φ                 Filter over characters
              κ         Outer index
               Iλ       Cast inner character to number
             ∨          Logical OR
     ⌊                  Minimum
   ⁼ι                   Equals the outer character
  ∧              ⊞Oυω   And also push to list i.e. increment `z`
                        Implicitly print

スライス可能な領域に下位の文字がないことを確認して、必要な文字をフィルタリングします。リージョンは最初のz+1文字で始まります(最初の文字をスライスすることができるためz必要に応じため)、保持されている各文字の終点が増加します。最初の文字にゼロを選択しないように注意します。

可能な最大数を計算するために使用される場合、高速アルゴリズムは30バイトです。

≔⪫…·NNωθF⊕N⊞υωΦθ∧⁼ι⌈✂θκLυ¹⊞Oυω

オンラインでお試しください!リンクは、コードの詳細バージョンです。編集:私はそれ以来、両方の結果を生成する2番目の56バイトのソリューションに上記の2つを組み合わせることができました:

≔⪫…·NNωθF⊕N⊞υω≔⮌υη⟦Φθ∧⁼ι⌈✂θκLυ¹⊞OυωΦθ∧⁼ι⌊Φ✂θκLη¹∨κIλ⊞Oηω

オンラインでお試しください!リンクは、コードの詳細バージョンです。説明:

≔⪫…·NNωθ

初期文字列を生成します。

F⊕N⊞υω

表すz+1リストの長さとして。

≔⮌υη

リストを逆にしてクローンを作成し、結果を保存します。

2つの結果を別々の行に印刷します。(これを行う別の方法は、結果をリテラル\r文字で区切ることです。)

Φθ∧⁼ι⌈✂θκLυ¹⊞Oυω

可能な最大数を生成します。

Φθ∧⁼ι⌊Φ✂θκLη¹∨κIλ⊞Oηω

を追跡するために、複製されたリストを使用して可能な限り最小の数を生成しzます。



1

05AB1E、16 バイト

ŸSDg³-.Æʒ¬Ā}{Ć`‚

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

完全なプログラム、y、x、zの順序で入力を読み取ります。文字の2つのリストのリストを出力します。

説明

ŸSDg³-.Æʒ¬Ā}{Ć`‚    Full program. Inputs: y, x, z.
Ÿ                   Inclusive binary range from x to y. Push [x ... y].
 S                  Dump the digits separately in a list.
  Dg                Duplicate, and use the second copy to get its length.
    ³-              Subtract z from the length.
      .Æ            Retrieve all combinations of length - z elements from the digits.
        ʒ  }        Keep only those that...
         ¬Ā         Don't start with a 0 (head, then Python-style boolean).
            {       Sort the remaining elements.
             Ć      Enclose. Pushes list + list[0] (appends its tail to itself)
              `     Dump all elements separately on the stack.
               ,    Pair, to get the last two, min and max (after enclosing)

ああ、Ć`‚かなり賢い、いい答えです!
ケビンクルイッセン

0

Matlab、95バイト

function[m]=f(s,e,c),a=sprintf('%d',s:e);x=str2num(combnk(a,length(a)-c));m=[min(x),max(x)];end

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

最小および最大の1x2行列を返します。

使い方

% Full code
function[m]=f(s,e,c),a=sprintf('%d',s:e);x=str2num(combnk(a,length(a)-c));m=[min(x),max(x)];end

% The function
function[m]=f(s,e,c),                                                                       end

                     % Creates the range in a single string
                     a=sprintf('%d',s:e);

                                                   % Gets all the combinations
                                                   combnk(a,length(a)-c)

                                         % Converts the string combinations to integers
                                         x=str2num(                     );

                                                                          % Finds min and max
                                                                          m=[min(x),max(x)];
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.