Construir una escalera

26

Introducción

Quiero construir una escalera. Para esto, he eliminado del depósito de chatarra dos tablas largas con agujeros en ellas, y quiero colocar los escalones en estos agujeros. Sin embargo, los agujeros no están colocados de manera uniforme, por lo que los pasos serán un poco torpes, y me resulta difícil estimar la cantidad de varilla que necesito para ellos. Tu trabajo es hacer los cálculos por mí.

Entrada

Su entrada son vectores de dos bits, dados como matrices de enteros, que representan las dos tablas. A 0representa un segmento de un aud ( unidad arbitraria de distancia ) sin un agujero, y a 1representa un segmento de un aud con un solo agujero. Las matrices pueden ser de diferentes longitudes y contener un número diferente de 1s, pero no estarán vacías.

Construiré mi escalera de la siguiente manera. Primero, coloco las dos tablas separadas exactamente una a una y alineo sus extremos izquierdos. Para cada índice i, mido la distancia entre el ihoyo th de la primera tabla con el ihoyo th de la segunda tabla, corto un trozo de varilla y lo adjunto entre los dos agujeros. Me detengo una vez que me quedo sin agujeros en una de las tablas.

Salida

Su salida es la cantidad total de varilla que necesitaré para los pasos, medidos en audios. La salida debe ser correcta al menos a seis dígitos significativos.

Ejemplo

Considere las entradas [0,1,1,0,1,1,1,1,0,0]y [1,0,0,1,1,1,0,0,1]. La escalera resultante se ve así:

Una escalera realmente funky.

La longitud total de la barra en esta escalera es 7.06449510224598auds.

Reglas

Puede escribir una función o un programa completo. El conteo de bytes más bajo gana, y las lagunas estándar no se permiten.

Casos de prueba

[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
Zgarb
fuente
32
Por su propia seguridad, realmente no recomiendo subir ninguna escalera que se vea así.
Alex A.

Respuestas:

10

J, 22 caracteres

No inspirado por la respuesta de randomra. La I.parte es igual, ya que es la forma obvia de encontrar los agujeros.

(4+/@:o.<.&#$-/@,:)&I.
  • I. y- todos los índices de yrepetidos tan a menudo como el elemento correspondiente de y. Por cierto, si yes un vector de booleanos, I. ycontiene los índices en los que se yencuentra 1. Por ejemplo, I. 1 0 0 1 1 1 0 0 1rendimientos 0 3 4 5 8.
  • x u&v y- lo mismo que (v x) u (v y). Aplicado como x u&I. y, lo conseguimos (I. x) u (I. y). Continuemos con la entrada transformada.
  • x <.&# y- la menor de las longitudes de xy y.
  • x -/@,: y- la diferencia de los elementos de xy y. Si un vector es más largo, se rellena con ceros.
  • x $ y- yremodelado a la forma especificada por x. Específicamente, si xes un escalar, xse toman elementos de y. En este uso, x (<.&# $ -/@,:) yse asegura de que se ignoren los agujeros finales.
  • 4 o. y- la función %: 1 + *: y, es decir, sqrt (1 + y ²). Por cierto, esta función asigna desde la distancia del agujero hasta la longitud de las barras.
  • +/ y- la suma de los elementos de y.
FUZxxl
fuente
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]))

Esto resultó similar a la solución de Mac . Convierta las listas de 0 y 1 en listas ordenadas de los índices uno, y luego sume la distancia entre los elementos respectivos.

xnor
fuente
2
Bien hecho. Buen truco con el complejo literal!
Mac
Estoy un poco triste porque este es un byte más corto que mi otra respuesta , lo que creo que es una solución más creativa.
xnor
6

J, 32 28 bytes

El verbo I.devuelve las posiciones de 1s en una cadena binaria que es de gran ayuda.

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

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

Para una mejor solución J, verifique la respuesta de FUZxxl .

randomra
fuente
5

R, 67

Usa el exterior para hacer una diferencia para los agujeros indexados. Diag devuelve las diferencias requeridas. Luego suma las distancias calculadas

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

Prueba de funcionamiento en R Fiddle. Lo he envuelto en una impresión para mostrar que la devolución cumple con las especificaciones.

> 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
>
MickyT
fuente
Buena esa. a==1puede ser a>0o !!a.
Freekvd
5

Haskell, 77 73 bytes

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

Uso: [0,1,0,1] # [1,0,0,1]que salidas2.414213562373095

Cómo funciona: la función rdevuelve una lista de las posiciones de los agujeros de un tablero, por ejemplo, r [0,1,0,1]-> [2,4]. #comprime dos de esas listas y la convierte en una lista de distancias entre los agujeros correspondientes y finalmente la suma.

nimi
fuente
4

CJam, 36 33 bytes

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

Enfoque muy ingenuo ... espera la entrada como matrices de estilo CJam en STDIN

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

Aquí hay un arnés de prueba para todas las entradas de ejemplo. Los resultados en el campo de entrada se usan antes de llamar al código real. Puedes eliminarlos si no confías en mí. ;)

Explicación

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.";
Martin Ender
fuente
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])

Una solución recursiva ingenua y de bajo nivel sin ninguna búsqueda en la lista.

Las listas de entrada son ay b. Si alguno está vacío, regrese0 .

De lo contrario, deje xy ysean sus primeros elementos (el código en realidad no los asigna porque no puede hacer asignaciones en a lambda, pero facilitará la explicación). Si ambos son 1, es decir, su producto es 1, entonces contribuyen a la distancia de la barra. Llevamos un registro de la distancia en el número complejo i, de modo que la distancia es el valor absoluto. En realidad, lo calculamos independientemente, luego lo multiplicamos por x*y.

Entonces, recurrimos. La idea es cambiar ambas listas un paso, a menos que una lista comience con un 0 y la otra con un uno, en cuyo caso solo cambiamos la lista 0. De esa manera, los 1 siempre se consumen en pares. Podríamos verificar estas condiciones con x<yy y<x, pero es más corto aprovechar la comparación de listas como a[:1]<=b. Finalmente, ajustamos el desplazamiento complejo entre los elementos actuales por x-y.

xnor
fuente
Como está molesto porque esto era 1 byte más que su otra solución, encontré una manera de guardar un byte. Cambiar a>[]<ba a>0<b. Funciona desde ambos []y 0son falsas, por lo que son equivalentes.
mbomb007
Además, ¿qué es a:?
mbomb007
1
@ mbomb007. ¿Hiciste alguna prueba? En python2:, ([] > []) != ([] > 0)y en python3 es un error (tipos no ordenados).
ekhumoro
@ mbomb007. El a:es parte de la rebanada [b[:1]<=a:].
ekhumoro
4

Python, 105 102 100 bytes

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)))

Bastante básico, solo convierte las listas de entrada en listas de índices de agujeros, luego calcula la distancia entre cada par de dichos índices.

Caso de prueba:

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

Gracias a @FryAmTheEggman por un par de sugerencias para guardar bytes. Resulta que esto se puede jugar más, como se demuestra en la respuesta de xnor .

Mac
fuente
Puede eliminar los espacios después enumerate(l)y el 0.5(que podría ser solo .5).
FryAmTheEggman
@FryAmTheEggman: absolutamente cierto, ¡gracias! Cambiado según lo sugerido.
Mac
Encontré otra cosa usando la asignación de estrellas:l=lambda*a:sum(((a-b)**2+1)**.5for a,b in zip(*map(i,a)))
FryAmTheEggman
@FryAmTheEggman: ¡gracias de nuevo! Desafortunadamente, parece que xnor se ha vuelto uno mejor , casi lo mismo, pero con el primer lambda incluido en el segundo como una lista de comprensión ...
Mac
3

Pyth, 30 bytes

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

Pruébelo en línea con la entrada[0,1,1,0,1,1,1,1,0,0], [1,0,0,1,1,1,0,0,1] .

Explicación:

Convierto las listas en las listas de índices [2, 3, 5, 6, 7, 8]y [1, 4, 5, 6, 9]y comprímalos juntos [(2,1), (3,4), (5,5), (6,6), (7,9)]. Luego resto los valores, los cuadro, sumo 1 y sumo sobre todas las raíces cuadradas.

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

Es una pena que sumno funcione para listas vacías.

Jakube
fuente
3

Python, 116 115 bytes

Esta es una solución recursiva.

Se volvió bastante molesto cuando descubrí que index()solo arroja un error cuando no se encuentra ningún valor, pero lo hice funcionar. Desafortunadamente, no puedo usar una lambda. También me molestó que list.remove()no devuelva la lista, sino que regrese 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)

Ejecute en línea aquí: http://repl.it/c5L/2

mbomb007
fuente
Incluso con pestañas, ese código es 116 bytes, no 112.
ekhumoro
Ah, perdí las nuevas líneas, gracias.
mbomb007
3

Clip 3 , 55 47 38

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

Para la lista con menos agujeros, el programa itera a través de ella y conecta cada agujero con el agujero correspondiente de la otra lista. Los tamaños son calculados y sumados.

>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

Explicación

[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 -.
  `

Si somos muy liberales con respecto al formato de entrada, podemos reducir esto a 36 bytes eliminando cada uno k. Esto requiere que la entrada sea una cadena de caracteres de caracteres de control \0y \1.

Ypnypn
fuente
3

ECMAScript 6, 86 bytes

Originalmente, esto comenzó usando reducir (quería ver si se podía hacer en un bucle en lugar de la respuesta @ 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)

Pero usando @ edc65 para mapy &&tpara devolver el valor pude acortarlo un poco.

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
qw3n
fuente
Todavía tengo que encontrar un solo caso cuando reduzco el mapa de latidos con un acumulador administrado por el usuario.
edc65
@ edc65 probablemente sea cierto, reducetiene más sentido semánticamente, pero aparte de eso, en realidad es un poco incómodo de usar. Por supuesto, desde cuándo los golfistas de código se preocuparon por la semántica.
qw3n
2

Java, 151

Esto simplemente camina en abusca de unos, luego camina bcuando encuentra uno. Si la floatprecisión es aceptable, podría guardar un par de bytes, pero doubleelegí la salida de prueba.

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;}

Con espacios en blanco:

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;
}
Geobits
fuente
Seis dígitos significativos son suficiente precisión, por lo que flota te da eso, ve a por ello.
Zgarb
@Zgarb Las adiciones repetidas en la mayoría de las entradas solo me dan 4-5 dígitos como máximo, así que me quedaré con la versión más precisa. Gracias por la aclaracion.
Geobits
2

JavaScript (ES6) 108

El punto principal es la función f que mapea las matrices de entrada 0..1 en matrices de posiciones de agujeros. Luego, las matrices se escanean calculando la longitud total de las barras utilizando el teorema de Pitágoras. Se |0necesita cerca del final para convertir los NaN que pueden resultar cuando la matriz de controladores (la primera) es más larga que la segunda.

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

Prueba en la consola 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

edc65
fuente
1

Octava, 60 59 42

@(a,b)trace(sqrt((find(a)'-find(b)).^2+1))
alephalpha
fuente
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}

Legible:

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
}

Pruebas:

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
choroba
fuente
0

APL, 35 28 bytes

Utiliza un algoritmo similar a la solución J, pero APL tiene menos componentes incorporados.

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

Entrada de ejemplo:

      {+/4○⊃-/{⍵⍴¨⍨⌊/⍴¨⍵}⍵/¨⍳¨⍴¨⍵}(1 0 0 1)(0 1 0 1)
2.414213562
lirtosiast
fuente