Bana hamlelerini söyle


28

Jack ve Jane uzakta iken bir satranç oyunu oynamaya karar verdi. Ne yazık ki, Jack görselleştirme konusunda oldukça kötü. Bir piyondan başka bir parçaya verilebilecek hamleleri bulmakta zorlanıyor elbette!

Buradaki zorluk, Jack'in verilen bir parça için olası seçenekleri bulmasına yardımcı olmaktır (piyon hariç).

Birinin unutması durumunda, çeşitli parçalar şöyle gösterilir:

  • K: King
  • S: Kraliçe
  • N: Şövalye
  • B: Piskopos
  • R: Kale

Bir örnek olarak, aşağıdaki görüntü Knight bulunmaktadır d4ve hareket edebilir c2, b3, b5, c6, e6, f5, f3, e2. Verilen bir giriş için:

Nd4

üreteceksin:

Nc2 Nb3 Nb5 Nc6 Ne6 Nf5 Nf3 Ne2

görüntü tanımını buraya girin

Kurallar:

  • Tüm olası hareketler listelendiği sürece çıktının sırası önemli değildir
  • Olası hareketler boşluklarla, yeni satırlarla veya diğer sınırlayıcılarla ayrılabilir
  • Giriş programa bir parametre olarak veya üzerinden iletilebilir STDIN
  • Programdaki boşluklar sayılmalıdır, bu yüzden onu en iyi şekilde kullanın

Bu kod golfü. (Lütfen amaç için özel olarak tasarlanmış araçları / araçları kullanmaktan kaçının.) En kısa cevap kazanır!


1
Bunun kod golf olarak işe yarayacağına inanıyorum
John Dvorak

3
Kod golf daha iyi bir seçimdir. Açıkça her zaman unutulur: Bir işlevi veya programı sunabileceğimizi ve girdi / çıkışın stdin / stout veya parametreler / dönüş değeri olabileceğini anlıyorum. Kraliçe için özyinelemenin burada faydalı olabileceğini düşünüyorum: f(x)... case "Q": {f("B");f("R")}Eğer işlev # içerirse, bunlar bayt sayısının bir parçası olmalıdır.
Seviye Nehri St

4
Bu grafikteki yazı tipi. xD
cjfaure

1
Olası hamlelerin boşluklarla ayrılması mı gerekiyor yoksa yeni satırlar da iyi mi?
Dennis,

1
Bir piyonun yasal hamleleri, diğer parçalara göre daha sarsıntılıdır (passant, çapraz yakalama ve 2 kare başlangıç ​​hareketi). öyleyse jack'in de castling kurallarını ezberlediğini varsayıyorum?
saat

Yanıtlar:


7

GolfScript, 94 93 karakter

Benim ilk GolfScript programım! Bu beni gerçekten ne yaptığımı bilmemekle uğraşmak için bir saat sürdü, ancak ısrar ettim ve sanırım dil temellerini öğrenmeyi ve oldukça iyi bir şekilde golf oynamayı başardım.

Tamamen golf :

{}/8,{97+.3$-.*:>8,{49+.4$-.*:^2$+.[3<>^*4=>^=>^*!.2$|]"KNBRQ"8$?=*{[5$3$@]""+p}{;}if}/;;}/];

Yorum ve güzel kaynak :

{}/              # tIn fIn rIn
8,{97+           #             fTst
  .3$-.*:>       #                  fDif^2 : >
  8,{49+         #                         rTst 
    .4$-.*:^     #                              rDif^2 : ^
    2$+.         #                                     ^>+
    [3<          # These    #                              [validK
     >^*4=       # checks   #                                      validN
     >^=         # do not   #                                             validB
     >^*!        # account  #                                                    validR
     .2$|]       # for null #                                                           validQ]
    "KNBRQ"8$?=  # move;    #                          valid
    *            # * does.  #                          validNotNull
    {[5$3$@]""+p}{;}if  # print? #  fDif^2
  }/;;           #        rIn
}/];

Claudiu'nun cevabı gibi görünebilir, çünkü cevabını ve benim yayınlanmamış (C) çözümümü referans olarak verdim. (Görece) karmaşık, çalışan bir GolfScript programının iyi bir örneğini sundu ve dil hakkında çok şey öğrenmeme yardımcı oldu. Teşekkürler, Claudiu!

Hala GolfScript'te yeni olmak, herhangi bir geri bildiriminiz varsa, duymanızı memnuniyet duyarım!


Müthiş! Güzel iş =). Benimkinden nasıl 40 karakter daha kısaldığını görmek için daha yakından bakmak zorunda kalacağım. Golfscript eğlenceli değil mi?
Claudiu

12

Python, 217 212 220 217 213 karakterler

213 baytlık Mathematica çözümünü bağladılar

R=range(8)
def f((p,x,y)):
 for a in R:
    for b in R:
     A,B=abs(a-ord(x)+97),abs(b-ord(y)+49);C=max(A,B);r=(A+B==3and C<3,C<2,A*B<1,A==B,0)
     if(r['NKRBQ'.index(p)],any(r[1:]))[p=='Q']*C:print p+chr(a+97)+chr(b+49)

Geçerli tüm hareketleri üreterek başladım, ancak bu çok büyüdü, bu yüzden yaklaşım Mathematica ile aynıydı.

>>> f("Nd4")
Nb3
Nb5
Nc2
Nc6
Ne2
Ne6
Nf3
Nf5
>>> f("Qa1")
Qa2
Qa3
Qa4
Qa5
Qa6
Qa7
Qa8
Qb1
Qb2
Qc1
Qc3
Qd1
Qd4
Qe1
Qe5
Qf1
Qf6
Qg1
Qg7
Qh1
Qh8

Bu argüman dizesiyle karakter karakterlerinin güzel bir şekilde çıkartılması. Python 3'te artık işe
yaramaması

10

Mathematica, 278 272 264 260 215 213 karakter

f=(FromCharacterCode@Flatten[Table[c=Abs[#2-x];d=Abs[#3-y];b=c==d;r=#2==x||#3==y;If[Switch[#-75,0,c~Max~d<2,-9,b,7,r,6,b||r,3,!r&&c+d==3],{p,x,y},##&[]],{x,97,104},{y,49,56}]&@@ToCharacterCode@#,1]~DeleteCases~#)&

Ungolfed versiyonu:

f[pos_] := (
  {piece, u, v} = ToCharacterCode@pos;
  board = Flatten[Table[{piece, i + 96, j + 48}, {i, 8}, {j, 8}], 1];
  DeleteCases[
    FromCharacterCode[
      Cases[board, {_, x_, y_} /; Switch[p,
        75, (* K *)
        ChessboardDistance[{x, y}, {u, v}] < 2,
        66, (* B *)
        Abs[u - x] == Abs[v - y],
        82, (* R *)
        u == x || v == y,
        81, (* Q *)
        Abs[u - x] == Abs[v - y] || u == x || v == y,
        78, (* N *)
        u != x && v != y && ManhattanDistance[{x, y}, {u, v}] == 3
        ]
      ]
    ], 
    pos (* remove the input position *)
  ]
)&

Örnek kullanım:

f["Nd4"]
> {"Nb3", "Nb5", "Nc2", "Nc6", "Ne2", "Ne6", "Nf3", "Nf5"}

Asılsız sürüm tam bir tahta oluşturur ve sonra ile doğru pozisyonları seçer Cases, oysaki golf versiyonunun Tableihracı hemen geçersiz olan komutları geçersiz kılar ##&[], sadece ortadan kaybolur.


Sadece girdiyi merak N4dediyorsun , değil mi? Bunun Nd4yerine olmamalı mı ?
devnull

@ devevull, bu bir yazım hatası. olmalı Nd4.
Martin Ender

Bir bugün işlevini bilen ÖğrenilmişChessboardDistance
homoseksüel

Mathematica / Wolfram Language belgelerine göre, "ChessboardDistance [u, v], Max [Abs [uv]] 'ye eşdeğerdir." Belki ikinci formu kullanarak karakterleri kaydedebilirsiniz, özellikle eğer Abs [uv] yerine | uv |
Michael Stern,

@MichaelStern tam olarak golf versiyonunda yapıyorum;). Ve ne yazık ki dikey çubuklar AbsMathematica'da işe yaramıyor , çünkü bir modeldeki alternatifleri gösteriyor.
Martin Ender

10

Haskell 225 220 208 205 200 182

f=fromEnum
m[p,a,b]=[[p,c,r]|c<-"abcdefgh",r<-"12345678",let{s=abs$f a-f c;t=abs$f b-f r;g"K"=s<2&&t<2;g"Q"=g"B"||g"R";g"N"=s+t==3&&(s-t)^2<2;g"B"=s==t;g"R"=s<1||t<1}in s+t>0&&g[p]]

İçinde satranç hamleleri varken Mathematica'ya dokunmak zorlaşacak: rollseyes: (iyi oynanmış m.buettner) Hepsini geri alıyorum. 31 yaşında Mathematica'yı yenmek!

En son düzenleme: R;

kullanımı:

ghci> m "Nd4"
["Nb3","Nb5","Nc2","Nc6","Ne2","Ne6","Nf3","Nf5"]

Ungolfed ('u' işaretlenmeden önce 208 karakter versiyonuna karşılık gelir):

f=fromEnum -- fromEnum is 'ord' but for all enum types,
           -- and it's in the prelude, so you don't need an extra import.
u piece dx dy= -- piece is the character eg 'K', dx/dy are absolute so >=0.
  dx+dy > 0 && -- the piece must move.
  case piece of
    'K'->dx<2&&dy<2         -- '<2' works because we already checked dx+dy>0
    'Q'->dx<1||dy<1||dx==dy -- rook or bishop move. see below.
    'N'->dx+dy == 3 &&      -- either 2+1 or 3+0. Exclude the other...
         (dx-dy)^2 < 2      -- 1^2 or 3^2, so valid move is '<2', ie '==1'
    'B'->dx==dy             -- if dx==dy, dx/=0 - we checked that. 
                            -- other moves with dx==dy are along diagonal
    _->dx<1||dy<1           -- use _ not 'R' to save space, default case is
                            -- the rook. '<1' saves chars over '==0'.
                            -- Again, dx==dy==0 edge case is excluded.
m[piece,file,rank]=       -- the move for a piece. 'parse' by pattern match.
 filter(                    -- filter...
  \[_,newfile,newrank]->    -- ...each possible move...
    u piece                 -- ...by, as everyone noticed, converting char..
      (abs$f file-f newfile) -- differences to absolute dx, dy differences,..
      (abs$f rank-f newrank)) -- and then using special routines per piece.
    [[piece,newfile, newrank] -- the output format requires these 3 things.
      |newfile<-"abcdefgh",newrank<-"12345678"] -- and this just generates moves.

Ungolfed versiyonunu da yayınlayabilir misin? (tabii varsa)
homoseksüel

@swish Yapmıyorum ama bunu yazmayı umursamıyorum.
bazzargh

@swish yapıldı. Umarım bu daha mantıklı. Açık bir şeye ihtiyacınız olup olmadığını sorun.
bazzargh

İyi iş! Desen eşleştirmesinde kullanmıyorsanız neden piecelisteye eklemeniz gerekiyor, [piece,newfile, newrank]size bazı karakterleri kaydedebilirsiniz?
homoseksüel

Çıktı için orada. Görüyorsunuz ki '... olası her hareket ...' içinde desen eşleşmem. Aslında ben buna sahip değildim - satranç hamleleri gerektirmiyor - ama sonra istediğini sordum ve herkes bunu yaptı, bu yüzden sadece adil.
bazzargh

8

Bash, 238

B={19..133..19}\ {21..147..21};K=1\ {19..21};N='18 22 39 41';R={1..7}\ {2..14..2}0;Q=$B\ $R
a=${1%??};b=$[20#${1:1}-200];c=`eval{,} echo '$'$a`;d=({a..h})
for i in $c -${c// / -};do echo $a${d[$[(i+=b)/20]]}$[i%20];done|grep '[a-h][1-8]$'

Nasıl çalışır

  • Fikir tahtadaki her alanı sayısal bir değerle temsil etmek, koordinatlarını taban-20 sayı olarak almak ve 200'ü çıkarmaktır. Bu şekilde a1olur 20 * 10 + 1 - 200 = 1, h8olur 20 * 17 + 8 - 200 = 148, vb.

    Şimdi, Piskopos'un muhtemel hamleleri, 19'luk (pozitif veya negatif) katlarla aynı - aynı miktarda basamak (+20) ve sola (-1) - veya 21 - aynı miktarda basamak (+20) ile temsil edilebilir. ) ve sağa (+1).

    Figürün hareketten sonraki yerleşimi, yalnızca orijinal pozisyonunun ve hareketin toplamıdır. Bu sayıları ekledikten sonra, toplamlarının tahtadaki geçerli bir alana karşılık gelip gelmediğini kontrol etmeliyiz.

    Taban (20), mümkün olan en yüksek sayıdan (8) iki kat daha büyük olduğundan, toplam, tahtanın etrafına saramaz , örneğin, Bh1'in yedi adım sağa ve yukarı hareket ettirilmesi , geçersiz bir pano pozisyonuna neden olur.

  • Çizgi

    B={19..133..19}\ {21..147..21};K=1\ {19..21};N='18 22 39 41';R={1..7}\ {2..14..2}0;Q=$B\ $R
    

    Pozitif sayılarla temsil edilen parçaların tüm olası hareketlerini sıralar.

  • Komutları

    a=${1%??};b=$[20#${1:1}-200];c=`eval{,} echo '$'$a`;d=({a..h})
    

    depolar Değişken olarak parçanın tanımlayıcı a , orijinal konumunun sayısal temsili b ve harfler bir üzere saat dizisi olarak d .

    Bağ büyütüldükten sonra eval{,} echo '$'$aolur eval eval echo '$'$a, örneğin, değerlendirir (iki kere kötü), eval echo $K, değerlendirir için echo 1 19 20 21.

  • for i in $c -${c// / -};do …; done tüm olası hareketler ve onların negatif meslektaşları üzerinde döngüler.

  • echo $a${d[$[(i+=b)/20]]}$[i%20] Hareketten sonra son pozisyonu verir.

  • grep '[a-h][1-8]$' geçerli bir yönetim kurulu pozisyonumuz olmasını sağlar.


7

Golfscript, 144 135 karakter

Python çözümümü golf oynamaya devam etmek yerine Golfscript'e çevirdim:

{}/49-:y;97-:x;:N;8,{.x-abs:A
8,{.y-abs:B@[\]$1=:C[B
A+3=\3<&2C>B
A*1<B
A=]81N={(;{|}*}{"NKRB"N?=}if
C*{[N
2$97+@49+]''+p}{;}if
A}/;;}/

Çok fazla golf oynamadan kolayca çeviri yapın, böylece daha da uzağa savuşturulabilir. Yeni bir satır olmadan stdin'den girdi alır, burada deneyin (ilk iki satır stdin'i taklit etmek içindir).


İyi çalışıyor gibi görünüyor! Umarım birileri de bir brainf * ck çözümü bulur.
devnull

6

C 634 632 629 625 600 karakter

#define F for(;i<4;i++){
#define B ;}break;
#define O x=X,y=Y,
P,X,Y,c,r,x,y,i=0, N[8][2]={{-2,1},{-1,2},{1,2},{2,1},{-2,-1},{-1,-2},{1,-2},{2,-1}},S[4][2]={{1,0},{0,1},{-1,0},{0,-1}},D[4][2]={{-1,1},{-1,-1},{1,1},{1,-1}};
C(){return((0<=c)&(c<8)&(0<r)&(r<9))?printf("%c%c%d ",P,c+'a',r):0;}
M(int*m){c=m[0]+x,r=m[1]+y;C()?x=c,y=r,M(m):0;}
main(int a,char**v){char*p=v[1];P=*p,X=p[1]-97,Y=p[2]-48; switch(P){case 75:F c=S[i][1]+X,r=S[i][0]+Y,C(),c=D[i][1]+X,r=D[i][0]+Y,C()B case 81:F O M(D[i]),O M(S[i])B case 78:for(;i<8;i++){c=N[i][1]+X,r=N[i][0]+Y,C()B case 66:F O M(D[i])B case 82:F O M(S[i])B}}

Bunun nasıl geliştirileceğine dair herhangi bir öneriniz var mı? Bu benim ilk kez bir cevap gönderiyorum.


Code Golf'a Hoşgeldiniz! Başlamak için, boşluktaki kodunuzu kaldırabilirsiniz. Unutmayın, kod golf, bu en kısa kodun kazandığını gösterir. Bu nedenle, programınızın boyutunu azaltmaya çalışın.
devnull

Karakter sayısını da güncellemeyi unutmayın!
devnull

@devnull gerekli boşluklar sayılıyor mu?
calccrypto

1
Bir şey daha: Cüçlü operatör ?:ve geri dönüş değeri kullanılarak büyük ölçüde basitleştirilebilir printf. ( printfYazılan karakter sayısını döndürür, bu durumda bu her zaman sıfır değildir.) C(P,c,r){return(0<=c)&(c<8)&(0<r)&(r<9)?printf("%c%c%d ",P,c+'a',r):0;}. Küçük bir düzenleme: Bundan Msonra ifkaldırabileceğiniz fazladan bir boşluk var .
user12205

1
Şu anda herhangi bir yeni satır saymıyor gibi görünüyorsun. İken bazı onlardan çıkarılabilir, diğerleri olamaz. Gerekli yeni satırlar kesinlikle bayt sayımına katkıda bulunmalıdır.
Dennis

3

Haskell, 300 269 ​​karakter

31 karakter kaybetme konusunda yardım için bazzargh'a teşekkürler ...

import Data.Char
f x=filter(x#)[x!!0:y|y<-[v:[w]|v<-"abcdefgh",w<-"12345678"],y/=tail x]
a%b=abs(ord a-ord b)
x#y=let{h=(x!!1)%(y!!1);v=(x!!2)%(y!!2);m=max h v;n=min h v}in case(x!!0)of{'N'->m==2&&n==1;'K'->m==1;'B'->h==v;'R'->n==0;'Q'->('R':tail x)#y||('B':tail x)#y}

Mathematica sürümüyle aynı algoritma. Ghci'den örnek çıktı:

*Main> f "Nd4"
["Nb3","Nb5","Nc2","Nc6","Ne2","Ne6","Nf3","Nf5"]
*Main> f "Ni9"
["Ng8","Nh7"]

(Akıl sağlığı kontrolünü istemediniz!)


Sözdizimsel boşluktan kurtulabilirsiniz. Cevabımı burada görün: codegolf.stackexchange.com/questions/19255/… (daha spesifik olmak gerekirse, izin verin {h = d (x !! 1) (y !! 1); ...})
bazzargh

1

Haskell, 446 karakter

import Data.Char
a=[-2,-1,1,2]
b=[-1,1]
d=[1..8]
e=[-8..8]
g=[-1..1]
h 'N' c r=[(c+x,r+y)|x<-a,y<-a,3==(sum$map abs[x, y])]
h 'B' c r=[(c+x*z,r+y*z)|x<-b,y<-b,z<-d]
h 'R' c r=[(c+x,r)|x<-e]++[(c,r+y)|y<-e]
h 'Q' c r=h 'B' c r++h 'R' c r
h 'K' c r=[(c+x,r+y)|x<-g,y<-g]
l s=ord s-96
m n=chr$n+96
k ch (c,r)=ch:m c:[intToDigit r]
f (x,y)=all(`elem`[1..8])[x, y]
i n c r=map(k n).filter(/=(c,r)).filter f$h n c r
j s=i(s!!0)(l$s!!1)(digitToInt$s!!2)

jİşlev kullanılarak çağrıldı

j "Nd4"

Haskell ile birkaç aydır çalışmadım, bu yüzden diğer çözümlerin çoğu kadar kısa olmadı, ama eminim ki, esas olarak bazı optimizasyonlar yapılacağına eminim h. Onu biraz kısaltabilirim.


1

q & k [ 311 262 karakter]

Daha fazla karakter azaltma potansiyeli var. Bir sonraki yinelemede düşüreceğim.

k)o:{n:#m:&(#x)##y;((),x)[m],'n#y}

k)a:`$"c"$(o/)c:+(97;49)+/:!8

k)r:{{|x@<x}'?,/{o[x]y}'[x](|"c"$c)}
k)k:{"c"$(6h$x)+/:(o/)2 3#-1 0 1}
k)n:{"c"$(6h$x)+/:(|:'t),t:o[-1 1;2 2]}
k)b:{"c"$(6h$x)+/:(n,'n),n,'|n:-8+!17}
k)q:{,/(r;b)@\:x}

d:{(`$("rknbq"!(r;k;n;b;q))[x]y)except`$y}
g:{a inter d[x 0]@1_x}

kullanım

Kale

g"ra1"
`a2`a3`a4`a5`a6`a7`a8`b1`c1`d1`e1`f1`g1`h1

kral

g"ka1"
`a2`b1`b2

Şövalye

g"na1"
`b3`c2

piskopos

g"ba1"
`b2`c3`d4`e5`f6`g7`h8

kraliçe

g"qa1"
`a2`a3`a4`a5`a6`a7`a8`b1`b2`c1`c3`d1`d4`e1`e5`f1`f6`g1`g7`h1`h8

0

R, 203 karakter

f=function(p,x,y){x=which((l=letters)==x);X=rep(1:8,8);Y=rep(1:8,rep(8,8));A=abs(X-x);L=abs(Y-y);B=A==L;R=!A|!L;i=switch(p,N=A+L==3&A&L,R=R,B=B,Q=R|B,K=(R|B)&A<2&L<2)&A+L>0;paste(p,l[X[i]],Y[i],sep="")}

Ungolfed versiyonu:

f = function(p,x,y) {
  x = which(letters == x)  # Gives index between 1 and 8.
  X = rep(1:8, 8)          # 1,2,...,7,8,1,2,.... (8x8).
  Y = rep(1:8, rep(8,8))   # 1,1,...2,2,.....,8,8 (8x8).
  dx = abs(X-x)
  dy = abs(Y-y)
  B = (dx == dy)           # Bishop solutions
  R = (!dx | !dy)          # Rock solutions
  i = switch(p,
             N=dx+dy==3 & dx & dx,  # Sum of dist. is 3, dx and dy must be <> 0.
             R=R, 
             B=B, 
             Q=R|B,                 # Queen is merge of rock and bishop.
             K=(R|B) & dx<2 & dy<2  # King's distance is < 2.
             ) & (dx+dy > 0)        # Exclude start field.

  paste(p, letters[X[i]], Y[i], sep="")
}

Kullanımı:

> f('N', 'a', 3)
[1] "Nb1" "Nc2" "Nc4" "Nb5"

Çözelti bile iyi okunur. Ancak R koduna aşina olmayan okuyucular için bazı parantezler ve yorumlar ekledim (eski sürümde).


0

Haskell (varsayımsal), 248 karakter

import Data.Char
f x=filter(o x)[x!!0:y|y<-[v:[w]|v<-"abcdefgh",w<-"12345678"],y/=tail x]
d a b=abs(ord a-ord b)
h x y=(c*(d(x!!1)(y!!1))-(d(x!!2)(y!!2)))+200*c
 where c=d (x!!0)'A'
o x y=elem(chr(h x y))"ਲ਼ੁߏߚߙÈേെ൅ൄൃ൙൪ൻඌඝථ඿౿౾౽౼౻౺౹ಐಏಠಞರಭೀ಼೐ೋೠ೚೰೩"

Ne yazık ki, şu an elime geçebilecek her Haskell derleyicisi, Unicode string değişmezleriyle ilgili sorunlara sahip. İşte gerçekten çalışan (daha uzun) sürüm:

import Data.Char
f x=filter(o x)[x!!0:y|y<-[v:[w]|v<-"abcdefgh",w<-"12345678"],y/=tail x]
d a b=abs(ord a-ord b)
h x y=(c*(d(x!!1)(y!!1))-(d(x!!2)(y!!2)))+200*c
 where c=d (x!!0)'A'
o x y=elem(chr(h x y))"\2611\2625\1999\2010\2009\200\3399\3398\3397\3396\3395\3394\3393\3417\3434\3451\3468\3485\3502\3519\3199\3198\3197\3196\3195\3194\3193\3216\3215\3232\3230\3248\3245\3264\3260\3280\3275\3296\3290\3312\3305"

Tanım h x y=...bir karma fonksiyonudur; geçerli hamleler, 41 karakterlik dizgideki karakter numaralarına göre olacaktır. Bu, bir "dava" ifadesine veya eşdeğerine duyulan ihtiyaçtan kurtulur.

Şu an bu konuda daha fazla çalışmayı planlamıyorum. Birinin daha kısa bir çözüm için bir özeti işlevini daha özlü bir dilde kullanıp kullanamayacağını görmek eğlenceli olacaktır.

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.