分割して分割して征服する


22

時々、目の前に出てくる数字をなんとなくしようとするとき¹、しばらくして、思ったより簡単だと気づきました。テイク2156例えば:最終的には、両方のことを私に起こる2156の倍数である7ので、確かに、とは2156 = 21 x 100 + 56またの倍数です7

あなたの仕事は、この種の偶然の一致により因数分解しやすい数字を識別するコードを書くことです。

より正確に:

n入力として正の整数を取り、2つに切り分けてそれぞれが2の倍数である2つの正の整数を生成できる除数d(より大きい1)が存在する場合、真理値を返すプログラムまたは関数を記述します。そうでない場合は、偽の値を返します。nd

  • 「2つにチョップ」とは、あなたが考えることを意味します。nある時点で前半と後半に分割され、他の2つの10進整数を生成する通常の10進表現です。2番目の整数の先頭にゼロが付いていても問題ありません(ただし、正の整数である必要があるため、分割1230して有効1230はないことに注意してください)。
  • 真実の値と偽の値は入力に依存します。たとえば、選択した言語でゼロ以外の整数が真である場合、除数dまたはn(またはnそのこと自体)。
  • たとえば、セット内の少なくとも2桁の偶数 {2, 4, 6, 8}があると、真の値が得られます。最初の偶数の後に分割するだけです。また、たとえば、n1桁の数値と同様に、素数は偽の値を生成します。
  • 素因数を考慮するだけで十分です。 d
  • 入力が有効であると仮定できます(つまり、正の整数)。

これはであるため、バイト単位の最短コードが優先されます。しかし、すべての言語のソリューションは歓迎されているため、全体の最短コードだけでなく、各言語の最短コードを目指して努力することができます。

テストケース

(真実または偽の値のみを出力する必要があります。以下の注釈は説明のためのものです。)真実の値を生成する入力は次のとおりです。

39  (3 divides both 3 and 9)
64  (2 divides both 6 and 4)
497  (7 divides both 49 and 7)
990  (splitting into 99 and 0 is invalid; but 9 divides both 9 and 90)
2233  (11 divides both 22 and 33)
9156  (3 divides both 9 and 156; or, 7 divides both 91 and 56)
11791  (13 divides both 117 and 91)
91015  (5 divides both 910 and 15)
1912496621  (23 divides both 1912496 and 621; some splittings are multiples of 7 as well)
9372679892  (2473 divides both 937267 and 9892; some splittings are multiples of 2 as well)

偽の値を生成する入力は次のとおりです。

52
61
130  (note that 13 and 0 is not a valid splitting)
691
899
2397
9029
26315
77300  (neither 7730 and 0 nor 773 and 00 are valid splittings)
2242593803

¹はい、私は本当にこれをします

回答:


7

網膜31 29バイト


,$';$`
\d+
$*
;(11+)\1*,\1+;

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

有効な入力には正の整数を、無効な入力にはゼロを出力します。

大きなテストケースを待つことはお勧めしません...

説明


,$';$`

入力の各位置にコンマを挿入し、次にその位置の前のすべて、セミコロン、この位置の後のすべてを挿入します。それは何をしますか?可能なすべての数値の分割(,、で区切られた;)を提供し、最後に再び入力を提供します。したがって、入力123

,123;1,23;12,3;123,;123
     ^     ^     ^

元の入力文字にマークを付けました(マークされていないものは挿入したものです)。これにより、実際の分割ではない無効な分割が作成されることに注意してください。また、後続コンポーネントがすべてゼロであるかどうかは気にしませんが、後で受け入れることは避けます。無効な分割を作成することの利点は、有効な分割のそれぞれ;が前後にあることを知っているため、ワード境界で2バイトを節約できることです。

\d+
$*

各数値を単項に変換します。

;(11+)\1*,\1+;

少なくとも2である数の倍数として両方の半分を一致させることにより、分割を一致させます。


Retinaに関する簡単な質問:主要な改行は何をしますか?
ハイパーニュートリノ

@HyperNeutrino最初の行は一致する最初の正規表現です。文字間のすべての単一の位置に置換を挿入するために、空の正規表現と一致させます。
マーティンエンダー

ああ、大丈夫。ありがとう!おそらくRetinaをもう少し見る必要があります。主に正規表現に基づいているため、コルモゴロフ複雑性の問題に適している可能性があります。
ハイパーニュートリノ

最後の行は;(11+)+,\1+;
ライリー

@Rileyは、最初のセグメントが同じ要素の倍数であることを保証しません。
マーティンエンダー

6

Brachylog(2)、8バイト

~c₂ḋᵐ∋ᵐ=

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

説明

~c₂ḋᵐ∋ᵐ=
~c₂       Split the input into two pieces
    ᵐ ᵐ   On each of those pieces:
   ḋ ∋      Choose a prime factor
       =  such that both the chosen factors are equal

明らかに、同じ数(1より大きい)が両方の部分を分割する場合、同じ素数が両方を分割します。因子が素数であることを要求すると、因子として1がきちんと拒否されます。また、リテラル0が数値のセグメントとして選択されるのを防ぎます(0素因数分解がないため、失敗します)。

一致する内部ゼロをチェックする必要はありません。スプリット場合x0y有効である、x0y同じようにうまく動作します(と他の道を行く場合、x0およびy作品、我々は関係なく、かどうかのワーキングソリューションを持っているxし、0y仕事をしたりしません)。

このようなBrachylogフルプログラムは、ブール値を返します。すべてのパスが障害につながる場合true.、エラーなしで実行する方法がある場合(つまり、エラーが発生しないように選択する場合)false.。ここでまさにそれが必要です。


4

ゼリー14 12 11 10バイト

ŒṖḌo1g/€P>

1バイトのゴルフをしてくれた@JonathanAllanに感謝します!

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

使い方

ŒṖḌo1g/€P>  Main link. Argument: n

ŒṖ          Compute all partitions of n's decimal digits.
  Ḍ         Undecimal; convert each array in each partition back to integer.
   o1       OR 1; replace disallowed zeroes with ones.
     g/€    Reduce (/) each (€) partition by GCD (g).
            The last GCD corresponds to the singleton partition and will always be
            equal to n. For a falsy input, all other GCDs will be 1.
        P   Take the product of all GCDs.
         >  Compare the product with n.

を有効にするとD、ドロップできると思います。make_digitsŒṖ
ジョナサンアラン

何らかの理由で、私はそれが範囲を作成すると思いました...ありがとう!
デニス

3

Mathematica、63 62バイト

(Greg Martinのおかげで1バイト)

1<Max@@GCD@@@Table[1~Max~#&/@Floor@{Mod[#,t=10^n],#/t},{n,#}]&

入力として整数を受け取り、Trueまたはを返す関数ですFalse。多数でテストする場合は、待っている間に本を読んでください。

説明:

  • Floor@{Mod[#,t=10^n],#/t}入力を最後のn桁と残りのm-n桁(ここmで、合計桁数)に算術的に分割します。
  • Table[1~Max~#&/@...,{n,#}]n入力番号まですべてに対してこれを行います。(これは大きすぎます。これは入力の数まで行うだけですが、この方法はバイトを節約し、正しい結果を提供します。)1~Max~#&/@ビットはゼロを取り除き130 -> {13,0}ます。としてTrue
  • 1<Max@@GCD@@@... これらの各ペアの最大公約数を見つけ、これらの約数のいずれかが1より大きいかどうかを確認します。もしそうであれば、分割することで数を因数分解する方法を見つけました。

1
いい答えだ!{#~Mod~10^n,#/10^n}またはのいずれかで1バイトを保存できます{Mod[#,t=10^n],#/t}
グレッグマーティン

試しましたが#~Mod~10^n、のMod[#,10]^n代わりに括弧でくくられているようですMod[#,10^n]。あなたの2番目の提案は考えていませんでした!
ツリーではない

フェアポイントMod[#,10]^n
グレッグマーティン


2

C、145の 142 139 138 135バイト

i,a,b;f(){char s[99];scanf("%s",s);for(char*p=s;*p++;)for(b=atoi(p),i=*p,*p=0,a=atoi(s),*p=i,i=1;i++<b;)*s=a%i-b%i|b%i?*s:0;return!*s;}

2

JavaScript(ES6)、74 71 70バイト

f=(s,t='',u)=>u?s%t?f(t,s%t,1):t:s&&f(t+=s[0],s=s.slice(1),1)>1|f(s,t)
<input oninput=o.textContent=f(this.value)><span id=o>

入力を文字列として受け取ります。これはスニペットに便利です。編集:@ user81655のおかげで3バイトを保存しました。


(c,i)-> ci+1-> ++it=''->の2バイトを節約します。i=t=''このトリックは、1から始まるインデックスを使用し、どこかに初期化iする必要がある場合に役立ちます0
user81655

また、とにかく文字列に強制を追加するt=''のでt=0、可能性がありcます。
user81655

@ user81655これは、最初にからにスライスしたために発生しましたi。したがって、1 から始まるインデックスは必要ありませんでしたが、最初のスライスをにゴルフしましたt+=c
ニール

ああ、わかった。最後にもう1つ、再帰関数としてこれを短くすることもできますf=(x,y,z)=>z?x%y?g(y,x%y):y:x?f(x,y,1)>1||f(x.slice(1),~~y+x[0]):0。あなたのGCD機能も組み合わせfました。おそらくさらにゴルフすることができます。最後の提案、約束します!:P
user81655

@ user81655残念なことに、単純化されたgcd機能はのときに機能せずx=0、それを回避するためにタイプミスで72バイトになったので、2バイト離れてゴルフをすることができたのは幸運でした。
ニール

2

Python 3、133 118 117バイト

i,j=int,input()
from fractions import*
print(any(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j))))

確かに最短ではありませんが、おそらく少し短くすることができます。で動作しO(n)た時間。入力は形式で取得され\d+、出力は(True|False)デフォルトのPythonブール値に従って形式で指定されます 。DeadPossumのおかげで
-3バイト
ovsのおかげで-15バイト
This Guyのおかげで-1バイト


from fractions import*3バイト救う
デッドポッサム

900に対してTrueを返します。それは間違っていると思います。Mbに変更する必要anyがありallますか?その場合は、その部分をi(j[k:])and i(j[:k])すべて125バイトに変更することができます。ここに修正があります
デッドポッサム

あなたは乗算と、すべてを置き換えることができますany(i(j[k:])*i(j[:k])*~-gcd(i(j[k:]),i(j[:k]))for k in range(1,len(j)))
OVS

@DeadPossumそうそう、そうするべきだった。ええ、私の現在の方法には多くのゴルフ可能な部分がありますが、ovsの提案に従うつもりです。それを指摘してくれてありがとう!(実際に自分でテストする必要があります...まあ...)
HyperNeutrino

間の空白を削除することでバイトを削除できます(ほとんど何もありません))) for
caird coinheringaahing

1

QBIC91 90バイト

;_LA|[a-1|B=left$(A,b)┘C=right$(A,a-b)┘x=!B!┘y=!C![2,x|~(x>1)*(y>1)*(x%c=0)*(y%c=0)|_Xq}?0

説明:

;               Get A$ from the command prompt
_LA|            Get the length of A$ and place it in a% (num var)
[a-1|           for b%=1; b% <= a%-1; b%++
B=left$(A,b)    break A$ in two components on index b%
C=right$(A,a-b)
x=!B!┘y=!C!     Convert both parts from string to num, assign to x% and y%
[2,x|           FOR c% = 2; c% <= x%; c%++

This next IF (~ in QBIC) is a bit ... iffy. It consists of a set of comparators.
Each comparator yields a -1 or a 0. We take the product of these. At any failed
comparison this will yield 0. When successful, it yields 1, which is seen as true by QBasic.

~(x>1)*(y>1)        IF X>1 and Y>1 --> this stops '00' and '1' splits.
*(x%c=0)*(y%c=0)    Trial divide the splits on loop counter c%.

|_Xq            Success? THEN END, and PRINT q (which is set to 1 in QBIC)
}               Close all language constructs (2 FOR loops and an IF)
?0              We didn't quit on match, so print 0


1

Perl 5、46バイト

43バイトのコード+ -pフラグ用の3バイト。

s~~$\|=grep!($`%$_|$'%$_),2..$`if$`*$'~ge}{

オンラインでお試しください!または、複数の入力を許可するこの修正版を試してください。
これは(非常に長い)時間がかかる可能性があるため、おそらく最大の入力でこれを試してみたいとは思わないでしょう。

説明:
私たちは、との言葉にそれぞれの位置を反復s~~~gして、$`数字の前と含んだ$'後に数字を。場合$`*$'(それはそのどれもが空でないことを意味し、およびnoneの真である0)2との間の数ならば、我々はチェックし$`、両方のそれらの除算(とgrep!(...),2..$`)。その場合、ゼロ以外の値に$\|=..設定さ$\れます。これは、-pフラグのおかげで暗黙的に最後に印刷されます。


2
誰かが$<backquote>SEマークダウンでレンダリングする方法を知っているなら、あなたがその方法を教えてくれればありがたいです。
ダダ

1
あなたは、明示的な使用を経由してそれを行うことができます<code>... </code>(というよりも`... `)、その後、としてバッククォートをエスケープします\`。また、このコメントはダブルエスケープする必要があるため、書くのが面倒でした(エスケープルールの2つのセットは異なります!)。

@ ais523素晴らしい、ありがとう!:)
ダダ

0

Python 2、69バイト

f=lambda n,d=10,k=2:k<d<n and(n/d%k+n%d%k<1<n%d)|f(n,d,k+1)|f(n,10*d)

GCDビルトインの代わりに再帰を使用します。

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

使い方

場合fは 1〜3個の引数(と呼ばれるDのデフォルトは10K2式の値)、これは、最初に確認しますk<d<n。不等式k <dおよびd <nの両方が成り立つ場合、次の式andが実行され、その値が返されます。それ以外の場合、fは単にFalseを返します。

前者の場合、式を評価することから始めますn/d%k+n%d%k<1<n%d

dは常に10の累乗であるためn/dnの小n%d数桁を2つのスライスに効果的に分割します。これらのスライスは、0と評価された場合にのみ、kで割り切れます。n/d%k+n%d%kと、結果を1と比較することでテストされます。

要件の一部は、両方のスライスが正の整数を表す必要があることであるため、の値n%d1と比較されます。注1は何の素因子を持っていないので、とのより高価な比較0が必要とされていません。また、d <nは既にn/d正の整数に評価されることを保証することに注意してください。

最後に、再帰的にすべてf(n,d,k+1)(次の潜在的な共通除数をf(n,10*d)試行)および(分割を試行)3つの結果すべての論理和を返します。この手段Fは戻ります真の場合(および場合のみ)、kはの公約数であるN / D%のD、N、または同じでの大きな値についても同様であるKおよび/または10のより高いパワーD

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