একটি প্রদত্ত যৌগের মিস্টার সন্ধান করুন!


12

চ্যালেঞ্জ

রাসায়নিকের সূত্র দেওয়া, যৌগের এম আর আউটপুট করুন ।

সমীকরণ

যৌগের প্রতিটি উপাদান একটি সংখ্যার দ্বারা অনুসরণ করা হয় যা যৌগের উল্লিখিত পরমাণুর সংখ্যা বোঝায়। যদি কোনও সংখ্যা না থাকে, তবে যৌগের সেই পরমাণুর মধ্যে একটিই রয়েছে।

কিছু উদাহরণ হ'ল:

  • ইথানল (সি 2 এইচ 6 ও) C2H6Oযেখানে দুটি কার্বন পরমাণু, 6 হাইড্রোজেন পরমাণু এবং 1 অক্সিজেন পরমাণু থাকবে
  • ম্যাগনেসিয়াম হাইড্রোক্সাইড (এমজিও 2 এইচ 2 ) MgO2H2যেখানে ম্যাগনেসিয়াম পরমাণু, দুটি অক্সিজেন পরমাণু এবং দুটি হাইড্রোজেন পরমাণু রয়েছে would

মনে রাখবেন যে আপনাকে কখনই বন্ধনী পরিচালনা করতে হবে না এবং প্রতিটি উপাদান সূত্রের মধ্যে একবার অন্তর্ভুক্ত করা হয়েছে।

যদিও বেশিরভাগ লোকেরা সম্ভবত যে ক্রমটি দিয়ে সবচেয়ে স্বাচ্ছন্দ্য বোধ করে সেটির সাথে লেগে থাকবে, সেখানে কোনও কঠোর অর্ডার দেওয়ার ব্যবস্থা নেই। উদাহরণস্বরূপ, জল হয় H2Oবা হিসাবে দেওয়া যেতে পারে OH2

এম আর

দ্রষ্টব্য: এখানে, ধরে নিন সূত্র ভর আণবিক ভর হিসাবে একই

একটি যৌগের M r , আণবিক ভর, অণুতে পরমাণুর পারমাণবিক ওজনের যোগফল ।

একমাত্র উপাদান এবং তাদের পারমাণবিক ওজন 1 দশমিক স্থানে যা আপনাকে সমর্থন করতে হবে (হাইড্রোজেন থেকে ক্যালসিয়াম, মহৎ গ্যাসগুলি সহ নয়) নিম্নলিখিত as সেগুলি এখানেও পাওয়া যাবে

H  - 1.0      Li - 6.9      Be - 9.0
B  - 10.8     C  - 12.0     N  - 14.0
O  - 16.0     F  - 19.0     Na - 23.0
Mg - 24.3     Al - 27.0     Si - 28.1
P  - 31.0     S  - 32.1     Cl - 35.5
K  - 39.1     Ca - 40.1

আপনার সর্বদা এক দশমিক জায়গায় আউটপুট দেওয়া উচিত।

উদাহরণস্বরূপ, ইথানল ( C2H6O) এর একটি এম আর রয়েছে 46.0কারণ এটি এতে থাকা উপাদানগুলির পারমাণবিক ওজনের যোগফল:

12.0 + 12.0 + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + 1.0 + 16.0
(2*C + 6*H + 1*O)

ইনপুট

উপরের ফর্ম্যাটটিতে একটি স্ট্রিং । আপনি গ্যারান্টি দিতে পারেন যে সমীকরণের অন্তর্ভুক্ত উপাদানগুলি হ'ল প্রকৃত প্রাথমিক প্রতীক।

প্রদত্ত যৌগটি বাস্তবে থাকার নিশ্চয়তা নেই।

আউটপুট

যৌগের মোট এম আর , 1 দশমিক স্থানে।

বিধি

যে বিল্টিনগুলি অ্যাক্সেস উপাদান বা রাসায়নিক ডেটা বাতিল নয় (দুঃখিত ম্যাথামেটিকা)

উদাহরণ

Input > Output
CaCO3 > 100.1
H2SO4 > 98.1
SF6 > 146.1
C100H202O53 > 2250.0

জয়লাভ

বাইটস মধ্যে সংক্ষিপ্ত কোড।

এই পোস্টটি কেয়ারড কোইনারিংহিংয়ের অনুমতি নিয়ে গৃহীত হয়েছিল । (পোস্ট এখন মুছে ফেলা হয়েছে)


আমরা যেমন quantifiers, হ্যান্ডেল করতে হবে: 2H2O?
মিঃ এক্সকোডার

6
NumberForm[#&@@#~ChemicalData~"MolecularMass",{9,1}]&
কৌতূহলের

উত্তর:


6

জেলি , 63 বাইট

ḟØDOP%⁽¡ṛị“ÇṚÆ’BH+“Ḳ"ɦṀ⁷6<s¡_-¦y⁼Ḟ¡¡FPɓ‘¤÷5
fØDVȯ1×Ç
Œs>œṗ⁸ḊÇ€S

একটি মোনাডিক লিঙ্ক অক্ষরের একটি তালিকা গ্রহণ করে এবং একটি নম্বর ফিরিয়ে দেয়।

এটি অনলাইন চেষ্টা করুন!

কিভাবে?

ḟØDOP%⁽¡ṛị“ÇṚÆ’BH+“Ḳ"ɦṀ⁷6<s¡_-¦y⁼Ḟ¡¡FPɓ‘¤÷5 - Link 1, Atomic weight: list of characters
                                            -                              e.g. "Cl23"
 ØD                                         - digit yield = "0123456789"
ḟ                                           - filter discard                      "Cl"
   O                                        - cast to ordinals                [67,108]
    P                                       - product                            7236
      ⁽¡ṛ                                   - base 250 literal = 1223
     %                                      - modulo                             1121
                                        ¤   - nilad followed by link(s) as a nilad:
          “ÇṚÆ’                             -   base 250 literal  = 983264
               B                            -   convert to binary = [    1,    1,     1,     1,   0,  0,  0,   0, 0,  0,  0, 0,     1,     1,     1, 0, 0,  0,  0,   0]
                H                           -   halve             = [  0.5,  0.5,   0.5,   0.5,   0,  0,  0,   0, 0,  0,  0, 0,   0.5,   0.5,   0.5, 0, 0,  0,  0,   0]
                  “Ḳ"ɦṀ⁷6<s¡_-¦y⁼Ḟ¡¡FPɓ‘    -   code-page indexes = [177  , 34  , 160  , 200  , 135, 54, 60, 115, 0, 95, 45, 5, 121  , 140  , 195  , 0, 0, 70, 80, 155]
                 +                          -   addition          = [177.5, 34.5, 160.5, 200.5, 135, 54, 60, 115, 0, 95, 45, 5, 121.5, 140.5, 195.5, 0, 0, 70, 80, 155]
         ị                                  - index into (1-indexed and modular)
                                            -    ...20 items so e.g. 1121%20=1 so 177.5
                                         ÷5 - divide by 5                          35.5

fØDVȯ1×Ç - Link 2: Total weight of multiple of atoms: list of characters   e.g. "Cl23"
 ØD      - digit yield = "0123456789"
f        - filter keep                                                            "23"
   V     - evaluate as Jelly code                                                  23
    ȯ1   - logical or with one (no digits yields an empty string which evaluates to zero)
       Ç - call last link (1) as a monad (get the atomic weight)                   35.5
      ×  - multiply                                                               816.5

Œs>œṗ⁸ḊÇ€S - Main link: list of characters                             e.g. "C24HCl23"
Œs         - swap case                                                      "c24hcL23"
  >        - greater than? (vectorises)                                      10011000
     ⁸     - chain's left argument                                          "C24HCl23"
   œṗ      - partition at truthy indexes                          ["","C24","H","Cl23"]
      Ḋ    - dequeue                                                 ["C24","H","Cl23"]
       Ç€  - call last link (2) as a monad for €ach                  [  288,  1,  816.5]
         S - sum                                                                 1105.5

এটি আমি দেখেছি দীর্ঘতম জেলি উত্তরগুলির মধ্যে একটি, তবে এটি বর্তমানে দ্বিতীয়টির পরে প্রোগ্রামটির দৈর্ঘ্যের অর্ধেকেরও কম, এত ভাল কাজ!
গ্রিফোন

6

পাইথন 3 ,  189 182  168 বাইট

-14 থেকে হ্যাশ ব্যবহার করে বাইট জাস্টিন নাবিকের জাভাস্ক্রিপ্ট (ES6) উত্তর

import re
lambda s:sum([[9,35.5,39.1,24.3,28.1,14,16,31,40.1,23,32.1,10.8,12,27,6.9,19,0,1][int(a,29)%633%35%18]*int(n or 1)for a,n in re.findall("(\D[a-z]?)(\d*)",s)])

এটি অনলাইন চেষ্টা করুন!


নীচে 182 বাইট সংস্করণ দেওয়া আছে, আমি এইটির জন্য ব্যাখ্যাটি রেখে দেব - উপরেরটি কেবল ওজনের ক্রম পরিবর্তন করে, intউপাদানটির নামটি বেস থেকে রূপান্তর করতে 29ব্যবহার করে এবং সংখ্যার পরিসরকে সংকোচিত করতে বিভিন্ন লভ্যাংশ ব্যবহার করে - দেখুন জাস্টিন মেরিনার উত্তর

import re
lambda s:sum([[16,31,40.1,32.1,0,24.3,12,39.1,28.1,19,0,9,10.8,23,27,35.5,6.9,14,1][ord(a[0])*ord(a[-1])%1135%98%19]*int(n or 1)for a,n in re.findall("(\D[a-z]?)(\d*)",s)])

একটি নামবিহীন ফাংশন একটি স্ট্রিং গ্রহণ করে sএবং একটি নম্বর ফিরিয়ে দেয়।

এটি অনলাইন চেষ্টা করুন!

কিভাবে?

ইনপুট বিভক্ত করতে, sএকটি উপাদান ব্যবহার করে উপাদানগুলি এবং তাদের গণনাগুলিতে বিভক্ত করতে একটি রেজেক্স ব্যবহার করে:
re.findall("(\D[a-z]?)(\d*)",s)
\Dঠিক এক অ-অঙ্কের সাথে [a-z]?মেলে এবং 0 বা 1 ছোট অক্ষরের সাথে মেলে, একসাথে উপাদানগুলির সাথে মেলে। \d*0 বা ততোধিক সংখ্যার সাথে মেলে। প্রথম বন্ধনীগুলি এটিকে দুটি গ্রুপে তৈরি করে এবং যেমন findall("...",s)স্ট্রিংয়ের টিপলগুলির তালিকা প্রদান করে [(element, number),...]

সংখ্যা বের করে আনতে সহজ, হাতল একমাত্র জিনিস যে একটি খালি স্ট্রিং মানে 1, এই একটি লজিক্যাল সঙ্গে অর্জন করা হয় orযেহেতু পাইথন স্ট্রিং falsey আছেন: int(n or 1)

উপাদানটির স্ট্রিংটি তার প্রথম এবং শেষ অক্ষরের অর্ডিনালগুলির পণ্য গ্রহণ করে একটি অনন্য নম্বর দেওয়া হয় (সাধারণত এগুলি একই উদাহরণস্বরূপ এস বা সি হয় তবে আমাদের ক্লার্ন, সি, সিএ এবং না এর মধ্যে পার্থক্য করতে হবে তাই আমরা কেবল একটিটি ব্যবহার করতে পারি না চরিত্র)।

এরপরে এই সংখ্যাগুলি [0,18] এর অনেক ছোট পরিসীমা আবরণে হ্যাশ করা হয়, এর ফলে পরিবর্তিত মডুলো স্থান অনুসন্ধান করে %1135%98%19। উদাহরণস্বরূপ "Cl"ordinals হয়েছে 67এবং 108যা গুণ দিতে 7736, যা, মডিউল 1135হয় 426, যা মডিউল 98হয় 34, যা মডিউল 19হয় 15; এই সংখ্যাটি পূর্ণসংখ্যার একটি তালিকায় সূচক হিসাবে ব্যবহৃত হয় - তালিকার 15 তম (0-সূচী) মান:
[16,31,40.1,32.1,0,24.3,12,39.1,28.1,19,0,9,10.8,23,27,35.5,6.9,14,1]
হ'ল 35.5, সিএলটির পারমাণবিক ওজন, যা পরে এই জাতীয় উপাদানগুলির সংখ্যার দ্বারা গুণিত হয় (উপরে পাওয়া যায়)।

এই পণ্যগুলি তখন ব্যবহার করে একসাথে যুক্ত করা হয় sum(...)


আপনি একজন প্রতিভা ... আমাকে 350 বাইট বেশি ছাপিয়ে গেছে
মিঃ এক্সকডার

4

পিএইচপি , 235 বাইট

preg_match_all("#([A-Z][a-z]?)(\d*)#",$argn,$m);foreach($m[1]as$v)$s+=array_combine([H,Li,Be,B,C,N,O,F,Na,Mg,Al,Si,P,S,Cl,K,Ca],[1,6.9,9,10.8,12,14,16,19,23,24.3,27,28.1,31,32.1,35.5,39.1,40.1])[$v]*($m[2][+$k++]?:1);printf("%.1f",$s);

এটি অনলাইন চেষ্টা করুন!

পরিবর্তে array_combine([H,Li,Be,B,C,N,O,F,Na,Mg,Al,Si,P,S,Cl,K,Ca],[1,6.9,9,10.8,12,14,16,19,23,24.3,27,28.1,31,32.1,35.5,39.1,40.1])আপনি [H=>1,Li=>6.9,Be=>9,B=>10.8,C=>12,N=>14,O=>16,F=>19,Na=>23,Mg=>24.3,Al=>27,Si=>28.1,P=>31,S=>32.1,Cl=>35.5,K=>39.1,Ca=>40.1]একই বাইট গণনা দিয়ে ব্যবহার করতে পারেন


3

জাভাস্ক্রিপ্ট (ES6), 150 বাইট

c=>c.replace(/(\D[a-z]?)(\d+)?/g,(_,e,n=1)=>s+=[9,35.5,39.1,24.3,28.1,14,16,31,40.1,23,32.1,10.8,12,27,6.9,19,0,1][parseInt(e,29)%633%35%18]*n,s=0)&&s

জোনাথন অ্যালানের পাইথন উত্তরের দ্বারা অনুপ্রাণিত হয়ে , যেখানে তিনি প্রতিটি উপাদানকে একটি অনন্য নম্বর দেওয়ার এবং সেই সংখ্যাগুলি একটি ছোট পরিসরে হ্যাশিংয়ের ব্যাখ্যা দিয়েছিলেন।

উপাদানগুলি বেস -৯৯ (০-৯ এবং এএস) হিসাবে ব্যাখ্যা করে অনন্য সংখ্যায় তৈরি করা হয়েছিল। আমি তখন দেখতে পেয়েছি যে স্বতন্ত্রতা বজায় রাখার সময় %633%35%18মানগুলিকে সীমাবদ্ধ করে দেয় [0, 17]

পরীক্ষার স্নিপেট

f=
c=>c.replace(/(\D[a-z]?)(\d+)?/g,(_,e,n=1)=>s+=[9,35.5,39.1,24.3,28.1,14,16,31,40.1,23,32.1,10.8,12,27,6.9,19,0,1][parseInt(e,29)%633%35%18]*n,s=0)&&s
Input: <input oninput="O.value=f(this.value)"><br>
Result: <input id="O" disabled>


ওহ, আমি মনে করি আপনার উপায় আমাকে কয়েক বাইটও বাঁচাতে পারে!
জোনাথন অ্যালান

2

Clojure, 198 194 বাইট

আপডেট: forচেয়ে ভাল reduce

#(apply +(for[[_ e n](re-seq #"([A-Z][a-z]?)([0-9]*)"%)](*(if(=""n)1(Integer. n))({"H"1"B"10.8"O"16"Mg"24.3"P"31"K"39.1"Li"6.9"C"12"F"19"Al"2"S"32.1"Ca"40.1"Be"9"N"14"Na"23"Si"28.1"Cl"35.5}e))))

মূল:

#(reduce(fn[r[_ e n]](+(*(if(=""n)1(Integer. n))({"H"1"B"10.8"O"16"Mg"24.3"P"31"K"39.1"Li"6.9"C"12"F"19"Al"2"S"32.1"Ca"40.1"Be"9"N"14"Na"23"Si"28.1"Cl"35.5}e))r))0(re-seq #"([A-Z][a-z]?)([0-9]*)"%))

আমি ভাবছি যে লুক-টেবিলটি এনকোড করার আরও কমপ্যাক্ট উপায় আছে কিনা।



1

গণিত, 390 338 329 বাইট

সত্যিকার অর্থে এখন জাগ্রত হওয়ার কারণে এবং আসলে আমার উদ্দেশ্যটি সংক্ষিপ্ত করে দেওয়ার কারণে 9 টি বাইট সংরক্ষণ করা হয়েছে।

সংস্করণ ২.১:

S=StringSplit;Total[Flatten@{ToExpression@S[#,LetterCharacter],S[#,DigitCharacter]}&/@S[StringInsert[#,".",First/@StringPosition[#,x_/;UpperCaseQ[x]]],"."]/.{"H"->1,"Li"->3,"Be"->9,"B"->10.8,"C"->12,"N"->14,"O"->16,"F"->19,"Na"->23,"Mg"->24.3,"Al"->27,"Si"->28.1,"P"->31,"S"->32.1,"Cl"->35.5,"K"->39.1,"Ca"->40.1}/.{a_,b_}->a*b]&

ব্যাখ্যা: সমস্ত বড় অক্ষরের অবস্থান সন্ধান করুন। প্রতিটি আগে একটি বিন্দু রাখুন। প্রতিটি বিন্দুতে স্ট্রিং বিভক্ত করুন। সাবস্ট্রিংয়ের এই তালিকার জন্য অক্ষরের উপর ভিত্তি করে নিম্নলিখিতটি বিভক্ত করুন এবং অঙ্কের ভিত্তিতে বিভক্ত করুন। অক্ষর দ্বারা বিভক্ত এগুলি স্ট্রিংকে সংখ্যায় রূপান্তর করে। অঙ্কগুলি দ্বারা বিভক্তগুলির জন্য প্রতিটি রাসায়নিককে তার আণবিক ওজন দিয়ে প্রতিস্থাপন করে। একটি আণবিক ওজন এবং একটি পরমাণু গণনা সঙ্গে তাদের জন্য এটি তাদের পণ্য সঙ্গে প্রতিস্থাপন। তাদের মোট খুঁজে।

সংস্করণ 1:

আমি নিশ্চিত যে এটি প্রচুর পরিমাণে গল্ফ করা যেতে পারে (বা কেবল পুরোপুরি নতুন করে লেখা)। আমি কীভাবে এটি করতে হবে তা নির্ধারণ করতে চেয়েছিলাম। (সকালে এটি প্রতিফলিত করবে।)

F=Flatten;d=DigitCharacter;S=StringSplit;Total@Apply[Times,#,2]&@(Transpose[{F@S[#,d],ToExpression@F@S[#,LetterCharacter]}]&@(#<>If[StringEndsQ[#,d],"","1"]&/@Fold[If[UpperCaseQ[#2],Append[#,#2],F@{Drop[#,-1],Last[#]<>#2}]&,{},StringPartition[#,1]]))/.{"H"->1,"Li"->3,"Be"->9,"B"->10.8,"C"->12,"N"->14,"O"->16,"F"->19,"Na"->23,"Mg"->24.3,"Al"->27,"Si"->28.1,"P"->31,"S"->32.1,"Cl"->35.5,"K"->39.1,"Ca"->40.1}&

ব্যাখ্যা: প্রথমে স্ট্রিংটিকে অক্ষরে ভাগ করুন। তারপরে অ্যারের উপরে ভাঁজ করে ছোট অক্ষরে এবং সংখ্যায় তাদের রাজধানীতে ফিরে যান। এরপরে শেষে কোনও সংখ্যা ছাড়াই যে কোনও রাসায়নিকের জন্য 1 যুক্ত করুন। তারপরে অ্যারেতে শর্তগুলির দুটি বিভাজন করুন - একটি সমস্ত সংখ্যায় বিভাজন এবং একটিতে সমস্ত অক্ষরে বিভাজন। প্রথমে অক্ষরগুলি তাদের মোলার জনসাধারণের সাথে প্রতিস্থাপন করুন তারপরে এই দুটি তালিকার বিন্দু পণ্যটি সন্ধান করুন।


1

পাইথন 3 - 408 বাইট

এটি মূলত @ovs এর সমাধান, যেহেতু তিনি এটিকে ১২০ বাইটের বেশি দিয়ে গলফ করেছেন ... নীচের প্রাথমিক সমাধানটি দেখুন।

e='Li Be Na Ca Mg Al Si Cl P S K H B C N O F'.split()
f,g=input(),[]
x=r=0
for i in e:
 if i in f:g+=[(r,eval('6.9 9 23 40.1 24.3 27 28.1 35.5 31 32.1 39.1 1 10.8 12 14 16 19'.split()[e.index(i)]))];f=f.replace(i,' %d- '%r);r+=1
h=f.split()
for c,d in zip(h,h[1:]):
 s=c.find('-')
 if-1<s:
  if'-'in d:
   for y in g:x+=y[1]*(str(y[0])==c[:s])
  else:
   for y in g:x+=y[1]*int(d)*(str(y[0])==c[:s])
print(x)

এটি অনলাইন চেষ্টা করুন!

পাইথন 3 - 550 548 535 বাইট (ইনডেন্টেশনের সাথে গণনাটি হারিয়েছে)

@ কায়ারডকোইনারিংগাহিংয়ের জন্য 10 বাইট সংরক্ষণ এবং ওভিএসকে 3 টি সংরক্ষণ করার জন্য ধন্যবাদ সংরক্ষণ করা হয়েছে

আমার কোনও ব্যক্তিগত লক্ষ্য ছিল যে কোনও রেইগেক্স না ব্যবহার করা এবং এটি মজাদার, পুরাতন-স্কুল উপায়ে করা ... এটি রেজিক্স সলিউশনের চেয়ে 350 বাইট দীর্ঘ হতে পারে, তবে এটি কেবল পাইথনের স্ট্যান্ডার্ড লাইব্রেরি ব্যবহার করে ...

a='Li6.9 Be9. Na23. Ca40.1 Mg24.3 Al27. Si28.1 Cl35.5 P-31. S-32.1 K-39.1 H-1. B-10.8 C-12. N-14. O-16. F-19.'.split()
e,m,f,g,r=[x[:1+(x[1]>'-')]for x in a],[x[2:]for x in a],input(),[],0
for i in e:
 if i in f:g.append((r,float(m[e.index(i)])));f=f.replace(i,' '+str(r)+'- ');r+=1;
h,x=f.split(),0
for i in range(len(h)):
 if '-'in h[i]:
    if '-'in h[i+1]:
     for y in g:x+=y[1]*(str(y[0])==h[i][:h[i].index('-')])
    else:
        for y in g:
         if str(y[0])==h[i][:h[i].index('-')]:x+=(y[1])*int(h[i+1])
 else:1
print(x)  

এটি অনলাইন চেষ্টা করুন!


যদি কেউ এটিকে গল্ফ করতে ইচ্ছুক থাকে (ইনডেন্টেশন ফিক্স এবং অন্যান্য কৌশল সহ ...), এটির জন্য আরও ভাল উপায় আছে বলে মনে হচ্ছে এটি 100% ভালভাবে গ্রহণ করা হবে ...


আপনি প্রতিস্থাপন করতে পারেন for y in g: if str(y[0])==h[i][:h[i].index('-')]:x+=y[1]সঙ্গেfor y in g:x+=y[1]*(str(y[0])==h[i][:h[i].index('-')])
caird coinheringaahing

@ কায়ারডকোইনারিংআহিং আহ, দুর্দান্ত ... আপডেট করার সময় আমি যখন একটি কম্পিউটারে অ্যাক্সেস পাই তখন
মিঃ এক্সকডার

@ovs অনেক ধন্যবাদ! উত্তরে আপনাকে জমা দিয়েছিল
মিঃ এক্সকোডার

পাইথনে, আপনি একটি নতুন লাইনের জায়গায় একটি সেমিকোলন ব্যবহার করতে পারেন, যা আপনাকে ইনডেন্টেশনে বাইট সংরক্ষণ করতে দেয়।
পাভেল

@ ফিনিক্স যদি if/for/whileপরের লাইনে কোনও থাকে না । যেহেতু প্রতিটি ইনডেন্টড লাইনে এটি হয়, আপনি এটি দ্বারা বাইট সংরক্ষণ করতে পারবেন না।
ovs
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.