整数のqvolume


31

すべての負でない整数は4つの2乗整数の合計として書き換えられることは古くからの知識です。たとえば、数値1は02+02+02+12として表現できます。または、一般に、負でない整数n、整数a,b,c,dように

n=a2+b2+c2+d2

ジョセフ=ルイ・ラグランジュはこれを1700年代に証明したので、しばしばラグランジュの定理と呼ばれます。

これは時々四元に関連して説明されている-によって発見数の種類ウィリアム・ハミルトンとして表さ1800年代に、

w+xi+yj+zk
w,x,y,zの実数であり、およびi,jおよびkは、可換的に乗算しない別個の虚数単位です。具体的には、四元数w 2 + x 2 + y 2 + zの各成分の2乗に関連して説明します。
w2+x2+y2+z2
この量は、ノルム、二乗ノルム、または四分とも呼ばれます。ラグランジュの定理のいくつかの現代の証明では、四元数を使用しています。

ルドルフ・リプシッツは、リプシッツ四元数と呼ばれる整数成分のみを持つ四元数を研究しました。四分円を使用すると、すべてのリプシッツ四元数が整数の友人を持つと考えることができると想像できます。たとえば、クォータニオン0+0i+0j+1kは、整数1=02+02+02+12関連付けられていると考えることができます。また、逆方向に進むと、すべての整数はリプシッツ四元数に友人がいると考えることができます。

しかし、ラグランジュの定理には興味深い詳細があります。合計は一意ではありません。各整数には、合計して作成できる4つの正方形のいくつかの異なるセットがある場合があります。たとえば、数値1は、非負の整数を使用して4つの方法で表現できます(このチャレンジでは非負のみを考慮してください):

1=02+02+02+12
1=02+02+12+02
1=02+12+02+02
1=12+02+02+02

被加数は常に0または1の2乗ですが、式の異なる位置に配置できます。

この課題では、重複を排除するために被加数を最低から最高に「ソート」して、この演習では1が4つの正方形の合計として表される1つの方法しかないと考えられるようにします。

1=02+02+02+12

もう1つの例は、4つの方法で表現できる42番です(ここでも、非負のa、b、c、dのみを考慮し、重複するコンポーネント配置を排除します)

42=02+12+42+52
42=12+12+22+62
42=12+32+42+42
42=22+22+32+52

整数を特定の四元数に関連付けられていると表現するこれらの異なる方法のそれぞれを想像するとどうなりますか?次に、42という数字がこれらの4つの四元数に関連付けられていると言えます。

0+1i+4j+5k
1+1i+2j+6k
1+3i+4j+4k
2+2i+3j+5k

ijkが3次元ユークリッド空間のベクトルであるため、クォータニオンの標準的なコンピューターグラフィックスの解釈を想像すると、クォータニオンのxyz成分は3次元のデカルト座標になります。整数は、この思考プロセスを通じて、空間内の3次元座標のセットに関連付けることができます。たとえば、番号42は、次の4つの(x,y,z)座標に関連付けられています:

(1,4,5),(1,2,6),(3,4,4),(2,3,5)

これは、点群、または空間内の点のセットと考えることができます。さて、空間内の有限点のセットに関する興味深い点の1つは、周囲に最小限の境界ボックスを常に描画できることです。このボックスは、すべてのポイントを収めるのに十分な大きさを持ちます。ボックスがx,y,z軸で整列された通常のボックスであると想像する場合、それは軸整列境界ボックスと呼ばれます。境界ボックスには、幅、長さ、高さを決定し、それらを掛け合わせることで計算可能なボリュームもあります。

次に、四元数によって形成されるポイントの境界ボックスのボリュームを想像できます。整数1には、この演習の基準を使用して、象限が0+0i+0j+1kである1つのクォータニオンがあります。これは非常に単純なポイントクラウドであり、1つのポイントしか持っていないため、バウンディングボックスのボリュームは0です。ボックスの最小点である(1,2,4)最大である(3,4,6) その結果、幅、長さ、高さが2、2、2になり、ボリュームが8になります。

整数ためものとするn、qvolumeはquadranceを有する四元により形成された全ての3D点の軸平行境界ボックスの容積が等しいn、ここで四元数の成分w+xi+yj+zkは非負で、w<=x<=y<=zです。

単一の非負整数n与えられると、nのqvolume を出力するプログラムまたは関数を作成します。

例:

input -> output
0 -> 0
1 -> 0
31 -> 4
32 -> 0
42 -> 8
137 -> 96
1729 -> 10032

これはコードゴルフで、最小バイト数が勝ちます。


what do i need to add? i meant to indicate that smallest number of bytes would win
don bright

3
You forgot the code-golf tag, I helped you add it
Embodiment of Ignorance

1
This is a nice challenge but it would be even better IMHO if it was a bit less verbose. Also, beware of irrelevant links (I'm not saying that all your links are irrelevant, but only a few of them really bring meaningful information for the challenge, while the other ones are just distracting).
Arnauld

1
Yes, but why take only i, j, k as 3D space but not 4D space?
tsh

1
@tsh。クォータニオンは必ずしも4次元ユークリッド空間を表すとは限らないためです。ハミルトンは、3次元空間を操作する方法を探しているときにそれらを発見しました。4Dバージョンを実行することは可能ですが、質問をしたときに3D空間での使用を熟考していました
明るく

回答:


13

Wolfram言語(Mathematica)67 58バイト

Volume@BoundingRegion[Rest/@PowersRepresentations[#,4,2]]&

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

                         ...&   Pure function:
PowersRepresentations[#,4,2]    Get the sorted reprs. of # as sums of 4 2nd powers
Rest/@                         Drop the first coordinate of each
BoundingRegion[...]            Find the bounding region, a Cuboid[] or Point[].
                               By default Mathematica finds an axis-aligned cuboid.
Volume                         Find volume; volume of a Point[] is 0.

4
うわー、PowersRepresentationsのようなものが言語に組み込まれるとは思いもしませんでした。私は実際に、整数を4つの2乗として合計するさまざまな方法を示すために挑戦することを考えましたが、そうしなかったことがうれしいです。
明るくしない

4
笑、Mathematicaには画像内のヤギを判別するためのビルトインさえあります。そのため、ビルトインを持っていることは本当に驚きません。xD
ケビンクルーイッセン

8

ゼリー、17 バイト

Żœċ4²S⁼ɗƇ⁸ZḊṢ€I§P

オンラインでお試しください!(かなり遅い-すべてのテストケースに対して十分な速度で、先頭に½

どうやって?

Żœċ4²S⁼ɗƇ⁸ZḊṢ€I§P - Link: non-negative integer, n    e.g. 27
Ż                 - zero-range                            [0,1,2,...,27]
   4              - literal four                          4
 œċ               - combinations with replacement         [[0,0,0,0],[0,0,0,1],...,[0,0,0,27],[0,0,1,1],[0,0,1,2],...,[27,27,27,27]]
        Ƈ         - filter keep those for which:          e.g.: [0,1,1,5]
       ɗ          -   last three links as a dyad:
    ²             -     square (vectorises)                     [0,1,1,25]
     S            -     sum                                     27
      ⁼  ⁸        -     equal to? chain's left argument, n      1
                  -                                       -> [[0,1,1,5],[0,3,3,3],[1,1,3,4]]
          Z       - transpose                             [[0,0,1],[1,3,1],[1,3,3],[5,3,4]]
           Ḋ      - dequeue                               [[1,3,1],[1,3,3],[5,3,4]]
            Ṣ€    - sort each                             [[1,1,3],[1,3,3],[3,4,5]]
              I   - incremental differences (vectorises)  [[ 0,2 ],[ 2,0 ],[ 1,1 ]]
               §  - sum each                              [2,2,2]
                P - product                               8

6

Haskell132 123バイト

z=zipWith
(!)=foldr1.z
h n=[0..n]
f n|p<-[[c,b,a]|a<-h n,b<-h a,c<-h b,d<-h c,a^2+b^2+c^2+d^2==n]=product$z(-)(max!p)$min!p

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

非常に簡単なソリューション。0からnまでのすべての値を反復処理することにより、考えられるすべての解決策をブルートフォースします(過剰な方法ですが、バイトカウントが短くなります)。@Lynnの魔法の(!)演算子を使用できるように、ポイントをリストとして出力します。その演算子は、左側の関数で各ディメンションを折りたたみ、各ディメンションにmax!p沿った最大値で構成され、min!p最小値でも同じことを行うサイズ3のリストを返します。次に、各次元の最小サイズを見つけます(最大値から最小値を引いてz(-))、それらを乗算します。

折りたたみzipマジックで9バイトを削除してくれた@Lynnに感謝します!


1
私は、いくつかのzipWithロジックを優先して転置を放棄することにより、数バイトを削ぎ落としました。123バイト
Lynn

5

スレッジハンマー0.2、12バイト

⡌⢎⣟⡊⢘⣚⡏⡨⠍⠁⡇⠨

Mathematica 11.2およびこのバージョンより前のこのバージョンのSledgehammerで使用してください。GUIを備え、Mathematica式を生成するバージョン0.3で動作するバージョンの編集履歴を参照してください。

これにより、入力がスタックにプッシュされ、一連のコマンドが呼び出されます

{intLiteral[4], intLiteral[2], call["PowersRepresentations", 3], call["Thread", 1], call["Rest", 1], call["Thread", 1], call["BoundingRegion", 1], call["Volume", 1]}

これは、Wolfram言語の答えから派生した次のWolframコードを評価することと同等です:

Volume[BoundingRegion[Thread@Rest@Thread@PowersRepresentations[#, 4, 2]]]&

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


これをテストするには数学が必要ですか?
明るくしない

@don brightはい、リポジトリには指示があります。それは進行中の作業なので、まだあまりユーザーフレンドリーではありません。setup.wlsを実行した後、wolframscriptまたはinteractive_app.wlsでテストできます。
リトシアスト

2
@Downgoatはい。ゴルフライブラリを実装する予定ですが、現在は単純なMathematicaに解凍されます。
リルトシアスト

2
@pipe古いバージョンは動作するはずです(今では考えてみれば、コードは1つの古いバージョンとまったく同じです)が、ダウンロードしてセットアップを再度実行する必要があります。(それ以降の変更は、主にGUIを記述し、機能に大きな変更を加えることなくコードをリファクタリングしました。)この回答は最も短いので、適格性を証明することが重要と思われるため、明日の朝に行います。
リルトシアスト

1
誰でもこれを実行できますか?私はそれがオール 'チェックマークを与える前にそれが動作することを確認したいと思います
明るくしない

4

Python 2、138バイト

q=lambda n,x=0,*t:[t]*(n==0)if t[3:]else q(n-x*x,x,x,*t)+q(n,x+1,*t+(0,)*(x>n))
p=1
for l in zip(*q(input()))[:3]:p*=max(l)-min(l)
print p

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

指定されたノルムで逆ソートされたクォータニオンを再帰的に生成し、最初の3つのインデックスのすべての可能な値の最大値と最小値の間の積を取ります。

itertools それはのような途方もなく長い名前を使用していなかった場合ショットを持っていたかもしれません itertools.combinations_with_replacement

Python 2 2、161バイト

from itertools import*
n=input();p=1
for l in zip(*[t[1:]for t in combinations_with_replacement(range(n+1),4)if sum(x*x for x in t)==n]):p*=max(l)-min(l)
print p

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

これがitertools答えにならない理由です


3

JavaScript(ES6)、 148  143バイト

n=>(r=[[],[],[]]).map(a=>p*=a.length+~a.indexOf(1),(g=(s,k=0,a=[])=>a[3]?s||r.map(r=>r[a.pop()]=p=1):g(s-k*k,k,[...a,++k],k>s||g(s,k,a)))(n))|p

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

コメント済み

配列を初期化します r 3つの空の配列。

r = [ [], [], [] ]

有効な値ごとに バツに設定します 1 の値 バツ+1最初の配列。同上y そして z それぞれ2番目と3番目の配列を使用します。

境界ボックスの寸法は、最初のエントリと最後のエントリ間の距離から推定されます 1 これらの配列で。

ステップ1

埋める r、再帰関数を使用します g

g = (              // g is a recursive function taking:
  s,               // s   = current sum, initially set to the input n
  k = 0,           // k   = next value to be squared
  a = []           // a[] = list of selected values
) =>               //
  a[3] ?           // if we have 4 values in a[]:
    s ||           //   if s is equal to zero (we've found a valid sum of 4 squares):
      r.map(r =>   //     for each array r[] in r[]:
        r[a.pop()] //       pop the last value from a[]
        = p = 1    //       and set the corresponding value in r[] to 1
                   //       (also initialize p to 1 for later use in step 2)
      )            //     end of map()
  :                // else:
    g(             //   do a recursive call:
      s - k * k,   //     subtract k² from s
      k,           //     pass k unchanged
      [...a, ++k], //     increment k and append it to a[]
      k > s ||     //     if k is less than or equal to s:
        g(s, k, a) //       do another recursive call with s and a[] unchanged
    )              //   end of outer recursive call

ステップ2

これで製品を計算できます p 次元の。

r.map(a =>         // for each array a[] in r[]:
  p *=             //   multiply p by:
    a.length +     //     the length of a[]
    ~a.indexOf(1)  //     minus 1, minus the index of the first 1 in a[]
) | p              // end of map(); return p



1

Haskell、108バイト

n%i=sum[maximum[t!!i*b|t<-mapM([0..n]<$f)[0..3],sum(map(^2)t)==n,scanr1 max t==t]|b<-[-1,1]]
f n=n%0*n%1*n%2

オンラインでお試しください!(より大きなテストケースではタイムアウト)

ここには奇妙な最適化がいくつかあります。特定の位置にある要素maximum l-minimum lのリストを計算するにはl、コンテキストで短くなり、2番目の項を否定することで両方を最大値に変換します:maximum l+maximum(map((-1)*))l、または同等sum[maximum$map(b*)l||b<-[-1,1]]です。

3つの次元を掛け合わせると、f n=n%0*n%1*n%2どのような種類のループを使用するよりも、製品を書くだけの方が短くなります。以下n%iは、iindexingで抽出された'th座標値の最小値と最大値の差!!iです。

有効な4つのタプルを生成するために[0..n]、2乗が合計しn、降順になっている4つの数値のリストを取得します。Haskellには組み込みのソートが含まれており、インポートにコストがかかるため、twithの逆ソートをチェックscanr1 max t==tします。Pythonの回答のように、4つのタプルを再帰的に生成するためのさまざまな方法を試しましたが、これらはすべてこの総当たり的な生成およびフィルターの方法よりも長くなりました。

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