Construire une échelle

26

introduction

Je veux construire une échelle. Pour cela, j'ai récupéré de la casse deux longues planches avec des trous, et je veux placer les marches dans ces trous. Cependant, les trous ne sont pas placés uniformément, donc les étapes seront un peu bancales, et j'ai du mal à estimer la quantité de tige dont j'ai besoin. Votre travail consiste à faire les calculs pour moi.

Contribution

Votre entrée est des vecteurs à deux bits, donnés sous forme de tableaux d'entiers, qui représentent les deux cartes. A 0représente un segment d'un aud ( unité arbitraire de distance ) sans trou, et a 1représente un segment d'un aud avec un seul trou. Les tableaux peuvent être de longueurs différentes et contenir un nombre différent de 1s, mais ils ne seront pas vides.

Je vais construire mon échelle comme suit. Tout d'abord, je place les deux planches exactement à une distance l'une de l'autre et j'aligne leurs extrémités gauches. Pour chaque index i, je mesure la distance entre le itrou de la première planche avec le itrou de la deuxième planche , je coupe un morceau de tige et je le fixe entre les deux trous. Je m'arrête une fois que je n'ai plus de trous dans l'une des planches.

Sortie

Votre sortie est la quantité totale de tige dont j'ai besoin pour les étapes, mesurée en auds. La sortie doit être correcte avec au moins six chiffres significatifs.

Exemple

Considérez les entrées [0,1,1,0,1,1,1,1,0,0]et [1,0,0,1,1,1,0,0,1]. L'échelle résultante ressemble à ceci:

Une échelle vraiment géniale.

La longueur totale de la tige dans cette échelle est 7.06449510224598auds.

Règles

Vous pouvez écrire soit une fonction soit un programme complet. Le nombre d'octets le plus bas l'emporte et les failles standard sont interdites.

Cas de test

[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
la source
32
Pour votre propre sécurité, je ne recommande vraiment pas de monter sur une échelle qui ressemble à ça.
Alex A.

Réponses:

10

J, 22 caractères

Pas inspiré par la réponse de randomra. La I.pièce est égale car c'est la manière immédiatement évidente de trouver les trous.

(4+/@:o.<.&#$-/@,:)&I.
  • I. y- tous les indices de yrépétés aussi souvent que l'élément correspondant de y. Soit dit en passant, si yest un vecteur de booléens, I. ycontient les indices auxquels yest 1. Par exemple, les I. 1 0 0 1 1 1 0 0 1rendements 0 3 4 5 8.
  • x u&v y- le même que (v x) u (v y). Appliqué comme x u&I. y, nous obtenons (I. x) u (I. y). Continuons avec l'entrée transformée.
  • x <.&# y- la moindre des longueurs de xet y.
  • x -/@,: y- la différence des éléments de xet y. Si un vecteur est plus long, il est rempli de zéros.
  • x $ y- yremodelé à la forme spécifiée par x. Plus précisément, s'il xs'agit d'un scalaire, les xéléments sont extraits de y. Dans cette utilisation, x (<.&# $ -/@,:) ys'assure que les trous de fuite sont ignorés.
  • 4 o. y- la fonction %: 1 + *: y, c'est-à-dire sqrt (1 + y ²). Soit dit en passant, cette fonction établit une correspondance entre la distance entre les trous et la longueur des tiges.
  • +/ y- la somme des éléments de y.
FUZxxl
la source
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]))

Cela s'est avéré similaire à la solution de Mac . Convertissez les listes de 0 et de 1 en listes ordonnées des un-indices, puis additionnez la distance entre les éléments respectifs.

xnor
la source
2
Bien fait. Belle astuce avec le littéral complexe!
Mac
Je suis un peu triste que ce soit un octet de moins que mon autre réponse , ce qui, à mon avis, est une solution plus créative.
2015 à 2h59
6

J, 32 28 octets

Le verbe I.renvoie les positions de 1s dans une chaîne binaire, ce qui est d'une grande aide.

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

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

Pour une meilleure solution J, vérifiez la réponse de FUZxxl .

randomra
la source
5

R, 67

Utilise extérieur pour faire une différence pour les trous indexés. Diag renvoie les différences requises. Additionnez ensuite les distances calculées

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

Test exécuté dans R Fiddle. Je l'ai enveloppé dans une impression pour montrer que le retour est conforme aux spécifications.

> 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
la source
Joli. a==1peut être a>0ou !!a.
freekvd
5

Haskell, 77 73 octets

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

Utilisation: [0,1,0,1] # [1,0,0,1]quelles sorties2.414213562373095

Comment ça marche: la fonction rretourne une liste des positions des trous d'une planche, par exemple r [0,1,0,1]-> [2,4]. #zippe deux de ces listes et les transforme en une liste de distances entre les trous correspondants et finalement la somme.

nimi
la source
4

CJam, 36 33 octets

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

Approche très naïve ... il attend l'entrée en tant que tableaux de style CJam sur STDIN

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

Voici un faisceau de test pour toutes les entrées d'exemple. Les résultats dans le champ de saisie sont utilisés avant l'appel du code réel. Vous pouvez les supprimer si vous ne me faites pas confiance. ;)

Explication

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
la source
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])

Une solution récursive de bas niveau et naïve sans recherche de liste.

Les listes d'entrée sont aet b. Si l'un ou l'autre est vide, retournez 0.

Sinon, laissez xet ysoyez leurs premiers éléments (le code ne les attribue pas réellement parce que vous ne pouvez pas faire les affectations dans a lambda, mais cela facilitera l'explication). Si les deux sont 1, c'est-à-dire que leur produit est 1, alors ils contribuent à la distance de la tige. Nous gardons une trace de la distance dans le nombre complexe i, de sorte que la distance est la valeur absolue. En fait, nous le calculons indépendamment, puis le multiplions par x*y.

Ensuite, nous récurons. L'idée est de décaler les deux listes d'une étape, à moins qu'une liste ne commence par un 0 et l'autre par un, auquel cas nous ne décalons que la liste 0. De cette façon, les 1 sont toujours consommés par paires. Nous pourrions vérifier ces conditions avec x<yet y<x, mais il est plus court de profiter de la comparaison de liste en tant que a[:1]<=b. Enfin, nous ajustons le déplacement complexe entre les éléments actuels par x-y.

xnor
la source
Puisque vous êtes contrarié que ce soit 1 octet de plus que votre autre solution, j'ai trouvé un moyen d'enregistrer un octet. Remplacez a>[]<bpar a>0<b. Cela fonctionne depuis les deux []et 0est faux, ils sont donc équivalents.
mbomb007
Et qu'est-ce que c'est a:?
mbomb007
1
@ mbomb007. Avez-vous fait des tests? En python2:, ([] > []) != ([] > 0)et en python3 c'est une erreur (types non triables).
ekhumoro
@ mbomb007. Le a:fait partie de la tranche [b[:1]<=a:].
ekhumoro
4

Python, 105 102 100 octets

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

Assez basique, convertit simplement les listes d'entrée en listes d'indices de trous, puis calcule la distance entre chaque paire de ces indices.

Cas de test:

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

Nous remercions @FryAmTheEggman pour quelques suggestions d'économie d'octets. Il s'avère que cela peut être approfondi, comme le montre la réponse de xnor .

Mac
la source
Vous pouvez supprimer les espaces après enumerate(l)et le 0.5(qui pourrait juste être 0,5).
FryAmTheEggman
@FryAmTheEggman: tout à fait raison, merci! Modifié comme suggéré.
Mac
l=lambda*a:sum(((a-b)**2+1)**.5for a,b in zip(*map(i,a)))
J'ai
@FryAmTheEggman: merci encore! Malheureusement, il semble que xnor soit allé mieux - à peu près la même chose, mais avec le premier lambda roulé dans le second comme compréhension de la liste ...
Mac
3

Pyth, 30 octets

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

Essayez-le en ligne avec l'entrée [0,1,1,0,1,1,1,1,0,0], [1,0,0,1,1,1,0,0,1].

Explication:

Je convertir les listes dans des listes d'indices [2, 3, 5, 6, 7, 8]et [1, 4, 5, 6, 9]et compressez- les ensemble [(2,1), (3,4), (5,5), (6,6), (7,9)]. Ensuite, je soustrais les valeurs, je les évalue au carré, j'ajoute 1 et je fais la somme de toutes les racines carrées.

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

Dommage que sumcela ne fonctionne pas pour les listes vides.

Jakube
la source
3

Python, 116 115 octets

Il s'agit d'une solution récursive.

Cela est devenu assez ennuyeux quand j'ai trouvé que index()lève juste une erreur lorsqu'aucune valeur n'est trouvée, mais je l'ai fait fonctionner. Malheureusement, je ne peux pas utiliser de lambda. Cela m'a aussi énervé de list.remove()ne pas retourner la liste, mais de revenir 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)

Exécutez en ligne ici: http://repl.it/c5L/2

mbomb007
la source
Même avec des tabulations, ce code est de 116 octets, pas 112.
ekhumoro
Ah, j'ai raté les nouvelles lignes, merci.
mbomb007
3

Clip 3 , 55 47 38

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

Pour la liste avec le moins de trous, le programme le parcourt et relie chaque trou au trou correspondant de l'autre liste. Les tailles sont calculées et additionnées.

>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

Explication

[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 nous sommes très libéraux sur le format d'entrée, nous pouvons le réduire à 36 octets en les supprimant chacun k. Cela nécessite que l'entrée soit une chaîne de caractères de caractères de contrôle \0et \1.

Ypnypn
la source
3

ECMAScript 6, 86 octets

Cela a commencé à l'origine à l'aide de réduire (je voulais voir si cela pouvait être fait en une seule boucle par opposition à la réponse @ 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)

Mais en utilisant @ edc65 pour mapet &&tpour renvoyer la valeur, j'ai pu la raccourcir un peu.

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
la source
Je dois encore trouver un seul cas lors de la réduction de la carte des battements avec un accumulateur géré par l'utilisateur.
edc65
@ edc65 probablement vrai, a reduceplus de sens sur le plan sémantique, mais à part cela, il est en fait assez délicat à utiliser. Bien sûr, depuis quand les golfeurs du code se préoccupent-ils de la sémantique.
qw3n
2

Java, 151

Cela marche juste à la arecherche de ceux-là, puis marche bquand il en trouve un. Si la floatprécision est acceptable, je pourrais économiser quelques octets, mais je suis allé avecdouble pour faire correspondre la sortie de test.

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

Avec espace:

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;
}
Géobits
la source
Six chiffres significatifs, c'est assez de précision, donc ça flotte ça vous donne ça, allez-y.
Zgarb
@Zgarb Les ajouts répétés sur la plupart des entrées ne me donnent que des sommets de 4 à 5 chiffres, donc je m'en tiendrai à la version plus précise. Merci pour la clarification, cependant.
Geobits
2

JavaScript (ES6) 108

Le point principal est la fonction f qui mappe les tableaux d'entrée 0..1 en tableaux de positions de trous. Ensuite, les tableaux sont balayés en calculant la longueur totale des tiges à l'aide du théorème de Pythagore. La |0fin proche est nécessaire pour convertir les NaN qui peuvent résulter lorsque le tableau de pilotes (le premier) est plus long que le second.

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

Test dans la console 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
la source
1

Octave, 60 59 42

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

Lisible:

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
}

Essai:

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
la source
0

APL, 35 28 octets

Utilise un algorithme similaire à la solution J, mais APL a moins de fonctions intégrées.

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

Exemple d'entrée:

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