Üçgen Bağımlılıklar


25

Bir üçgen sayısı toplamı olan bir sayıdır n, 1 ila doğal sayılar n. Örneğin 1 + 2 + 3 + 4 = 10böylece 10üçgen bir sayıdır.

0 < n <= 10000Giriş olarak pozitif bir tamsayı ( ) verildiğinde ( bir tamsayı veya bir dize olarak alınabilir), başka bir üçgen sayı oluşturmak için girişe eklenebilecek en küçük üçgen sayısını döndürün.

Örneğin verilen girdi 26, 10sonuçların 36üçgen şeklinde olduğu bir sonuç eklemek . Başka bir üçgen sayı oluşturmak 10için eklenebilecek sayıdan daha küçük üçgen sayıları yoktur , bu durumda bu doğru sonuçtur.2610

0 üçgen bir sayıdır, bu nedenle girişin kendisi de üçgen bir sayıysa 0

testcases

Vakalar formatta verilmiştir. input -> output (resulting triangular number)

0     -> 0   (0)
4     -> 6   (10)
5     -> 1   (6)
7     -> 3   (10)
8     -> 28  (36)
10    -> 0   (10)
24    -> 21  (45)
25    -> 3   (28)
26    -> 10  (36)
34    -> 21  (55)
10000 -> 153 (10153)

puanlama

Bu yani her dilde en az bayt kazanıyor!


Öyle değil mi 26 -> 2?
Okx,

@Okx Aynı hatayı ben yaptım, başka bir üçgen sayı yapmak için geçerli olana eklemek için üçgen bir sayı bulmanız gerekiyor .
Martin Ender

2
İlgili. (borderline duplicate)
Martin Ender

Yanıtlar:


21

Java 8, 58 57 bayt

n->{int i=0,m=0;while(n!=0)n+=n<0?++i:--m;return-~i*i/2;}

Çevrimiçi test paketi

1-byte tasarruf için Dennis'e teşekkürler .


6
Şimdi bu Java, golf! :)
Olivier Grégoire

4
@ Computronium, işlemlerin sırası Java Dil Belirtimi ile garanti altına alınmıştır . Java kasıtlı olarak C'nin bazı zayıflıklarından kaçınır
Peter Taylor


2
return-~i*i/2;bir bayt kaydeder.
Dennis

1
@Okx Java, ilkel türler için by-value ve nesneler (diziler dahil) için by-by-pass değeridir. Aslında aynı değişkende çıktı almak istiyorsanız, referansa göre bir bağlamda olmanız gerekir (açıkça bağlantınızda belirtilir). İşe yarayabilecek referans olarak görebilmemin tek yolu int[], bir intargüman yerine bir dize geçmek . Ancak bu daha sonra dizilerle ilgilenmek anlamına gelir. Bu işe yarayabilir: x->{int i=0,m=0,n=x[0];while(n!=0)n+=n<0?++i:--m;x[0]=-~i*i/2;}ama 63 bayttır.
Olivier Grégoire

7

Matl , 13 12 bayt

1 bayt, Emigna'nın 05AB1E yanıtından bir fikir (kesişme kümesi) kullanarak kaldırıldı

Q:qYstG-X&X<

Çevrimiçi deneyin!

açıklama

- Üçgen sayıyı t(n) = 1 + 2 + ··· + ngösterelim n.

Kod, verilen gerçeği kullanır n çözümün üst sınırlarat(n-1) . Bunu görmek için, t(n-1) + neşittir t(n)ve bu yüzden üçgen bir sayı olduğunu gözlemleyin .

8Bir örnek olarak girişi düşünün .

Q:q   % Input n implicitly. Push [0 1 2 ... n]
      % STACK: [0 1 2 3 4 5 6 7 8]
Ys    % Cumulative sum
      % STACK: [0 1 3 6 10 15 21 28 36]
t     % Duplicate
      % STACK: [0 1 3 6 10 15 21 28 36], [0 1 3 6 10 15 21 28 36]
G-    % Subtract input, element-wise
      % STACK: [0 1 3 6 10 15 21 28 36], [-8 -7 -5 -2  2  7 13 20 28]
X&    % Set intersection
      % STACK: 28
X<    % Minimum of array (in case there are several solutions). Implicit display
      % STACK: 28

QSınırlılık hakkındaki argümanınızla öncüyü kaldırabilir misiniz ?
Giuseppe

@Giuseppe Hayır, bu giriş için başarısız olur 8. Çıktı sınırlamaya eşit olduğunda, t(n-1)kod onu alır t(n)-n. Bu yüzden t(n)gerekli. Yine de fikir için teşekkürler!
Luis Mendo

7

Java (OpenJDK 8) , 83 bayt

n->{int m=0,a=n,b;for(;a-->0;)for(b=0;b<=n;)m=2*n+b*~b++==a*~a?a*a+a:m;return m/2;}

Çevrimiçi deneyin!

Kredi


1
Güzel cevap (her zamanki gibi ..). Benimkileri gönderdiğimde zaten bir Java cevabı olduğunu fark etmemiştim .. Mine başlangıçta kısaydı, fakat artık görünmüyordu. :)
Kevin Cruijssen

Teşekkürler! Evet, ilk cevabım gerçekten gereksizdi. Ben de onu daha fazla açgözlü olsa da düzelttim ve daha fazla matematik yaptım. Bir saniye içinde seninkini kontrol edeceğim!
Olivier Grégoire

Burada ne olduğunu hala anlamadım. Neden çalışıyor Her seferinde m'yi değiştiriyorsun, peki nokta ne?
V. Courtois,

2
@ V.Courtois Soru en küçük soruyor m. Bu yüzden aaşağıdan aşağıya gidiyorum 0. "ama sen belki 100 kat aynı değeri atıyorsanız a*a+aiçin mde b, evet, bunu 100 kere yapmanız gerekmez -loop" ama kırarak vermeyerek bayt kazanıyor ediyorum bönceki -loop.
Olivier Grégoire

@ Olivier Gargoire'ı görüyorum. Yani bu bilerek anti-verimli: D
V. Courtois

5

Mathematica, 46 bayt

Min[Select[(d=Divisors[2#])-2#/d,OddQ]^2-1]/8&

4

Neim , 12 9 bayt

tS𝕊Λt𝕚)0𝕔

Bu, hesaplanması çok uzun sürüyor (ancak sonsuz zaman ve bellek verilen eserler), bu yüzden bağlantıda sadece ilk 143 üçgen sayıyı oluşturuyorum - kullanarak £𝕖, 10.000 girişini işlemek için yeterli ancak zaman aşımına uğramak için yeterli değil.

Uyarı: bu gelecek sürümlerde çalışmayabilir. Öyleyse, 143 yerine £ kullanın

Açıklama:

t                 Infinite list of triangular numbers
 [ 𝕖]             Select the first  v  numbers
 [£ ]                              143
     S𝕊           Subtract the input from each element
       Λ  )       Only keep elements that are
        t𝕚          triangular
           0𝕔     Get the value closest to 0 - prioritising the higher number if tie

Dene!


0 ile 10000 arasındaki herhangi bir giriş için ilk 143 üçgen sayıları nasıl olur? Girişi ile 9998, beklenen sonuç 3118753, yol ( '10296 olan) 143 üçgen sayısının üzerinde olan.
Olivier Grégoire

@ OlivierGrégoire çünküThis takes too long to compute (but works given infinite time and memory)
Stephen

Teşekkürler @StepHen ama dediğim bu değildi. Kastettiğim şudur: "ilk 143 üçgen sayıları, 10.000 girdiyle başa çıkmak için yeterlidir" cümlesi yanlıştır. Ben matematik yapmadım, ancak 10000'e kadar olan durumları ele almak için yaklaşık 10000 (vermek veya almak) üçgen numaralarına ihtiyaç duymanız gerektiğine inanıyorum.
Olivier Grégoire

@ OlivierGrégoire 10.000 giriş yapmanın yeterli olduğunu, ancak ondan daha az sayılamayacağını söyledim. £200 gibi daha yüksek bir sayıya geçmek için çekinmeyin .
Okx

@Okx Tamam, ilk okuduğumda böyle bir şey anlamadım, açıklamaya zaman ayırdığınız için teşekkür ederim :)
Olivier Grégoire

4

PHP , 45 bayt

for(;!$$t;$t+=++$i)${$argn+$t}=~+$t;echo~$$t;

Çevrimiçi deneyin!

Kısa çeşididir for(;!$r[$t];$t+=++$i)$r[$argn+$t]=~+$t;echo~$r[$t];

Expanded

for(;!$$t;  # stop if a triangular number exists where input plus triangular number is a triangular number
$t+=++$i) # make the next triangular number
  ${$argn+$t}=~+$t; # build variable $4,$5,$7,$10,... for input 4 
echo~$$t; # Output result 

PHP , 53 bayt

for(;$d=$t<=>$n+$argn;)~$d?$n+=++$k:$t+=++$i;echo+$n;

Çevrimiçi deneyin!

PHP 7'de yeni uzay gemisi operatörünü kullanın.

Expanded

for(;$d=$t<=>$n+$argn;) # stop if triangular number is equal to input plus triangular number 
  ~$d
    ?$n+=++$k  # raise additional triangular number
    :$t+=++$i; # raise triangular number sum
echo+$n; # Output and cast variable to integer in case of zero

PHP , 55 bayt

for(;fmod(sqrt(8*($t+$argn)+1),2)!=1;)$t+=++$i;echo+$t;

Çevrimiçi deneyin!


4

Java 8, 110 102 100 93 92 bayt

n->{int r=0;for(;t(r)<-t(n+r);r++);return r;}int t(int n){for(int j=0;n>0;n-=++j);return n;}

@PeterTaylor sayesinde -2 bayt . -JollyJoker
sayesinde -7 bayt . @Ceilingcat sayesinde -1 bayt .

Açıklama:

Çevrimiçi deneyin.

n->{                  // Method with integer as parameter and return-type
  int r=0;            //  Result-integer (starting at 0)
  for(;t(r)<-t(n+r);  //  Loop as long as neither `r` nor `n+r` is a triangular number
    r++);             //   And increase `r` by 1 after every iteration
  return r;}          //  Return the result of the loop

int t(int n){         // Separate method with integer as parameter and return-type
                      // This method will return 0 if the input is a triangular number
  for(int i=0;n>0;)   //  Loop as long as the input `n` is larger than 0
    n-=++j;           //   Decrease `n` by `j` every iteration, after we've raised `j` by 1
  return n;}          //  Return `n`, which is now either 0 or below 0

1
Java çözümlerini okumak en kolay :)
JollyJoker

@ JollyJoker Belki de bu yüzden en uzun. ;) Yoksa ek açıklamam yüzünden mi?
Kevin Cruijssen

Hayır, kod hakkında düşünüyordum. Peter Taylor'ın çözümünün nasıl çalıştığını bulmak için muhtemelen 15 dakika harcadım. Seninki bile yorum yapmadan belli oluyor.
JollyJoker

3

Brachylog , 17 15 bayt

⟦{a₀+}ᶠ⊇Ċ-ṅ?∧Ċh

Çevrimiçi deneyin!

açıklama

⟦                  [0, …, Input]
 {   }ᶠ            Find all…
  a₀+                …Sums of prefixes (i.e. triangular numbers)
       ⊇Ċ          Take an ordered subset of two elements
         -ṅ?       Subtracting those elements results in -(Input)
            ∧Ċh    Output is the first element of that subset

3

Python 2 , 59 bayt

lambda n:min((r-2*n/r)**2/8for r in range(1,2*n,2)if n%r<1)

Çevrimiçi deneyin!

Bu, üçgen bir sayı elde tetmek niçin eklenebilecek üçgen sayıların aşağıdaki karakterizasyonunu kullanır :

8*t+1 = (r-2*s)^2bölen çiftleri için (r,s)olan r*s==nve rtek.

Kod, tüm bu üçgen sayıların minimumunu alır.


3

Jöle , 8 bayt

0r+\ðf_Ḣ

Çevrimiçi deneyin!

Nasıl çalışır

0r+\ðf_Ḣ  Main link. Argument: n

0r        Build [0, ..., n].
  +\      Take the cumulative sum, generating A := [T(0), ..., T(n)].
    ð     Begin a dyadic chain with left argument A and right argument n.
      _   Compute A - n, i.e., subtract n from each number in A.
     f    Filter; keep only numbers of A that appear in A - n.
       Ḣ  Head; take the first result.

3

Japt , 24 23 16 15 bayt

ò å+
m!nNg)æ!øU

Dene

ETH sayesinde 1 bayt kurtarıldı


açıklama

    :Implicit input of integer U.
ò   :Create an array of integers from 0 to U, inclusive.
å+  :Cumulatively reduce by summing. Result is implicitly assigned to variable V.
m   :Map over U.
!n  :From the current element subtract...
Ng  :  The first element in the array of inputs (the original value of U).
æ   :Get the first element that returns true when...
!øU :  Checking if U contains it.
    :Implicit output of resulting integer.

Sanırım bir bayt kurtarabilirsin æ!øV. Bunun dışında, harika görünüyor :-)
ETHproductions



2

Mathematica, 62 bayt

(s=Min@Abs[m/.Solve[2#==(n-m)(n+m+1),{n,m},Integers]])(s+1)/2&

I don't know Mathematica, but would Solve[2*#==m(m+1)-n(n+1) be shorter (if it works)?
Kritixi Lithos

yes, I just posted my answer and trying to golf it right now
J42161217

2

Python 2, 78 71 70 bytes

Seven bytes saved, thanx to ovs and theespinosa

One more byte saved due to the remark of neil, x+9 is suffisant and checked for all natural numbers 0 <= n <= 10000. It was also verified for x+1 instead of x+9, it works also.

x=input()
I={n*-~n/2for n in range(x+1)}
print min(I&{i-x for i in I})

Try it online!


2
You can use n*-~n/2 instead of n*(n+1)/2
ovs

2
Would range(x+9) work?
Neil

2
You can use {n*(n+1)/2for n in range(999)} instead of explicit set and also use {} instead of set in the third line
TheEspinosa

2

JavaScript (ES6), 43 42 bytes

f=(n,a=s=0)=>n?f(n+=n>0?--s:++a,a):a*++a/2
<input type=number min=0 value=0 oninput=o.textContent=f(+this.value)><pre id=o>0

Edit: Saved 1 byte thanks to @PeterTaylor.


Setting a global variable is a hideous abuse of a default parameter. +1. But FWIW you can save a further byte by replacing -++s with --s, as I did in my independently derived but quite similar Java version. (Addendum: you also need to change the test to n>0).
Peter Taylor

@PeterTaylor Huh, so the n>s check was a red herring all along!
Neil

Works not for 8192
Jörg Hülsermann

@JörgHülsermann If you're referring to the snippet, then your browser's stack size may not be large enough, or you may need a browser with experimental tail call optimisation. Alternatively, if you're using NodeJS for testing, use node --stack_size= to increase its stack size.
Neil

2

Python 3, 60 44 bytes

f=lambda n,k=1:(8*n+1)**.5%1and f(n+k,k+1)+k

Thanks to @xnor for a suggestion that saved 16 bytes!

Try it online!

Background

Let n be a non-negative integer. If n is the kth triangular number, we have

condition

which means there will be a natural solution if and only if 1 + 8n is an odd, perfect square. Clearly, checking the parity of 1 + 8n is not required.

How it works

The recursive function n accepts a single, non-negative integer as argument. When called with a single argument, k defaults to 1.

First, (8*n+1)**.5%1 tests if n is a triangular number: if (and only if) it is, (8*n+1)**.5 will yield an integer, so the residue from the division by 1 will yield 0.

If the modulus is 0, the and condition will fail, causing f to return 0. If this happens in the initial call to f, note that this is the correct output since n is already triangular.

If the modulus is positive, the and condition holds and f(n+k,k+1)+k gets executed. This calls f again, incrementing n by k and k by 1, then adds k to the result.

When f(n0, k0) finally returns 0, we back out of the recursion. The first argument in the first call was n, the second one n + 1, the third one n + 1 + 2, until finally n0 = n + 1 + … k0-1. Note that n0 - n is a triangular number.

Likewise, all these integers will be added to the innermost return value (0), so the result of the intial call f(n) is n0 - n, as desired.


If you increment n in recursing as well, you can write n rather than (n+k).
xnor


Wow, that's a lot nicer than what I was trying.
xnor

2

C# (.NET Core), 291 281 bytes

class p{static int Main(string[]I){string d="0",s=I[0];int c=1,j,k;for(;;){j=k=0;string[]D=d.Split(' '),S=s.Split(' ');for(;j<D.Length;j++)for(;k<S.Length;k++)if(D[j]==S[k])return int.Parse(D[k]);j=int.Parse(D[0])+c++;d=d.Insert(0,$"{j} ");s=s.Insert(0,$"{j+int.Parse(I[0])} ");}}}

Try it online! Program that takes a string as input and outputs through Exit Code.

Saved 10 Bytes thanks to Kevin Cruijssen


1
Hi, welcome to PPCG! You don't need a full program unless the challenge states otherwise. The default is program/function, so a lambda is allowed as well in C#. But if you want to use program, you can golf some things in your current code: class p{static int Main(string[]I){string d="0",s=I[0];int c=1,j,k;for(;;){j=k=0;string[]D=d.Split(' '),S=s.Split(' ');for(;j<D.Length;j++)for(;k<S.Length;k++)if(D[j]==S[k])return int.Parse(D[k]);j=int.Parse(D[0])+c++;d=d.Insert(0,$"{j} ");s=s.Insert(0,$"{j+int.Parse(I[0])} ");}}} (281 bytes)
Kevin Cruijssen

@KevinCruijssen Thanks for the advice! using for(;;) to make an infinite loop is a nice bump, and I'll make sure to think more carefully about whether using var is actually more efficient than using an explicit type but combining the declarations, and I guess be more diligent in removing unnecessary brackets. As for the program vs. function, I started with a lambda but couldn't get it to run in TIO. I know a TIO link isn't actually necessary, but it's something I like to see in others' answers so I wanted at least something similar in my own.
Kamil Drakari

I'm also not very good in C# lambdas tbh, I usually codegolf in Java. But I think this should be correct. (252 bytes). Also, in case you haven't seen it yet: Tips for code-golfing in C# and Tips for golfing in <all languages> might be interesting to read through. Again welcome, and +1 from me. Nice first answer. Enjoy your stay. :)
Kevin Cruijssen

2

JavaScript (ES7), 46 44 bytes

f=(n,x=r=0)=>(8*(n+x)+1)**.5%1?f(n,x+=++r):x

Try it

o.innerText=(
f=(n,x=r=0)=>(8*(n+x)+1)**.5%1?f(n,x+=++r):x
)(i.value=8);oninput=_=>o.innerText=f(+i.value)
<input id=i type=number><pre id=o>


1
Would r=x=0 work?
Kritixi Lithos

Sadly not, @KritixiLithos.
Shaggy

1

05AB1E, 8 bytes

ÝηODI-Ãн

Try it online! or as a Test suite

Explanation

Ý          # range [0 ... input]
 η         # prefixes
  O        # sum each
   D       # duplicate
    I-     # subtract input from each
      Ã    # keep only the elements in the first list that also exist in the second list
       н   # get the first (smallest)

1

Dyalog APL, 19 bytes

6 bytes saved thanks to @KritixiLithos

{⊃o/⍨o∊⍨⍵+o←0,+\⍳⍵}

Try it online!

How?

o←0,+\⍳⍵ - assign o the first triangular numbers

o/⍨ - filter o by

o∊⍨⍵+o - triangular numbers that summed with produce triangulars

- and take the first


+\⍳⍵ should work instead of what you are using to generate the triangular numbers.
Kritixi Lithos

I think works instead of ⌊/
Kritixi Lithos



1

Add++, 68 bytes

L,RBFEREsECAAx$pBcB_B]VARBFEREsB]GEi$pGBcB*A8*1+.5^1%!!@A!@*b]EZBF#@

Try it online!, or see the test suite!

Even Java is beating me. I really need to add some set commands to Add++

How it works

L,    - Create a lambda function
      - Example argument:  8
  R   - Range;     STACK = [[1 2 3 4 5 6 7 8]]
  BF  - Flatten;   STACK = [1 2 3 4 5 6 7 8]
  ER  - Range;     STACK = [[1] [1 2] ... [1 2 3 4 5 6 7 8]
  Es  - Sum;       STACK = [1 3 6 10 15 21 28 36]
  EC  - Collect;   STACK = [[1 3 6 10 15 21 28 36]]
  A   - Argument;  STACK = [[1 3 6 10 15 21 28 36] 8]
  A   - Argument;  STACK = [[1 3 6 10 15 21 28 36] 8 8]
  x   - Repeat;    STACK = [[1 3 6 10 15 21 28 36] 8 [8 8 8 8 8 8 8 8]]
  $p  - Remove;    STACK = [[1 3 6 10 15 21 28 36] [8 8 8 8 8 8 8 8]]
  Bc  - Zip;       STACK = [[1 8] [3 8] [6 8] [10 8] [15 8] [21 8] [28 8] [36 8]]
  B_  - Deltas;    STACK = [-7 -5 -2 2 7 13 20 28]
  B]  - Wrap;      STACK = [[-7 -5 -2 2 7 13 20 28]]
  V   - Save;      STACK = []
  A   - Argument;  STACK = [8]
  R   - Range;     STACK = [[1 2 3 4 5 6 7 8]]
  BF  - Flatten;   STACK = [1 2 3 4 5 6 7 8]
  ER  - Range;     STACK = [[1] [1 2] ... [1 2 3 4 5 6 7 8]]
  Es  - Sum;       STACK = [1 3 6 10 15 21 28 36]
  B]  - Wrap;      STACK = [[1 3 6 10 15 21 28 36]]
  G   - Retrieve;  STACK = [[1 3 6 10 15 21 28 36] [-7 -5 -2 2 7 13 20 28]]
  Ei  - Contains;  STACK = [[1 3 6 10 15 21 28 36] [0 0 0 0 0 0 0 1]]
  $p  - Remove;    STACK = [[0 0 0 0 0 0 0 1]]
  G   - Retrieve;  STACK = [[0 0 0 0 0 0 0 1] [-7 -5 -2 2 7 13 20 28]]
  Bc  - Zip;       STACK = [[0 -7] [0 -5] [0 -2] [0 2] [0 7] [0 13] [0 20] [1 28]]
  B*  - Products;  STACK = [0 0 0 0 0 0 0 28]
  A   - Argument;  STACK = [0 0 0 0 0 0 0 28 8]
  8*  - Times 8;   STACK = [0 0 0 0 0 0 0 28 64]
  1+  - Increment; STACK = [0 0 0 0 0 0 0 28 65]
  .5^ - Root;      STACK = [0 0 0 0 0 0 0 28 8.1]
  1%  - Frac part; STACK = [0 0 0 0 0 0 0 28 0.1]
  !!  - To bool;   STACK = [0 0 0 0 0 0 0 28 1]
  @   - Reverse;   STACK = [1 28 0 0 0 0 0 0 0]
  A   - Argument;  STACK = [1 28 0 0 0 0 0 0 0 8] 
  !   - Not;       STACK = [1 28 0 0 0 0 0 0 0 0]
  @   - Reverse;   STACK = [0 0 0 0 0 0 0 0 28 1]
  *   - Multiply;  STACK = [0 0 0 0 0 0 0 0 28]
  b]  - Wrap;      STACK = [0 0 0 0 0 0 0 0 [28]]
  EZ  - Unzero;    STACK = [[28]]
  BF  - Flatten;   STACK = [28]
  #   - Sort;      STACK = [28]
  @   - Reverse;   STACK = [28]

1

R, 46 44 43 41 bytes

function(x,y=cumsum(0:x))y[(x+y)%in%y][1]

Try it online!

An anonymous function with one mandatory argument, x; computes first x+1 triangular numbers as an optional argument to golf out a few curly braces. I used choose before I saw Luis Mendo's Octave answer.

I shaved off a few bytes of Luis Mendo's answer but forgot to use the same idea in my answer.





0

Clojure, 74 bytes

#(nth(for[t[(reductions +(range))]i t :when((set(take 1e5 t))(+ i %))]i)0)
#(nth(for[R[reductions]i(R + %(range)):when((set(R - i(range 1e5)))0)]i)0)

Pick your favourite :) Loops might be shorter...


0

Python 2, 82 bytes

f=lambda n,R=[1]:n-sum(R)and f(n,[R+[R[-1]+1],R[1:]][sum(R)>n])or sum(range(R[0]))

Try it online

This was created by modifying this answer from the related question.


works not for 8192
Jörg Hülsermann

It doesn't work for that on the related question either, because of the recursion depth. I'm not sure what the consensus is on that.
mbomb007

Some other answers have the same problem. I give only the info
Jörg Hülsermann
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.