1000003で割り切れますか?簡単です。最後の桁に300001を掛けて加算するだけです!


16

Pより大きい素数が与えられた場合10、プログラムまたは関数xは、素数の最後の桁を乗算して元の残りに加算したときに元の素数の倍数を生成する最小絶対値を持つ整数として定義されるその分割可能性ルールを把握する必要がありますプライム。

入力が与えられる31と、最後の数字はで1あり、残りの数字は3です。したがって、プログラムは、の倍数であるxような最小絶対値を持つ整数を見つける必要があります。この場合、機能するため、プログラムまたは関数はを返します。1*x + 331x=-3-3

入力が与えられる1000003と、最後の数字はで3あり、残りの数字は100000です。したがって、プログラムはの倍数であるx=300001ため3*300001+100000 = 1000003、見つけるでしょう1000003

数学的背景

の値はx、可分性テストとして使用できます。数がいる場合Nで割り切れるP、その後、追加xの回の最後の桁Nの残りの部分にはN、複数の得られますPし、場合にのみがあればNで割り切れるP最初の場所でします。

ためにP=11、我々が得るx=-1ために、よく知られた整除ルールに相当する、11数はで割り切れる:11その桁の交互の違いで割り切れます11

ルール

  • 出力は、出力の符号と値の両方を明確にエンコードする任意の形式にすることができます。
  • 入力素数は10〜2 ^ 30の間です。
  • 入力が素数でない場合や範囲内にない場合は処理する必要はありません。
  • あなたは、両方の場合はハンドルに必要としないx-x有効な出力(起こるべきではありません)です。
  • ブルートフォースは許可されますが、より創造的なソリューションが評価されます。
  • これはなので、各言語で最も短いコード勝ちです!ゴルフ言語での回答が他の言語での投稿を妨げないようにしてください。

テストケース

Input   Output
11  -1
13  4
17  -5
19  2
23  7
29  3
31  -3
37  -11
41  -4
43  13
47  -14
53  16
59  6
61  -6
67  -20
71  -7
73  22
79  8
83  25
89  9
97  -29
101 -10
103 31
107 -32
109 11
113 34
127 -38
131 -13
1000003 300001
2000003 600001
2999999 300000
9999991 -999999

3
便利な単純化:入力で割り切れるx絶対値の最小値を探して10*x-1います。
-xnor

誰もがヒント理由を提供することができます(3 / (n % 5 * 2 - 5) * n + 1) / 10し、(n % 5 * 2 - 5^2) * n / 10 + 1このような何かのための最小限の絶対値を見つけることができますか?私の最初の直観は、ユークリッドのアルゴリズムで計算された最大公約数を使用して最小公倍数を計算することでした。
デビッドフォースター

1
@DavidFoerster数値を指定すると、最後の桁を削除し、それを数値xで乗算し、加算しても、で割り切れる数値を取得できnます。その後、新しい数に10を掛けて元の数を引くと、まだで割り切れnます。xnorのコメントは、代数から続きます。次のステップは、x =のx項で式が得られるように式を再配置することです。私たちは、最も小さい絶対にしたいので、そのため私たちは、最小絶対欲しい、これはどちらかのいずれかでなければなりません、、または(に応じて、正確な部門を作ることの最後の桁)。n(k*n+1)/10xk-3-113n
ニール

回答:


14

JavaScript(ES6)、32 25 23バイト

f=
n=>(3/(n%5*2-5)*n+1)/10
<input type=number min=1 oninput=o.textContent=this.value%5*(this.value%2)?f(this.value):``><pre id=o>

3/(n%5*2-5)9/n(mod -10)バランスのとれたモジュロ除算にアクセスできた場合に記述されます。編集:@EgorSkriptunoffのおかげで2バイト保存


3
あなたは置き換えることによって、2つのバイトを保存することができn=>((n%10*2%14-3)*n+1)/10n=>(3/(n%5*2-5)*n+1)/10
Egor Skriptunoff


@KevinCruijssenおそらくJava 8のニアミスポリグロット...ちょっと待って、今あなたの答えが見えます!
ニール

@ニールあなたは正しい。私は通常Javaの回答を投稿するので、あなたの回答を見たとき、私はすでにxnorの移植に取り組んでいました。退屈なポートがあなたを信用しているとしてどちらにでもそれを掲示しました。
ケビンCruijssen

8

Python 2、27バイト

lambda n:(n%5*2-5^2)*n/10+1

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

操作は左から右に行われます (((n%5)*2)-5)^2

算術ブルートフォーサーを使用して、剰余mod 5の負の逆数を範囲に入れて、n%5*2-5^2実行する式を見つけ{1:-1,3:3,2:-3,4:1}[k]ました[-2..2]


この算術ブルートフォーサーはどこかで公開されていますか?
リン

それはそれが見つけた唯一の式ですか、それとも与えられた長さの最初の式を印刷するだけですか?(。3/(n%5*2-5)と同じ長さ(n%5*2-5^2)です)
ニール

@Lynnいいえ、時間があるときにクリーンアップして投稿するかもしれません。
xnor

1
@Neil同等のものとのみが見つかりましたn%5*2-6^3。括弧なしの式の長さだけを調べましたが、3/(n%5*2-5)2文字は長くなりますが、優先順位により外側の括弧を節約します。この長さの式の検索には時間がかかります。このユースケースは、優先度が十分に高い最も外側の操作を介して、特定のコンテキストで使用できる式のみを検索するオプションを提案します。
XNOR



5

パイソン269の 54、53バイト

編集:@ Mr.Xcoderのおかげで-15バイト

編集:再帰を使用して-1バイト

f=lambda a,x=-1:(a%10*x+a/10)%a and f(a,-x-(x>0))or x

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


54バイト。あなたはこれらの変数を持っているなぜあなたは一度だけそれらを使用するとき、私は表示されません
氏Xcoder

うん、私はそれを書いたときに少し急いでいた
ハルヴァード・ハンメル


5

Japt16 9バイト

@xnorによる観察のおかげで、あまりにも多くのバイトを節約

_*AÉ vU}c

オンラインでテストしてください!大きな入力では数秒かかる場合があります。

説明

_  *AÉ  vU}c    Implicit: U = input integer
Z{Z*A-1 vU}c    Ungolfed
Z{        }c    Loop through each integer Z in [0, -1, 1, -2, ...] and yield the first where
  Z*A             Z times 10
     -1           minus 1
        vU        is divisible by the input.
                Implicit: output result of last expression

2

Javaの8、23の 21バイト

n->3/(n%5*2-5)*++n/10

@NeilのJavaScrip(ES6)回答のポート。ただし、整数の暗黙のフローリングによる@Nevayのおかげで-2バイト。

ここで試してみてください。


1
21バイト:n->3/(n%5*2-5)*++n/10
Nevay

1
私はトップの答えのポートを作成するとき@Nevayでも、あなたはまだゴルフを持っている私.. xDさん(読む:!おかげで、素敵な仕事)
ケビンCruijssen



1

パイソン244の 43バイト

(クロスアウトされた44はまだ44です。)バイトを保存してくれたFireflame241に感謝します!

P=input();i=P/3
while i*10%P-1:i-=1
print i

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

0との間にちょうど1つの数字があり、P-1これはの逆数です10。しかし、その逆uがたまたまより大きい場合P/2、それ(u-P)も逆であり、より小さい絶対値を持ちuます。だから、私たちは本当にユニークな番号を探していることが判明x-P/2P/2の逆です10

上記のコードは(のフロア)から開始しP/2、逆に到達するまで下にステップ実行します。これは、より大きい素数である-P/2限り、より大きい数で発生する必要があります。より正確には、が互いに素である場合にのみ終了します。P10P10

編集:それは実際に判明x間であることが保証されている-P/3P/3、現在のバージョンはから始まるので、P/3そこからステップダウン。この説明については、「改良された境界」というラベルのセクションを参照してください。

数学的説明

分割可能性テストがなぜ機能したのか、すぐにはわかりませんでした。他の誰かが疑問に思っている場合のために、ここに説明があります。

させるPプライム、より大きくなり10、その最後の桁です、b。かくして

P = 10a + b

ここでa > 0、および0 <= b < 10。実際にはbどちらかである137、または9、よりプライム大きいため、10これらの数字の1で必須の終わり。

今と仮定bx + a = 0 (mod P)。それから

a = -bx (mod P)

10a + b = 10(-bx) + b (mod P)

0 = 10(-bx) + b (mod P)

0 = b(1 - 10x) (mod P)

のでP素数である、整数がmod Pある一体型ドメイン。したがってb = 0 (mod P)、またはのいずれか1 - 10x = 0 (mod P)です。

私たちは知ってい0 <= b < 10 < Pそうであれば、b = 0 (mod P)それからb = 0。しかし、我々が言ったbのいずれかである137、または9、そう、これは不可能です。したがって1 - 10x = 0 (mod P)、そう10x = 1 (mod P)。つまり、はのx逆で10、モジュロPです。

ここでN、最後の桁がである非負の整数であると仮定しますd。したがってN = 10c + d. 、同等のステートメントのチェーンがあります。

10c + d = 0 (mod P)

<==> 10xc + dx = 0 (mod P)

<==> c + dx = 0 (mod P)

QED。

使いやすさ?

私はまた、整除テストは(与えられたかどうかを疑問に思ったN = 10c + d、交換するNことでdx + c)実際に、実際に生産的だろう。または、少なくとも(絶対値で)Nより小さい数で確実に置き換えられNますか?

仮定しN = 10c + d、どこc >= 00 <= d < 10。したがって10c = N - d <= N。三角形の不等式により、

|c + dx| <= |c| + |dx| = c + d|x| <= N/10 + d|x|

< N/10 + 10|x| <= N/10 + 10P/2 = N/10 + 5P

したがって5P <= 9N/10、その場合|c + dx| < N

特に、if N >= 6P、then |c + dx| < N。このように、与えられたP我々は計算することから始め2P3P、...、6Pと一緒に、x。次に与えられたN、私たちは数未満に達するか等しいまで繰り返し整除テストを実行し6P、その結果が数字のいずれかであるかどうかを確認します0P2P、...、 6P

(もちろん、負の数に達するたびに、その絶対値で置き換えます。これはqPifである場合にのみ割り切れるので問題ありません(-q)。)

改善されたバウンド

私は|x|/P決して近くには見えないことに気づきました1/2。それは常に未満だったように実際にはそれが見えた1/3...か、綿密に検討すると、それは非常に近いのいずれかに常にでした1/103/10。それは今までに得た最大のではと思われた4/13(ときたまたまP=13x=4)。これはなぜですか?

してみましょうu整数になるとしたとする10u = kP + 1いくつかの整数をk、そうuとは逆の10モジュロ、P。そして、我々はまた、それが知っているkと互いに素である10ことから、k(-P)と等価である1モジュロ10

これで、10モジュロの逆数はPすべての倍数で異なることがわかっているPので、整数uを取得し、任意の倍数を加算または減算できP、結果は常に10モジュロの逆数になりますP。私たちは減算することを選択したと仮定Pからu:私たちが得ます

10(u - P) = 10u - 10P = kP + 1 - 10P

10(u - P) = (k - 10)P + 1

換言すれば、減少(それぞれ、増加)uによってP(増加)の減少に対応kすることによって10。左側の絶対値が最小になるまでPfromの倍数を加算/減算しuます。しかし、右側が最小化されたときに左側が正確に最小化されるため、右側が絶対値で最小化さ10れるkまで、そこから加算/減算します。

しかし、我々は時にこれが起こるだろうことを知っているkとの間にある-55、それゆえ(以降kと互いに素である10)、この手段kのいずれか-3-11、または3。(これはOPの下での@Neilのコメントの内容です。ありがとう、Neil!

このようにする場合|u|(すなわち、最小化されたu=x)、私たちは持っているだろうx/P = u/P = k/10 + 1/(10P)、どこkのいずれかである-3-11、または3。したがって|x|/P <= 3/10 + 1/(10P)。同様に、|x| <= (3P + 1)/10

さらに、この不平等は、厳しいP=11であるため、P=11私たちは持っているx=-1k=-1P等式が成立する最小値はP=13(where x=4およびk=3)です。

したがって、|x|/Pこれまでに得られる最大のものは3/10 + 1/(10*13)、です。なぜなら、これP=13は最初の素数でありk=3、の中k=3で、1/(10P)Pは最小のとき(つまりP=13)に最大です。したがって、すべてのためにP、私たちも持ってい|x|/P <= 3/10 + 1/130 = 4/13 < 1/3ます。これは、上記のコードでi = P/3で開始するのではなくで初期化できる理由を説明していP/2ます。

さらに、上記の「有用性」セクションの境界を改善できるようになりました。

補題N = 10c + dどこにc > 0しましょう0 <= d <= 9。その後c + d|x| < N/10 + 9(3P + 1)/10。(厳密な不等式に注意してください。)

補題の証明:場合によって。ケースI:d = 0のでN = 10c。その後c + d|x| = c = N/10 < N/10 + 9(3P + 1)/10

ケースII: 0 < d <= 9。それでは10c = N - d < N、そうc < N/10。したがってc + d|x| < N/10 + d|x| <= N/10 + 9|x| <= N/10 + 9(3P + 1)/10。QED。

したがって、N > 3PN = 10c + d以前と同様に)

3P + 1 <= N

9(3P + 1)/10 <= 9N/10

N/10 + 9(3P + 1)/10 <= N

c + d|x| < N/10 + 9(3P + 1)/10 <= N

だから、もしN > 3P、その後c + d|x| < N

したがって、我々は唯一見つけなければならないP2P3P一緒に、x。与えられたN > 0一方で、N > 3P我々は交換するNことにより|c + dx|減少します、N。最終的には取得しN <= 3Pます。その時点で、私たちは停止し、かどうかを確認N番号のいずれかに等しい0P2P、または3P

私たちは3P一般よりもうまくやることができません。例えば、仮定P = 13およびN = 39ので、x = 4。そして、交換するNことにより、dx + c = 9(4) + 3N変わりません。


とてもいい説明です!あなたは移動してバイトを保存することができます-1:括弧の外に 43バイト
fireflame241を

@ fireflame241ありがとうございます!私はそれを消すことができるように44で残したと主張することができました(これは嘘になるでしょうが)。
mathmandan

1

空白、92バイト

この言語の構文は、 whitespaceのみでているため、各空白文字にはS、T、またはL(それぞれSpace、Tab、およびLinefeedに対応)のプレフィックスが付いている。これらは機能を失うことなく削除できますが、正しく表示するためにここに含まれています。

S S S L
T   L
T   T   S S S L
T   T   T   S L
S S S S T   T   L
T   S S L
S L
T   S S S T S T L
T   S T T   S L
S T S S S S S S T   S T L
T   S S T   T   S T S S S S T   L
T   S S S S S S T   S T S L
T   S T S T L
S T L
L
L
.

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




0

Excel、27バイト

=0.3/(MOD(A1,5)*2-5)*A1+0.1

セルに次のように入力できます

=.3/(MOD(A1,5)*2-5)*A1+.1

25バイトですが、Excelは自動更新されます。


実際、入力する必要があるバイト数を要求することは許可されていると思います(ただし、メタをチェックするのは面倒です)。
ニール
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.