构造梯子


26

介绍

我想搭梯子。为此,我从垃圾场清理了两个长板,其中有孔,我想将台阶放到这些孔中。但是,孔的位置不均匀,因此步骤会有点儿摇晃,我发现很难估算出我需要的杆数量。你的工作是为我做计算。

输入项

您的输入是两个位向量,以整数数组形式给出,代表了两个板。A 0代表一个不带孔的1 aud的片段(距离的任意单位),而a 1代表一个不带孔的1 aud的片段。数组的长度可能不同,并且包含不同数量1的,但是它们不会为空。

我将按以下方式构造我的梯子。首先,我将两块电路板精确地相距一个aud,然后对齐它们的左端。对于每个索引i,我测量i第一块板的i孔与第二块板的孔之间的距离,切下一根杆,然后将其连接在两个孔之间。一旦我在其中一块板上的孔用完了,我就会停下来。

输出量

您的输出是我将要执行的步骤所需的总杆数,以奥德为单位。输出应正确至少为六个有效数字。

考虑输入[0,1,1,0,1,1,1,1,0,0][1,0,0,1,1,1,0,0,1]。生成的梯形看起来像这样:

一个非常时髦的梯子。

该梯子7.06449510224598中杆的总长度为奥兹。

规则

您可以编写函数或完整程序。最低字节数获胜,并且不允许出现标准漏洞。

测试用例

[0] [0] -> 0.0
[0] [1,0] -> 0.0
[1,0,0] [1,1,1,1,1] -> 1.0
[0,1,0,1] [1,0,0,1] -> 2.414213562373095
[0,1,1,0,1,1,1,1,0,0] [1,0,0,1,1,1,0,0,1] -> 7.06449510224598
[1,1,1,1,1] [0,0,1,1,0,1,0,0,1] -> 12.733433128760744
[0,0,0,1,0,1,1,0,0,0,1,1,1,0,0,1,0,1,1,0,0,0,1,0] [0,0,1,1,0,1,1,1,0,0,0,0,0,1,1,0,1,1,0,0,0,1] -> 20.38177416534678

32
为了您自己的安全,我真的不建议您爬任何看起来像这样的梯子。
Alex A.

Answers:



10

J,22个字符

不受randomra答案的启发。该I.部分是相等,因为这是发现孔的立即明显的方式。

(4+/@:o.<.&#$-/@,:)&I.
  • I. y–所有y重复的索引,其重复次数与的相应项目相同y。顺便提及,如果y是布尔值的向量,I. y包含索引处y1。例如,I. 1 0 0 1 1 1 0 0 1yields 0 3 4 5 8
  • x u&v y–与相同(v x) u (v y)。应用为x u&I. y,我们得到(I. x) u (I. y)。让我们继续转换后的输入。
  • x <.&# y-的长度的较小者xy
  • x -/@,: y-对项目的差异xy。如果一个向量较长,则用零填充。
  • x $ y–调整y为所指定的形状x。具体来说,如果x是标量,则x元素取自y。在这种用法中,请x (<.&# $ -/@,:) y确保忽略尾随孔。
  • 4 o. y-功能%: 1 + *: y,即,SQRT(1个+ ý ²)。顺便说一句,此功能从孔距到杆的长度进行映射。
  • +/ y–的元素之和y

10

Python,85岁

lambda*A:sum(abs(x-y+1j)for x,y in zip(*[[i for i,x in enumerate(l)if x]for l in A]))

事实证明,这类似于Mac的解决方案。将0和1的列表转换为一索引的有序列表,然后求和各个元素之间的距离。


2
做得很好。复杂字面量不错!
Mac

我比其他答案短一个字节,这让我感到有点难过,我认为这是一种更具创造力的解决方案。
xnor 2015年

6

J,32 28字节

该动词I.返回1s在二进制字符串中的位置,对您有很大帮助。

   +/@,@(=/&(#\)*[:>:&.*:-/)&I.

   0 1 0 1 (+/@,@(=/&(#\)*[:>:&.*:-/)&I.) 1 0 0 1
2.41421

为了获得更好的J解决方案,请检查FUZxxl的答案


5

R,67

使用外部对分度孔进行不同处理。诊断返回所需的差额。然后将计算出的距离相加

function(a,b)sum((diag(outer(which(a==1),which(b==1),"-"))^2+1)^.5)

在R Fiddle中进行测试。我将其包装在印刷物中以显示退货符合规格。

> print((function(a,b)sum((diag(outer(which(a==1),which(b==1),"-"))^2+1)^.5))(c(0,1,1,0,1,1,1,1,0,0),c(1,0,0,1,1,1,0,0,1)),digits=10)
[1] 7.064495102
> print((function(a,b)sum((diag(outer(which(a==1),which(b==1),"-"))^2+1)^.5))(c(1,1,1,1,1),c(0,0,1,1,0,1,0,0,1)),digits=10)
[1] 12.73343313
>

好东西。a==1可以是a>0!!a
freekvd

5

Haskell,77 73字节

r x=[a|(a,1)<-zip[1..]x]
i#j=sum$zipWith(\n m->sqrt((n-m)**2+1))(r i)$r j

用法:[0,1,0,1] # [1,0,0,1]输出哪个2.414213562373095

工作原理:该函数r返回电路板孔位置的列表,例如r [0,1,0,1]-> [2,4]#压缩其中两个列表,并将其转换为相应孔之间的距离列表,最后对其求和。


4

CJam,36 33字节

l~]{:L,{L=},}%z{,(},0\{~-_*)mq+}/

非常幼稚的方法...它期望输入为STDIN上的CJam样式的数组

[0 1 1 0 1 1 1 1 0 0] [1 0 0 1 1 1 0 0 1]

这是所有示例输入的测试工具。在调用实际代码之前,将使用输入字段中的结果。如果您不信任我,可以将其删除。;)

说明

l~]                               "Read and eval input, wrap in an array.";
   {        }%                    "Map this block onto both input arrays.";
    :L,                           "Store array in L, get its length N.";
       {L=},                      "In the range [0 .. N-1] get all elements where L is 1.";
                                  "At this point we've converted each array into a list of its
                                   non-zero indices.";
              z                   "Transpose the array, pairing up indices at the same position.";
               {,(},              "Filter the extraneous elements of the longer input.";
                    0\            "Put a 0 before the array.";
                      {        }/ "For each pair of holes...";
                       ~-         "Unwrap the pair, take the difference.";
                         _*)mq    "Square, increment, square root.";
                              +   "Add to the running total.";

4

Python,86

f=lambda a,b,i=1j:a>[]<b and a[0]*b[0]*abs(i)+f(a[a[:1]<=b:],b[b[:1]<=a:],i+a[0]-b[0])

无需任何列表搜索的低级天真的递归解决方案。

输入列表是ab。如果任何一个为空,则返回0

否则,让xy是他们的第一个元素(代码实际上不分配这些,因为你不能在完成作业lambda,但它将使解释更容易)。如果两者均为1,即其乘积为1,则它们会影响杆的距离。我们跟踪复数中的距离i,因此距离是绝对值。实际上,我们无论如何都进行计算,然后乘以x*y

然后,我们递归。这个想法是将两个列表都移动一步,除非一个列表以0开头,而另一个列表以1开头,在这种情况下,我们只移动0列表。这样,1总是成对消耗。我们可以使用x<y和检查这些条件y<x,但是利用列表比较的时间要短一些a[:1]<=b。最后,我们通过调整当前元素之间的复数位移x-y


由于您不满意这比其他解决方案多了1个字节,因此我找到了一种保存字节的方法。更改a>[]<ba>0<b。由于两者都有效[]并且0是虚假的,所以它们是等效的。
mbomb007'3

另外,什么是a:
mbomb007'3

1
@ mbomb007。你有做测试吗?在python2:([] > []) != ([] > 0)和python3中,这是一个错误(无序类型)。
ekhumoro 2015年

@ mbomb007。该a:是切片的一部分[b[:1]<=a:]
ekhumoro

4

Python,第105个 102 100字节

i=lambda l:(i for i,h in enumerate(l)if h)
l=lambda*a:sum(((a-b)**2+1)**.5for a,b in zip(*map(i,a)))

非常基本,只需将输入列表转换为孔索引列表,然后计算每对此类索引之间的距离。

测试用例:

>>> print l([0,1,1,0,1,1,1,1,0,0], [1,0,0,1,1,1,0,0,1])
7.06449510225

感谢@FryAmTheEggman提供了一些节省字节的建议。事实证明,如xnor的回答所示,这可以进一步进行。


您可以后删除空格enumerate(l)0.5(这可能只是.5)。
FryAmTheEggman 2015年

@FryAmTheEggman:完全正确,谢谢!根据建议更改。
Mac

使用l=lambda*a:sum(((a-b)**2+1)**.5for a,b in zip(*map(i,a)))
加注

@FryAmTheEggman:再次感谢!不幸的是,似乎xnor的情况有所改善 -大致相同,但是第一个lambda进入了第二个lambda作为列表理解...
Mac

3

Pyth,30个字节

s+0m^h^-hded2 .5CmfTm*hb@kblkQ

使用输入在线尝试[0,1,1,0,1,1,1,1,0,0], [1,0,0,1,1,1,0,0,1]

说明:

我转换成列表指数的名单[2, 3, 5, 6, 7, 8],并[1, 4, 5, 6, 9]和压缩在一起[(2,1), (3,4), (5,5), (6,6), (7,9)]。然后,我减去值,将它们平方,再加1并求和所有平方根。

CmfTm*hb@kblkQ
 m           Q     map each list k in input() to the following list:
    m      lk         map each value b of [0, 1, 2, ..., len(k)-1] to the value:
     *hb@kb              (b + 1) * k[b]
  fT                  filter the list for positive values
C                  zip these two resulting lists

s+0m^h^-hded2 .5...
   m            ...  map each pair of values d to: 
    ^h^-hded2 .5         ((d[0] - d[1])^2 + 1)^0.5
 +0                  insert 0 at the front of the list
s                    sum

sum对于空列表不起作用的耻辱。


3

Python,116115字节

这是一个递归解决方案。

当我发现index()在找不到任何值时只会抛出错误时,这变得非常烦人,但是我使它起作用了。不幸的是,我不能使用lambda。这也让我很烦,因为list.remove()它没有返回列表,而是返回None

def f(x,y,r=0):
    try:i,j=x.index(1),y.index(1)
    except:return r
    x.pop(i);y.pop(j);return f(x,y,r+((i-j)**2+1)**.5)

在此处在线运行:http//repl.it/c5L/2


即使有突片,该代码是116个字节,而不是112
ekhumoro

啊,错过了换行符,谢谢。
mbomb007'3

3

夹355 47 38

[cr+`j[v[w#)#mvw2B}}(c)c]sl`{%ky1%kx1`

对于孔较少的列表,程序将对其进行迭代,并将每个孔与另一个列表的相应孔连接。计算大小并求和。

>java -jar Clip3.jar ladder.clip
{0,1,1,0,1,1,1,1,0,0}
{1,0,0,1,1,1,0,0,1}
7.064495102245980096000721459859050810337066650390625

说明

[c          .- Assign c to the lists, in order of size    -.
  r+`       .- The sum of...                              -.
   j[v[w    .- Join the lists with a function on v, w     -.
     #      .- Square root                                -.
      )     .- 1 plus                                     -.
       #    .- The square of                              -.
        mvw .- The distance between v and w               -.
       2
     B      .- (one-half, so #...B means square root)     -.
   }}(c)c   .- Apply joining function to the lists        -.
  ]sl`{     .- c is the (sorted by size) list of...       -.
    %ky1    .- Indices of y (the second input) which are 1-.
    %kx1    .- Indices of x (the first input) which are 1 -.
  `

如果我们对输入格式非常宽容,可以通过删除每个格式将其减少到36个字节k。这要求输入为控制字符,字符,\0和的字符串\1


3

ECMAScript 6,86字节

最初使用reduce来开始(我想看看是否可以在一个循环中完成它,而不是@ edc65答案)。

f=(c,b,a=[0,...c],j)=>a.reduce((c,v,i)=>c+=v&&(j=b.indexOf(1,j)+1,v=i-j,j)?Math.sqrt(1+v*v):0)

但是使用@ edc65作为map&&t返回值,我可以将其缩短很多。

f=(a,b,j,c=0)=>a.map((v,i)=>c+=v&&(j=b.indexOf(1,j)+1,v=i+1-j,j)&&Math.sqrt(1+v*v))&&c

f=(a,b,j,c=0)        //variables note the j can be undefined
=>a.map((v,i)=>      //loop through the first array
c+=                  //add 
v&&                  //test to see if we have a hole
(j=b.indexOf(1,j)+1, //if so see if there is a whole on the other board
v=i+1-j,             //calculate index difference
j)                   //the last var gets evaluated so check to see if indexOf returned -1
&&Math.sqrt(1+v*v))  //calculate 
&&c                  //return sum

当使用用户管理的累加器减少心跳图时,我仍然必须找到一种情况。
edc65

@ edc65可能为true,从reduce语义上讲更有意义,但除此之外,它实际上有点尴尬。当然,高尔夫球手从什么时候开始担心语义问题。
qw3n 2015年

2

爪哇151

这只是在a寻找一个,然后b在找到一个时走。如果float可以接受,我可以节省几个字节,但是我去double匹配了测试输出。

double d(int[]a,int[]b){double z=0;for(int x=-1,y=0,d=b.length;x++<a.length&y<d;z+=a[x]>0?Math.sqrt((y-x)*(y++-x)+1):0)for(;y<d&&b[y]<1;y++);return z;}

带空格:

double d(int[]a,int[]b){
    double z=0;
    for(int x=-1,y=0,d=b.length;
            x++<a.length&y<d;
            z+=a[x]>0?Math.sqrt((y-x)*(y++-x)+1):0)
        for(;y<d&&b[y]<1;y++);
    return z;
}

六位有效数字就足够了,因此浮点数可以满足您的要求。
Zgarb 2015年

@Zgarb大多数输入上的重复添加仅使我有4-5位数字的顶部,因此我将坚持使用更准确的版本。不过,感谢您的澄清。
Geobits 2015年

2

JavaScript(ES6)108

要点是f函数,该函数将输入0..1数组映射到孔位置数组中。然后使用毕达哥拉斯定理扫描阵列以计算总杆长度。在|0靠近端部是需要转换的NaN可导致当驱动器阵列(第一)比所述第二长。

F=(a,b,f=a=>a.map(v=>++u*v,u=0).filter(x=>x))=>
  f(a,b=f(b)).map((v,i)=>t+=Math.sqrt((w=b[i]-v)*w+1|0),t=0)&&t

在Firefox / FireBug控制台中测试

;[[[0],[0]]
 ,[[0],[1,0]]
 ,[[1,0,0],[1,1,1,1,1]]
 ,[[0,1,0,1],[1,0,0,1]]
 ,[[0,1,1,0,1,1,1,1,0,0],[1,0,0,1,1,1,0,0,1]]
 ,[[1,1,1,1,1],[0,0,1,1,0,1,0,0,1]]
 ,[[0,0,0,1,0,1,1,0,0,0,1,1,1,0,0,1,0,1,1,0,0,0,1,0],[0,0,1,1,0,1,1,1,0,0,0,0,0,1,1,0,1,1,0,0,0,1]]]
.forEach(v=>console.log('['+v[0]+']','['+v[1]+']',F(...v)))

[0] [0] 0
[0] [1,0] 0
[1,0,0] [1,1,1,1,1] 1
[0,1,0,1] [1,0,0 ,1] 2.414213562373095
[0,1,1,0,1,1,1,1,0,0] [1,0,0,1,1,1,0,0,1] 7.06449510224598
[1,1, 1,1,1] [0,0,1,1,0,1,0,0,1] 12.733433128760744
[0,0,0,1,0,1,1,0,0,0,1,1 ,1,0,0,1,0,1,1,0,0,0,1,0] [0,0,1,1,0,1,1,1,0,0,0,0, 0,1,1,0,1,1,0,0,0,1] 20.38177416534678



0

Perl 98

sub l{$r=0;@a=grep$a->[$_],0..$#$a;@b=grep$b->[$_],0..$#$b;$r+=sqrt 1+(shift(@a)-shift@b)**2 while@a&&@b;$r}

可读性:

sub l {
    $r = 0;
    @a = grep $a->[$_], 0 .. $#$a;
    @b = grep $b->[$_], 0 .. $#$b;
    $r += sqrt 1 + (shift(@a) - shift @b) ** 2 while @a && @b;
    $r
}

测试:

use Test::More;
for (<DATA>) {
    my ($A, $B, $r) = /\[ ([0-9,]+) \] \s \[ ([0-9,]+) \] \s -> \s ([0-9.]+) /x;
    $a = [split /,/, $A];
    $b = [split /,/, $B];
    cmp_ok l(), '==', $r, "test $_";
}
done_testing($.);
__DATA__
[0] [0] -> 0.0
[0] [1,0] -> 0.0
[1,0,0] [1,1,1,1,1] -> 1.0
[0,1,0,1] [1,0,0,1] -> 2.414213562373095
[0,1,1,0,1,1,1,1,0,0] [1,0,0,1,1,1,0,0,1] -> 7.06449510224598
[1,1,1,1,1] [0,0,1,1,0,1,0,0,1] -> 12.733433128760744
[0,0,0,1,0,1,1,0,0,0,1,1,1,0,0,1,0,1,1,0,0,0,1,0] [0,0,1,1,0,1,1,1,0,0,0,0,0,1,1,0,1,1,0,0,0,1] -> 20.38177416534678

0

APL,35个 28字节

使用与J解决方案类似的算法,但APL的内置函数较少。

{+/4○⊃-/{⍵⍴¨⍨⌊/⍴¨⍵}⍵/¨⍳¨⍴¨⍵}

输入示例:

      {+/4○⊃-/{⍵⍴¨⍨⌊/⍴¨⍵}⍵/¨⍳¨⍴¨⍵}(1 0 0 1)(0 1 0 1)
2.414213562
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.