精致分区


19

考虑一个整数数组:

[1, 0, 9, 1, 3, 8]

有很多方法可以将该列表划分为连续的子列表。这是三个:

A: [[1, 0, 9], [1, 3, 8]]
B: [[1], [0, 9], [1, 3], [8]]
C: [[1, 0], [9, 1], [3, 8]]

我们将调用一个分区Ÿ另一个分区的和改进X,如果X可以从以下地址获得ÿ通过加入一些子列表的重新走到一起。

所以,B是的改进A:如果我们前两个和最后两个子列表加入到一起,我们得到A。但是,C不是的改进A:我们不得不分手的91以恢复A从它。同样,任何分区本身都是琐碎的改进。

请注意,我们不允许在任何时候重新排列任何子列表或元素。

挑战

鉴于两个分区(整数列表的列表)X,并Y,确定是否Y是一个细化X

您可以假设分区将仅包含从0到的整数9(含)。您不能假定XY是同一列表的分区(如果不是,则它们也不是彼此的优化)。X和/或Y可能为空,但永远不会包含空子列表。

您可以编写程序或函数,通过STDIN(或最接近的替代方案),命令行自变量或函数自变量获取输入,并通过STDOUT(或最接近的替代方案),函数返回值或函数(out)参数输出结果。

输入可以采用任何方便的字符串或列表格式。由于元素只能是一位整数,因此您可以选择在子列表中省略定界符,但请确保前导0s是可能的。您可以选择采取XY顺序相反。

输出应该是truthy如果Y是的细化Xfalsy否则。

您的代码必须能够在一台合理的台式机上在一秒钟内解决以下每个测试用例。(这仅仅是为了避免简单的暴力解决方案而进行的健全性检查。)

这是代码高尔夫球,因此最短的答案(以字节为单位)获胜。

测试用例

每个测试用例都单独显示,写成X Y。我正在使用GolfScript / CJam样式的数组表示法来节省一些水平空间:

真相:

[] []
[[0]] [[0]]
[[1 0 9 1 3 8]] [[1 0 9] [1 3 8]]
[[1 0 9 1 3 8]] [[1 0 9 1 3] [8]]
[[1 0 9 1 3 8]] [[1] [0] [9] [1] [3] [8]]
[[1 0 9] [1 3 8]] [[1 0 9] [1 3 8]]
[[1 0 9] [1 3 8]] [[1] [0 9] [1 3] [8]]
[[9 8 8 5 8 2 7] [5] [1 4] [2 0 0 6 0 8 4 2 6 4 2 3 7 8 7 3 9 5 7 9 8 2 9 5] [3 9 8] [7 1 4 9 7 4 5 9] [3 3 3] [9 0 7 8] [3 9 4 7 2 7 8 0 3 0] [8 2 2 7 3 9 3 2] [2 9 0 8 5 4 1 8 5 5 6 2 0 9 2 7 7 9 2 7] [3 6] [1 2 7 7 4 4 2 9]] [[9 8] [8] [5 8 2] [7] [5] [1 4] [2] [0 0 6] [0] [8 4 2] [6 4] [2] [3] [7 8] [7 3] [9] [5 7 9] [8 2] [9 5] [3] [9 8] [7 1 4] [9 7] [4 5 9] [3 3] [3] [9 0] [7 8] [3] [9] [4] [7 2] [7 8] [0] [3 0] [8 2] [2] [7 3] [9 3] [2] [2] [9] [0] [8 5 4] [1 8] [5 5] [6] [2 0] [9] [2] [7 7 9] [2 7] [3 6] [1 2] [7 7] [4 4 2] [9]]

虚假:

[[0]] []
[[0]] [[1]]
[[1 0 9]] [[1 0 9] [1 3 8]]
[[1 0 9] [1 3 8]] [[1 0 9 1 3 8]]
[[1 0 9] [1 3 8]] [[1 0 9]]
[[1 0 9] [1 3 8]] [[1 0] [9]]
[[1 0 9] [1 3 8]] [[1 0] [9 1] [3 8]]
[[1] [0 9] [1 3] [8]] [[1 0 9] [1 3 8]]
[[9 8 8 5 8 2 7] [5] [1 4] [2 0 0 6 0 8 4 2 6 4 2 3 7 8 7 3 9 5 7 9 8 2 9 5] [3 9 8] [7 1 4 9 7 4 5 9] [3 3 3] [9 0 7 8] [3 9 4 7 2 7 8 0 3 0] [8 2 2 7 3 9 3 2] [2 9 0 8 5 4 1 8 5 5 6 2 0 9 2 7 7 9 2 7] [3 6] [1 2 7 7 4 4 2 9]] [[9 8] [8] [5 8 2] [7] [5 1] [4] [2] [0 0 6] [0] [8 4 2] [6 4] [2] [3] [7 8] [7 3] [9] [5 7 9] [8 2] [9 5] [3] [9 8] [7 1 4] [9 7] [4 5 9] [3 3] [3] [9 0] [7 8] [3] [9] [4] [7 2] [7 8] [0] [3 0] [8 2] [2] [7 3] [9 3] [2] [2] [9] [0] [8 5 4] [1 8] [5 5] [6] [2 0] [9] [2] [7 7 9] [2 7] [3 6] [1 2] [7 7] [4 4 2] [9]]

排行榜

这是一个堆栈片段,用于按语言生成常规排行榜和获胜者概述。

为确保您的答案显示出来,请使用以下Markdown模板以标题开头。

# Language Name, N bytes

N您提交的文件大小在哪里。如果您提高了分数,则可以将旧分数保留在标题中,方法是将它们打掉。例如:

# Ruby, <s>104</s> <s>101</s> 96 bytes

<script>site = 'meta.codegolf'; postID = 5314; isAnswer = true; QUESTION_ID = 51719</script><script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script><script>jQuery(function(){var u='https://api.stackexchange.com/2.2/';if(isAnswer)u+='answers/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJeRCD';else u+='questions/'+postID+'?order=asc&sort=creation&site='+site+'&filter=!GeEyUcJFJO6t)';jQuery.get(u,function(b){function d(s){return jQuery('<textarea>').html(s).text()};function r(l){return new RegExp('<pre class="snippet-code-'+l+'\\b[^>]*><code>([\\s\\S]*?)</code></pre>')};b=b.items[0].body;var j=r('js').exec(b),c=r('css').exec(b),h=r('html').exec(b);if(c!==null)jQuery('head').append(jQuery('<style>').text(d(c[1])));if (h!==null)jQuery('body').append(d(h[1]));if(j!==null)jQuery('body').append(jQuery('<script>').text(d(j[1])))})})</script>

相关挑战


[[[1 0 9] [1 3 8]] [[1] [0 9] [1 3] [8]]]或者[["109" "138"] ["1" "09" "13" "8"]]是一个可接受的输入格式?
丹尼斯

@Dennis将整个输入包装在一个数组中似乎很奇怪。我不知道这是标准做法,但可能值得提出一个元问题。没有这些外部括号,那肯定没问题。
马丁·恩德

我将尝试写一个元问题。
丹尼斯

Answers:


6

果酱,13 10 9字节

lr.-F-U-!

在中在线尝试 CJam解释器中

感谢@MartinBüttner的建议 @ edc65的巧妙输入格式

感谢@ jimmy23013改进了输入格式并打了3个附加字节。

输入输出

输入项

子列表被分开;并且彼此由,

1;0;9,1;3;8
1,0;9,1;3,8

输出量

1

怎么运行的

lr e# Read line and a whitespace-separated token from STDIN.
.- e# Vectorized difference. Pushes the differences of corresponding code points.
F- e# Remove all occurrences of 15 (';' - ',') from the array.
U- e# Remove all occurrences of 0 from the array.
!  e# Push 1 if the resulting array is empty and 0 if not.

对于不同长度的字符串,.-会将字符保留在数组中,该字符不能等于整数0或15。


如果您可以使用;作为分隔符... ll.m27m0-!
jimmy23013 2015年

@ jimmy23013:我不明白为什么不这样做。,;都是通用的数组语法(CJam都不使用它们)。谢谢!
丹尼斯

9

Pyth,19个字节

&gF_m{.u+NYdYQqFsMQ

在线试用:演示测试工具

我正在使用Pyth的元组/列表格式作为输入。只需用逗号替换测试用例的空格即可。

说明:

                     implicit: Q is the evaluated input
    m        Q       map each input list d to:
      .u   dY          reduce with intermediate states over d, initial value = []
        +NY              update initial value N with sum of N and Y (current element of d)
     {                 generate a set
   _                 invert
 gF                  check, if the first element is >= (superset) than the second
&                    and
                sMQ  check, if the joined lists of the input
              qF     are equal

由于伪代码仍然有些混乱,因此我将使用示例输入来演示该算法。

Input: [[1,0,9],[1,3,8]],[[1],[0,9],[1,3],[8]]

.u+NYdY零件计算包含第一个元素的所有连续子列表。

[[1,0,9],[1,3,8]]     => [[], [1,0,9], [1,0,9,1,3,8]]
[[1],[0,9],[1,3],[8]] => [[], [1], [1,0,9], [1,0,9,1,3], [1,0,9,1,3,8]]

B是的细化形式A,前提是的每个连续子列表A也是的连续子列表B(只有一个例外)。

所以我只是检查,如果设定的连续子列表的A是一组连续的子表的子集BgF_m.u+NYdYQ)。

唯一的例外是,如果第一个输入列表包含的元素少于第二个输入列表。例如<Fm.u+YdYQ将返回True输入[[1]],[[1],[2]]

因此,我还要检查联接列表是否也相等 &...qFsMQ


7

JavaScript(ES6),67 70

编辑保存的3个字节thx @apsillers

在Firefox中运行以下代码段进行测试

f=(a,b)=>a+''==b // same values in the lists ?
&![...a.join(' ')].some((c,p)=>c<','&b.join(c)[p]>c) // splits in a are present in b?

// TEST

out=x=>O.innerHTML += x+'\n';

OK=[
[[],[]],
[[[0]],[[0]]],
[[[1,0,9,1,3,8]],[[1,0,9],[1,3,8]]],
[[[1,0,9,1,3,8]],[[1,0,9,1,3],[8]]],
[[[1,0,9,1,3,8]],[[1],[0],[9],[1],[3],[8]]],
[[[1,0,9],[1,3,8]],[[1,0,9],[1,3,8]]],
[[[1,0,9],[1,3,8]],[[1],[0,9],[1,3],[8]]],
[[[9,8,8,5,8,2,7],[5],[1,4],[2,0,0,6,0,8,4,2,6,4,2,3,7,8,7,3,9,5,7,9,8,2,9,5],[3,9,8],[7,1,4,9,7,4,5,9],[3,3,3],[9,0,7,8],[3,9,4,7,2,7,8,0,3,0],[8,2,2,7,3,9,3,2],[2,9,0,8,5,4,1,8,5,5,6,2,0,9,2,7,7,9,2,7],[3,6],[1,2,7,7,4,4,2,9]],[[9,8],[8],[5,8,2],[7],[5],[1,4],[2],[0,0,6],[0],[8,4,2],[6,4],[2],[3],[7,8],[7,3],[9],[5,7,9],[8,2],[9,5],[3],[9,8],[7,1,4],[9,7],[4,5,9],[3,3],[3],[9,0],[7,8],[3],[9],[4],[7,2],[7,8],[0],[3,0],[8,2],[2],[7,3],[9,3],[2],[2],[9],[0],[8,5,4],[1,8],[5,5],[6],[2,0],[9],[2],[7,7,9],[2,7],[3,6],[1,2],[7,7],[4,4,2],[9]]]
];

KO=[
[[[0]],[]],
[[[0]],[[1]]],
[[[1,0,9]],[[1,0,9],[1,3,8]]],
[[[1,0,9],[1,3,8]],[[1,0,9,1,3,8]]],
[[[1,0,9],[1,3,8]],[[1,0,9]]],
[[[1,0,9],[1,3,8]],[[1,0],[9]]],
[[[1,0,9],[1,3,8]],[[1,0],[9,1],[3,8]]],
[[[1],[0,9],[1,3],[8]],[[1,0,9],[1,3,8]]],
[[[9,8,8,5,8,2,7],[5],[1,4],[2,0,0,6,0,8,4,2,6,4,2,3,7,8,7,3,9,5,7,9,8,2,9,5],[3,9,8],[7,1,4,9,7,4,5,9],[3,3,3],[9,0,7,8],[3,9,4,7,2,7,8,0,3,0],[8,2,2,7,3,9,3,2],[2,9,0,8,5,4,1,8,5,5,6,2,0,9,2,7,7,9,2,7],[3,6],[1,2,7,7,4,4,2,9]],[[9,8],[8],[5,8,2],[7],[5,1],[4],[2],[0,0,6],[0],[8,4,2],[6,4],[2],[3],[7,8],[7,3],[9],[5,7,9],[8,2],[9,5],[3],[9,8],[7,1,4],[9,7],[4,5,9],[3,3],[3],[9,0],[7,8],[3],[9],[4],[7,2],[7,8],[0],[3,0],[8,2],[2],[7,3],[9,3],[2],[2],[9],[0],[8,5,4],[1,8],[5,5],[6],[2,0],[9],[2],[7,7,9],[2,7],[3,6],[1,2],[7,7],[4,4,2],[9]]]
];

dump=l=>l.map(x=>'['+x+']').join(',');

out('YES');
OK.forEach(l=>out(f(l[0],l[1])+' a['+dump(l[0])+'] b['+dump(l[1])+']'));
out('NO');
KO.forEach(l=>out(f(l[0],l[1])+' a['+dump(l[0])+'] b['+dump(l[1])+']'));
<pre id=O></pre>


这些天之一,我将不得不下载Firefox才能看到您的出色解决方案在运行。:)
Alex A.

@AlexA。没有它你怎么能生活?
edc65 2015年

使用repl.it,我认为它支持ES6:D
Mark K Cowan

我喜欢您如何命名变量OKKO
rr-

7

C,69 75

具有2个字符串参数的函数,返回0或1。

参数格式:子列表用空格('')分隔,列表元素用逗号分隔。

例: "1,0,9 1,3,8" "1,0 9,1,3,8"

f(char*a,char*b){for(;*a-44?*a&&*b==*a:*b<48;a++)b++;return!(*b|*a);}

少打高尔夫球

int f(char *a, char *b)
{
    // expected in a,b: digit,separator,digit... with separator being ' ' or ','
    for(; *a; a++,b++)
       // ' ' or digit in a must be the same in b
       // comma in a must be comma or space in b
       if (*a != ',' ? *b != *a : *b > *a) return 0;
    return !*b; // must have a null in *b too
}

测试 Idone(已过时)


1
输入格式的明智选择。我已将其借给Haskell的另一个答案。
nimi 2015年

我剥夺了您输入JS答案的想法,结果证明比我的C版本一个字节,直到我将其升级到ES6为止……谁能想到……
Mark K Cowan

6

Haskell,76个字节

[]#[]=1<2
[x]#[y]=x==y
x@(a:b)#(c:d:e)|a==c=b#(d:e)|1<2=x#((c++d):e)
_#_=2<1

退货TrueFalse。用法示例:[[1,0,9],[1,3,8]] # [[1,0],[9]]->False

简单的递归方法:如果第一个元素匹配,则继续使用尾巴,否则从头开始,但将两个元素串联在第二个列表的前面。基本情况是:两个列表都为空-> True;两个列表都有一个元素->比较它们;只有一个列表为空-> False


6

CJam,19个字节

q~]{_,,\f>:sS.+}/-!

在线尝试。

输入输出

输入项

[[1 0 9] [1 3 8]] [[1] [0 9] [1 3] [8]]

输出量

1

理念

可以通过观察以下两个属性来唯一标识每个分区:

  • 通过串联所有子列表形成的列表。

  • “切入点”,包括列表的极端。

通过将每个切割点替换为从切割点到列表末尾的元素子列表,我们可以将这两个条件组合为一个。

为了验证给定的分区是否比另一个分区更好,我们只需要验证较粗的分区(如上所示)是否是更精细的分区的子集,并且两个分区的最大列表是否匹配。

q~]   e# Read from STDIN and evaluate.
{     e# For each array P from the input:
  _,, e#   Push [0 ... L], where L == length(P) - 1.
  \f> e#   Push [P[0:] ... P[L]].
  :s  e#   Stringify each P[k:] (flattens).
  S.+ e#   Vectorized concatenation. This appends a space to the first element.
}/    e#
-!    e# Push the logical NOT of the difference A-B to check if A is a subset of B.

对于I / O示例的输入,堆栈保存

["109138 " "138"] ["109138 " "09138" "138" "8"]

执行之前 -!

请注意,每个数组的第一个元素都有一个尾随空格。这样可以确保我们将第一个输入的完整列表与第二个输入的完整列表进行比较。


5

CJam,24个字节

l~L\{+_a2$1<={;1>L}&}/+!

算法

在这里,我们仅使用贪婪算法来查看N第二个列表的第一个子列表是否可以合并在一起以形成第一个列表的第一个子列表。找到此类文件后N,我们将删除第一个N将从第二个列表中个子列表,并从第一个列表中个子列表,然后重复该过程。

理想情况下,如果第二个列表是第一个列表的改进,则应该在堆栈上保留2个空列表。我们只是检查一下,然后打印出来1。在任何其他组合中,在完全迭代第二个列表的子列表之后,我们将不会得到2个空列表。因此在0这种情况下将打印一个。

代码扩展

l~L\{+_a2$1<={;1>L}&}/+!
l~L\                       e# Read the line, evaluate the two lists and put an empty list
                           e# between them
    {               }/     e# Iterate over all sub-lists of the second list
     +                     e# Append the current sub-list to whatever is on stack. Originally
                           e# an empty array, but eventually the sum of first N sub-lists
      _a                   e# Copy this and wrap it in an array
        2$                 e# Copy the first list on top of stack
          1<               e# Get only its first element wrapped in an array. This approach
                           e# is exception safe in case the array was already 0 length
            ={    }&       e# If we have a match, remove both first sub-lists
              ;            e# Remove the first N sub-lists array
               1>          e# Remove the first element from the first array
                 L         e# Put an empty array on stack to repeat the process
                      +!   e# If we are left with two empty arrays, sum them and do logical
                           e# not to get 1. If any of the arrays is non-empty, logical not
                           e# gives 0

在此处在线尝试此处运行完整的测试套件


3

C,120个 114字节

#define C(x),x+=(*x/93)*(1+!!x[1])|1
o;R(char*s,char*t){for(o=1;*s;o&=*s==t[2*(*t==93&&93>*s)]C(s)C(t));return o;}

我最近没有打高尔夫球,所以我想尝试一下。

我们定义了一个函数R(char* s, char* t),该函数返回1if t是的精炼分区s0否则返回。st预计将在格式[DDDD...][DDDD...]...凡每一D都是另一个一位数字元素”。

测试代码:

#include "stdio.h"

int main(int argc, char** argv) {
    char* str1, *str2;
    str1 = "[109][138]";
    str2 = "[1][09][13][8]";
    printf("Input: %s, %s --> %d\n", str1, str2, R(str1, str2));

    str1 = "[109][138]";
    str2 = "[1][19][13][8]";
    printf("Input: %s, %s --> %d\n", str1, str2, R(str1, str2));

    str1 = "[109][138]";
    str2 = "[10][91][3][8]";
    printf("Input: %s, %s --> %d\n", str1, str2, R(str1, str2));
}

上面打印了以下内容:

Input: [109][138], [1][09][13][8] --> 1
Input: [109][138], [1][19][13][8] --> 0
Input: [109][138], [10][91][3][8] --> 0

至少似乎可行。


3

Haskell,52 50 53字节

x#y=and$zipWith(\a b->a==b||a==',')(x++"..")(y++"..")

与我的其他解决方案完全不同。使用与@ edc65的答案相同的巧妙输入格式,即,元素用,和列出,用

用法示例:"1,0,9,1,3,8" # "1,0,9 1,3,8"->True

如果第二个参数在每个位置上具有相等的元素,或者第一个为,则第二个参数为第一个参数的改进,。我必须在..两个参数后附加一个唯一的结束标记(-> ),因为它会zipWith截断较长的参数,例如"1,2,3" # "1,2"也会是True


1
(\a b->a==b||a>b)就是(>=)
alephalpha

不会只是添加"."而不是".."工作吗?
自豪的haskeller

这失败了,"2"#"1"因为函数仅检查值是否更大而不相等
骄傲的haskeller

@alephalpha:哦,亲爱的,我多么愚蠢地忽略了这一点。但这是错误的。查看其他评论。
nimi 2015年

@proudhaskeller:该死的最后一分钟编辑。是的,这是一个错误。固定它。感谢您的发现。顺便说一句,单个点将"."不起作用,因为它将给出错误的肯定结果,"2,1" # "2"该错误结果 将首先扩展为"2,1." # "2.",然后被截断zipWith"2," # "2."。第一个字符串中的逗号匹配所有内容。
nimi 2015年

2

Mathematica,65个字节

f@__=1<0;{}~f~{}=1>0;{a_,b___}~f~{c__,d___}/;a==Join@c:={b}~f~{d}

1
不错的解决方案。仅供参考,我有一个59字节的解决方案,它不使用递归(或多个定义)。
马丁·恩德

2

带正则表达式的数学很有趣!

ES6 Javascript,53个字符

(a,b)=>RegExp('^'+a.replace(/,/g,'[ ,]')+'$').test(b)

Vintage Javascript,70个字符

function f(a,b){return RegExp('^'+a.replace(/,/g,'[ ,]')+'$').test(b)

使用与edc65的answer相同的输入格式。

完整的演示,包括此处的所有测试用例。


聪明!从未考虑过此任务的正则表达式。
edc65

我编写了一个perl程序,该程序使用递归函数对整数进行因子分解,该函数使用回溯正则表达式找到了主要因子……它们虽然不漂亮,而且绝对不是很快,但是它们可以做一些很酷的事情!
Mark K Cowan 2015年

我还编写了一个解析器生成器,它将语言规范转换为正则表达式,然后该正则表达式可用于解析指定语言的表达式。基本上,将人类可读的语言规范“编译”为“可执行”正则表达式。 github.com/battlesnake/d-slap 生成的用于解析AngularJS理解表达式的正则表达式长约400-500个字符...
Mark K Cowan

2

Mathematica,55个字节

Equal@@Join@@@#&&SubsetQ@@(Accumulate[Length/@#]&)/@##&

这定义了一个未命名的函数,将两个分区以相反的顺序放在一个列表中(即,Y首先,X第二)。

说明

Equal@@Join@@@#

这将检查两个分区是否实际上是同一列表的分区。

SubsetQ@@(Accumulate[Length/@#]&)/@##

这是我在有关Mathematica.SE的问题中采用的打高尔夫球方式,这激发了这一挑战。基本上,一个分区定义为在其中插入了拆分的多个索引,这将通过累积子列表的长度来检查所有拆分位置是否X也出现在Y其中。


2

Python 2,68 51字节

感谢xnor节省了大量字节!

匿名函数,采用两个字符串形式"1,0,9 1,3,8"(从edc65的C答案中获取)并返回TrueFalsemap(None)不再适用于Python 3的新版本。

lambda a,b:all(i in[j,","]for i,j in map(None,a,b))

测试套件:

>>> def runTests(f):
    assert f("1,0,9 1,3,8","1 0,9 1,3 8")
    assert not f("1,0,9 1,3,8","1,0 9,1 3,8")
    assert f("1 0,9 1,3 8","1 0,9 1,3 8")
    assert not f("1 0,9 1,3 8","1,0,9 1,3,8")
    assert not f("1 0,9 1,3 8","1 0,9 1,3")
    assert not f("1 0,9 1,3,8","1 0,9 1,3")
    print("All tests pass.")


>>> runTests(lambda a,b:all(i in[j,","]for i,j in map(None,a,b)))
All tests pass.

以前的92字节解决方案,其输入为"109 138"

def R(a,b):
 r=1
 for i in b.split():r&=a.find(i)==0;a=a[len(i):].strip()
 return r and""==a

我认为您可以通过映射None来避免进行显式的长度检查。一个列表比另一个列表长的情况将被拒绝,因为一个列表有一个列表,None而另一个索引有一个数字,因为i==j or"0">i>j无法保存。
xnor

除非我缺少任何东西,否则第二项测试可以是i==','。这使您可以将测试合并为i in[',',j](我们不能这样做i in ','+j),因为j可能是None
xnor 2015年

@xnor哇,谢谢。#1并没有发生在我身上,因为我现在已经习惯于使用Python 3了。#2并没有出现在我身上,因为“那个地方如果b有数字怎么办?” ...忘记了这种输入格式是不可能的。
DLosc
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.