Это не ракетостроение


59

Напишите программу или функцию, которая принимает однострочную строку. Вы можете предположить, что он содержит только печатный ASCII . Распечатать или вернуть строку художественной ракеты ASCII, такую ​​как

  |
 /_\
 |E|
 |a|
 |r|
 |t|
 |h|
 |_|
/___\
 VvV

с входной строкой, написанной сверху вниз на фюзеляже. В этом случае вход был Earth. Высота ракеты (включая пламя) всегда равна длине струны плюс пять.

Каждая строка в выходных данных может иметь до двух завершающих пробелов, и может быть один необязательный завершающий символ новой строки. Самый короткий код в байтах побеждает.

Больше примеров:

[empty string]

  |
 /_\
 |_|
/___\
 VvV

a

  |
 /_\
 |a|
 |_|
/___\
 VvV

|0

  |
 /_\
 |||
 |0|
 |_|
/___\
 VvV

\/\

  |
 /_\
 |\|
 |/|
 |\|
 |_|
/___\
 VvV

 _ _ [note trailing space]

  |
 /_\
 | |
 |_|
 | |
 |_|
 | |
 |_|
/___\
 VvV

    [4 spaces]

  |
 /_\
 | |
 | |
 | |
 | |
 |_|
/___\
 VvV

SPACEY

  |
 /_\
 |S|
 |P|
 |A|
 |C|
 |E|
 |Y|
 |_|
/___\
 VvV

Leaderboard


1
Относящиеся . Могут быть и другие, достаточно близкие, чтобы это считалось обманом.
Питер Тейлор

2
@Sefa Spaces да. Нет для других пробелов. Как указывает связанная вики .
Увлечения Кэлвина

6
Я видел название и ожидал что-то насчет операции на головном мозге. :(

17
И если нижние точки указывают на небо, вы не отправитесь в космос сегодня.
AstroDan

4
«Это сработало в космической программе Кербал ...»
Волшебная Осьминога Урна

Ответы:


55

Excel VBA, 142 179 175 160 155 байтов

Инструкция:

Установите рабочий лист Excel, где ячейка A1 является входом, а столбец C - выходным. Установите выравнивание текста в столбце C по центру . Напишите и запустите следующий код в Immediate Window:

[C1]="|":[C2]="/_\":T=[A1]&"_":For i=1To Len(T):Cells(i+2,3)="|"&Mid(T,i,1)&"|":Next:Cells(i+2,3)="/__\":Cells(i+3,3)="VvV":[C:C].HorizontalAlignment=-4108

Разрушил код:

Sub R()
    [C1] = "|"
    [C2] = "/_\"
    T = [A1]&"_"

    For i = 1 To Len(T)
        Cells(i + 2, 3) = "|" & Mid(T, i, 1) & "|"
    Next

    Cells(i + 2, 3) = "/__\"
    Cells(i + 3, 3) = "VvV"
    [C:C].HorizontalAlignment = -4108   'Set the text alignment in column C to center
End Sub

Выход:

введите описание изображения здесь

Примечание: шрифт и цвет - это только личный выбор.


15 байтов сохранено благодаря предложению edc65. Благодарю.

5 байтов сэкономлено благодаря предложению ТейлорСкотта. Благодарю.


Сохраните 15 байтов, добавляя "_"к T. Как это[C1]="|":[C2]="/_\":T=[A1]&" ":For i=1To Len(T):Cells(i+2,3)="|"&Mid(T,i,1)&"|":Next:Cells(i+2,3)="/__\":Cells(i+4,3)="VvV":Columns(3).HorizontalAlignment=-4108
edc65

(Хорошо, в моем коде есть ошибка, и ее уже слишком поздно редактировать. Но вы
поняли

@ edc65 Понятия не имею. Ваш код точно такой же, как у меня, так что я должен редактировать, чтобы сохранить 15 байтов?
Анастасия-Романова

1
154 байта:[C:C].HorizontalAlignment=-4108:[C1]="|":[C2]="/_\":T=[A1]&"_":For i=1To Len(T):Cells(i+2,3)="|"&Mid(T,i,1)&"|":Next:Cells(i+2,3)="/__\":Cells(i+3,3)="VvV
Тейлор Скотт

1
Или вы можете уменьшить его до 151 байта, сохранив центрирующий аспект[C:C].HorizontalAlignment=3:[C1]="|":[C2]="/_\":T=[A1]&"_":For i=1To Len(T):Cells(i+2,3)="|"&Mid(T,i,1)&"|":Next:Cells(i+2,3)="/___\":Cells(i+3,3)="VvV
Тейлор Скотт

30

Perl 6, 75 байт

"  |\n /_\\".say;" |$_|".say for slurp.chomp.comb;" |_|\n/___\\\n VvV".say;

101
slurp.chomp.comb... Perl странный.
Mego

14
Хлюпая !!! Грызть !!! ГРЕБЕНЬ !! А вот и монстр Perl!
Stommestack

Обратите внимание, что с помощью функции и конкатенации вы можете вырезать много: {[~] " |\n /_\\\n",|(" |$_|\n"for $_.comb)," |_|\n/___\\\n VvV"}65 байтов
user0721090601

Но вы можете пойти еще ниже, позаимствовав у JS: tio.run/…
user0721090601

22

JavaScript (ES6), 54

прямой

x=>`  |
 /_\\
 |${[...x+'_'].join`|
 |`}|
/___\\
 VvV`

Контрольная работа

f=x=>`  |
 /_\\
 |${[...x+'_'].join`|
 |`}|
/___\\
 VvV`

function update() {
  O.textContent=f(I.value)
}

update()
<input id=I value='hello' oninput='update()'><pre id=O></pre>


16

На самом деле, 40 байтов

"/___\
 VvV",'_o"|
 |"j'|o" |"+"  |
 /_\

Да, эти новые строки должны быть там.

Попробуйте онлайн!

Объяснение:

Новые строки представлены \nдля упрощения форматирования

"/___\\n VvV",'_o"|\n |"j'|o" |"+"  |\n /_\
"/___\\n VvV"                                create the bottom of the rocket
             ,'_o                            get input, append a "_" (for the last section before the jets)
                 "|\n |"j                    insert "|\n |" between every pair of characters
                         '|o                 append "|"
                            " |"+            prepend " |"
                                 "  |\n /_\  create the nose cone

12
Ваша программа выглядит удручающе похожей на взорвавшуюся ракету.
CorsiKa

15

C, 83 , 82 байта

F(char*c){for(puts("  |\n /_\\");*c;printf(" |%c|\n",*c++));puts(" |_|\n/___\\\n VvV");}

Основной тест:

int main() {
  F("");
  F("a");
  F("|0");
  F("\\/\\");
  F(" _ _ ");
  F("    ");
  F("SPACEY");
}

7
Я разработал свое собственное C-решение, и оно оказалось именно вашим, персонаж за персонажем. +1 от меня.
Коди

На телефоне и лень SSH, так что это не проверено, но должно работать. Сохраняет 2 байта (если я правильно посчитал):F(char*c){for(puts(" |\n /_\\");*c;printf(" |%c|\n",*c++),puts(" |_|\n/___\\\n VvV");}
algmyr

На самом деле @algmyr сохраняет один байт, потому что последний putsдолжен выполняться только один раз, а не после каждого printf. Но да, 1 байт сохранен, ууу!
Стефано Санфилиппо

Правильно. Я обвиню это в игре в гольф, когда я должен был спать.
'12

Разве это не 88 байтов?
Гастропнер

10

Python 2, 93 66 62 61 байт

ФГИТУ. Вероятно, может быть сильно в гольфе. Предложения приветствуются.

Изменить: 27 байтов благодаря Мего. 4 байта благодаря TheBikingViking. 1 байт благодаря пользователю 3030010.

Попробуйте онлайн!

lambda x:r"""  |
 /_\
 |%s|
/___\
 VvV"""%"|\n |".join(x+"_")

9

PHP, 73 72 69 62 байта

  |
 /_\
 |<?=join('|
 |',str_split($argv[1]._))?>|
/___\
 VvV

Принимает строку для печати на фюзеляже в качестве первого аргумента из командной строки при вызове сценария.

Улучшения:

  1. Сохранил байт, заменив \ n реальной новой строкой LF в первом аргументе join.
  2. Сохранены еще три байта, добавив к входу базу ракеты с одним подчеркиванием
  3. Благодаря Исмаилу Мигелю : сэкономил еще 7 байтов, воспользовавшись тем, что PHP был «препроцессором гипертекста», поэтому вы можете выводить столько текста, сколько хотите, и запускать код где-то посередине.

Попробуйте онлайн!

Это было весело! :-)

Образцы звонков:

php rocket.php ""
php rocket.php EARTH
php rocket.php "This is a very long rocket"


Приятно играть в гольф! Я полностью забыл об этой возможности. Спасибо!
YetiCGN

Пожалуйста. Также я сохранил 2 байта в первой строке. У вас было 2 дополнительных пробела. Должен сказать, что этого я не ожидал найти.
Исмаэль Мигель

1
Я знаю, это было действительно глупо, но также очень трудно обнаружить. Я только заметил, как только я нашел 64 байта в вашей улучшенной версии, и мне пришлось выяснить, почему.
YetiCGN

8

брейкфук , 179 байт

>-[-[-<]>>+<]>-..[->+>++++<<]>>----.<<++++++++++.>.>>>+[-[--<]>>--]<.[-<+<++>>]<<+.---.<,[<<<.>.>.>.<.>,]<<<.[->>>+<<<]>.>.>>+++.<<.>.>>.<...---.<.<<.>>>------.[-<<<+<+>>>>]<<<.<.

Попробуйте онлайн!


@ user00001 Эта фраза используется всеми мусульманами мира, а не только террористами. Вы действительно думаете, что террористы представляют всех мусульман?
Утренняя монахиня


8

Рубин, 57 55 байт

-2 байта от @ValueInk
-5 байтов, если предположить, что во входе нет новой строки, как это предлагается @manatwork. Ввод без новой строки может быть предоставлен, например echo -n, как echo -n hey | ruby rocket.rb.

puts'  |
 /_\
 |'+gets.chars*'|
 |'+'|
 |_|
/___\
 VvV'
Старая версия, предполагает ввод новой строки:

Рубин, 62 60 байт

puts'  |
 /_\
 |'+gets.chop.chars*'|
 |'+'|
 |_|
/___\
 VvV'

Согласно комментарию владельца вопроса, ввод не будет содержать символ новой строки, поэтому вы можете удалить его .chop.
manatwork

@ manatwork аккуратно, спасибо :)
Даниеро

Если вы используете одинарные кавычки строки, вы должны быть в состоянии заменить оба ваши \\ с \ . (В одинарных строках в кавычках символы не экранированы, за исключением \'.
Value Ink


7

Retina , 44 37 байт

7 байтов благодаря Мартину Эндеру.

$
_
.
¶ |$0|
$
¶/___\¶ VvV
^
  |¶ /_\

Попробуйте онлайн!


оставляет пробел в ряду внизу :( для «Космос, последний рубеж».
xQbert

@xQbert работает для меня, вы можете прикрепить ссылку TIO?
Утренняя монахиня

странно, теперь у меня все нормально ... а в конце моей ошибки был перевод строки.
xQbert

Retina - единственный язык, который я знаю, добавление завершающего символа новой строки может полностью изменить программу.
caird coinheringaahing

6

Желе , 37 36 байт

;”_⁾ |;ЀŒB;“/___\“ VvV”“  |“ /_\”;Y

Тот же счет, что и у существующей записи, но использует забавную новую функцию - ŒBвекторизованную версию ŒḄ, известную как bounce. Отскок выполняется через список до конца, а затем обратно, x[:-1]+x[::-1]например:bounce("codegolf") == "codegolflogedoc" .

-1 байт благодаря Деннису (используйте векторизованную версию bounce)

Как?

;”_⁾ |;ЀŒB;“/___\“ VvV”“  |“ /_\”;Y - argument: a string, S
                        “  |“ /_\”   - the top of the rocket ["  |", " /_\"] 
;”_                                  - concatenate to make S=S+"_"
   ⁾ |;                              - concatenate to make c=" |"+c
       Ѐ                            - map over right argument i.e. for c in S
         ŒB                          - bounce! With vectorisation c[:-1]+c[::-1]
                                       e.g. " |B" -> " |B| "
           ;                         - concatenate with
            “/___\“ VvV”             - the bottom of the rocket ["/___\", " VvV"]
                                  ;  - concatenate the top with everything else
                                   Y - join with line feeds

Проверьте это на TryItOnline


2
ŒBэто сокращение от ŒḄ€.
Деннис


5

V , 41, 39 байтов

ys$_òlé
òÎá|I |
Hr/$r\YO  |GpX2á_o VvV

Попробуйте онлайн!

Обратите внимание, что по какой-то причине онлайн-переводчик выдал неожиданные результаты, поэтому я отправил отладочную версию онлайн-интерпретатору, который работает намного медленнее. Это должно дать правильные результаты сейчас.

Так как эта программа содержит непечатаемые символы, вот hexdump:

0000000: 7973 245f f26c e90a f2ce e17c 4920 7c0a  ys$_.l.....|I |.
0000010: 4872 2f24 725c 594f 2020 7c1b 4770 5832  Hr/$r\YO  |.GpX2
0000020: e15f 6f20 5676 56                        ._o VvV

Хорошо, но это не совсем верно для пробелов в «Космосе, последней границе».
xQbert

5

R 163 байта

v=c();l="\n";for(i in 1:nchar(a<-scan(,"")))v=c(v,paste0(" |",strsplit(a,"")[[1]][i],"|",l,collapse=""));cat("  |",l," /_\\",l,v," |_|",l,"/___\\",l," VvV",sep="")

Ungolfed:

v=c()     #Empty vector
l="\n"    #Line break

for(i in 1:nchar(a<-scan(,"")))                  #For the number of character of the input
    v=c(v, paste0(" |",strsplit(a,"")[[1]][i],"|","\n",collapse=""))
    #This part cut the input into its letters, paste each letter between `|`'s, 
    #and a line break

cat("  |",l," /_\\",l,v," |_|",l,"/___\\",l," VvV",sep="") #Puts everything in the STDOUT,
                                                           #with spaces where needed

Мне не очень нравится тот факт, что мне пришлось поместить несколько пробелов в последнюю строку, но эй!


5

PowerShell v2 +, 59 55 51 байт

"  |
 /_\"
$args|% t*y|%{" |$_|"}
" |_|
/___\
 VvV"

Попробуйте онлайн!

Злоупотребляет значением Write-Outputпо умолчанию в конце выполнения, чтобы вставить новую строку между каждым элементом, так как это все буквальные строки в конвейере. Единственный «хитрый» бит - это цикл через каждый элемент ввода $argsв виде массива символов, чтобы получить тело ракеты.

Использует буквальные переводы строк, как указано в ConnorLSW, для сохранения некоторых байтов.
Еще 4 байта благодаря Веске.


вы можете поместить в строку фактические символы новой строки, чтобы сохранить 3, оболочка и ise будут выполняться без\r
colsw


4

PowerShell, 70 байт

"  |`n /_\`n$(([char[]]$a|%{" |$_|"})-join("`n"))`n |_|`n/___\`n VvV 

Установите $ a для ввода.

Если он должен принимать ввод, отличный от переменной, он может быть передан в:

"Hello World"|%{"  |`n /_\`n$(([char[]]$_|%{" |$_|"})-join("`n"))`n |_|`n/___\`n VvV "}

Пример:

  |
 /_\
 |H|
 |e|
 |l|
 |l|
 |o|
 | |
 |W|
 |o|
 |r|
 |l|
 |d|
 |_|
/___\
 VvV 

4

Mathematica, 50 байтов

"  |
 /_\\
 |"<>(#<>"|
 |"&/@#)<>"_|
/___\\
 VvV"&

Анонимная функция. Принимает список символов в качестве ввода и возвращает строку в качестве вывода.


4

PHP, 108 100 88 байт

-8 байт благодаря бизнес-кошке

-12 байт благодаря YetiCGN

echo'  | 
 /_\\
';foreach(str_split($argv[1])as$c){echo" |$c|
";}echo' |_|
/___\\
 VvV';

довольно просто

Ideone


1
Вы можете сэкономить много байтов, используя foreach(str_split($a)as$c)вместо другого цикл for. Кроме того, вы можете поместить $ c непосредственно в строку, если используете двойные кавычки:echo" |$c| ....";
Business Cat

@BusinessCat Правда, спасибо, что двойные кавычки не работали со стилем массива из-за непонятных скобок
Sefa

Как насчет регулярного выражения? function f($a){echo' |.␤ /_\\␤',preg_replace('/./',' |$0|␤',$a),' |_|␤/___\\␤ VvV';}
manatwork

1
Почему даже поставить функцию вокруг этого? Замена $aс $argv[1]и работает из командной строки делает его намного короче.
YetiCGN

@manatwork Вероятно, это верная альтернатива, но, поскольку я не понимаю ее, и она не соответствует моему духу, я позволю вам опубликовать ее.
Сефа

4

C #, 106 97 80 74 байта

s=>$@"  |
 /_\
 |{string.Join("|\n |",s.ToCharArray())}|
 |_|
/___\
 VvV";

У меня нет C # 6, чтобы попробовать выше, но я верю, что это будет работать

Сохранено 7 байтов благодаря Кевину Круйссену

Спасибо Manatwork за указание мне в правильном направлении, чтобы сэкономить 17 байт

Сохранено 6 байт благодаря молоку


+1. Кстати, конечные пробелы являются необязательными, поэтому вы можете изменить их на: using System.Linq;s=>$(" |\n /_\\\n{string.Join("",s.Select(c=>" |"+c+"|\n"))} |_|\n/___\\\n VvV");( 100 байт )
Кевин Круйссен

1
@KevinCruijssen Я только что обновлял это после ваших комментариев к моему предыдущему ответу :) Спасибо за помощь
TheLethalCoder

Вы можете сохранить некоторые символы, используя один строковый литерал внутри Select: " |"+c+"|\n"c+"|\n |"вместе с перемещением `|` после него {}перед ним.
manatwork

@manatwork Я не могу заставить это работать
TheLethalCoder

1
Новая строка составляет 1 байт по сравнению с \n с 2 байтами. Таким образом, вы сэкономите еще 5 байтов, заменив их новыми строками. Да, если вы используете Visual Studio, то по умолчанию новые строки будут иметь размер 2 байта, но вы можете открыть исходный файл в шестнадцатеричном редакторе (в Visual Studio он есть) и удалить символы возврата каретки. Вывод будет все тот же.
молоко

4

C,  131  , 121 байт

#define P printf
main(){char s[99],*p=s;gets(s);P("  |\n /_\\\n");while(*p)P(" |%c|\n",*p++);P(" |_|\n/___\\\n VvV\n");}

Вы можете удалить три символа, перейдя p=sв инициализацию и используя pизнутри scanf:main(){char s[99],*p=s;scanf("%s",p);P(" |\n /_\\\n");while(*p)P(" |%c|\n",*p++);P(" |_|\n/___\\\n VvV\n");}
Квентин

хорошо .... я не знаю, почему "scanf ("% s ", & s)" вместо "scanf ("% s ", s)" выводит в конце правильный результат ... в конце, потому что scanf не получает пробелы, которые я предпочитаю, опасность получает () ...
RosLuP

2
Пожалуйста, не вандализируйте свои сообщения. Спасибо!
NobodyNada


3

05AB1E , 50 47 43 37 байт

I'_J"  |
 /_\"svy" |ÿ|"}"/___\
 VvV"»

Попробуйте онлайн!

Сохранено 9 байт благодаря Аднану.


Строка также может принимать переводы строк в 05AB1E: p, вот так .
Аднан

@ Adnan Хорошо, спасибо! Есть идеи, как лучше обойти пустой ввод?
Эмигна

Я думал о подходе IðJв начале программы, который также включает в себя основу фюзеляжа.
Аднан

@ Adnan Отличная идея. Я попробовал это «раньше без особой удачи. Это намного лучше, хотя.
Эмигна

Снятие Uи замена Xс sтакже экономит байты :).
Аднан

3

Котлин, 68 байт

{"""  |
 /_\${it.replace(Regex("."),"\n |\$0|")}
 |_|
/___\
 VvV"""}

Довольно просто. Использует многострочную строку и замену регулярного выражения. Это лямбда с (String)->Stringтипом. Контрольная работа:

fun main(args: Array<String>) {
    val function : (String)->String = {"""  |
 /_\${it.replace(Regex("."),"\n |\$0|")}
 |_|
/___\
 VvV"""}
    println(function(" _ _ "))
}

3

Гема, 50 знаков

\A=  |\n\ /_\\\n
?=\ |?|\n
\Z=\ |_|\n/___\\\n\ VvV

Образец прогона:

bash-4.3$ echo -n gema | gema '\A=  |\n\ /_\\\n;?=\ |?|\n;\Z=\ |_|\n/___\\\n\ VvV'
  |
 /_\
 |g|
 |e|
 |m|
 |a|
 |_|
/___\
 VvV

3
Я думаю, вы пропустили `| _ |` до основания ракеты
TheLethalCoder

Уч. Тупой мисс. Спасибо @TheLethalCoder.
manatwork

1
+1 за знакомство с новым (для меня) (не играющим в гольф) языком.
Джордан

3

BASH 84 70

Сохранено 14 благодаря manatwork

(cat&&echo _)|sed 's~.~ |&|\n~g;1s~^~  |\n /_\\\n~;$s~$~/___\\\n VvV~'

Более половины байтов предназначены для добавления носа и двигателя.


Почему то grep? (cat&&echo _)|sed 's~.~ |&|\n~g;1s~^~ |\n /_\\\n~;$s~$~/___\\\n VvV~', На самом деле я не вижу смысла использовать catи echoто и другое. Короче превратился бы в чистый sedраствор.
Манатворк

С помощью чистого sed вы не получите никакого вывода, если у вас нет ввода
Riley

Doh. Ты прав. Извините, я забыл эту часть требования.
manatwork

@manatwork Я тоже забыл об этом с первой попытки.
Райли

Для дальнейшего использования избегайте использования тегов <pre> <code>. Используйте 4 пробела, предшествующих коду в будущем, так как это автоматически экранирует форматирование Markdown. Я сохранил текущее форматирование из-за зачеркивания, но вы можете просто оставить это в истории редактирования и для тех, кому интересно посмотреть на него.
Аддисон Крамп

3

GolfScript, 61 51 байт

Мой первый кодовый гольф, надеюсь, он достаточно хорош.

"  |
 /_\\
"\1/.,{" |"\(\"|
"\}\*" |_|
/___\\
 VvV"

объяснение

"  |\n /_\\\n"   # Push the rocket's head
\                # Swap the head with the user's string
1/               # The string is converted into an array
.,               # Push array length
{" |"\           # Push the rocket's body and swap
(\               # Array's first element cut out
"|\n"\           # Push rocket's body and swap
}\*              # Repeat for array length times
" |_|\n/___\\\n VvV" # Push rocket's bottom

Попробуйте онлайн!


3

Vim, 41 39 байт

Здесь <End>буквально ключ «Конец».

i <End>_:s/./ |&|\r/g
/___\
 VvVggxo /_\

Непечатные так:

i <End>_^O:s/./ |&|\r/g
/___\
 VvV^[ggxo /_\^[

3

GNU sed , 54 49 48 байтов

Это был мой первый ответ на вызов на этом сайте. Решение простое, в основном печатное, поэтому я потратил некоторое время на то, чтобы больше не играть в гольф.

s:.:\n |&|:g
s::  |& /_\\&:
a\ |_|\n/___\\\n VvV

Попробуйте онлайн!

Спустя полгода, я переписал сценарий, использовал трюк для хорошей меры и увеличил его до 1 байта. Теперь это прогресс!

Пояснение: пространство шаблона на каждом шаге упоминается для ясности, учитывая пример ввода «GO»

s:.:\n |&|:g
   # turn each input char into a section of the rocket (\n |G|\n |O|)
s::  |& /_\\&:
   # 's::' is a trick; the search part is actually the one from the previous 's'
   #command, i.e. a char. Only the first char, '\n', the modifier 'g' is not
   #inherited. The replace part is the head of the rocket. (  |\n /_\\n |G|\n |O|)
a\ |_|\n/___\\\n VvV
   # append the tail of the rocket, plus implicit printing at the end

  |
 /_\
 |G|
 |O|
 |_|
/___\
 VvV

3

Lua, 83 , 92 байта

function f(x)return' |\n /_\\\n'..x:gsub('(.)',' |%1|\n')..' |_|\n/___\\\n VvV'end

print('  |\n /_\\\n'..(arg[1] and arg[1]:gsub('(.)',' |%1|\n') or '')..' |_|\n/___\\\n VvV')

Если я не добавлю вход в ваш ответ. Это не работает.
Нолан
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.