Mengilustrasikan kuadrat binomial


28

Diberikan (dengan cara apa pun) dua bilangan alami yang berbeda (dengan ukuran apa pun yang masuk akal), menghasilkan (dengan cara apa pun) kuadrat dari jumlah mereka seperti dalam contoh di bawah ini:

Diberikan 4 dan 3, output:

12 12 12 12  9  9  9
12 12 12 12  9  9  9
12 12 12 12  9  9  9
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12

Diberikan 1 dan 3, output:

3 9 9 9
3 9 9 9
3 9 9 9
1 3 3 3

Ruang kosong mungkin berbeda-beda dalam alasan tetapi kolom harus kiri-lurus, kanan-lurus, atau (pseudo-) berpusat.

Baris baru yang tertinggal baik-baik saja, tetapi celah standar tidak.

Ini adalah jadi sertakan tajuk seperti # LanguageName, 123dalam jawaban Anda, di mana angkanya chars (byte untuk bahasa yang tidak berbasis teks). Kode pengemasan ke karakter Unicode besar tidak diperbolehkan.


Bonus: -3 jika kode Anda hanya menghasilkan satu kuadrat ketika salah satu angka adalah 0; misalnya diberikan 0 dan 3, output:

9 9 9
9 9 9
9 9 9

berapakah nilai maksimum dari nomor input? Terima kasih.
don bright

1
@donbright Tidak ada batasan buatan. Hanya batasan yang dapat ditangani oleh komputer dan bahasa Anda saat berbicara tentang representasi, perhitungan (dengan algoritme pilihan Anda), dan hasilnya. Berpotensi, komputer modern yang dilengkapi dengan printer yang menerima data baris demi baris, hampir tidak memiliki batas ... :-)
Adám

Apakah orientasi kuadrat diberikan, atau bisakah kita memutarnya 90 derajat?
John Dvorak

1
Mengapa bonus untuk 0 nilai? Apa yang akan dihasilkan jika tidak hanya satu kotak?
Maret

@MarchHo Itu sebabnya bonusnya sangat kecil. Namun, beberapa bahasa mungkin tidak dapat menangani array kosong.
Adám

Jawaban:


14

J, 9 byte - 3 = 6

#~@|.*/#~

Terinspirasi oleh jawaban APL @ NBZ , diturunkan oleh @randomra. Ini mendefinisikan kata kerja yang mengambil array angka. Ini digunakan sebagai berikut:

   (#~@|.*/#~) 4 3
12 12 12 12  9  9  9
12 12 12 12  9  9  9
12 12 12 12  9  9  9
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12

Saya juga mengklaim bonus 3-byte, karena input 0 menghasilkan sub-matriks ukuran nol:

   (#~@|.*/#~) 4 0
16 16 16 16
16 16 16 16
16 16 16 16
16 16 16 16
   (#~@|.*/#~) 0 3
9 9 9
9 9 9
9 9 9

Penjelasan

J memiliki keunggulan dalam tantangan ini. Selain makan masalah manipulasi array untuk sarapan, ia mencetak matriks 2D dalam format yang benar secara default.

       #~  Replicate each number n in input n times
#~@|.      The same for reversed input
     */    Compute their multiplication table

Ini membuat saya merasa seperti di rumah.
Adám

3
Solusi ini terlihat seperti variasi yang tidak jelas dari table flipperemotikon ASCII (╯ ° □ °) ╯︵ ┻━┻
Pete TNT

10

Oktaf, 45 byte - 3 = 42

s=@(m,n)[a=ones(n,1)*n;b=ones(m,1)*m].*[b;a]'

Penjelasan

Ini membangun dua vektor (mari kita asumsikan m = 4dan n = 3):

ones(n, 1)membangun sebuah array yang berukuran n x 1, jadi mengalikannya dengan nkita dapatkan:

ones(n, 1) * n => [3 3 3]' (where ' is transpose... n x 1 is a column vector)

a = [3 3 3  4 4 4 4]'   %// a is a column vector
b = [4 4 4 4  3 3 3]    %// b is a row vector

Kemudian vektor dikalikan dengan cara elemen-bijaksana, dengan ekspansi siaran otomatis sehingga vektor 7-elemen menghasilkan matriks elemen 7x7:

    [3] .* [4 4 4 4 3 3 3]
    [3]
    [3]
    [4]
    [4]
    [4]
    [4]

Misalnya, perkalian baris pertama adengan bmemberi:

    [3] .* [4 4 4 4 3 3 3] = [12 12 12 12  9  9  9]

Dan juga untuk baris yang tersisa a.

Keluaran:

>> s(4,3)
ans =

   12   12   12   12    9    9    9
   12   12   12   12    9    9    9
   12   12   12   12    9    9    9
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12

>> s(3,0)
ans =

   9   9   9
   9   9   9
   9   9   9

Anda dapat mencobanya di sini di ideone


Anda dapat menghapus s=. Kami memiliki konvensi bahwa fungsi anonim / lambdas tidak harus disimpan dalam variabel.
flawr

6
@ flawr tapi kemudian jawabannya tidak menjadi 42 ...
gelas kimia

OK.
Adam

9

Dyalog APL , 10-3 = 7

Terinspirasi oleh jawaban ini tempat argumen direplikasi dan kemudian digunakan dalam tabel perkalian:

⊖∘.×⍨(/⍨⎕)

Menerbitkan prompt ( ⎕:) dan mengevaluasi ekspresi apa pun yang dimasukkan. (Untuk alasan keamanan, ini tidak berfungsi pada TryAPL tetapi berfungsi pada NGN / APL .)
/⍨Menggandakan argumennya sendiri kali ( /⍨4 33 3 3 4 4 4 4)
∘.×⍨ Membuat tabel multiplikasi.
Membalik terbalik.

Ini terjadi untuk bekerja pada input panjang apa pun (input indentasi 6 spasi, output berada di margin kiri):

      ⊖∘.×⍨(/⍨⎕)
⎕:
      ⍬      ⍝ Empty list (the square of nothing)
      ⊖∘.×⍨(/⍨⎕)
⎕:
      0      ⍝ 0​² = 0
      ⊖∘.×⍨(/⍨⎕)
⎕:
      0 1      ⍝ (0+1)​² = 1²
1
      ⊖∘.×⍨(/⍨⎕)
⎕:
      2 3      ⍝ (2+3)​² = 2² + 3²
6 6 9 9 9
6 6 9 9 9
6 6 9 9 9
4 4 6 6 6
4 4 6 6 6
      ⊖∘.×⍨(/⍨⎕)
⎕:
      1 2 3      ⍝ (1+2+3)​² = 1² + 2(1×2) + 2(1×3) + 2² + 2(2×3) + 3²
3 6 6 9 9 9
3 6 6 9 9 9
3 6 6 9 9 9
2 4 4 6 6 6
2 4 4 6 6 6
1 2 2 3 3 3
      ⊖∘.×⍨(/⍨⎕)
⎕:
      ⍳4    ⍝ Integers 1 through 4
4 8 8 12 12 12 16 16 16 16
4 8 8 12 12 12 16 16 16 16
4 8 8 12 12 12 16 16 16 16
4 8 8 12 12 12 16 16 16 16
3 6 6  9  9  9 12 12 12 12
3 6 6  9  9  9 12 12 12 12
3 6 6  9  9  9 12 12 12 12
2 4 4  6  6  6  8  8  8  8
2 4 4  6  6  6  8  8  8  8
1 2 2  3  3  3  4  4  4  4

* Awalnya, saya memiliki solusi yang berbeda dalam pikiran: Setiap persegi panjang dibuat secara terpisah dengan membuat tabel perkalian untuk setiap kombinasi dari dua argumen. Kemudian empat kotak diperbaiki bersama-sama secara vertikal dan horizontal. Ini terlihat seperti ini:

,/⍪⌿⊖∘.(,⍴×)⍨⎕

Prompt, seperti di atas.
,⍴×<Gabungkan ( ,) args dan gunakan itu untuk membentuk ( ) persegi panjang yang diisi dengan produk mereka ( ×).
∘.(... )⍨Buat tabel di mana setiap sel adalah apa pun yang ditentukan dalam (... )
Balik secara vertikal.
⍪⌿Gabungkan sel secara vertikal.
,/Gabungkan sel secara horizontal.


1
Bagus! Gagasan yang sama dalam J dengan skor yang sama:(|.*/])@#~
Zgarb

@Zgarb Perbarui jawaban Anda dan tuliskan catatan kaki seperti milik saya. Aku pantas menerimanya!
Adám

7

R, 31 - 3 = 28

rev(b<-rep(a<-scan(),a))%*%t(b)

Penjelasan:

           a<-scan()            # take numeric input and store as vector a
    b<-rep(         ,a)         # repeat each numeric input by itself and store as vector b
rev(                   )        # the reverse of vector b
                        %*%     # matrix multiplication
                           t(b) # the transposed of vector b

Ini juga berfungsi untuk lebih dari dua angka. Misalnya, output untuk (5,3,2) terlihat seperti ini:

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]   10   10   10   10   10    6    6    6    4     4
 [2,]   10   10   10   10   10    6    6    6    4     4
 [3,]   15   15   15   15   15    9    9    9    6     6
 [4,]   15   15   15   15   15    9    9    9    6     6
 [5,]   15   15   15   15   15    9    9    9    6     6
 [6,]   25   25   25   25   25   15   15   15   10    10
 [7,]   25   25   25   25   25   15   15   15   10    10
 [8,]   25   25   25   25   25   15   15   15   10    10
 [9,]   25   25   25   25   25   15   15   15   10    10
[10,]   25   25   25   25   25   15   15   15   10    10

Anda mungkin perlu membungkusnya menjadi catatau writeagar itu menjadi jawaban yang valid.
David Arenburg

@ DavidArenburg Saya tidak melihat mengapa? Itu mengatakan "Output (dengan cara apa pun)". Saya hanya membutuhkan satu cara untuk menghasilkan sehingga menempatkan saya dalam persyaratan.
freekvd

Ya, mungkin Anda benar. Tidak yakin apa yang mereka maksud dengan itu.
David Arenburg

@ Davidviden Ya, tidak apa-apa. Ini adalah tantangan data / teks, bukan tantangan input / output.
Adám

5

Haskell, 153 125 byte - 3 = 122

(#)=replicate
d=length.show
y%x=unlines$(>>= \n->(1+d(x*x+y*y)-d n)#' '++show n)<$>x#(y#(x*y)++x#(x*x))++y#(y#(y*y)++x#(x*y))

Setengah dari kode adalah untuk pemformatan output. Ini bekerja untuk bilangan bulat besar yang sewenang-wenang. Contoh output:

> putStrLn $ 4 % 3
12 12 12 12  9  9  9
12 12 12 12  9  9  9
12 12 12 12  9  9  9
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12
16 16 16 16 12 12 12

> putStrLn $ 6 % 0
36 36 36 36 36 36
36 36 36 36 36 36
36 36 36 36 36 36
36 36 36 36 36 36
36 36 36 36 36 36
36 36 36 36 36 36

Terkadang ada spasi putih tambahan di antara angka-angka, karena saya menghitung ruang yang dibutuhkan berdasarkan x*x+y*ybukan max (x*x) (y*y), misalnya

> putStrLn $ 2 % 3
  6  6  9  9  9
  6  6  9  9  9
  6  6  9  9  9
  4  4  6  6  6
  4  4  6  6  6

Tapi paling banyak satu spasi putih.


4

Mathematica 56-3 = 53

Pembaruan : Saya menambahkan metode kedua, dengan ukuran kode yang persis sama, yang menggunakan fungsi bernama. Ini mempekerjakan ArraydaripadaTable tetapi mengikuti logika yang sama. (Lihat di bawah.)

Metode 1

Ini membuat tabel produk, faktor-faktor yang bergantung pada baris, nilai kolom. Pasangan angka dimasukkan sebagai daftar bilangan bulat. Fungsi anonim seperti berikut ini, paling berguna jika hanya digunakan sekali dalam suatu program. Kalau tidak, lebih masuk akal untuk menggunakan fungsi bernama.

Grid@Table[If[r>#2,#,#2]If[c>#,#2,#],{r,#+#2},{c,#+#2}]&

Setiap faktor adalah pernyataan Jika-maka:

  • If[r>#2,#,#2] berarti, "Jika nomor baris lebih besar dari input kedua, gunakan input pertama sebagai faktor, jika tidak gunakan input kedua.
  • If[c>#,#2,#] berarti, "Jika nomor kolom lebih besar dari input pertama, gunakan input kedua sebagai faktor, jika tidak gunakan input pertama.

Contoh 1

 Grid@Table[If[r>#2,#,#2]If[c>#,#2,#],{r,#+#2},{c,#+#2}]&@@{5,3}

ex1


Contoh 2

Grid@Table[If[r>#2,#,#2]If[c>#,#2,#],{r,#+#2},{c,#+#2}]&@@{0,3}

ex2


Metode 2 (Juga 56-3 = 53)

Ini bekerja mirip dengan Metode 1. Tetapi membutuhkan lebih sedikit kode ketika dipanggil. Dan sel-selnya dapat dialamatkan, tidak seperti sel dalam sebuah tabel. Metode ini lebih baik digunakan jika fungsinya akan digunakan lebih dari satu kali.

a_~f~b_:=Grid@Array[If[#>a,a,b]If[#2>a,b,a]&,{a+b,a+b}]

Contoh-contoh di atas dihasilkan oleh yang berikut:

Kel 1:

f[4,3]

Kel 2:

f[0,3]

1
Itu cerdik. Dengan metode itu saya dapat mengurangi solusi saya sendiri hingga 4 karakter.
Adám

Terima kasih. Saya baru menyadari bahwa pendekatan yang sama berfungsi dengan fungsi bernama. Lihat Metode 2 di atas.
DavidC

4

Oktaf, 34 - 3 = 31

@(a)rot90(b=repelems(a,[1,2;a]))*b

Contoh:

octave:1> f = @(a)rot90(b=repelems(a,[1,2;a]))*b;
octave:2> f([4,3])
ans =

   12   12   12   12    9    9    9
   12   12   12   12    9    9    9
   12   12   12   12    9    9    9
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12
   16   16   16   16   12   12   12

octave:3> f([0,3])
ans =

   9   9   9
   9   9   9
   9   9   9

Wow, saya tidak tahu repelemsada. Luar biasa!
gelas kimia

4

CJam, 27 byte - 3 = 24

q:L~_]ze~_ff{*sL,2*Se[}W%N*

Mengambil input sebagai larik gaya CJam. Ini menggunakan sedikit lebih banyak jarak daripada yang diperlukan, tapi saya pikir itu "masuk akal", dan selalu selaras dengan benar.

Uji di sini.

Penjelasan

q:L    e# Read the input and store it in L.
~_     e# Evaluate the input, pushing [A B] onto the stack and duplicate it.
]z     e# Wrap both in an array and transpose it to get [[A A] [B B]].
e~     e# Run-length decode, getting A copies of A and B copies of B.
_ff{   e# Double map over each pair of entries in this new array...
  *s   e#   Multiply the two values.
  L,2* e#   Push twice the length of the input string.
  Se[  e#   Pad the result to this width with spaces (from the left).
}
W%     e# Reverse the resulting matrix to get the correct orientation.
N*     e# Join the rows with linefeed characters.

Bagus, tapi apa yang menyebabkan ruang putih sebanyak itu, dan apa yang dibutuhkan untuk menguranginya?
Adám

1
@NBZ Cara terpendek yang saya temukan sejauh ini untuk menghitung batas atas yang dapat diandalkan pada lebar sel adalah dengan menggunakan dua kali panjang string input (karena jumlah yang lebih besar kuadrat tidak akan memiliki lebih dari dua kali lebih banyak digit dari nomor diri). Tentu saja saya bisa menghitung jumlah aktual yang diperlukan berdasarkan angka yang dihasilkan, tetapi itu akan sedikit lebih lama.
Martin Ender

4

Fungsi C (menggunakan glibc), 122 byte - 3 = 119

Sebagian besar implementasi langsung dengan 2 loop. Saya berharap ada beberapa peluang golf yang saya lewatkan di sini:

f(n,m,x,y){for(x=0;x<n+m;x+=puts(""))for(y=0;y<n+m;y++)printf(" %*d",snprintf(0,0,"%d",n>m?n*n:m*m),(x<m?m:n)*(y<n?n:m));}

Input diberikan dalam dua parameter pertama dari fungsi, dua lainnya adalah boneka. Kolom lurus rata.

Catatan glibc puts()sepertinya selalu mengembalikan jumlah byte yang ditulis termasuk baris tambahan tersirat, yang kita butuhkan di sini. Tidak ada jaminan ini akan bekerja dengan libc lainnya.

Dalam program lengkap:

f(n,m,x,y){for(x=0;x<n+m;x+=puts(""))for(y=0;y<n+m;y++)printf(" %*d",snprintf(0,0,"%d",n>m?n*n:m*m),(x<m?m:n)*(y<n?n:m));}

int main (int argc, char **argv) {
    if (argc == 3) {
        f(atoi(argv[1]),atoi(argv[2]));
    }
}

Kompilasi sebagai gcc sqrbin.c -o sqrbin(ataumake sqrbin ). Peringatan dapat diabaikan dengan aman.

Contoh output:

$ ./sqrbin 4 3
 12 12 12 12  9  9  9
 12 12 12 12  9  9  9
 12 12 12 12  9  9  9
 16 16 16 16 12 12 12
 16 16 16 16 12 12 12
 16 16 16 16 12 12 12
 16 16 16 16 12 12 12
$ ./sqrbin 4 0
 16 16 16 16
 16 16 16 16
 16 16 16 16
 16 16 16 16
$ 

Berdasarkan pengalaman saya, nilai kembali puts()bergantung pada mesin. Misalnya 10 milik saya. Juga, inilah tipnya: Anda biasanya dapat mengompres dua loop menjadi satu jika Anda menambah penghitung secara kondisional dalam loop eksternal. Solusi saya menunjukkan bagaimana hal itu dapat dilakukan.
xsot

@ xsot Ya, puts()kode pengembalian hanya dijamin + ve untuk sukses. Namun pengujian saya dengan glibc tampaknya menunjukkan bahwa nilai kembali adalah jumlah byte yang ditulis. Adapun konsolidasi loop - ya, saya menyadari teknik itu dan telah mencobanya di sini, sejauh ini tanpa pemendekan dalam kasus ini.
Digital Trauma

2

Ruby, (133 - 3) = 130 byte

s=1
a=ARGV.map{|e|s*=(e=e.to_i);[e]*e}.flatten
s=s.to_s.size
a.reverse.each{|i|a.each{|j|print (i*j).to_s.rjust(s).ljust(s+3)};puts}

untuk 4,3

12   12   12   12    9    9    9   
12   12   12   12    9    9    9   
12   12   12   12    9    9    9   
16   16   16   16   12   12   12   
16   16   16   16   12   12   12   
16   16   16   16   12   12   12   
16   16   16   16   12   12   12

untuk 1,3

3   9   9   9   
3   9   9   9   
3   9   9   9   
1   3   3   3

untuk 0,3

9   9   9   
9   9   9   
9   9   9

2
Selamat datang di PPCG! Saya tidak berpikir padding Anda cukup untuk jumlah besar. Pertimbangkan memiliki 1dan sejumlah besar suka 9999. Dari sakan keluar sebagai 4, jadi Anda padding ke lebar s+3 = 7tetapi 9999^2membutuhkan 8 digit. Anda mungkin ingin menggunakannya 2*s.
Martin Ender

2
Terlepas dari itu, berikut adalah beberapa tips bermain golf: Saya tidak mengerti mengapa Anda membutuhkannya rjustsebelum melakukan ljust. Anda dapat menyingkat printmenjadi $><<(dan menyingkirkan ruang setelahnya). ARGVmemiliki alias $*. Anda mungkin dapat menghindari flattendengan membangun array Anda dengan sesuatu seperti ini: codegolf.stackexchange.com/a/19493/8478 . Juga, jawaban fungsi saja pasti diperbolehkan di sekitar sini (bahkan fungsi yang tidak disebutkan namanya), sehingga fungsi tersebut dapat mengambil bilangan bulat sebagai input, dan Anda tidak perlu melakukan apapun .to_i.
Martin Ender

@ MartinBüttner, terima kasih atas tipsnya.
Harsh Gupta

2

Python 2, 176 byte - 3 = 173

def g(m,n):
 y,x,z,l,f='y','x','z','l','%'+str(len(str(max(m*m,n*n))))+'s'
 d={y:m*n,x:n*n,z:m*m,l:'\n'}
 for i in map(lambda x:d[x],(y*m+x*n+l)*n+(z*m+y*n+l)*m): print f % i,

Ini menggunakan fungsi string Python untuk membuat kisi karakter, lalu mengganti karakter dengan integer dan mencetak output yang diformat.


Metode yang menarik.
Adám

1

Matlab, 58 - 3 = 55

Menggunakan fungsi anonim:

@(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)

Contoh:

>> @(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)
ans = 
    @(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)
>> ans(4,3)
ans =
    12    12    12    12     9     9     9
    12    12    12    12     9     9     9
    12    12    12    12     9     9     9
    16    16    16    16    12    12    12
    16    16    16    16    12    12    12
    16    16    16    16    12    12    12
    16    16    16    16    12    12    12

>> @(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)
ans = 
    @(a,b)flipud(blkdiag(a^2*ones(a)-a*b,b^2*ones(b)-a*b)+a*b)
>> ans(0,3)
ans =
     9     9     9
     9     9     9
     9     9     9

(Solusi lama) 59 - 3 = 56

Menggunakan fungsi anonim:

@(a,b)[b*a*ones(b,a) b^2*ones(b);a^2*ones(a) a*b*ones(a,b)]

1

C, (125 - 3) byte

i,j,a;main(b,s){for(sscanf(gets(s),"%d %d",&a,&b);j<a+b;)printf(++i>a+b?i=!++j,"\n":"%*d",strlen(s)*2,(i<a?a:b)*(j<b?b:a));}

Input diambil sebagai dua bilangan bulat yang dipisahkan spasi pada baris yang sama. Setiap sel diisi dengan spasi hingga dua kali panjang string input.


Saya mengalami kesulitan mendapatkan ini untuk dikompilasi dengan gcc (4.8.4) ...
don bright

1
Saya menguji ini di golf.shinh.org/check.rb yang menggunakan paket debian gcc-4.6.1-2. Apa kesalahan kompilasi yang Anda dapatkan?
xsot

maaf saya mencoba lagi karena semua satu baris dan berhasil, ... tetapi ketika saya menjalankan saya mendapatkan segfault. saya memasuki string 2 3 dan tekan kembali dan ia mengatakan kesalahan Segmentasi (core dumped)
don bright

Maaf tapi saya tidak tahu mengapa itu tidak berhasil untuk Anda. Setidaknya Anda masih dapat mencoba kode di situs yang saya
tautkan

1

Pyth, 39 - 3 = 36

Pyth tidak memiliki pemformatan matriks bawaan, yang sangat meningkatkan ukurannya, karena seseorang harus secara manual mengisi nomor keluaran. Inilah yang saya pikirkan.

JAQL*b]jdm.[`d\ l`eS^R2Jsm*d]*bdJj+yHyG

Cobalah online.


1

Blok , 51 byte 52 62 82 87 (tidak bersaing)

::`+`1|U;{`*`1}|A;`+`1,0+`1={`1^2}|;0+`,`1+`={`^2}|

Tidak Terkumpul:

::
  ` + `1                    | Expand;
  {` * `1}                  | SetAll;
  ` + `1, 0 + `1 = {`1 ^ 2} | Set;
  0 + `, `1 + `  = {` ^ 2}  | Set

Cobalah

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.