ম্যাট্রিক্স র‌্যাঙ্ক এক?


21

পূর্ণসংখ্যার একটি ম্যাট্রিক্স দেওয়া হয়েছে, এটি র‌্যাঙ্ক-এক হলে পরীক্ষা করুন, অর্থাত প্রতিটি সারি একই ভেক্টরের একাধিক is উদাহরণস্বরূপ, ইন

 2   0  -20  10  
-3   0   30 -15
 0   0   0   0

প্রতিটি সারি একটি একাধিক 1 0 -10 5

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

 *    1   0  -10  5
    ----------------
 2 |  2   0  -20  10  
-3 | -3   0   30 -15
 0 |  0   0   0   0

আমরা সারি লেবেল r[i]এবং কলাম লেবেলগুলি অর্পণ করেছি c[j]যাতে প্রতিটি ম্যাট্রিক্স এন্ট্রি M[i][j]সম্পর্কিত লেবেলের পণ্য হয় M[i][j] = r[i] * c[j]

ইনপুট:

আপনার পছন্দসই 2D ধারক হিসাবে একটি পূর্ণসংখ্যা ম্যাট্রিক্স। উদাহরণস্বরূপ, তালিকাগুলির একটি তালিকা, একটি 2 ডি অ্যারে বা অনুরূপ। অ্যারে ফর্ম্যাটটির প্রয়োজন না হলে আপনি অতিরিক্ত ইনপুট হিসাবে প্রস্থ বা উচ্চতা গ্রহণ করবেন না।

ম্যাট্রিক্স অ-স্কোয়ার হতে পারে। এটিতে কমপক্ষে একটি ননজারো এন্ট্রি থাকবে - আপনাকে খালি বা শূন্য ম্যাট্রিক্সের সাথে ডিল করতে হবে না।

আপনি ধরে নিতে পারেন যে পূর্ণসংখ্যাগুলি ওভারফ্লো সমস্যার কারণ হবে না।

আউটপুট:

র‌্যাঙ্ক-ওয়ান ম্যাট্রিক্সের জন্য একটি সামঞ্জস্যপূর্ণ মান এবং অন্যান্য ম্যাট্রিকের জন্য আলাদা ধারাবাহিক মান।

অন্তর্নির্মিত-ইনগুলি:

আপনি করতে পারেন না কোনো বিল্ট-ইন নির্ণয় করতে র্যাঙ্ক ব্যবহার করুন অথবা সরাসরি র্যাঙ্ক এক চেক করুন। আপনি অন্যান্য বিল্ট-ইনগুলি যেমন ইগেনভ্যালু, পচন ইত্যাদি ব্যবহার করতে পারেন তবে আমি উত্তরগুলি উত্সাহিত করব যাতে বিল্ট-ইনগুলি বেশিরভাগ কাজ করে না।

পরীক্ষার কেস:

মান-এক:

[[2, 0, -20, 10], [-3, 0, 30, -15], [0, 0, 0, 0]]
[[0, 0, 0], [0, 3, 0], [0, 0, 0]]
[[-10]]
[[0, 0, 0], [0, 4, 11], [0, -4, -11]]

এক নম্বর নয়:

[[-2, 1], [2, 4]]
[[0, 0, 3], [-22, 0, 0]]
[[1, 2, 3], [2, 4, 6], [3, 6, 10]]
[[0, -2, 0, 0], [0, 0, 0, 1], [0, 0, -2, 0]]

লিডারবোর্ড:


2
কৌতূহলের জন্য, বিল্টইনগুলি ব্যবহার করে একটি গাণিতিক প্রতিক্রিয়া এর মতো দেখায় (16 বাইট):MatrixRank@#==1&
জংহওয়ান মিন


2
একটি সুন্দর উপপাদ্য হ'ল সীমাবদ্ধ মাত্রিক ম্যাট্রিক্সের জন্য কলাম র‌্যাঙ্ক সারি র‌্যাঙ্কের সমান।
লিকি নুন

3
আমাদের কি ভাসমান নির্ভুলতার বিষয়ে চিন্তা করতে হবে? তারা উদাহরণস্বরূপ র‌্যাঙ্ক -১ ম্যাট্রিক্সকে র‌্যাঙ্ক ২ বলে মনে করতে পারে
লুইস মেন্ডো

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

উত্তর:


13

জেলি , 6 বাইট

ẸÐfÆrE

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

কিভাবে এটা কাজ করে

ẸÐfÆrE  Main link. Argument: M (2D array)

ẸÐf     Filter by any, removing rows of zeroes.
   Ær   Interpret each row as coefficients of a polynomial and solve it over the
        complex numbers.
     E  Test if all results are equal.

স্পষ্টতা

Ærসংখ্যাসূচক পদ্ধতি ব্যবহার করে, সুতরাং এর ফলাফলগুলি সাধারণত অনর্থক থাকে। উদাহরণস্বরূপ, ইনপুট [6, -5, 1] , যা বহুপদী 6 - 5x + x² উপস্থাপন করে , এর শিকড়গুলির ফলাফল 3.000000000000000004 এবং 1.9999999999999998 । যাইহোক, বহু বহির্ভুতের সমস্ত সহগকে একই অ-শূন্য ধ্রুবক দ্বারা গুণিত করা সমানভাবে অক্ষত শিকড়গুলির ফলাফল। উদাহরণস্বরূপ, [6, -5, 1] এবং [6 × 10 100 , -5 × 10 100 , 10 100 ] এরÆr জন্য একই শিকড় প্রাপ্ত ।

এটা যে সীমিত স্পষ্টতা উল্লেখ করা উচিত ভাসা এবং জটিল ধরনের পারেন ত্রুটি হতে। উদাহরণস্বরূপ, [1, 1] এবং [10 100 , 10 100 + 1] এরÆr জন্য একই শিকড় পাওয়া যাবে । যেহেতু আমরা ধরে নিতে পারি যে ম্যাট্রিক্সটি বড় নয় এবং বিশেষত ভুলভাবে শ্রেণিবদ্ধ হওয়ার জন্য বেছে নেওয়া হয়নি , এটি ঠিক করা উচিত।


5
সমান অযোগ্য শিকড়গুলিতে একই অ-শূন্য ধ্রুবক ফলাফল দ্বারা বহুবর্ষের সমস্ত সহগকে গুন করা এটি একটি উজ্জ্বল পদ্ধতির
লুইস মেন্ডো

8

হাস্কেল , 50 বাইট

rIntegers এর তালিকার একটি তালিকা নেয় এবং Falseম্যাট্রিক্সের র‌্যাঙ্ক এক থাকলে তা ফেরত দেয় True

r l=or[map(x*)b<map(y*)a|a<-l,b<-l,(x,y)<-zip a b]

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

কিভাবে এটা কাজ করে

  • সমস্ত জোড়া সারি aএবং b(সমান সারি সহ) উত্পন্ন করে এবং প্রতিটি জোড়ের জন্য আসুন xএবং yসংশ্লিষ্ট উপাদানগুলির মাধ্যমে চালিত হন।
  • সারিটি bদ্বারা xএবং সারিটি গুণ aকরে y। ফলাফল সর্বদা সমান হলে ম্যাট্রিক্সের এক পদমর্যাদা থাকবে।
  • যেহেতু জোড়া উভয় অর্ডারে উত্পন্ন হয়, <তাই কোনও অসমতা আছে কিনা তা পরীক্ষা করতে ব্যবহার করা যেতে পারে। পরীক্ষার ফলাফলগুলির তালিকার সাথে মিলিত হয় or, Trueযদি কোনও আন-আনুপাতিক সারি থাকে giving

7

গণিত, 51 33 বাইট

RowReduce@#~Count~Except@{0..}<2&

ইনপুট

[{{2,0, -20,10}, {- 3,0,30, -15}, {0,0,0,0}}]

-202729 ব্যবহারকারীর কাছ থেকে -14 বাইট
3 টি আরও বাইট জাঙ্গওয়ানমিন থেকে সংরক্ষণ করা হয়েছে


আমি প্রস্তাব দিচ্ছি যে এর সমান দৈর্ঘ্যের সাথে একটি সারণী বানানোর পরিবর্তে First@#আপনি গণনা করতে পারবেন 0First@#যেহেতু 0 দিয়ে গুণক সমস্ত 0 এবং গুণকটি তালিকাভুক্ত। এছাড়াও আপনি Tr[1^<list>]তালিকার দৈর্ঘ্য গণনা করতে ব্যবহার বিবেচনা করতে পারেন ।
ব্যবহারকারী 202729

খুব সুন্দর।আমি সম্পাদনা করব!
J42161217

পরিবর্তে 0#&@@#, {0..}খুব কাজ করবে। এবং তারপরে Infixকাজ করে, তাই চূড়ান্ত কোডটি হতে পারে RowReduce@#~Count~{0..}==Tr[1^#]-1&, 2 বাইট সংরক্ষণ করে।
জংহওয়ান মিন

আসলে, স্টাফ থেকে Exceptমুক্তি পেতে ব্যবহার করা যেতে পারে Tr। -3 বাইট:RowReduce@#~Count~Except@{0..}==1&
জংহওয়ান মিন

আমি মনে করি সারি-হ্রাসিত ম্যাট্রিক্সটি ননজারো হওয়ার গ্যারান্টিযুক্ত (কারণ মূল ম্যাট্রিক্স নঞ্জেরো), সুতরাং গণনার ফলাফলটি ইতিবাচক পূর্ণসংখ্যার হবে, সুতরাং <2পরিবর্তে এটি ব্যবহার করা যেতে পারে ==1
ব্যবহারকারী 202729

4

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

এটি একটি নীল এর 05AB1E উত্তরের উপর ভিত্তি করে এবং আমার মূল পদ্ধতির চেয়ে উল্লেখযোগ্যভাবে দক্ষ।

falseর‌্যাঙ্ক-ওয়ান এবং trueঅন্যথায় ফেরত দেয় ।

f=(a,R,V,X)=>a.some(r=>r.some((v,x)=>R?v*V-r[X]*R[x]:f(a,r,v,x)))

পরীক্ষার মামলা


আসল উত্তর, ৮৪ বাইট

falseর‌্যাঙ্ক-ওয়ান এবং trueঅন্যথায় ফেরত দেয় ।

a=>a.some(r=>r.some((x,i)=>(isNaN(x/=a.find(r=>r.some(x=>x))[i])?r:1/r[0]?r=x:x)-r))

পরীক্ষার মামলা

কিভাবে?

a => a.some(r =>          // given a matrix a, for each row r of a:
  r.some((x, i) =>        //   for each value x of r at position i:
    (                     //
      isNaN(x /=          //     divide x by a[ref][i]
        a.find(r =>       //       where ref is the index of the first row that
          r.some(x => x)  //       contains at least one non-zero value
        )[i]              //       (guaranteed to exist by challenge rules)
      ) ?                 //     we get NaN for 0/0, in which case:
        r                 //       use r, so that this column is ignored
      :                   //     else:
        1 / r[0] ?        //       if r is still holding the current row:
          r = x           //         set it to x (either a float, +Inf or -Inf)
        :                 //       else:
          x               //         use x
    ) - r                 //     subtract r from the value set above (see table)
  )                       //   end of some()
)                         // end of every()

কোডের শেষে যে বিয়োগফলটি সম্পাদিত হয় সেগুলি বিভিন্ন বিভিন্ন পরিস্থিতিতে ডেকে আনতে পারে, যা নীচে সংক্ষিপ্ত বিবরণ দেওয়া হয়েছে:

A                   | B              | A - B       | False / True
--------------------+----------------+-------------+-------------
array of 1 number   | same array     | 0           | False
array of 2+ numbers | same array     | NaN         | False
a number            | same number    | 0           | False
+Infinity           | +Infinity      | NaN         | False
-Infinity           | -Infinity      | NaN         | False
a number            | another number | <> 0        | True
+Infinity           | -Infinity      | +Infinity   | True
-Infinity           | +Infinity      | -Infinity   | True
a number            | +/-Infinity    | +/-Infinity | True
+/-Infinity         | a number       | +/-Infinity | True

পরীক্ষা তাড়াতাড়ি আমরা truthy মান পান ব্যর্থ হলে: এই ঘটনার যখন আমরা দুটি স্বতন্ত্র অনুপাত (ব্যতীত অন্য সম্মুখীন 0/0 মধ্যে) একটি (আমি, Y) এবং একটি (আমি, R) কোন সারিতে Y ম্যাট্রিক্স, যেখানে r হ'ল একটি শূন্যের সারির সূচক।


হু, আমি নিজেই ভাবছিলাম যে ...
নীল

@ নীল আপনি কি এটি একটি নতুন উত্তর হিসাবে পোস্ট করতে চান? আমাকে জানতে দাও.
আর্নল্ড


3

জেলি , 12 বাইট

ẸÐfµ÷"ЀZE€Ẹ

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

ব্যাখ্যা

ẸÐfµ÷"ЀZE€Ẹ  Main link
 Ðf           Filter; keep all elements where
Ẹ             At least one element is truthy (remove zero-rows)
      Ѐ      For each row on the right side
    ÷"        Divide it by each row in the original
        Z     Zip the array
          €   For each submatrix
         E    Are all rows equal?
           Ẹ  Is at least one of the elements from above truthy?

এটি আমার আসল অ্যালগরিদমের মাইল গল্ফ সম্পর্কে আমার ব্যাখ্যা হিসাবে ব্যাখ্যা কিছুটা ভুল হতে পারে

মাইল -5 বাইট ধন্যবাদ


... আপনার কোডটি টাকার প্রতি আসক্ত। (আমি
দেজা

@ আইক্রিরিটিম আরে কমপক্ষে ডলারের চিহ্নের সংখ্যা এবার কোডের দৈর্ঘ্যের অর্ধেকেরও কম! : পি
হাইপারনিউটারিনো

1
@ আইক্রিওয়ারিটিম একটি বাগ ঠিক করেছে এবং এখন আরও কম ডলার লক্ষণ: পি
হাইপার নিউট্রিনো

আমি বিশ্বাস করি এটি 12 বাইট ẸÐfµ÷"ЀZE€Ẹ টিআইও
মাইলের

@ মাইল ওহ সুন্দর! আপনার দৃষ্টিভঙ্গি কিছুটা আলাদা (আমি মনে করি?) যাতে আপনি নিজের উত্তরটি নিজের পছন্দ হিসাবে পোস্ট করতে পারেন :)
হাইপারনিউটারিনো

3

05 এ বি 1 ই , 16 বাইট

2ãεø2ãε`R*`Q}W}W

এটি অনলাইন চেষ্টা করুন! যে কোনও আয়তক্ষেত্রের বিপরীত কোণগুলির একই পণ্য রয়েছে এমন গুণক সারণীর বৈশিষ্ট্য ব্যবহার করে। ব্যাখ্যা:

2ãε           }     Loop over each pair of rows
   ø                Transpose the pair into a row of pairs
    2ãε     }       Loop over each pair of columns
       `R*`Q        Cross-multiply and check for equality
             W W    All results must be true

3

টিআই-বেসিক (টিআই -83 সিরিজ), 28 27 28 বাইট (62 অক্ষর)

:Prompt [A]
:{0→X
:Matr►list(ref([A])ᵀ,L₁,X
:not(max(abs(ᶫX

ম্যাট্রিক্সের সারি-একেলোন ফর্মটি গণনা করে [A], এর প্রথম সারিটি (বাতিল করতে হবে) L₁এবং এর দ্বিতীয় সারিতে এটি সংরক্ষণ করে ᶫX। তারপরে max(abs(ᶫXশূন্য হবে যদি ᶫXকেবল শূন্য থাকে এবং ধনাত্মক মান হয় অন্যথায়, যা not(ম্যাট্রিক্স 1 এর র‌্যাঙ্ক হলে 1 এ পরিবর্তিত হয়, অন্যথায় 0।

1-সারি ম্যাট্রিক্সের ᶫXজন্য সেট করা থাকে {0}এবং তারপরে পরিবর্তন হয় না যখন আমরা ম্যাট্রিক্সের অস্তিত্বহীন দ্বিতীয় সারিটি দেখার চেষ্টা করি।


-1 বাইট ধন্যবাদ স্কট মিলনারকে

1-সারি ম্যাট্রিক্সের জন্য মাত্রা ত্রুটিটি ঠিক করতে +1 বাইট। সক্রিয় আউট Matr►list( কমান্ড অভিযোগ আপনি শুধুমাত্র এক সারি সঙ্গে একটি ম্যাট্রিক্স থেকে দ্বিতীয় সারির বের করে আনতে চেষ্টা; তবে, আপনি যদি ম্যাট্রিক্স থেকে প্রথম এবং দ্বিতীয় সারির উভয়ই বের করার চেষ্টা করেন তবে এটি নিঃশব্দে ব্যর্থ হবে।


1
এর Prompt [A]পরিবর্তে আপনি একটি বাইট সংরক্ষণ করতে পারেন Ans→[A]
স্কট মিলনার

@ স্কটমিলনার ধন্যবাদ! যদি আমরা ClrListআরম্ভ করার মতো কিছু ব্যবহার করি তবে হয় এড়িয়ে যাওয়ার সম্ভবত উপায় আছে ᶫXতবে আমি কম জায়গায় কাজ করার পক্ষে তেমনটা অর্জন করতে পারি নি।
মিশা লাভরভ

দ্বিতীয় লাইনটি থেকে মুক্তি পান, যেহেতু Matr►list(তালিকাটি অস্তিত্ব নেই এমনকি তালিকাটি ওভাররাইট করবে এবং আপনি 5 বাইট সংরক্ষণ করবেন।
kamoroso94

1
@ kamoroso94 দ্বিতীয় লাইনের বিন্দুটি উপস্থিত না থাকলে তালিকা তৈরি করা নয়: দ্বিতীয় লাইনের বিন্দুটি যখন ম্যাট্রিক্সের কেবল একটি সারি থাকে তখন দ্বিতীয় সারির জন্য একটি ডিফল্ট মান তৈরি করা হয়। আপনি যদি দ্বিতীয় লাইনের হাত থেকে মুক্তি পান তবে কোডটি 1xN ম্যাট্রিক্সের জন্য ক্র্যাশ হবে।
মিশা লাভরভ

2
@ কামোরসো94 আমাদের এল 1 প্রতিস্থাপন করতে হবে, ওয়াই নয়; অন্যথায়, ক্যালকুলেটর ভাববে "ম্যাট্রিক্সের Y-th সারিটি toX এ বের করুন", "প্রথম সারিটি ᶫY- তে এবং দ্বিতীয় সারিটি toX" এ বের করবেন না "।
মিশা লাভরভ

3

ব্র্যাচল্যাগ , 27 বাইট

{⊇Ċ}ᶠzᵐ{↰₁ᶠ{⟨hz{t↔}⟩×ᵐ=}ᵐ}ᵐ

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

"প্রতিটি আয়তক্ষেত্রের বিপরীত কোণগুলির পণ্য সমান হওয়া উচিত" এর জন্য নীলের দৃষ্টিভঙ্গি ব্যবহার করুন। ক্রস পণ্য ব্যয়বহুল এবং 10 টি পুরো বাইট লাগে, তবে এটি যে বিভাগ বিভাগ ভিত্তিক পদ্ধতির চেয়ে আমি চেষ্টা করেছি তার চেয়ে এখনও এটি সংক্ষিপ্ত, মূলত প্রশ্নটিতে সত্য এবং মিথ্যা জন্য দুটি ধারাবাহিক আউটপুট নির্ধারণের কারণে - মিথ্যা তৈরি করা কেবলমাত্র একটি হতে পারে false., এবং কখনও কখনও একটিও হয় না বিভাজন দ্বারা শূন্য ত্রুটি, অনেকগুলি বাইট ব্যবহার করে।

{⊇Ċ}ᶠzᵐ{↰₁ᶠ{⟨hz{t↔}⟩×ᵐ=}ᵐ}ᵐ
{⊇Ċ}ᶠ                        Get each pair of rows from the matrix
                             eg.: [ [[a, b, c], [k, l, m]], ... ]
     zᵐ                      Zip each pair's elements
                                  [ [[a, k], [b, l], [c, m]], ... ]
       {                 }ᵐ  Map this over each pair of rows:
                                  [[a, k], [b, l], [c, m]]
        ↰₁ᶠ                  Get each pair of paired elements from the rows
                                  [[[a, k], [b, l]], [[b, l], [c, m]], [[a, k], [c, m]]]
           {           }ᵐ    Map this over each pair of pairs
                                  [[a, k], [b, l]]
            ⟨hz{t↔}⟩         Zip the first pair with the reverse of the second
                                  [[a, l], [k, b]]
                    ×ᵐ       Multiply within each sublist
                                  [al, kb]
                      =      The results should be equal
                             (If the results are unequal for any pair, the whole predicate fails,
                              and outputs false.)

উপাদান-ভিত্তিক বিভাগের ভিত্তিতে বিকল্প পদ্ধতি ( 30 বাইট ):

{≡ᵉ¬0&}ˢ\↰₁ˢ{c׬0&⟨hz∋⟩ᶠ/ᵐ²=ᵐ}

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



1

সেজম্যাথ, 40 বাইট

lambda M:any(M.rref()[1:])*(M.nrows()>1)

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

এই অজ্ঞাতনামা ফাংশনটি Falseযদি ম্যাট্রিক্স র‌্যাঙ্ক-এক হয় এবং Trueঅন্যথায় ফিরে আসে।

ফাংশনটি Mইনপুট হিসাবে একটি ম্যাট্রিক্স নেয় , এটিকে হ্রাস করা সারি-একেলোন ফর্ম ( M.rref()) এ রূপান্তর করে anyএবং প্রথম সারির অ-শূন্যের জন্য পরীক্ষা করে। তারপরে, সেই মানটি দ্বারা গুণিত হয় M.nrows()>1(ম্যাট্রিক্সের একাধিক সারি রয়েছে?)


1

পাইথন 3 , 93 91 বাইট

lambda m,e=enumerate:any(h*g-r[j]*s[i]for r in m for i,h in e(r)for s in m for j,g in e(s))

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

কিভাবে এটা কাজ করে

কোনও 2-নাবালিকাকে ননজারো নির্ধারক রয়েছে কিনা তা পরীক্ষা করে। যদি এটি হয় তবে র‌্যাঙ্কটি অবশ্যই কমপক্ষে 2 হওয়া উচিত: "নন-ভিশন পি-মাইনর (পি-পি সাবমেট্রিক্স নন-শূন্য নির্ধারক সহ) দেখায় যে সেই সাবম্যাট্রিক্সের সারি এবং কলামগুলি লাইনগতভাবে স্বাধীন, এবং এইভাবে সারিগুলি এবং পূর্ণ ম্যাট্রিক্সের কলামগুলি সম্পূর্ণরূপে স্বতন্ত্র (সম্পূর্ণ ম্যাট্রিক্সে) থাকে, সুতরাং সারি এবং কলামের র‌্যাঙ্ক অন্তত নির্ধারক র‌্যাঙ্কের চেয়ে বড় হয় "( উইকিপিডিয়া থেকে )

দ্রষ্টব্য: শেভ দুটি বাইট ব্যবহারকারী 71546 এর মন্তব্যে ধন্যবাদ।


1
91 - যদি ফাংশন আর্গুমেন্টগুলিতে গণনা করা যায় এবং এভাবে প্রয়োজনীয়তা দূর করা হয় তবে সংক্ষিপ্ত f=:lambda m,e=enumerate:any(h*g-r[j]*s[i]for r in m for i,h in e(r)for s in m for j,g in e(s))
শিওরু আসাকোটো

@ user71546 ধন্যবাদ! ইহা শেষ!
লুকা সিটি

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.