合同の公式


10

中国剰余定理は、剰余演算に威力を発揮することができます。

たとえば、次の一連の合同関係について考えてみます。

合同のセット

このような合同関係のセットの場合、すべての基数(3, 5, 7この例では)は互いに素であり、とのn間に13*5*7 = 105この例では)基数の積の間に唯一の整数があり、関係を満たします。 。

この例では、数値はであり14、次の式で生成されます。

式

ここで、2, 4, and 0上記の例で示されています。

70, 21, 15は式の係数であり、基底に依存し3, 5, 7ます。

70, 21, 15一連の基底の式の係数(この例では)を計算するには、次の手順を使用します。

a一連の基数の各数値について:

  1. として示される他のすべての基底の積を求めますP
  2. で割ったときにP余りが残る最初の倍数を見つけます。これはの係数です。1aa

たとえば、base 3に対応する係数を計算するには、他のすべてのbase の積(つまり5*7 = 35)を求め、次に1baseで割ったときに余りを残すその積の最初の倍数を求めます。

この場合には、35の残りの葉2で割ったとき3、しかし35*2 = 70、葉の残りの部分1で割ったときの3ように、70に対応する係数です3。同様3*7 = 21の残りの葉1で割ったとき53*5 = 15の残りの葉1で割ったときに7

一言で言えば

a一連の数値の各数値について:

  1. 他のすべての数値の積を求めますP
  2. で割ったときにP余りが残る最初の倍数を見つけます。これはの係数です。1aa

チャレンジ

  • 課題は、2つ以上のベースのセットの場合、対応する係数のセットを見つけることです。
  • 塩基のセットはペアワイズ素数であることが保証されており、各塩基は1よりも大きいことが保証されています。
  • 入力は、入力[3,4,5]またはスペースで区切られた文字列としての整数のリストですが、入力は"3 4 5"機能します。
  • 出力は、整数のリストか、係数のセットを示すスペースで区切られた文字列のいずれかである必要があります。

テストケース

input             output
[3,5,7]           [70,21,15]
[2,3,5]           [15,10,6]
[3,4,5]           [40,45,36]
[3,4]             [4,9]
[2,3,5,7]         [105,70,126,120]
[40,27,11]        [9801,7480,6480]
[100,27,31]       [61101,49600,56700]
[16,27,25,49,11]  [363825,2371600,2794176,5583600,529200]

Leaky Nunがこの課題の執筆に協力してくれたことに感謝します。いつものように、問題が不明な場合はお知らせください。幸運と良いゴルフを!


入力には常に3つの数値がありますか?
xnor

@xnorいいえ。テストケースを編集しました。
Sherlock9

回答:


5

Haskell、61 55 53バイト

f x=[[p|p<-[0,product x`div`n..],p`mod`n==1]!!0|n<-x]

f入力を受け取り、整数のリストとして出力を提供する関数を定義します。

f x=[                                          |n<-x]  (1)
              product x                                (2)
                       `div`n                          (3)

最初に、入力(1)のすべての整数をループします。次に、すべての整数の積(2)を取り、nで除算して、非n整数の積P(3)のみを得ます。

           [0,               ..]                       (4)
     [p|p<-                     ,p`mod`n==1]           (5)
                                            !!0        (6)

次に、結果(P)をゼロ(4)から始まる範囲のステップ値として使用します。結果を受け取り、[0, P, 2P, 3P, ...]それをmod-n操作の結果が1である値でフィルタリングします。最後に、最初の要素を取り上げます。これは遅延評価のおかげで機能します(6)。

2バイトの@xnorに感謝!


1
haskellへようこそ!私は、あなたが考えるquotことができdiv、かつhead可能!!0
xnor

4

ゼリー11 7 バイト

P:*ÆṪ%P

オンラインでお試しください!またはすべてのテストケースを確認します

バックグラウンド

レッツPと厳密に正であることが互いに素の整数。

当該二段階プロセス-複数の発見Pの葉の残りのことは1で割った-は、次の合同式によって記述することができます。

線形合同式

オイラー・フェルマーの定理、我々は持っています

オイラー・フェルマーの定理

ここで、φオイラーのトーテント関数を示します。この結果から、以下を推論します。

線形合同式の式

課題は、計算するために私たちを必要とするので、最後に、Pxとし、我々はそれを観察します

最終結果の式

ここで、Paはすべての係数の積として計算できます。

使い方

P:*ÆṪ%P  Main link. Argument: A (list of moduli)

P        Yield the product of all moduli.
 :       Divide the product by each modulus in A.
   ÆṪ    Apply Euler's totient function to each modulus.
  *      Raise each quotient to the totient of its denominator.
     %P  Compute the remainder of the powers and the product of all moduli.

2

J、13バイト

*/|5&p:^~*/%]

@Dennisの驚くべき回答に基づいています

使用法

一部のテストケースでは、サフィックスを持つ拡張整数として入力が必要になりますx

   f =: */|5&p:^~*/%]
   f 3 5 7
70 21 15
   f 40x 27 11
9801 7480 6480
   f 16x 27 25 49 11
363825 2371600 2794176 5583600 529200

説明

*/|5&p:^~*/%]  Input: list B
         */    Reduce B using multiplication to get the product of the values
            ]  Identity function, get B
           %   Divide the product by each value in B, call the result M
   5&p:        Apply the totient function to each value in B, call the result P
       ^~      Raise each value in M to the power of its corresponding value in P
*/             The product of the values in B
  |            Compute each power modulo the product and return

ここで試してください。




1

ゼリー、14 13 バイト

P:×"Ḷð%"’¬æ.ḷ

@ デニスのおかげでバイトを節約しました!

チャレンジ仕様で説明されているプロセスを使用します。入力はベースのリストで、出力は係数のリストです。

オンラインで試すか、すべてのテストケースを確認してください

説明

P:×"Ḷð%"’¬æ.ḷ  Input: a list B
P              Get the product of the list
 :             Divide it by each value in the B, call it M
    Ḷ          Get a range from 0 to k for k in B
  ×"           Vectorized multiply, find the multiples of each M
     ð         Start a new dyadic chain. Input: multiples of M and B
      %"       Vectorized modulo, find the remainders of each multiple by B
        ’      Decrement every value
               If the remainder was 1, decrementing would make it 0
         ¬     Logical NOT, zeros become one and everything else becomes 0
            ḷ  Get the multiples of M
          æ.   Find the dot product between the modified remainders and the multiples
               Return

1

JavaScript(ES6)、80バイト

a.map(e=>[...Array(e).keys()].find(i=>p*i/e%e==1)*p/e,p=a.reduce((i,j)=>i*j))

拡張ユークリッドアルゴリズムを試しましたが、98バイトかかります。

a=>a.map(e=>(r(e,p/e)+e)%e*p/e,p=a.reduce((i,j)=>i*j),r=(a,b,o=0,l=1)=>b?r(b,a%b,t,o-l*(a/b|0)):o)

値がすべて素数の場合、ES7は56バイトで実行できます。

a=>a.map(e=>(p/e%e)**(e-2)%e*p/e,p=a.reduce((i,j)=>i*j))

1

Python + SymPy、71バイト

from sympy import*
lambda x:[(prod(x)/n)**totient(n)%prod(x)for n in x]

これは私のゼリーの答えからのアルゴリズムを使用しています。I / OはSymPy番号のリストの形式です。


1

Python 2、87 84バイト

アルゴリズムの単純な実装。ゴルフの提案を歓迎します。

a=input();p=1
for i in a:p*=i
print[p/i*j for i in a for j in range(i)if p/i*j%i==1]

完全なプログラムは3バイトを節約します。
Dennis


0

GAP、51バイト

GAPにはで動機付けの例を計算できる関数がありますChineseRem([2,5,7],[2,4,0])が、それでも係数を取得するのは簡単ではありません。2番目の引数として、n番目の位置に1があり、他の位置に0があるリストを使用して、n番目の係数を取得できます。したがって、これらのリストを作成し、それらすべてに関数を適用する必要があります。

l->List(Basis(Integers^Size(l)),b->ChineseRem(l,b))

0

バッチ、148バイト

@set p=%*
@set/ap=%p: =*%
@for %%e in (%*)do @for /l %%i in (1,1,%%e)do @call:l %%e %%i
@exit/b
:l
@set/an=p/%1*%2,r=n%%%1
@if %r%==1 echo %n%

0

実際には、14バイト

これはDennisのJelly answerのアルゴリズムを使用しています。私のPythonの回答に基づく別の回答が近づいています。ゴルフの提案を歓迎します。オンラインでお試しください!

;π;)♀\;♂▒@♀ⁿ♀%

使い方

                 Implicit input a.
;                Duplicate a.
 π;)             Take product() of a, duplicate and rotate to bottom.
    ♀\           Integer divide the product by each element of a. Call this list b.
      ;♂▒        Take that list, duplicate, and get the totient of each element.
         @♀ⁿ     Swap and take pow(<item in b>, <corresponding totient>)
            ♀%   Modulo each item by the remaining duplicate product on the stack.
                 Implicit return.

22バイトでのPythonの回答に基づく別の回答。ゴルフの提案を歓迎します。オンラインでお試しください!

;π╖`╝╛╜\╛r*"╛@%1="£░`M

使い方

            Implicit input a.
;π╖         Duplicate, take product of a, and save to register 0.
`...`M      Map over a.
  ╝           Save the item, b, in register 1.
  ╛╜\         product(a) // b. Call it P.
  ╛r          Take the range [0...b].
  *           Multiply even item in the range by P. Call this list x.
  "..."£░     Turn a string into a function f.
              Push values of [b] where f returns a truthy value.
    ╛@%         Push b, swap, and push <item in x> % b.
    1=          Does <item> % b == 1?
            Implicit return.
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.