ソースコードに素数が含まれていない数値が2017年に壊れやすいかどうかを判断する


41

私がこの挑戦をしてきたすべての年のうち、2017年は素数であった最初の年です。したがって、問題は素数とその性質についてです。

あなたの仕事は、入力として任意の大きな正の整数を受け取り、2,017-friableであるかどうか、つまりその数の最大素因数が2,017以下であるかどうかを出力または返すプログラムまたは関数を生成することです。


いくつかの入力例とその出力:

1 (has no prime factors)
true

2 (= 2)
true

80 (= 2 x 2 x 2 x 2 x 5)
true

2017 (= 2017)
true

2019 (= 3 x 673)
true

2027 (= 2027)
false

11111 (= 41 x 271)
true

45183 (= 3 x 15061)
false

102349 (= 13 x 7873)
false

999999 (= 3 x 3 x 3 x 7 x 11 x 13 x 37)
true

1234567 (= 127 x 9721)
false

4068289 (= 2017 x 2017)
true

あなたのプログラムは、文字通り出力する必要がないtruefalse-任意のtruthyやfalsy値、および実際には真と偽のケース全体で一貫している任意の二つの異なる出力が細かいです。


ただし、ソースコードで素数を使用することはできません。プライムには2つのタイプがあります。

  • 素数リテラルを表す文字、または文字のシーケンス。

    • 文字235、と7数字が有効なトークンでの言語で違法です。

    • 数は141、それが含まれているため、違法である41にもかかわらず、1及び4それ以外の場合は有効です。

    • 文字Band D(またはband d)は、CJamやBefungeなど、通常11および13として使用される言語では違法です。

  • 素数のUnicode値を持つ文字、またはエンコーディングに素数のバイトが含まれる文字。

    • %)+/5;=CGIOSYaegkmqASCIIでは、文字はキャリッジリターン文字と同様に違法です。

    • óUTF-8では、エンコーディングに文字が含まれているため、この文字は無効0xb3です。ただし、ISO-8859-1では、エンコードは単に0xf3であり、これは複合であるため問題ありません。

任意の言語で上記を実行する最短のコードが優先されます。


サイドノート:「壊れやすい」とは、この文脈で古くて説明のつかない「スムーズ」よりも改善されていることです。
グレッグマーティン

1
真実と偽の値は一貫している必要がありますか?または、それらが真実であるか、または偽である限り、それらは変わることができますか?
ルイスメンドー

10
=ほとんどの標準言語のルールの欠如...
ニール

4
Yチャレンジのないdo Xの場合は-1。かなり不必要な文字制限のセットの後ろに隠されているのは本当にささいなことです
-Downgoat

1
私はそれらがarbitrarily意的に大きいという部分が好きではありません。彼らが2 ^ 31-1まで上がったらもっといいでしょう。
ビジャン

回答:


37

ゼリー、8バイト

44‘²!*ḍ@

オンラインでお試しください!テストケース11111以上は、TIOには少々多すぎることに注意してください。

検証

$ source="34,34,fc,82,21,2a,d5,40"
$ xxd -ps -r > 2017.jelly <<< $source
$ xxd -g 1 2017.jelly
0000000: 34 34 fc 82 21 2a d5 40                          44..!*.@
$ eval printf '"%d "' 0x{$source}; echo # Code points in decimal
52 52 252 130 33 42 213 64
$ test_cases="1 2 80 2017 2019 2027 11111 45183 102349 999999 1234567 4068289"
$ for n in $test_cases; do printf "%11d: %d\n" $n $(jelly f 2017.jelly $n); done
      1: 1
      2: 1
     80: 1
   2017: 1
   2019: 1
   2027: 0
  11111: 1
  45183: 0
 102349: 0

テストケース999999は13時間実行されています。私は2025の計算に悲観的です4068289 ...

使い方

44‘²!*ḍ@  Main link. Argument: n

44        Yield 44.
  ‘       Increment to yield 45.
   ²      Square to yield 2025.
          Note that no integers in [2018, ..., 2025] are prime numbers.
    !     Take the factorial of 2025.
     *    Raise it to the n-th power.
          This repeats all prime factors in 2025! at least n times, so the result
          will be divisible by n if (and only if) all of its prime factors fall
          in the range [1, ..., 2025].
      ḍ@  Test the result for divisibility by n.

22
あなたは数字に残酷です。:)
グレッグマーティン

3
@GregMartinバハ。サイズ6の入力が数時間メモリを占有し、その後クラッシュするという答えを(別の言語で)見ました。私はただ言います:(2^n)!。これは6サイズの入力でもクラッシュしますが、少なくとも入力は2進数ではなく10進数のアルファベットです。
ジョンドヴォルザーク

これは13バイトではありませんか?デニス、あなたはとても評判が高いので、間違いなくここで間違いを犯していると思います笑
アルバートレンショー

7
@AlbertRenshaw実際にはUTF-8では13バイトですが、Jellyは、理解できるすべての文字をそれぞれ1バイトとしてエンコードするカスタムコードページを使用します
デニス

3
@Dennisは説明があることを知っていました。学ぶのはとてもクールです、ありがとう!
アルバートレンショー

11

ゼリー、8文字、14バイトのUTF-8

Æf½ṀḤ<90

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

Jellyは通常、プログラム用に独自のコードページを使用します。ただし、その主な関連ビルトインのほとんどは、Æコードポイント13で始まります。あまり役に立たない。幸いなことに、インタプリタはUTF-8をサポートしています。これは、より使いやすいエンコーディングを備えています。

検証

UTF-8のこのプログラムは、次のようなhexdumpsです。

00000000: c386 66c2 bde1 b980 e1b8 a43c 3930  ..f........<90

すべてのバイトが複合であることの検証:

$ for x in c3 86 66 c2 bd e1 b9 80 e1 b8 a4 3c 39 30; do factor $((0x$x)); done
195: 3 5 13
134: 2 67
102: 2 3 17
194: 2 97
189: 3 3 3 7
225: 3 3 5 5
185: 5 37
128: 2 2 2 2 2 2 2
225: 3 3 5 5
184: 2 2 2 23
164: 2 2 41
60: 2 2 3 5
57: 3 19
48: 2 2 2 2 3

すべてのUnicodeコードポイントが複合であることの検証:

$ perl -Mutf8 -E '$a = ord, print `factor $a` for split //, "Æf½ṀḤ<90"'
198: 2 3 3 11
102: 2 3 17
189: 3 3 3 7
7744: 2 2 2 2 2 2 11 11
7716: 2 2 3 643
60: 2 2 3 5
57: 3 19
48: 2 2 2 2 3

数値として解析される唯一のトークンは90です。、、、およびのいずれも素数90はありません90

説明

ここでの主な数学的洞察は、45²は2025年であり、2017年(現在の年)から2027年(次の素数)の間にきちんと収まっているということです。したがって、数値のすべての素因数の平方根を取得し、いずれかが45を超えるかどうかを確認できます。残念ながら、45リテラルのために書き込むことができないため5、それを2倍にして90と比較する必要があります。

Æf½ṀḤ<90
Æf        In the list of prime factors,
  ½       taking the square root of each element
   Ṁ      then taking the largest element
    Ḥ     and doubling it
     <90  produces a result less than 90.

2
JellyはUTF-8を使用するためにフラグ(1バイト)を必要としませんか?
ルイスメンドー

@LuisMendo:コマンドラインインタープリターは機能しますが、Try It Onlineのインタープリターは機能します!構成が異なり、必要ありません。だから、これはあなたのプログラムをあなたが望むように解釈するインタプリタを選ぶだけの場合です。(いずれにせよ、問題のフラグu、は複合であるため、スコアを無効にするものではなく、スコアを変更するだけです。)

10

Mathematica、62 58 55バイト

保存された最後の3バイトは、完全にMartin Enderによるものです!

#4<4||#<44*46&&#6[#^-1#4]&[Divisors[#][[6-4]],,,#,,#0]&

正の整数引数を取り、Trueまたはを返す名前のない関数False

#4<4真実の基本ケースである再帰アルゴリズム(入力True1 に戻るために必要なだけですが、追加の基本ケースは問題ありません)。そうでなければ、入力の2番目に小さい除数(必然的に素数)を計算しDivisors[#][[6-4]]ます; 2024(44*46)より大きい場合、で終了しますFalse。それ以外の場合は、この小さな素因数で割った入力で(#6setを使用して#0)関数を再帰的に呼び出します(許可されないため、input ##^-1時間として表現する必要があります)。#4/

構造的には、前半は#4<4||#<44*46&&#6[#^-1#4]&6つの引数の無名関数は、引数で呼び出されてDivisors[#][[6-4]]NullNull#Null、と#0。これは文字に禁止を回避することで23、と5

ais523のJelly回答に触発されたに置き換え8018-6000て4バイトを節約した以前のバージョン(Martin Enderはais523コメントにも触発されたようです):44*46

#<4||Divisors[#][[6-4]]<44*46&&#0[Divisors[#][[6-4]]^-1#]&

これはかなり厄介でした。これらの制限の下でMathematicaで変数を実際に設定する方法がまだわかりません!どちら=eSet禁止されています。回避+)も問題でしたが、より多くのバイトを犠牲にして回避するにはあまりにも難しいことではありません。


変数ではなく、ラムダパラメータを設定することもできます。(そうは言って#2も、許可されないので、ラムダがどのようにネストされているかに注意する必要があります。括弧がないと難しくなります。)

@ ais523の提案を実装#4<4||#<44*46&&#6[#^-1#4]&[Divisors[#][[6-4]],,,#,,#0]&すると、3バイト節約されます。Divisors[#][[2]]入力が1(または3)より大きいことを確認する前に試行するため、大量の警告がスローされますが、結果は依然として正しいです。
マーティンエンダー

ああ、それは恐ろしいだ。
グレッグマーティン

7

Haskell、48 47バイト

\n->[snd$[product[1..44*46]^n]!!0`divMod`n]<[1]

基本的にデニスのゼリーの答えの翻訳。xnorはバイトを保存しました。

用途[…]!!0括弧などがあるため)禁止されており、snd+ divMod理由mmodrem禁止されています。


divModを使った素敵なトリック!私はあなたが交換することができると思います!!0<1<[1]。しかし、divとして使用するために短絡しているように見え[\p n->p^n`div`n*n>p^n-1]!!0$product[1..44*46]ます。
-xnor

また\n->[0|p<-[product[1..44*46]^n],0<-[p,p-n..0]]、出力が一貫している必要があることを使用するがあります。
-xnor

@xnorそれらを別々の回答として投稿してください。それらは私のものとは十分に異なっていると思います^^
Lynn

6

パイク、10 8 7 9バイト

P_Z|hwMX<

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

2025を生成するデニスの方法を使用して1バイトを節約しました

P         -     factors(input)
 _        -    reversed(^)
  Z|      -   ^ or 0
    h     -  ^[0] or 1
        < - ^ < V
     wM   -  ⁴45 (ord("M")-32)
       X  -  ^**2

5

Brachylog9 10バイト

*$ph$r*<90

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

基本的に、他の答えと同じアルゴリズムを使用します。$ph最初の(h)素因数()を見つけ$pます。Brachylogの素因数リストは最大のものから最小のものへと進むため、これは最大の素因数です。次に、平方根($r)、二重(*)を取得し、90未満かどうかをテストします(<90)。

1には素因数がない(したがって最初の素因数がない)ため、最初に入力を2倍にしなければなりませんでした。これにより、2の追加の素因数が追加されます。これは、数値が2017脆弱であるかどうかには影響しませんが、1を処理するときの障害を防ぎます。


5

実際には、9バイト

τyM:44u²≥

たくさんのバイトをしてくれたデニスに感謝します!

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

説明:

τyM:44u²≥
τyM        largest prime factor of 2*input (doubled to deal with edge case of n = 1)
   :44u²   2025 (2027 is the next prime after 2017, so any number in [2017, 2026] can be used here - 2025 is very convenient)
        ≥  is 2025 greater than or equal to largest prime factor?

5

Mathematica、66 74バイト

U+F4A1禁止されていることを指摘してくれたデニスに感謝します。

Fold[Function[{x,d},And[x,Tr[Divisors@d^0]>6-4||d<44*46]],0<1,Divisors@#]&

説明:

Divisors@#:最初の引数の整数除数のリスト#

0<1:Golf for True(文字の使用も避けますe)。

Divisors@d^0{1, 1, ..., 1}長さがの約数の数に等しいフォームのリストd

Tr:フラットリストの場合Tr、そのリストの合計を返します。したがってTr[Divisors@d^0]、の約数の数を返しますd

Function[{x,d},And[x,Tr[Divisors@d^0]>6-4||d<44*46]]:2つの引数xd。これdは、除数であるという考えであり、#それが複合であるか、それ以下2017(包含的)であるかどうかをテストします。2017-friabilityは、この条件を満たすすべての除数と同等です。ais523が発見され、素数未満であるか等しい2017素数未満であることと等価です2025グレッグ・マーティンは指摘し、それは以下であるかどうかをテストするだけで十分2024=44*46。引数xは、これまでに検出されたすべての除数がこのプロパティを満たすかどうかのアキュムレーターとして機能します。その後、開始値Fold#持つすべての約数を使用してこの関数を終了しましたTrue、にもアクセスできMapないため/@です。


1
制限を克服する方法!
グレッグマーティン

2

05AB1E、10バイト

fθ46n99-›È

trueの場合は1、それ以外の場合は0を返します。

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

説明

f          # Push the list of prime factors (ordered)
 θ         # Get the last element
  46n99-   # Push 2017 (46² - 99)
        >  # Push 1 if the last prime factor is greater than 2017, 0 otherwise
         È # Is the resulting number even ? Transforms 1 to 0 and 0 to 1.
           # Implicit display

PPCGへようこそ!
マーティンエンダー

1

MATL、15バイト

t:\~ftZp*44QU<A

02017年以外の脆弱性または2017年の脆弱性の出力1

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

このプログラムは、すべてのバイトが合成されていることを確認します。

説明

t       % Implicit input n. Duplicate
:       % Range [1 2 ... n]
\       % Modulo. Gives 0 for divisors of n
~f      % Indices of zero values
t       % Duplicate
Zp      % Is-prime. Gives 1 for primes, 0 for composites
*       % Multiply
44QU    % 44, add 1, square: 2025
<       % Less than, element-wise
A       % True (1) if all entries are nonzero

1

バッシュ、144バイト

ASCIIエンコード:

{
printf '[ '
`tr D-Z _-z <<<KFH`tor $1|tr -d :|`tr B-Z _-z <<<JUH`p -o '[0-9]*$'
printf ' -lt $[24*86-46] ]'
}|tr \\n \ |`tr B-Z _-z <<<EDVK`

シェルの場合と同様に、終了コードは成功(0)または失敗(0以外)を示します。

これは事実上異なるスペルです

[ factor $1|tr -d :|grep -o '[0-9]*$' -lt 2018 ]

で最大の因子を取得しfactor $1|grep -o '[0-9]*$'ます; これtr -d :はinput =の特殊なケースです1

$[6*6*69-466]は2018に評価されます。

trコマンド名に使用し、それでもコマンド置換を使用するのはトリッキーでした-ネストフォームを使用できなかったため$( )、結果を評価するために別のBashにパイピングしました。

試験結果:

$ for i in 1 2 80 2017 2019 2027 11111 45183 102349 999999 1234567 4068289; do printf '%d %s\n' $i `./105241.sh $i  && echo true || echo false`; done
1 true
2 true
80 true
2017 true
2019 true
2027 false
11111 true
45183 false
102349 false
999999 true
1234567 false
4068289 true

文字コードの確認:

$ grep -v '^#' ./105241.sh | perl -n -Mutf8 -E '$a = ord, print `factor $a` for split //, $_' | grep -v ': .* ' | wc -l
0




0

Braingolf、11バイト[非常に競合しない]

VRp#ߢ-?0:1

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

以下のために読めないߢ数字とされ、ねじ、しかしまだインタプリタで動作します。

私はこれを書いたときに文字の制限に気づきませんでしたが、私がしなければならなかったのは、2017年から2018年に奇妙なユニコード文字を変更することだけでした。

2018年は素数ではないことを考えると、任意の素数<= 2018<= 2017

説明

VRp#ߢ-?0:1  Implicit input from command-line args
VR            Create stack2, return to stack1
  p           Split last item into prime factors, push each one to stack in asc order
   #ߢ         Push 2018
     -      Subtract last 2 items (highest prime factor - 2017)
      ?     If last item > 0..
       0    ..push 1
        :   Else..
         1  ..Push 1
            Implicit output of last item on stack
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.