生命,宇宙和ASCII艺术的答案


25

简单的挑战:尝试以尽可能少的字节输出以下文本:

       the        answer
      toli      fetheuniv
     ersea     nde     ver
    ything     the     ans
   wer tol     ife     the
  uni  ver           sean
 dev   ery         thin
gth    ean       swer
tolifetheuni    ver
seandeveryth   ing
       the     ans      wer
       tol     ifetheuniver
       sea     ndeverything

原始图形包含332个字符。

规则

  • 无输入或未使用的输入。
  • 输出可以采用任何合理的格式(字符串,字符串列表,字符矩阵等)。
  • 如果愿意,可以在图形中使用大写而不是小写。
  • 允许尾随空格和换行符。
  • 这是,因此每种语言中最短的程序/功能可能会获胜!

笔记


这来自沙盒
查理

1
就个人而言,我认为这只是话题,而不是虚假的。不过,我认为您不需要扰人的报价。
程序员

1
@凤凰我不认为这是一个骗子索格尔已经超越了泡泡糖。因此,压缩不是执行此操作的最佳方法。
程序员

1
老实说,我没有意识到我的重新开始投票具有约束力。出于@ programmer5000已经提到的原因,我真的不认为这是“ 我们不是陌生人...”的欺骗。这可能是对另一个挑战(尚未确定)的欺骗,但不是这个挑战。
Arnauld

1
@Nacht最好的部分是,首先我42*字符绘制了字符,然后用完美适合的文本替换了它们。我不必修改原始图形即可使句子合适。巧合?
查理

Answers:


21

Python 3中224个220 219 215 211 194字节

  • 感谢@TFeld 1 5个字节:if(j%27<1)*j而不是if j*(j%27<1)简化的打印语句。
  • 感谢@Leaky Nun的4个字节:反转0和1,不需要用零填充 7*'0'
  • @Leaky nun凭借出色的高尔夫技巧节省了17个字节(非常感谢!!!):出色地使用了模块化索引
i=j=0
k=int("OHZE5WCKDTW6JYMO1JNROAAJQVAN6F8KEO0SMKJM86XIBMCEH5FXXONZGBAVCN3689DS",36)
while k:j+=1;print(k%2*'theanswertolifetheuniverseandeverything'[i%39]or' ',end='\n'*(j%27<1));i+=k%2;k//=2

在线尝试!

说明:

使用base-36压缩来压缩此二进制数(不包括换行符)

111111100011111111000000111
111111000011111100000000011
111110000011111000111110001
111100000011111000111110001
111000100011111000111110001
110001100011111111111000011
100011100011111111100001111
000111100011111110000111111
000000000000111100011111111
000000000000111000111111111
111111100011111000111111000
111111100011111000000000000
111111100011111000000000000

我们基本上有两个柜台ij。遇到a时,1我们打印一个空格;否则,如果0我们从字符串中打印下一个字母并增加ij每增加一个0 or 1。我们还会在必要时(即j%27<1变为true 时)打印换行符。


1
您可以通过更改if j*(j%27<1):if(j%27<1)*j:
TFeld 17'July


2
201个字节与整数算术
漏嫩

2
200字节的模块化索引
Leaky Nun


8

Python 2中235 218 213字节

x=bin(int('OC5POO6MZYQNBWY0RP6BKBZCOZL13MIAB6I8YZ5N7LXSZBVKX7GC57AW5631YCJ6XCLC',36))[2:].replace('1',' ')
for c in'theanswertolifetheuniverseandeverything'*4:x=x.replace('0',c,1)
while x:y,x=x[:27],x[27:];print y

在线尝试!

切换到以w提示的字母位置的int为36的基数int。

一次替换每个字符。

       111        111111                              the        answer
      1111      111111111                            toli      fetheuniv
     11111     111     111                          ersea     nde     ver
    111111     111     111                         ything     the     ans
   111 111     111     111                        wer tol     ife     the
  111  111           1111                        uni  ver           sean
 111   111         1111             --->        dev   ery         thin
111    111       1111                          gth    ean       swer
111111111111    111                            tolifetheuni    ver
111111111111   111                             seandeveryth   ing
       111     111      111                           the     ans      wer
       111     111111111111                           tol     ifetheuniver
       111     111111111111                           sea     ndeverything

编辑:似乎Officialaimm在我之前使用了基数36。


7

泡泡糖,125字节

0000000: 45 8f c5 01 03 31 0c 04 ff ae 62 4b 0b 99 02 c7  E....1....bK....
0000010: d8 7d 84 e7 f9 59 30 5e 41 59 4a 84 71 ef e6 3d  .}...Y0^AYJ.q..=
0000020: 4e c1 ea fd b7 42 48 91 66 d6 ae 6e da 89 d3 1c  N....BH.f..n....
0000030: ef 60 ba 97 ae 6e b6 74 2e a5 76 d9 ad ae e4 16  .`...n.t..v.....
0000040: 69 59 08 a6 a6 e8 23 d4 22 af 08 d0 20 7d 17 f0  iY....#."... }..
0000050: 8a 9b 7c 76 c2 61 7b c8 4b 01 41 23 50 24 32 87  ..|v.a{.K.A#P$2.
0000060: f5 98 9e 88 35 24 21 83 ac 50 b2 e0 a2 16 0e 42  ....5$!..P.....B
0000070: bb ba a5 bc ae 6e bd 76 b7 69 d9 f9 07           .....n.v.i...

在线尝试!


您是如何产生的?我能找到的最接近的是127
musicman523 '17

1
zopfli
丹尼斯,

我确实使用过zopfli,但我发誓我尝试过不带换行符,并且带有多余的空格。...不能低于127
musicman523 '17

6

05AB1E83 79 74字节

-4个字节感谢外长者埃里克(Erik the Outgolfer)

输出字符串列表以保存一个字节。

•2ÖH₆Ôn₅Ò\ÊÑĆ¸Ý¾*£„ÔûC∞qΘœ™‚¹µ—₃₄fm•vNÈy×vyiðë¾¼’€€Ž»to‚쀀ªÜ€ƒ‰Ö’è}}}J27ô

在线尝试!

说明

2ÖH₆Ôn₅Ò\ÊÑĆ¸Ý¾*£„ÔûC∞qΘœ™‚¹µ—₃₄fm 是十进制数字的基数255表示形式:

73869469755353565353431353533323902433339443437469034389033390735363735903735903

分别编码1s和0s的游程,偶数索引为1s且不均匀指数0s。计算结果为二进制数:

111111100011111111000000111
111111000011111100000000011
111110000011111000111110001
111100000011111000111110001
111000100011111000111110001
110001100011111111111000011
100011100011111111100001111
000111100011111110000111111
000000000000111100011111111
000000000000111000111111111
111111100011111000111111000
111111100011111000000000000
111111100011111000000000000

•...•                                         Convert from base 255 to decimal
     v                                }       For each digit, do:
      NÈy×                                       is_even(index) repeated that many times
          v                          }           For each digit, do:
           yi                       }               If digit is truthy, then:
             ð                                         Push space
              ë                                     Else:
               ¾¼                                      Get and increment counter, starts at 0
                 ’€€Ž»to‚쀀ªÜ€ƒ‰Ö’                    Push "theanswertolifetheuniverseandeverything"
                                   è                   Get the character at that index
                                       J      Join whole stack
                                        27ô   Split into parts of 27

更换"ÔAo îιË3š1ĆRÕ₃FWš{ÓÛÏ.!XµM§&¶ñD°3PŸ{óNι2Ðbмh"253ö•—."Ôq‚Ā0Ál0j¿«ªžé¨0õ₄7“Ÿ!½ÏiæÆø-δq–Å05q½Yñá+•为-4。
暴民埃里克(Erik the Outgolfer)'17年

@EriktheOutgolfer谢谢,更新了我的答案,现在我终于知道了这些是做什么的:)
kalsowerus

好的答案:)。希望您继续学习该语言。如果您有任何疑问,请随时与我聊天。
魔术章鱼缸

@MagicOctopusUrn非常感谢!:)
kalsowerus

6

Python 2220个213 212字节

通过从()*4%39 @officialaimm 切换-1字节

s=""
w=l=i=0
for g in`int("352G7FS4XC8J2Q2M2HNK7IZI65Z9TVUMHOZ6MR3HY46RQBLWY4PR",36)`[:-1]:
	for j in g*int(g):l+=1;s+=[' ',"theanswertolifetheuniverseandeverything"[w%39]][i%2]+"\n"*(l%27<1);w+=i%2
	i+=1
print s

在线尝试!

这是与其他Python答案不同的方法。我使用图像的PNG样式RLE样式编码十六进制 基数36(节省的7个字节)编码(一串数字,指示连续重复的像素数)。

数字字符串是

73869469755353565353431353533323902433339443437469034389033390735363735903735903

然后,我遍历这些数字,并从调色板中交替打印该数量的'或字符('theanswer ...')。当重复超过9个字符时,我只需添加0,然后再添加其余部分。


+1为不同的方法。您可以使用"theanswertolifetheuniverseandeverything"[w%39] TIO
Officialaimm

谢谢,并指出。我正在尝试将它替换为我现在在这里使用的布尔值设置的“或”替代方法,但是它弄乱了我的换行符...
Coty Johnathan Saxman

我不知道PNG使用这种压缩算法-我认为那是GIF。
wizzwizz4

不错的收获。不是PNG(也不是GIF),而是RLE。我将添加一个链接到答案。
Coty Johnathan Saxman '17

5

SOGL V0.12,74 个字节

"ō⅓׀?@C⁶¬IΧΖO‘@øŗč"βΘ⅔Μv∙KΩqψ3╥W≡A;2ļm½±iq╗∆Δ⁶Πqīσ‽ε⁰5τΩ⅜δσΞoΤi┘‽N¹\Λ:‘'    n

在这里尝试!

"...‘              push "the answer to life the universe and everything". because of a bug-not-really-bug, the starting quote is required
     @øŗ           remove spaces
        č          chop it into characters
         "...‘     push a string of spaces and ŗ where ŗ gets replaced with each next characters of the character array
              ' n  split into an array of line length 27

5

请允许我回答我自己的问题...

木炭140个126 112字节

A⟦⟧βF⁶⁸F⁻℅§”c#*U[“⎆Vl¶·δ‴ü"Ip8ξZ{e/⪫¦σMM⪫¢Q⁸ULê←⪫W?—υ⁻$⌀)”ι³⁴«¿﹪鲧”m⌊0Y℅¿№”XJ-⁵η}Z¿8_*<o%!±Ÿ”L⊞Oβω ¿¬﹪L⊞Oυω²⁷⸿

在线尝试!

你有 此处具有最接近的详细版本的链接。

说明(有关详细信息,请参见详细版本):

  • )%*(+&(+)''%'%'('%'%&%#%'%'%%%$%-&%%%%+&&%&%)&(.&%*.%%2%'%(%)%'.)%'.字符串(68个字节,48个字节的压缩)是RLE编码图的的表示。每个字符代码减34是要连续打印的空格数(偶数位置)或文本字符数(奇数位置)。
  • 该算法仅解压缩RLE编码的字符串,然后写入 gtheanswertolifetheuniverseandeverythin每次需要写入非空白字符时(39字节,压缩后的27字节)。当我检查列表的长度以获取下一个字符并且该列表以一个元素开头时,字符串的最后一个字符将写入第一个位置。
  • 每写入27个字符,我都会插入一行。

致谢

  • 非常感谢Neil和他的惊人技巧,他们让我节省了28个字节并最终击败了Bubblegum。:-)

1
如果使用,Assign(Minus(1, c), c);则可以使用if (c) { ... } else Print(" ");
尼尔

实际上,如果您使用for (68)AtIndex("...", i)那么您可以使用它Modulo(i, 2)来代替,而您根本不需要c
尼尔

如果使用,if (Not(Modulo(Length(PushOperator(u, w)), 27)))则不需要a
尼尔

哦,AtIndex不自动Modulo因此Modulo(b, 39)可以只b
尼尔

1
u是一个预定义的变量,它只是一个空数组(使用保存A⟦⟧υ)。每次将某项推入该对象时,其长度都会增加1。这比显式分配要短。
尼尔

5

JavaScript的(ES6),207 205 203字节

返回带有一些尾随空格的字符串数组。

let f =

_=>[16515968,33489856,k=58950624,k+16,k-40,31458204,7865230,1966983,462847,233471,117670784,k=134185856,k].map(n=>'heanswertolifetheuniverseandeverythingt '.replace(/./g,(_,i,s)=>s[n>>i&i<27?k++%39:39]))

console.log(f().join('\n'));


4

视网膜,183字节


7386¶6469¶555353¶465353¶33135353¶23239024¶133394¶034374¶090343¶090333¶735363¶735903¶735903¶theanswertolifetheuniverseandeverything
.*$
$&$&$&$&
(\d)(.)
$1$* $2$*
+s`1([ 1¶]+)(.)
$2$1

在线尝试!说明:第一阶段将单元位图和文本的RLE编码相加,然后第二阶段将其复制到正确的长度,而第三阶段则对RLE编码进行解码。然后,第四阶段将文本移到单元格中。


4

果冻,83个字节

“¡eu⁾ṃṣƬİḂṃ½)ṣṾṘƇ@^AṀẆṫ+¢ṗɲ⁾ṭḋZ`⁺×Ṗj½Ṇ-Þḣ2żṿƤc’BCẋ"`“ÆZ⁺ƙ{ÆߥŀŒ1gỤ3Ḍṭṁ ṃjɓ»ṁȯ€⁶s27Y

在线尝试!

怎么运行的

“XX’BCẋ"`“YY»ṁȯ€⁶s27Y
“XX’                   a large number
    B                  binary
     C                 complement
      ẋ"`              1 becomes [1] and 0 becomes []
             ṁ         reshape
         “YY»             "theanswertolifetheuniverseandeverything"
              ȯ€⁶      replace [] with " "
                 s27   split into chunks of length 27
                    Y  join with newline

3

加++,1398字节

+32
&
&
&
&
&
&
&
+84
&
-12
&
-3
&
-69
&
&
&
&
&
&
&
&
+65
&
+13
&
+5
&
+4
&
-18
&
+13
&
-104
&
+22
&
&
&
&
&
&
+84
&
-5
&
-3
&
-3
&
-73
&
&
&
&
&
&
+70
&
-1
&
+15
&
-12
&
-3
&
+16
&
-7
&
-5
&
+13
&
-108
&
+22
&
&
&
&
&
+69
&
+13
&
+1
&
-14
&
-4
&
-65
&
&
&
&
&
+78
&
-10
&
+1
&
-69
&
&
&
&
&
+86
&
-17
&
+13
&
-104
&
+22
&
&
&
&
+89
&
-5
&
-12
&
+1
&
+5
&
-7
&
-71
&
&
&
&
&
+84
&
-12
&
-3
&
-69
&
&
&
&
&
+65
&
+13
&
+5
&
-105
&
+22
&
&
&
+87
&
-18
&
+13
&
-82
&
+84
&
-5
&
-3
&
-76
&
&
&
&
&
+73
&
-3
&
-1
&
-69
&
&
&
&
&
+84
&
-12
&
-3
&
-91
&
+22
&
&
+85
&
-7
&
-5
&
-73
&
&
+86
&
-17
&
+13
&
-82
&
&
&
&
&
&
&
&
&
&
&
+83
&
-14
&
-4
&
+13
&
-100
&
+22
&
+68
&
+1
&
+17
&
-86
&
&
&
+69
&
+13
&
+7
&
-89
&
&
&
&
&
&
&
&
&
+84
&
-12
&
+1
&
+5
&
-100
&
+93
&
+13
&
-12
&
-72
&
&
&
&
+69
&
-4
&
+13
&
-78
&
&
&
&
&
&
&
+83
&
+4
&
-18
&
+13
&
-104
&
+106
&
-5
&
-3
&
-3
&
-3
&
-1
&
+15
&
-12
&
-3
&
+16
&
-7
&
-5
&
-73
&
&
&
&
+86
&
-17
&
+13
&
-104
&
+105
&
-14
&
-4
&
+13
&
-10
&
+1
&
+17
&
-17
&
+13
&
+7
&
-5
&
-12
&
-72
&
&
&
+73
&
+5
&
-7
&
-93
&
+22
&
&
&
&
&
&
&
+84
&
-12
&
-3
&
-69
&
&
&
&
&
+65
&
+13
&
+5
&
-83
&
&
&
&
&
&
+87
&
-18
&
+13
&
-104
&
+22
&
&
&
&
&
&
&
+84
&
-5
&
-3
&
-76
&
&
&
&
&
+73
&
-3
&
-1
&
+15
&
-12
&
-3
&
+16
&
-7
&
-5
&
+13
&
-17
&
+13
&
-104
&
+22
&
&
&
&
&
&
&
+83
&
-14
&
-4
&
-65
&
&
&
&
&
+78
&
-10
&
+1
&
+17
&
-17
&
+13
&
+7
&
-5
&
-12
&
+1
&
+5
&
-7
&
P

在线尝试!

看起来像硬编码是最短的方法(至少在Add ++中)


3

Vim,239次按键

:h4<CR>3hy5bZZitheanswerto<Esc>p:%s/ \|,//g<CR>ye3P
lqqi<CR><Esc>qqw3li <Esc>lq3@wbhr<CR>16l@q@w3-@w6l@ql@w9l@qll3@whr<CR>3l9@w4l@q 2@w4l@q2@w4l@q9l2@wlr<CR>9l@w4klr<CR>4whr<CR>jj
el<C-v>3k"aD0jji <Esc>qqdiwukPi <Esc>q5@qwy04j$"ap6+<C-v>GPp3kw3i <Esc>2@q4kbXj2@qywh<C-v>4jp2je<C-v>jj4A <Esc>8j5i <Esc>b<C-v>jj2I <Esc>

添加换行符以提高“可读性”

说明

第一行显示life, the universe and everything在帮助页面上,该页面比简单地输入要短一个字节。然后将其转换为:

theanswertolifetheuniverseandeverythingtheanswertolifetheuniverseandeverythingtheanswertolifetheuniverseandeverythingtheanswertolifetheuniverseandeverything

第二行将字符串分成:

the answer
toli fetheuniv
ersea nde ver
ything the ans
wer tol ife the
uni ver sean
dev ery thin
gth ean swer
tolifetheuni ver
seandeveryth ing
the ans wer
tol ifetheuniver
sea ndeverything

然后最后一行将其缩进为:

       the        answer
      toli      fetheuniv
     ersea     nde     ver
    ything     the     ans
   wer tol     ife     the
  uni  ver           sean
 dev   ery         thin
gth    ean       swer
tolifetheuni    ver
seandeveryth   ing
       the     ans      wer
       tol     ifetheuniver
       sea     ndeverything

3

果冻,76字节

“¡¢ʋỵṆ⁻kỴ⁷ṁḤæ ƊVṛĠ¥¡¢tṢ}ȧƘ=ẒṆ_`-p1ḷṠ’ḃ⁴ĖŒṙḂ¬R“£:(ḥB⁼Ṇ#¥Ṡ1ɗĠðȮ $¿⁹½ɓ»ṁȯ€⁶s27Y

在线尝试!


2

视网膜,185字节


7!8&sw'6Bi6fe!Av¶5#sea5nde5v'4y%g5!5&s¶3w#1B5ife5!¶2A2v#92se&¶1dev3#y9%¶gth4e&7sw'Bife!A4v'se&dev#yth3ing¶7!5&s6w'7B5ife!Av'7sea5ndev#y%g
'
#¶
&
an
%
thin
#
er
!
the
A
uni
B
tol
\d
$* 

在线尝试!


2

JavaScript,215个字节

基于guest44851的解决方案

$=>'a21xb0k9qf30155yiv016ewp3018lkhz0ohfdb077or302cl5b0mgzr0b8hz028ghs7028gi67028gi67'.split(p=0).map(x=>parseInt(x,36).toString(2).slice(1).replace(/./g,x=>" theanswertolifetheuniverseandeverything"[+x&&1+p++%39]))

2

红宝石,216字节

o=i=1
puts"6iffnqxq0opdbco5e3f1zk5d7eezo2j6zwly9z5yykqsc1hl5svaof".to_i(36).to_s(17).chars.map{|c|
o=!o
c.to_i(17).times.map{o ? (i+=1)&&"ngtheanswertolifetheuniverseandeverythi"[i%39]:" "}.join
}.join.scan /.{1,27}/

在线尝试!

说明与Python解决方案类似,但是在转换为基数36之前我使用了运行长度编码。因此数据字符串仅为54个字符,而不是68个字符。

但是它最终的使用寿命仍然更长,希望它可以打得更远。



2

C(GCC) 220个 219 217 213 210字节

-1字节,感谢ceilingcat

-3个字节,感谢Jerry Jeremiah

q,i,j,t;main(c){for(;c="HDIG@GEGJ@FFFDFD@EGFDFD@DDBDFDFD@CDCDLE@BDDDJE@ADEDHE@AMED@AMDD@HDFDGD@HDFM@HDFM"[t++];)for(c%=64,j=c?q=!q,c:2;--j;)putchar(c?q?32:"theanswertolifetheuniverseandeverything"[i++%39]:10);}

在线尝试!


函数是只有一半的节目-只需使用一个完整的计划,214个字节
杰里耶利米书

@JerryJeremiah非常正确;不错的收获!也可以从中再剃一个字节。
gastropner

1

JavaScript中,265个 237 219字节

(i=0)=>'jwq80,13ntvk,26p62g,25g7w8,239k3c,zg4xc,7rpbk,1e9dc,b8mw,5mbc,4f9reg,4f9r0g,4f9r0g'.split`,`.map(b=>parseInt(b,36).toString(2).slice(1).replace(/./g,c=>'  theanswertolifetheuniverseandeverything'[+c||2+i++%39]))

多亏了@tsh,这使字节数减少了。

JSFiddle


.substr-> .slice(1)保存一些字节
tsh

“输出可以在字符串列表中”,所以只需跳过join
tsh

@tsh。谢谢。。。

1

Pyth,121个字节

其中包含太多字节,我无法在TIO中显示,所以这是一个十六进制转储:

00000000: 7558 6848 477c 2a64 6548 622c 5658 434d  uXhHG|*deHb,VXCM
00000010: 2290 8d8d 817e 7e7b 7875 7572 6663 5753  "....~~{xuurfcWS
00000020: 504d 4946 4343 3f3c 3939 3633 302d 2d2a  PMIFCC?<99630--*
00000030: 2721 211e 1b16 160d 0909 0300 225d 545d  '!!........."]T]
00000040: 3133 6a43 2202 1232 a464 b09d 7303 4244  13jC"..2.d..s.BD
00000050: 9386 74d2 e954 b89e e722 3132 2a34 2e22  ..t..T..."12*4."
00000060: 6179 1aa6 55ad c176 932b 6088 d5c5 556c  ay..U..v.+`...Ul
00000070: e4f4 5575 12a0 e7fb 1f                   ..Uu.....

在线尝试!

您可以将通话添加到 wcxxd在bash脚本中在bash脚本中以查看字节长度或我在上面生成的hexdump。

有趣的是,该程序演示了Pyth中的一个小错误(?)。字符串文字中的所有回车字节(0x0d)均作为换行符(0x0a)读取。这迫使我添加6个字节:X ... ]T]13用13替换不正确的10。

否则,此代码背后的想法就非常简单:记录运行空白的每个位置。然后,将每个索引与该运行中的空格数配对。然后,通过重复四次短语来重建原始字符串,然后将其插入正确的位置。如果记录的空格数为零,则插入换行符。


1

爪哇(OpenJDK 8)258 252 251字节

z->{int i=0,x,j,N[]={16515968,33489856,x=58950624,x+16,x-40,31458204,7865230,1966983,462847,233471,117670784,x=134185856,x};for(int n:N)for(j=32;j-->0;n/=2)System.out.print(n%2<1?j<1?"\n":" ":"theanswertolifetheuniverseandeverything".charAt(i++%39));}

在线尝试!

这是一个非常幼稚的实现。首先,为打印的字符设置遮罩,然后将文本滚动显示直到完成。

  • 感谢Carlos Alejo,节省了6个字节!

您可以使用保存一些字节int[]{16515968,33489856,x=58950624,x+16,x-40,31458204,7865230,1966983,462847,233471,117670784,x=134185856,x}
查理

0

Javascript,近似图。319字节

s=32
t="theanswertolifetheuniverseandeverything"
j=0
o=""
b=document.createElement('canvas'),c=b.getContext('2d')
b.width=b.height=s
c.font="25px Verdana"
c.fillText('42',0,20)
m=c.getImageData(0,0,s,s)
i=0
while(i<m.data.length) {
 d=m.data[i+3]
 o+=d?t[j%t.length]:" "
 if(d)j++
 i+=4
}
o.match(/.{1,32}/g).join("\n")

^的价值,实际上并没有多少,但是在删除失败的代码之前。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.