私の電話番号はde Polignac番号ですか?


21

数値がde Polignac数であるのは、それが奇数であり、p + 2 nの形式で表現できない場合に限られます。ここで、nは非負の整数で、pは素数の整数です。

仕事

正の整数を受け取り、それがde Polignac数であるかどうかを判別するコードを作成します。trueとfalseの2つの異なる値を出力できます。バイト数を最小限に抑えることを目指してください。

テストケース

ポジティブなケースについては、ここにOEISがあります

1, 127, 149, 251, 331, 337, 373, 509, 599, 701, 757, 809, 877, 905, 907, 959, 977, 997, 1019, 1087, 1199, 1207, 1211, 1243, 1259, 1271, 1477, 1529, 1541, 1549, 1589, 1597, 1619, 1649, 1657, 1719, 1759, 1777, 1783, 1807, 1829, 1859, 1867, 1927, 1969, 1973, ...

いくつかの否定的なケースは次のとおりです。

22, 57

2つの異なる出力の代わりに、真実で偽の出力を使用できますか?
Okx

@Okx私はノーと言うつもりです。
小麦ウィザード


Err ...負の場合、それは基本的にOEISにない数字ですか?明らかなものを見逃していないことを確認します。
マジックタコOct

@MagicOctopusUrnはい。
ウィートウィザード

回答:


11

Japt9 14 13バイト

o!²mnU dj |Uv

オンラインでテストしてください!または1000未満のすべてのde Polignac整数を検索します

1虚偽の入力および真実の出力0

説明

 o!²  mnU dj |Uv
Uo!p2 mnU dj |Uv  : Ungolfed
                  : Implicit: U = input integer (e.g. 9)
Uo                : Create the range [0..U), and map each item X to
  !p2             :   2 ** X.               [1, 2, 4, 8, 16, 32, 64, 128, 256]
      m           : Map each of these powers of 2 by
       nU         :   subtracting from U.   [8, 7, 5, 1, -7, -23, -57, -119, -247]
          d       : Return whether any item in the result is
           j      :   prime.                (5 and 7 are, so `true`)
             |    : Take the bitwise OR of this and
              Uv  :   U is divisble by (missing argument = 2).
                  : This gives 1 if U cannot be represented as p + 2^n or if U is even.
                  : Implicit: output result of last expression

これは、2と3に対して間違った結果を与えているようです。それは戻ってきfalseていますが、彼らはデポリニャックの数字ではありません。
シャギー

@Shaggy 3は修正されていますが、最初はケースを処理する必要はありませんでした。修正。
-ETHproductions

@Shaggyが修正されました。
ETHproductions

私はそれが修正のための修正が3すべてのバイトを要さなかった良いことだと言っていました、それから私は修正を見ました2-痛い!
シャギー

:O +1エンコードエラーのように見えない競合プログラムの場合
Downgoat

8

ゼリー11 10バイト

@Dennisのおかげで1バイト節約

Ḷ2*³_ÆPS<Ḃ

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

使い方

Ḷ2*³_ÆPS<Ḃ   Main link. Argument: n (integer)
Ḷ            Lowered range; yield [0, 1, 2, ..., n-1].
 2*          Reversed exponentiation with 2; yield [1, 2, 4, ..., 2**(n-1)].
   ³_        Reversed subtraction with the input; yield [n-1, n-2, n-4, ..., n-2**(n-1)].
     ÆP      Replace each item with 1 if it is prime, 0 otherwise.
       S     Sum; yield a positive integer if any item was prime, 0 otherwise.
         Ḃ   Yield n % 2.
        <    Yield 1 if the sum is less than n % 2, 0 otherwise.
             This yields 1 if and only if the sum is 0 and n is odd.

Ḷ2*⁸_ÆPS<Ḃ バイトを保存します。tio.run/##ASQA2/9qZWxsef//4bi2Mirigbhfw4ZQUzzhuIL/…–
デニス

@Dennisありがとう、の代わりに3バイトの代替が必要だと知っていました¬;ḂẠS<Ḃ少なくとも私にとっては、箱の外の方法です:
ETHproductions

8

JavaScript(ES6)、 56 54  53バイト

0または1返します。

f=(n,p=1,x=y=n-p)=>n>p?y%--x?f(n,p,x):x!=1&f(n,p*2):n

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

どうやって?

p=1から始めます。y=npが合成かどうかをテストし、それに応じてブール値を生成します。次のテストはp×2実行されます。

pnより大きくなるとすぐに、再帰を停止してnを返します。

すべての反復の結果はANDで結合され、ブール値が0または1に強制されます。

すべての中間結果が真実であれば、次のようなビットごとのテストになります。

1 & 1 & 1 & n

これは、nが奇数の場合にのみ1なります。これは、入力をde Polignac数として検証するために必要な最後の条件です。n


3
素晴らしいテクニック。おそらく、明示的n%2または類似していない唯一の有効な答え:P
ETHproductions

これには、262145や2097153などの2 ^ M + 1形式のde Polignac番号に対する誤検出があります(後続のものは4722366482869645213697、38685626227668133590597633、5192296858534827628530496329220097などです)。たとえば、262139、262259、2097131、および2097187を正しく識別するため、数値の大きさは問題ではありません。もちろん、再帰のために、これをテストするためにスタックサイズを非常に大きなものに拡大する必要があり、上記の最初の2つの2 ^ M + 1 de Polignac数の範囲のみをテストしました。
デッドコード

1
@Deadcodeこれを報告していただきありがとうございます。修正されました。
アーナウルド

1
@Arnauldああ、あなたは正しいです:)確かに、私はこれしました、そして確かに、それは修正されました。
デッドコード

1
@Deadcode Neat!:)
アーナウド

7

パイソン260の 57 56バイト

f=lambda n,k=1,p=-1:k/n or(n-k&n-k-p%k>0)&n&f(n,k+1,p*k)

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


うわー、これは非常に非効率的です。ウィルソンの定理による素数検定。プラス側では、262145および2097153で正常に動作します(無制限のスタックとbignumサイズを想定)。他の提出物のいくつかはそうではありません。is-primeアルゴリズムは、(-6)%4 = 2であるため、4で「真」を生成しますが、偶数によって偶数が拒否されるため、これは問題になりません&n&。1 + 4 = 5であるため、デポリニャック数である場合、5は偽陰性になりますが、2 + 3 = 5であるため、これは問題ではありません。
デッドコード

7

ゼリー、10 バイト

既に投稿されているものに代わる10バイトの代替ゼリー提出。

_ÆRBS€’×ḂẠ

de Polignac番号に対して1を返し、それ以外の場合は0を返すモナドリンク。

オンラインでお試しください!または 1000未満のものを参照してください。

どうやって?

_ÆRBS€’×ḂẠ - Link: number, n  e.g.  1    3      5                  6                   127
 ÆR        - prime range            []   [2]    [2,3,5]            [2,3,5]             [2,3,5,7,11,13,17,19,23,29,31,37,41,43,47,53,59,61,67,71,73,79,83,89,97,101,103,107,109,113,127]
_          - subtract from n        []   [1]    [3,2,0]            [4,3,1]             [125,124,122,120,116,114,110,108,104,98,96,90,86,84,80,74,68,66,60,56,54,48,44,38,30,26,24,20,18,14,0]
   B       - convert to binary      []   [[1]]  [[1,1],[1,0],[0]]  [[1,0,0],[1,1],[1]  [[1,1,1,1,1,0,1],[1,1,1,1,1,0,0],[1,1,1,1,0,1,0],[1,1,1,1,0,0,0],[1,1,1,0,1,0,0],[1,1,1,0,0,1,0],[1,1,0,1,1,1,0],[1,1,0,1,1,0,0],[1,1,0,1,0,0,0],[1,1,0,0,0,1,0],[1,1,0,0,0,0,0],[1,0,1,1,0,1,0],[1,0,1,0,1,1,0],[1,0,1,0,1,0,0],[1,0,1,0,0,0,0],[1,0,0,1,0,1,0],[1,0,0,0,1,0,0],[1,0,0,0,0,1,0],[1,1,1,1,0,0],[1,1,1,0,0,0],[1,1,0,1,1,0],[1,1,0,0,0,0],[1,0,1,1,0,0],[1,0,0,1,1,0],[1,1,1,1,0],[1,1,0,1,0],[1,1,0,0,0],[1,0,1,0,0],[1,0,0,1,0],[1,1,1,0],0]
    S€     - sum €ach               []   [1]    [2,1,0]            [1,2,1]             [6,5,5,4,4,4,5,4,3,3,2,4,4,3,2,3,2,2,4,3,4,2,3,3,4,3,2,2,2,3,0]
      ’    - decrement              []   [0]    [1,0,-1]           [0,1,0]             [5,4,4,3,3,3,4,3,2,2,1,3,3,2,1,2,1,1,3,2,3,1,2,2,3,2,1,1,1,2,-1]
        Ḃ  - n mod 2                1    1      1                  0                   1
       ×   - multiply               []   [0]    [1,0,-1]           [0,0,0]             [5,4,4,3,3,3,4,3,2,2,1,3,3,2,1,2,1,1,3,2,3,1,2,2,3,2,1,1,1,2,-1]
         Ạ - all truthy?            1    0      0                  0                   1

これがどのように機能するかを理解するために約10分かかりました...素晴らしいテクニック、配列に2のべき乗が含まれていないかどうかを確認する良い方法は考えられませんでした:
ETHproductions


6

Python 2、99バイト

lambda n:n&1-any(n-2**k>1and all((n-2**k)%j for j in range(2,n-2**k))for k in range(len(bin(n))-2))

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

Leaky Nunのおかげで-4バイト

-Wondercricketのおかげで2バイト

間違いを修正するには+8バイト

Xcoder氏のおかげで-1バイト

Einkorn Enchanterのおかげで-3バイト

間違いを修正するには+12バイト


これもPython 3互換の答えだと思いますか?
アリクーパーデイビス

これには、1に対する偽陰性と、262145や2097153などの2 ^ M + 1形式のすべてのde Polignac番号に対する偽陰性があります(後続のものは、4722366482869645213697、38685626227668133590597633、5192296858534827628530496329220097などです)。たとえば、262139、262259、2097131、および2097187を正しく識別するため、数値の大きさは問題ではありません。
デッドコード

1
「素数」が1でないことを確認する@Deadcode明示的チェック。今動作するはずです
HyperNeutrino

6

正規表現(ECMAScript)、97バイト

この問題は、非原子の先読みがないという問題を回避する興味深い事例となりました。そして、これまでのところ、2のべき乗のテストの両方のバージョンを同じ正規表現に入れる正当な理由が((x+)(?=\2$))*x$あり(?!(x(xx)+)\1*$)、プライムテストをマッチングから保護する必要があるのはこれまでで唯一の時間です1、として(?!(xx+)\1+$)xx、より大きな正規表現で使用される場合。

^(?!(xx)*$|(x+)((?!(xx+)\4+$).*(?=\2$)((x+)(?=\6$))*x$|(?!(x(xx)+)\7*$).*(?=\2$)(?!(xx+)\9+$)xx))

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

# For the purposes of these comments, the input number = N.
^
# Assert that N is not the sum of a prime number and a power of 2.
(?!
    (xx)*$                 # Assert that N is odd.
|
    # Since we must cycle through all values for a number X and a corresponding number
    # N-X, this cannot be in an atomic lookahead. The problem then becomes that it
    # consumes characters. Thus we must let X be the larger of the two and N-X be the
    # smaller, and do tests on X followed by tests on N-X. We can't just test X for
    # being prime and N-X for being a power of 2, nor vice versa, because either one
    # could be smaller or larger. Thus, we must test X for being either prime or a
    # power of 2, and if it matches as being one of those two, do the opposite test on
    # N-X.
    # Note that the prime test used below, of the form (?!(xx+)\2+$), has a false match
    # for 0 and 1 being prime. The 0 match is harmless for our purposes, because it
    # will only result in a match for N being a power of 2 itself, thus rejecting
    # powers of 2 as being de Polignac numbers, but since we already require that N is
    # odd, we're already rejecting powers of 2 implicitly. However, the 1 match would
    # break the robustness of this test. There can be de Polignac numbers of the form
    # 2^M+1, for example 262145 and 2097153. So we must discard the 1 match by changing
    # the prime test to "(?!(xx+)\2+$)xx". We only need to do this on the N-X test,
    # though, because as X is the larger number, it is already guaranteed not to be 1.
    (x+)           # \2 = N-X = Smaller number to test for being prime or a power of 2;
                   # tail = X = larger number to test for being prime or a power of 2.
    (
        (?!(xx+)\4+$)      # Test X for being prime.
        .*(?=\2$)          # tail = N-X
        ((x+)(?=\6$))*x$   # Test N-X for being a power of 2. Use the positive version
                           # since it's faster and doesn't have a false match of 0.
    |
        (?!(x(xx)+)\7*$)   # Test X for being a power of 2. Use the negative version
                           # because the testing of X has to be in a lookahead, and
                           # putting the positive version in a positive lookahead would
                           # be worse golf. It doesn't matter that this can have a false
                           # match of 0, because X is guaranteed never to be 0.
        .*(?=\2$)          # tail = N-X
        (?!(xx+)\9+$)xx    # Test N-X for being prime. We must prevent a false match of
                           # 1 for the reason described above.
    )
)

正規表現(ECMAScript +分子先読み)、53 52バイト

^(?!(xx)*$|(?*xx+(((x+)(?=\4$))*x$))\2(?!(xx+)\5+$))

# For the purposes of these comments, the input number = N.
^
# Assert that N is not the sum of a prime number and a power of 2.
(?!
    (xx)*$                   # Assert that N is odd.
|
    (?*
        xx+                  # Force N - \2 to be > 1, because the prime test used
                             # below has a false match of 1, which would otherwise
                             # give us false negatives on de Polignac numbers of the
                             # form 2^M+1, such as 262145 and 2097153.
        (((x+)(?=\4$))*x$)   # Cycle through subtracting all possible powers of 2 from
                             # tail, so we can then test {N - {power of 2}} for being
                             # prime.
                             # \2 = the power of 2
    )
    \2                       # tail = N - \2
    (?!(xx+)\5+$)            # Test tail for being prime. If it matches, this will fail
                             # the outside negative lookahead, showing that N is not a
                             # de Polignac number.
)

このバージョンははるかにクリーンであるだけでなく、Nが2つの数値の合計であるすべての可能な方法を循環する代わりに、Nから2のべき乗をすべて減算して素数であるかどうかをテストできるため、はるかに高速です。

分子の先読みは、可変長の後読みに簡単に変換できます。

正規表現(.NETまたはECMAScript 2018)、55 54バイト

^(?!(xx)*$|xx+(((x+)(?=\4$))*x$)(?<=(?<!^\5+(x+x))\2))

オンラインでお試しください!(.NET)
オンラインでお試しください!(ECMAScript 2018)

# For the purposes of these comments, the input number = N.
^
# Assert that N is not the sum of a prime number and a power of 2.
(?!
    (xx)*$                 # Assert that N is odd.
|
    xx+                    # Force N - \2 to be > 1, because the prime test used
                           # below has a false match of 1, which would otherwise
                           # give us false negatives on de Polignac numbers of the
                           # form 2^M+1, such as 262145 and 2097153.
    (((x+)(?=\4$))*x$)     # Cycle through subtracting all possible powers of 2 from
                           # tail, so we can then test {N - {power of 2}} for being
                           # prime.
                           # \2 = the power of 2
    (?<=
        (?<!^\5+(x+x))     # Test tail for being prime. If it matches, this will fail
                           # the outside negative lookahead, showing that N is not a
                           # de Polignac number.
        \2                 # tail = N - \2
    )
)

正規表現は、^(?!(x+)((?!(xx+)\3+$)x*(?!(x(xx)+)\4*$)|x(?!(x(xx)+)\6*$)x*(?!(xx+)\8+$)x)?\1$)それほど困難なく最適化できます。次に、慎重に考えて、さらにゴルフをすることができます^(?!(x+)((x?)(?!(x(x\3)+)\4+$)x*(?!(x(xx)+|\3\3+)\6+$)\3)?\1$)。さらに短くなる可能性があります
H.PWiz

私の最も短いとはいえ、非常に遅いです
H.PWiz

ああ、(x(xx)+|\3\3+)->(x\3?(xx)+)
H.PWiz

4

Mathematica、41バイト

OddQ@#&&!Or@@PrimeQ[#-2^Range[0,Log2@#]]&

1
これには組み込み機能はありませんか?うわー、驚いた。
ハイパーニュートリノ

1
ここで非常に迷惑なので、Mathematicaは負の素数を素数とみなすか、またはで置換PrimeQ[#-2^Range[0,Log2@#]]してPrimeQ[#-2^Range[0,#]]からで置換することでバイトを節約できますPrimeQ[#-2^Range@#/2]
グレッグマーティン



4

Brachylog15 13バイト

/₂ℕ|>ṗ;?-₍ḃ+1

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

1000までのde Polignac番号を出力します。

false.de Polignac番号などを返しますtrue.

@LeakyNunの削除された回答に基づき、いくつかのバグ修正(許可を得て投稿)。

(@Jonathan Allanのメソッドを使用して、数値が2のべき乗であるかどうかを確認することにより、-2バイト。)

次の場合、指定された番号はde Polignac番号ではありません。

/₂ℕ              It's an even number
   |>ṗ           Or there exists a prime number less than the input
      ;?-₍       which when subtracted from the input
          ḃ      gives a result that has a binary form
           +     such that the sum of the bits 
            1    is 1

=h21バイト短くなりますが、3どちらにも機能しません。
18

(非モバイル)自己への注意:14バイトオンラインで試してみてください!。ジョナサンアランのゼリーの答えに触発されました。
スンダ


あなたのメモのリマインダーは私が推測する?
クロペブ

1
@Deadcodeこれが投稿されたときは機能していたが、その間に分割に関する何かが変更されたようだ。オンラインでお試しください!変更は64の代わりにfalseを返します。変更は言語へのこのコミットによる可能性がありますが、ここでしばらくアクティブになっていないので、意図的なものかバグなのかわかりません。
スンダ-モニカを

3

ゼリー、13バイト

ÆRạl2=Ḟ$o/o‘Ḃ

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

ÆRạl2=Ḟ$o/     Main link; argument is z
ÆR             Generate all primes in the range [2..z]
  ạ            Absolute difference with z for each prime
   l2          Logarithm Base 2
     =Ḟ$       For each one, check if it's equal to its floored value (i.e. if it is an integer)
        o/     Reduce by Logical OR to check if any prime plus a power of two equals the z
          o‘Ḃ  Or it's not an odd number. If it's not an odd number, then automatically return 1 (false).

1falseおよび0trueの出力。


Ḷ2*ạfÆRṆ次にパリティを確認します
リーキー修道女

@LeakyNunはとの両方をḶ2*ạfÆRṆo‘Ḃ返します。そうではありません。それがあなたが提案したものでない限り。112722
ハイパーニュートリノ

使用する必要があります。(または、最後の否定を削除してから9/10バイトでそれを行うことができます)
漏れの修道女

@LeakyNunそこにあなたのスニペット0は149 を与えます。
ETHproductions

@ETHproductionsの権利。それ_@修正するために変更します。
リーキー修道女

2

Perl 6、55バイト

{so$_%2&&$_∉((1,2,4...*>$_) [X+] grep &is-prime,^$_)}

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

  • (1, 2, 4 ... * > $_) 入力引数までの2のべき乗のシーケンスです(Perlは指定された要素から幾何級数を推測します)。
  • grep &is-prime, ^$_ 入力引数までの素数のリストです。
  • [X+] 2つのシリーズの外積のすべての要素の合計を評価します。

so2バイト少なくすることもできましたが、2つの異なる偽の値(0およびFalse)を返します。


2

公理、86バイト

f(n:PI):Boolean==(~odd?(n)=>false;d:=1;repeat(n<=d or prime?(n-d)=>break;d:=d*2);n<=d)

テストと結果

(21) -> for i in 1..600 repeat if f(i) then output i
   1
   127
   149
   251
   331
   337
   373
   509
   599

2

Haskell、104 102バイト

p x=[x]==[i|i<-[2..x],x`mod`i<1]
h k|even k=1>2|2>1=notElem k$((+)<$>(2^)<$>[0..k])<*>filter(p)[1..k]

説明

  • pは素数を見つける関数です(非常に非効率的です!)
  • リストに(+)適用される2 ^部分関数に適用されるリストの作成[0..input]
  • 1をフィルタリングしたリストに上記を適用して素数を入力する
  • 入力がデカルト積に存在しないことを確認するために、すべての可能な値の結果のデカルト積が検索されます
  • 偶数入力が自動的にfalseになるように保護されています。

更新:2バイトのゴルフでEinkorn Enchanterに大声で叫ぶ!


1
p x=[x]==[i|i<-[2..x],x`mod`i<1]短い素数テストです。
小麦ウィザード

@EinkornEnchanter素晴らしいキャッチ!あなたは私に2バイトのゴルフをしました!
maple_shaft

1
filter p[1..k]代わりに行うこともできますfilter(p)[1..k]
ウィートウィザード

1

Common Lisp、134バイト

(lambda(x)(flet((p(x)(loop for i from 2 below x always(>(mod x i)0))))(or(evenp x)(do((j 1(* j 2))(m()(p(- x j))))((or(>= j x)m)m)))))

NIL引数がポリニャック数の場合に戻りTます。それ以外の場合。

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

ゴルフをしていない:

(lambda (n)
  (flet ((prime? (x)                 ; x is prime
           loop for i from 2 below x ; if for i in [2..n-1]
           always (> (mod x i) 0)))  ; is x is not divisible by i
    (or (evenp n)                    ; if n is even is not a Polignac number
        (do ((j 1( * j 2))           ; loop with j = 2^i, i = 0, 1,... 
             (m () (prime? (- n j)))); m = n - 2^i is prime?
            ((or (>= j n)            ; terminate if 2^i ≥ n
                 m)                  ; or if n - 2^i is prime
             m)))))                  ; not a polignac if n - 2^i is prime

1

APL(Dyalog Extended)、12バイト

2∘|⍲0⍭⊢-2*…

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

匿名プレフィックス暗黙関数。真実の場合は1、偽の場合は0を返します。

主にETHProductionsのJapt answerに基づいています

私の元の答えでゴルフを手伝ってくれて、そのためにDyalog Extendedを作ってくれた@Adámに感謝します。

どうやって:

2∘|⍲0⍭⊢-2*…    Tacit prefix function; input will be called 
                Inclusive Range [0..⍵]
         2*      2 to the power of each number in the range
       ⊢-        Subtract each from 
     0          Non-primality check on each resulting number
                Logical NAND
 2∘|             Mod 2
                Not any (bitwise OR reduction, then negated)




0

APL(NARS)80文字、160バイト

∇r←f w;n
r←¯1⋄→0×⍳(w≤0)∨w≥9E9⋄r←0⋄→0×⍳0=2∣w⋄n←r←1
→0×⍳w≤n⋄→3×⍳0πw-n⋄n×←2⋄→2
r←0
∇

関数0πは、引数が素数であるかどうかを返す関数です。私にとって、この関数は再帰的ではないため、もう少し長くなります...テスト:

  {1=f ⍵:⍵⋄⍬}¨1..1000
1  127  149  251  331  337  373  509  599  701  757  809  877  905  907  959  977  997 

入力<= 0または入力> = 9E9の場合、¯1(エラー)を返します

  f¨0 ¯1 ¯2 900000000001
¯1 ¯1 ¯1 ¯1 

0

C#(Visual C#Interactive Compiler)、107バイト

x=>{var r=Enumerable.Range(2,x);return x%2>0&r.All(p=>r.Any(d=>d<p&p%d<1)|r.All(n=>x!=p+Math.Pow(2,n-2)));}

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

最も効率的なコードではありませんが、機能しているようです。私の元のソリューションは、数式でテストする前に素数をフィルター処理したため、はるかに優れたパフォーマンスを発揮しました。現在のバージョンは11バイト短くなっています。

// input x is an integer
x=>{
  // we need to generate several
  // ranges. since this is verbose,
  // generate 1 and keep a reference
  var r=Enumerable.Range(2,x);
  // this is the main condition
  return
     // input must be odd
     x%2>0&
     // generate all possible p's
     // over our range and ensure that
     // they satisfy the following
     r.All(p=>
       // either p is not prime
       r.Any(d=>d<p&p%d<1)
       |
       // or there is no n that satisfies
       // the formula: x=p+2^n
       r.All(n=>x!=p+Math.Pow(2,n-2))
     );
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.