Manhattan distance de rotation séquence

9

Je pensais que ce serait un bon défi: http://adventofcode.com/2016/day/1

Description de la tâche

Étant donné une séquence de rotations et de distances suivant le motif (L | R) [1-9] [0-9] *, donnez la distance manhattan entre le point de départ et le point d'arrivée, c'est-à-dire le nombre minimal de mouvements verticaux et horizontaux sur une grille.

Exemples

Par exemple, si nous supposons que vous avez commencé à faire face au Nord:

Après R2, L3 vous laisse 2 blocs à l'est et 3 blocs au nord, ou 5 blocs plus loin. R2, R2, R2 vous laisse 2 pâtés de maisons au sud de votre position de départ, qui est à 2 pâtés de maisons. R5, L5, R5, R3 vous laisse à 12 pâtés de maisons.

Détails techniques

Vous pouvez choisir le séparateur entre les mouvements (par exemple: "\ n", "," ou ","). Vous devez donner la réponse sous forme d'entier en base 10.

Pas un doublon!

Ce n'est pas un doublon pour plusieurs raisons:

  • Les mouvements ne sont pas les mêmes. Ici, ce sont des rotations , pas des directions.
  • Je veux la distance de Manhattan, pas l'euclidienne.
Labo
la source
3
Vous devez inclure une description de la distance de Manhattan dans votre question. Le simple fait de poster un lien est un peu collant.
Gabriel Benamy
2
C'est très différent ! Nous n'avons que des rotations!
Labo
1
@Labo, je suis d'accord. Ce n'est pas seulement le fait que la réponse ici est à distance de Manhattan alors que l'autre est à distance euclidienne. Cela a un mouvement de style tortue tandis que l'autre spécifie les directions de la boussole NSEW (le fait qu'il les appelle UDLR n'est pas pertinent.)
Level River St
2
Veuillez utiliser le bac à sable à l'avenir pour obtenir des commentaires sur vos défis avant de les publier sur le site principal.
Mego
2
@Labo Ça va, nous ne nous attendons pas à ce que les nouveaux utilisateurs connaissent immédiatement tous les tenants et aboutissants de ce site. C'est juste une douce suggestion pour la prochaine fois. :)
Mego

Réponses:

4

Python 3, 109 99 104 101 octets

Il s'agit d'une réponse simple qui utilise des nombres complexes, avec une entrée sous forme de chaîne séparée par des espaces ou une chaîne séparée par des sauts de ligne. Suggestions de golf bienvenues!

Edit: -13 octets grâce à Labo. +5 octets pour la conversion en int.

d=p=0
for r in input().split():d+=1-2*(r<'R');p+=1j**d*int(r[1:])
print(int(abs(p.real)+abs(p.imag)))

Ungolfing

def manhattan_rotation(seq, nsew=0, pos = 0):
    for rot in seq.split():
        # change direction
        if rot[0] == "L":
            nsew += -1 
        else:
            nsew += 1
        # move in that direction rot[1:] times
        pos += 1j ** nsew * int(rot[1:])
    return int(abs(pos.real)+abs(pos.imag))
Sherlock9
la source
1-2 * (r [0] <'R') vous fera économiser 2 octets :)
Labo
Ne faites pas de fonction, la lecture de l'entrée vous fait économiser plus de caractères!
Labo
Attribuez 2 variables sur la même ligne pour économiser 2 octets: d = p = 0
Labo
J'ai encore joué à votre réponse et cela fait 99 caractères! pastie.org/private/hm7lejqosdqnkgo000u7q
Labo
2
@Labo Je ne suis pas sûr que vous puissiez modifier les spécifications d'une manière qui invaliderait les réponses existantes, mais permettez-moi de poser quelques mods.
Sherlock9
2

PHP, 93 octets

while($m=$argv[++$i])${chr(80|3&$d+=(P<$m)-(M>$m))}+=substr($m,1);echo abs($P-$R)+abs($Q-$S);

panne

while($m=$argv[++$i])       // loop through arguments:
    ${                      // 5. use as variable name
        chr(                // 4. cast to character (P,Q,R,S) 
        80|                 // 3. add 80
        3&                  // 2. modulo 4
        $d+=(P<$m)-(M>$m)   // 1. change direction depending on letter
    )}+=substr($m,1);       // 6. add number to variable
echo abs($P-$R)+abs($Q-$S); // calculate distance, print
Titus
la source
2

Python 2, 86 octets

x=y=0
for d in input().split():c=cmp(d,'M');x,y=int(d[1:])-y*c,x*c
print abs(x)+abs(y)

Suit le courant xet les ycoordonnées. Lorsque vous tournez, au lieu de mettre à jour la direction, tourne la valeur actuelle afin que le mouvement soit toujours dans la direction x-positive. Les nombres complexes étaient trop coûteux pour en extraire les coordonnées.

xnor
la source
1

Python 2, 103 102 octets

l=c=0
for i in input().split():c+=cmp(i[0],'N');l+=1j**c*int(i[1:])
print int(abs(l.imag)+abs(l.real))

repl.it

L'entrée est une chaîne de directions séparées par des espaces, par exemple "R5 L5 R5 R3".
Imprime la distance de Manhattan entre l'emplacement de départ et la destination.

Comment?

Commence à l'origine du plan complexe, l=0;

Avec un compteur de virage quart de droite cumulé c=0;

Pour chaque instruction, ila rotation est analysée en comparant le premier caractère de la direction au caractère 'N'et cest ajustée en conséquence.

La distance à parcourir est analysée int(i[1:])et l'instruction est exécutée en prenant autant de pas de la taille d'un bloc dans la direction donnée en prenant la cpuissance e0+1j avec 1j**c.

La distance finale de Manhattan est la somme des distances absolues de l'origine dans les deux directions - imaginaire et réelle; réalisé avecabs(l.imag)+abs(l.real)

Jonathan Allan
la source
1
@ Sherlock9 - Oh, euh, réponds à la convergence. Économisez 2 octets en passant à Python 2 et en utilisant cmpcomme ma réponse, faites le moi savoir et je supprimerai.
Jonathan Allan
0

JavaScript (ES2016), 98 100

2 octets enregistrés thx @Neil

d=>d.replace(/.(\d+)/g,(d,l)=>(o+=d>'M'||3,l*=~-(o&2),o&1?x-=l:y+=l),x=y=o=0)&&(x*x)**.5+(y*y)**.5

100 octets pour ES6

d=>d.replace(/.(\d+)/g,(d,l)=>(o+=d>'M'||3,l*=~-(o&2),o&1?x-=l:y+=l),x=y=o=0)&&(x>0?x:-x)+(y>0?y:-y)

Moins golfé

d => d.replace(/.(\d+)/g,
  (d,l)=>( // L or R in d, distance in l
    o += d>'M' || 3, // orientation in o, used %4
    l *= ~-(o&2), // convert to number and change sign if needed
    o&1 ? x -= l : y += l // move based on orientation
  ), x = y = o = 0)
&& (x>0?x:-x) + (y>0?y:-y)

Test (ES6)

F=
d=>d.replace(/.(\d+)/g,(d,l)=>(o+=d>'M'||3,l*=~-(o&2),o&1?x-=l:y+=l),x=y=o=0)&&(x>0?x:-x)+(y>0?y:-y)

function update() {
  O.textContent=F(I.value)
}

update()
<input id=I value='R5, L5, R5, R3' oninput='update()'><pre id=O></pre>

edc65
la source
1
Ma réponse ES6 était à l'origine de 106 octets; la copie de votre variable intermédiaire m'a fait gagner 3 octets; le passage de la correspondance à votre remplacement m'a sauvé 2 octets, et la copie de votre traitement de la direction et de la distance en même temps m'a fait gagner un octet final, ce qui donne ceci s=>s.replace(/.(\d+)/g,(c,n)=>(d+=c<'R'||3,n*=~-(d&2),d&1?x+=n:y+=n),x=y=d=0)&&(x<0?-x:x)+(y<0?-y:y):, qui est maintenant deux octets plus court que votre réponse ES6, grâce aux astuces c<'R'||3et n*=~-(d&2).
Neil