合同数


21

定義:

  • 三角形が考慮される直角三角形内角の一つが正確に90度である場合。
  • 番号が考えられる合理的なことは、すなわち、整数の比で表すことができるならばp/q、両方の場所、pおよびq整数です。
  • 3つの辺すべてが合理的な領域の直角三角形が存在する場合n、数値は合同の数値ですn
  • これはOEIS A003273です。

チャレンジ

これは課題です。入力数が与えられると、合同数であるx場合xは明確で一貫した値を出力し、合同数でxない場合は別個の明確で一貫した値を出力します。出力値は、必ずしも言語で真実/偽である必要はありません。

特別ルール

この挑戦の目的のために、バーチとスウィナートン-ダイアーの予想は真実である仮定することができます。あるいは、Birch and Swinnerton-Dyerの予想を証明できる場合は、1,000,000ドルのミレニアム賞金を請求​​してください。;-)

True合同数などに使用False)。

5 True
6 True
108 False

規則と説明

  • 入力と出力は、任意の便利な方法で指定できます。
  • 結果をSTDOUTに出力するか、関数結果として返すことができます。出力でどの値を取ることができるかを提出してください。
  • 完全なプログラムまたは機能のいずれかが受け入れられます。
  • 標準的な抜け穴は禁止されています。
  • これはので、通常のゴルフルールがすべて適用され、最短のコード(バイト単位)が勝ちます。

3
入力は正の整数ですか?
リン

私の最初のアプローチは、ピタゴラスのトリプルの足の積の半分になるまで入力に任意の平方数を掛けることでしたが、非合同入力で実際に終了するのは少し難しいかもしれないことに気付きました。
無関係な文字列

@ Xi'anわかりましたが、課題は自己完結型でなければなりません。
リン

@Lynnはい、入力は正の整数になります。
AdmBorkBork

回答:


8

R、179 173 142 141 137 135 134バイト

Tunnellの定理に基づいて同じ引数を使用すると、0if nが合同で1ない場合とそうでない場合を返します。(2乗のない整数にのみ適用される条件の制約を見つけるのに長い時間がかかりました。)

function(n){b=(-n:n)^2
for(i in b^!!b)n=n/i^(!n%%i)
P=1+n%%2
o=outer
!sum(!o(y<-o(8/P*b,2*b,"+")/P-n,z<-16/P*b,"+"),-2*!o(y,4*z,"+"))}

オンラインで試す

ArnaudGiuseppeによってもたらされた改善(最終コードはほとんどGuiseppeのものです!)、Robinのおかげで-3

構文解析:

for(i in b[b>0])n=n/i^(!n%%i) #eliminates all square divisors of n
P=2^(n%%2)                    #n odd (2) or even (1)
o=outer                       #saves 3 bytes 
o(8/P*b,2*b,"+")/P-n          #all sums of (8/P)x^2+(2/P)*y^2-n
o(...,16/P*b,"+")             #all sums of above and (16/P)*z^2
o(...,4*z,"+"))               #all sums of above and (64/P)*z^2
!o(...,4*z,"+"))              #all sums of above equal to zero
!sum(!...,2*!...)             #are zeroes twice one another (Tunnell)

Tunnellの定理は、そのn個を述べ合同である場合にのみに整数解の数2x²+y²+8z²= nは二倍の2x²に整数解の数として+y²+32z²= nのnが奇数と番号であれば8x²+y²+16z²= nの整数解の数は、nが偶数の場合、8x²+y²+64z²= nの整数解の数の2倍です。


1
PPCGへようこそ!目標は、コードをできるだけ短くすることです。おそらく、ゴルフのためのこれらのヒントまたはこれらのR固有のヒントを見るかもしれません。
ジュゼッペ

1
空白がたくさんあります。また、Try It Onlineへのリンクを含めることをお勧めします。コードの検証を支援するために:-)
ジュゼッペ

1
必要に応じて、Rゴルファーのチャットでも気軽に連絡してください。を使用して通知できます@[username]... Robin Ryderによってコードゴルフに引き込まれたと思いますか?
ジュゼッペ

1
142バイト -匿名の関数は完全に素晴らしいです、そして私は説明してうれしい他のいくつかのゴルフを作りました
ジュゼッペ

1
いいね!使用する理由はあります-n:nか?トンネルの定理は読んでいませんでしたがn:0、-1バイトでも同じように機能するようです...また、TIOの上部にある[リンク]ボタンを押すと、いい感じになります。 PPCGにコピーアンドペーストするための形式:-)編集:なるほど、n:0動作しない場合があります。
ジュゼッペ

3

錆-282バイト

fn is(mut n:i64)->bool{let(mut v,p)=(vec![0;4],n as usize%2);while let Some(l)=(2..n).filter(|i|n%(i*i)==0).nth(0){n/=l*l;}for x in -n..=n{for y in -n..=n{for z in -n..=n{for i in 0..2{if n-6*x*x*(n+1)%2==2*x*x+(2-n%2)*(y*y+(24*i as i64+8)*z*z){v[2*p+i]+=1};}}}}v[2*p]==2*v[2*p+1]}
  • Jerrold B. Tunnellの定理を使用してくださいこれは実際には理解できませんが、とにかくうまくいくようです。
  • Tunnellの定理は平方なしのみについて説明されているので、nをそのすべての平方因子で除算して「平方なし」にします。
    • すべての合同数に正方形を掛けると、より大きな合同数が作成され、その逆も同じであるため、これが機能する可能性があると思います。したがって、小さい数をテストすることで、大きい数(この場合はn)を検証できます。(すべての削除された正方形は、1つの大きな正方形を作るために一緒に乗算することができます)。
  • if n is odd, test if n = 2x2+y2+32z2 and/or 2x2+y2+8z2
    if n is even, test if n = 8x2+2y2+64z2 and/or 8x2+2y2+16z2
    • コード自体では、4つの方程式は、偶数/奇数のモジュロを使用して、ループ内で1つに平滑化されています。
  • どの方程式がnに一致するかを集計する
  • ループ後、集計の比率をテストします(Tunnel1ごと)

参照:

偶数/奇数を修正、 @ Level River St に感謝


1
まあ、私はこの作業を私が唯一間違っていたC ++の答えを見てしまった時に...
明るいドン

Level River Stに感謝
明るい

3

C ++(gcc)251 234バイト

@arnauldに、私の愚かな誤植を指摘してくれてありがとう。

@ceilingcatのおかげで-17バイト。

#import<cmath>
int a(int n){int s=sqrt(n),c,x=-s,y,z,i=1,X;for(;++i<n;)for(;n%(i*i)<1;n/=i*i);for(;x++<s;)for(y=-s;y++<s;)for(z=-s;z++<s;c+=n&1?2*(n==X+24*z*z)-(n==X):2*(n==4*x*x+2*X+48*z*z)-(n/2==2*x*x+X))X=2*x*x+y*y+8*z*z;return!c;}

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

n一致する場合は1 、そうでない場合は0を返します。

バーチとスウィナートン-ダイアーの推測が真実であると仮定できることを考えると、テストとしてトンネルの定理を使用しました。定義された4つの数値はxの2乗を使用するため、正のセット(x、y、z)はそれぞれが負の場合により多くのセットを意味するため、技術的にはゼロ以外のx、y、およびzのみをテストする必要があることに注意してくださいy、およびzの計算。さらに、2つの数値AとB、またはCとD の比率のみが望ましいため、これらの他のセットについて心配する必要さえありません。したがって、AまたはCのすべての解に対して2を加算し、BまたはDのすべての解に対して1を減算し、0で終了するかどうかを確認するだけです。また、入力は平方なしの整数に削減されます。q 一致数 s2q また、合同です(アルゴリズムは、正方形を含むいくつかの数値で中断するようです。


1
@アーナウルド:ああ、それは私の側のタイプミスでした。一定。
ニールA.

1

JavaScript(ES7)、165バイト

@NeilA。の答えと同じように、これはTunnellの定理に基づいているため、BirchとSwinnerton-Dyerの推測が正しいと仮定しています。

ブール値を返します。

n=>(r=(g=i=>i<n?g(i+!(n%i**2?0:n/=i*i)):n**.5|0)(s=2),g=(C,k=r)=>k+r&&g(C,k-1,C(k*k)))(x=>g(y=>g(z=>s+=2*(n==(X=(n&1?2:8)*x+(o=2-n%2)*y)+o*32*z)-(n==X+o*8*z))))|s==2

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

どうやって?

最初に入力を変換します n 正方形のない対応物に n、計算 r=n そして初期化する s2

r = (                // we will eventually save isqrt(n) into r
  g = i =>           // g = recursive function taking an integer i
    i < n ?          //   if i is less than n:
      g(i + !(       //     do a recursive call with either i or i + 1
        n % i**2 ?   //     if n is not divisible by i²:
          0          //       yield 0 and therefore increment i
        :            //     else:
          n /= i * i //       divide n by i² and leave i unchanged
      ))             //     end of recursive call
    :                //   else:
      n ** .5 | 0    //     stop recursion and return isqrt(n)
  )(s = 2)           // initial call to g with i = s = 2

次に、ヘルパー関数を定義します g コールバック関数を呼び出します Ck2 ために r<kr

  g = (C, k = r) =>  // C = callback function, k = counter initialized to r
    k + r &&         //   if k is not equal to -r:
    g(               //     do a recursive call:
      C,             //       pass the callback function unchanged
      k - 1,         //       decrement k
      C(k * k)       //       invoke the callback function with k²
    )                //     end of recursive call

最後に、ネストされた3つの呼び出しを使用して g すべてのトリプレットを歩く バツyz[r+1r]3 そして更新 s かどうかをテストする 2An=Bn もし n 奇数または 2Cn=Dn if n is even, with:

An=#{(x,y,z)[r+1,r]3n=2x2+y2+32z2}Bn=#{(x,y,z)[r+1,r]3n=2x2+y2+8z2}Cn=#{(x,y,z)[r+1,r]3n=8x2+2y2+64z2}Dn=#{(x,y,z)[r+1,r]3n=8x2+2y2+16z2}

g(x =>                            // for each x:      \    NB:
  g(y =>                          //   for each y:     >-- all these values are
    g(z =>                        //     for each z:  /    already squared by g
      s +=                        //       add to s:
        2 * (                     //         +2 if:
          n == (                  //           n is equal to either
            X =                   //           An if n is odd (o = 1)
            (n & 1 ? 2 : 8) * x + //           or Cn if n is even (o = 2)
            (o = 2 - n % 2) * y   //
          ) + o * 32 * z          //
        ) - (                     //         -1 if:
          n == X + o * 8 * z      //           n is equal to either
        )                         //           Bn if n is odd
    )                             //           or Dn if n is even
  )                               //
)                                 // if s in unchanged, then n is (assumed to be) congruent

1

Ruby, 126 bytes

->n{[8,32].product(*[(-n..-t=1).map{|i|i*=i;n%i<1&&n/=i;i}*2+[0]]*3).map{|j|d=2-n%2
k,x,y,z=j
2*d*x+y+k*z==n/d&&t+=k-16}
t==1}

Try it online!

found a place to initialize t=1 and expanded the list of squares into a triplet instead of using q to make additional copies.

Ruby, 129 bytes

->n{t=0
[8,32].product(q=(-n..-1).map{|i|i*=i;n%i<1&&n/=i;i}*2+[0],q,q).map{|j|d=2-n%2
k,x,y,z=j
2*d*x+y+k*z==n/d&&t+=k-16}
t==0}

Try it online!

Uses Tunnell's theorem like the other answers. I use a single equation as follows.

2*d*x^2 + y^2 + k*z^2 == n/d  where d=2 for even n and d=1 for odd n

We check the cases k=8 and k=32 and check if there are twice as many solutions for k=8 than k=32. This is done by adding k-16 to t every time we find a solution. This is either +16 in the case k=32 or -8 in the case k=8. Overall the number is congruent if t is the same as its initial value at the end of the function.

It is necessary to find all solutions to the test equation. I see many answers testing between +/-sqrt n. It is perfectly OK to test also outside these limits if it makes code shorter, but no solutions will be found because the left side of the equation will exceed n. The thing I missed in the beginning is that negative and positive x,y,z are considered separately. Thus -3,0,3 yields three squares 9,0,9 and all solutions must be counted separately (0 must be counted once and 9 must be counted twice.)

Ungolfed code

->n{t=0                              #counter for solutions

  q=(-n..-1).map{|i|i*=i;n%i<1&&n/=i #make n square free by dividing by -n^2 to -1^2 as necessary 
  i}*2+[0]                           #return an array of squares, duplicate for 1^2 to n^2, and add the case 0 

  [8,32].product(q,q,q).map{|j|      #make a cartesian product of all possible values for k,x,y,z and iterate
    d=2-n%2                          #d=1 for odd n, 2 for even n
    k,x,y,z=j                        #unpack j. k=8,32. x,y,z are the squared values from q.
    2*d*x+y+k*z==n/d&&t+=k-16}       #test if the current values of k,x,y,z are a valid solution. If so, adjust t by k-16 as explained above.
t==0}                                #return true if t is the same as its initial value. otherwise false.

about positive and negative solutions, same here, I wasted quite a while missing this point!
Xi'an
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.