Estoy caminando por Manhattan, ¿a qué distancia estoy de mi hotel?

27

La historia innecesaria y enrevesada

Estoy caminando por Manhattan, bloque por bloque y mis pies se han cansado y quiero volver a casa.

El tráfico es bastante malo, pero afortunadamente soy muy rico y tengo un helicóptero en espera en el hotel. Pero necesito que sepan cuánto combustible empacar para el vuelo y para eso necesitan saber mi distancia directa desde el hotel. Recordé qué bloques caminé y puedo decirles qué ruta tomé. Sin embargo, esta distancia debe ser precisa; si son demasiado cortos, no volveremos demasiado, y compré combustible que no puedo usar.

¿Puedes escribirme un programa para convertir eso en la distancia que tendrán que recorrer en su vuelo para traerme?

Especificación:

Escríbeme una función que:

  1. Acepta una lista o cadena de bloques recorridos en relación con una cuadrícula arbitraria:
    • U p, D propia, izquierda y derecha .
    • Puede ser mayúscula o minúscula, por ejemplo. si es más corto de usar en ulugar de Useguir adelante.
    • Una dirección no válida tiene un comportamiento indefinido, por ejemplo. una dirección de X puede causar una falla.
  2. Devuelve un flotante / decimal / doble que es el doble de la distancia en línea recta desde el punto de origen.

Para ilustración y aclaración:

Mi viaje

Mi viaje podría haberse registrado tan fácilmente como "luluu..."o ['l','u','l'...]pero debe registrarse como Arriba, Abajo, Izquierda, Derecha.


fuente
15
¿Eres lo suficientemente rico como para tener un helicóptero pero te importa si se compra combustible extra? : O
Fez Vrasta
8
@fezvrasta porque soy tacaño.
77
Manera de meterse con mi cabeza al no hacer esto sobre la distancia de Manhattan
Kendall Frey
25
La respuesta correcta es "No importa. Eres un tipo rico, así que buscas en tu bolsillo, sacas un fajo de $ 20 y lo agitas en el aire para atraer la atención de un taxista; eres luego fue atacado por un grupo de matones de jardín de infantes que lo robaron y lo golpearon hasta convertirlo en una pulpa sangrienta. Luego lo arrestan por tirar basura y vagancia pública, acusado de terrorismo por intentar causar pánico masivo y una pandemia al propagar su exudado corporal a través de un público acera, condenado, enviado a prisión, y encerrado con un compañero de celda apodado Bruto que toma un verdadero gusto fuerte para usted. Bienvenido a Nueva York!"
Bob Jarvis - Restablece a Monica
2
@McKay Lo interpreto como direcciones en un mapa, de todos modos (de lo contrario, probablemente sería "hacia adelante" y "hacia atrás"), y la medida de distancia es bastante inequívoca "el doble de la distancia en línea recta desde el punto de origen", por lo que no distancia de manhattan).
FireFly

Respuestas:

32

J, 17 caracteres

2*|+/0j1^'urdl'i.

Utiliza el hecho de que los poderes de jrepresentan las direcciones correctas.

  • 'urdl'i. tomar una cadena y calcular índices (0 para 'u', 1 para 'r', ...)
  • 0j1^se transforma en la dirección en el plano complejo utilizando la potencia correspondiente de j.
  • +/ resume los pasos individuales
  • 2*| dos veces el módulo

Ejemplo:

> 2*|+/0j1^'urdl'i.'uuuudrrrl'
7.2111
Howard
fuente
55
Buen trabajo. Conocimientos matemáticos para la victoria. :-)
Gareth
Haga este ASCII "no extendido" y luego son solo 15 bytes (porque no usa el octavo bit).
Timtech
11

Python 2.7 56 58 56 51 48

Con el Number One Dime robado de Scrooge McDuck , hice mi fortuna y ahora tengo más riqueza que Scrooge.

y=lambda s:2*abs(sum(1j**(ord(i)%15)for i in s))

Python 2.7 - 61 53 50 (sin distinción entre mayúsculas y minúsculas)

y=lambda s:2*abs(sum(1j**(ord(i)%16%9)for i in s))

Implementación

>>> from random import sample
>>> y=lambda s:2*abs(sum((-1j)**(ord(i)%15)for i in s))
>>> path=sample('RLUD'*1000, 100)
>>> y(path)
20.0
>>> path=sample('RLUD'*1000, 100)
>>> y(path)
34.058772731852805
Abhijit
fuente
Me estoy poniendo IndexError: list index out of range. ¿Qué forma debe tener la entrada?
plannapus
@plannapus: He agregado una sección de implementación
Abhijit
Ah y no fue %5así %8. Ok, ahora tiene más sentido :)
plannapus
5

APL (29)

{|+/2 0j2×-⌿2 2⍴+/'URDL'∘.=⍵}

p.ej

     {|+/2 0j2×-⌿2 2⍴+/'URDL'∘.=⍵} 'UUUUDRRRL'
7.211102551

Explicación:

  • +/'URDL'∘.=⍵: ver con qué frecuencia URDLaparecen los caracteres en el argumento
  • -⌿2 2⍴: resta el Uvalor del Dvalor y el Rvalor del Lvalor
  • 2 0j2×: multiplica el valor vertical por 2y el valor horizontal por2i
  • +/: suma
  • |: magnitud
marinus
fuente
4

Rubí 1.9+ (67)

f=->s{2*(((g=s.method :count)[?U]-g[?D])**2+(g[?R]-g[?L])**2)**0.5}

Ejemplo

f["DRUULULLULL"] => 10.0
f["UUUUDRRRL"] => 7.211102550927978
daniero
fuente
3

perl6: 44 caracteres

2*abs [+] i <<**>>%(<U R D L>Z ^4){get.comb}
  • get.comb obtiene una línea de entrada y se divide en caracteres
  • <U R L D> es una lista de palabras, caracteres en este caso
  • (1,2,3) Z (4,5,6)== (1,2), (2,5), (3,6), por lo que comprime 2 listas entre sí, haciendo una lista de parcelas que se %()convierte en un hash
  • <<**>>hace pares **, extendiendo la lista más corta para ajustarse a la más larga. La lista más corta pasa a ser soloi
  • [+]suma todos los elementos de una lista, abstoma el módulo para números complejos

Sí, eliminé todos los espacios posibles.

Ayiko
fuente
2

Python 2.7 - 65

Agradable y corto, esto usa números complejos para atravesar el avión:

x=lambda s:2*abs(sum([[1,-1,1j,-1j]['RLUD'.index(i)]for i in s]))

Apoyos para DSM y Abhijit en otras preguntas que me mostraron el uso de 1jcalcular esto.


fuente
Se 1jpuede escribir como j, -1jcomo -j? Además, ¿esto maneja la entrada superior e inferior, o solo la superior?
DavidC
1
Tío Scrooze , te odio. Al menos deberías dejar algo de dinero para tus sobrinos.
Abhijit
1
@DavidCarraher: No, no puedes. Sería imposible diferenciar entre la variable jy la unidad imaginariaj
Abhijit
¿No dijiste que se suponía que debía producir el doble de distancia? cuando intento con UUUUDRRRL obtengo 3.606 con esta función en lugar de 7.21.
plannapus
44
Puede guardar 2 caracteres más, multiplicando las constantes en 2lugar de multiplicar el resultado final.
Abhijit
2

Mathematica 92 49

Calle merece todo el crédito por racionalizar el código.

f@l_:=2 N@Norm[Tr[l/.{"r"→1,"l"→-1,"u"→I,"d"→-I}]]

Ejemplo

f[{"u", "u", "u", "u", "d", "r", "r", "r", "l"}]

7.2111

DavidC
fuente
1
Estás haciendo mucho trabajo que no es requerido por el OP, f@l_ := 2 N@Norm[Tr[l /. {"r" -> 1, "l" -> -1, "u" -> I, "d" -> -I}]]será suficiente.
Me sale 2 Norm[(2. + 2. I) + "U" + "X"]como la salida de su código.
DavidC
1
Sí, pero el OP dice que está bien fallar con dicha entrada. Así es como yo y todos los demás lo interpretamos. No puedo leer estos otros idiomas, pero verá que a menudo codifican para usted, r, ly d.
Okay. Lo tengo. Gracias por señalar eso.
DavidC
Si reemplaza los dos pares de paréntesis restantes con @s, obtendrá otros dos caracteres menos.
shrx
2

PHP, 67

function f($a){foreach($a as$d)@$$d++;return 2*hypot($U-$D,$L-$R);}

Ejemplo:

<?php
var_dump(f(array('U', 'U', 'U', 'U', 'D', 'R', 'R', 'R', 'L')));

>float(7.211102550928)
Boann
fuente
2

Julia, 45

f(l)=2*abs(sum([im^(c=='d'?3:c) for c in l]))

Robó el itruco de poderes. Además, todos los caracteres excepto d tienen valores que funcionan como potencias aceptables para i.

gggg
fuente
1

J, 29 caracteres

+:+&.*:/-/_2[\#/.~/:~'ruld'i.

Sólo funciona con direcciones minúsculas y caracteres que no sean r, u, l, y dhará que se dará una respuesta equivocada.

Uso:

   +:+&.*:/-/_2[\#/.~/:~'ruld'i.'uuuudrrrl'
7.2111

Explicación:

'ruld'i.'uuuudrrrl'La forma diádica de i.encuentra el índice de elementos del argumento derecho en el argumento izquierdo. En este caso:

   'ruld'i.'uuuudrrrl'
1 1 1 1 3 0 0 0 2

/:~ ordena esta lista en orden ascendente:

   /:~'ruld'i.'uuuudrrrl'
0 0 0 1 1 1 1 2 3

#/.~ cuenta el número de ocurrencias de cada número:

   #/.~/:~'ruld'i.'uuuudrrrl'
3 4 1 1

_2[\ lo corta en 2 filas:

   _2[\#/.~/:~'ruld'i.'uuuudrrrl'
3 4
1 1

-/ resta la parte inferior de la parte superior

   -/_2[\#/.~/:~'ruld'i.'uuuudrrrl'
2 3

+&.*:Toma prestado un truco de otra respuesta J que vi esta mañana , y cuadra los elementos, luego los suma, luego realiza una raíz cuadrada. Ver debajo de la&. documentación:

   +&.*:/-/_2[\#/.~/:~'ruld'i.'uuuudrrrl'
3.60555

+: duplica el resultado:

   +:+&.*:/-/_2[\#/.~/:~'ruld'i.'uuuudrrrl'
7.2111
Gareth
fuente
1

R, 86 74 56 caracteres

Ok, en realidad es mucho más corto con números imaginarios:

2*Mod(sum(sapply(scan(,""),switch,u=1i,d=-1i,l=-1,r=1)))

Uso:

> 2*Mod(sum(sapply(scan(,""),switch,u=1i,d=-1i,l=-1,r=1)))
1: u u u u d r r r l
10: 
Read 9 items
[1] 7.211103

Antigua solución a 74 caracteres con coordenadas xy:

2*sqrt(sum(rowSums(sapply(scan(,""),switch,u=0:1,d=0:-1,l=-1:0,r=1:0))^2))

Uso:

> 2*sqrt(sum(rowSums(sapply(scan(,""),switch,u=0:1,d=0:-1,l=-1:0,r=1:0))^2))
1: u u u u d r r r l
10: 
Read 9 items
[1] 7.211103

Toma la entrada como stdin, debe estar en minúsculas y separadas por espacios. Utilice las coordenadas xy a partir de (0,0).

plannapus
fuente
1

k ( 50 49)

{2*sqrt x$x:0 0f+/("udlr"!(1 0;-1 0;0 -1;0 1))@x}

Ejemplo

{2*sqrt x$x:0 0f+/("udlr"!(1 0;-1 0;0 -1;0 1))@x}"uuuudrrrl"
7.211103
skeevey
fuente
1

Java, 185, 203 , 204 , 217 , 226

class A{public static void main(String[] a){int x=0,y=0;for(int i=0;i<a[0].length();i++) switch(a[0].charAt(i)){case'U':y++;break;case'D':y--;break;case'L':x++;break;case'R':x--;}System.out.print(Math.hypot(x,y)*2);}}

Supuse que cada "U" era "1 arriba", por lo que dos unidades arriba serían "UU"

Editar: interruptor intercambiado por ifs

class A{public static void main(String[]a){int x=0,y=0;for(int i=0;i<a[0].length();i++){int c=a[0].charAt(i);if(c=='U')y++;if(c=='D')y--;if(c=='L')x++;if(c=='R')x--;}System.out.print(Math.hypot(x,y)*2);}}

Movido por iterador

class A{public static void main(String[]a){int x=0,y=0;for(int i=0;i<a[0].length();){int c=a[0].charAt(i++);if(c=='U')y++;if(c=='D')y--;if(c=='L')x++;if(c=='R')x--;}System.out.print(Math.hypot(x,y)*2);}}

Ya no toma la entrada como una cadena, sino un conjunto de direcciones

class A{public static void main(String[]a){int x=0,y=0;for(String s:a){char c=s.charAt(0);if(c=='U')y++;if(c=='D')y--;if(c=='L')x++;if(c=='R')x--;}System.out.print(Math.hypot(x,y)*2);}}
James Webster
fuente
Comprendí que el resumen era que solo necesita una función, no un programa completo.
Boann
1

T-SQL, 158

IF PATINDEX('%[^UDLR]%', @s)=0 select 2*sqrt(power(LEN(REPLACE(@s,'U',''))-LEN(REPLACE(@s,'D','')),2)+power(LEN(REPLACE(@s,'L',''))-LEN(REPLACE(@s,'R','')),2))

@S es la cadena de entrada del tipo varchar (max)

duanxn
fuente
1

ES6, 77 69

Definición:

f=s=>{u=d=l=r=0;for(c of s)eval(c+'++');return 2*Math.hypot(u-d,l-r)}

Uso:

>>> f('uuuudrrrl')
7.211102550927979
>>> f( 'uuuudrrrl'.split('') )
7.211102550927979
  • Acepta cadena O matriz (en minúsculas)
  • No usa números imaginarios
  • No hubiera sido posible solo 3 días antes de que OP publicara la pregunta ; es decir, solo se ejecuta en Firefox 27+ (y tal vez también Chrome con material experimental habilitado, ¡no lo he probado :)!

(Inspirado parcialmente por la respuesta de Boann).

No yo
fuente
Realmente quiero hacer algo complicado para deshacerme del retorno, como convertir todo en una expresión booleana que solo se evalúa y se devuelve automáticamente, pero no estoy seguro de que haya una manera de hacerlo a menos que pueda reemplazar la fordeclaración con algo expresión (un cuerpo de función de flecha que contiene declaraciones requiere los corchetes y el retorno explícito, los cuerpos que son solo expresiones no).
Noyo
1

JavaScript - 142 caracteres - sin eval ()

function r(a){return Math.sqrt(Math.pow(a.match(/u/g).length-a.match(/d/g).length,2)+Math.pow(a.match(/l/g).length-a.match(/r/g).length,2))*2}

donde a es una cadena como 'uudrrl'

usar así

a='uudrrl'
r(a)

Prueba en la consola del navegador.

var x = "luluurrrrurd"
r(x)
8.48528137423857
rahulroy9202
fuente
1

C # - 90 caracteres

Recién salido de LINQPad.

int x=0,y=0;input.Max(i=>i==85?y++:i==82?x++:i==68?y--:x--);(Math.Sqrt(x*x+y*y)*2).Dump();

Donde input es una cadena válida.

>string input = "LULUURRRRURD";

>8.48528137423857
tdink
fuente
0

Befunge-93 (65)

Tiene 65 caracteres que no son espacios en blanco (217 con espacios en blanco, aunque eso se puede reducir con un diseño más compacto (para 69/176 caracteres)). Toma un poco de liberalidad con el formato de salida, pero es indudablemente preciso. No parece que valga la pena el esfuerzo de implementar / robar una implementación de raíz cuadrada.

v                  >$:*\:*+88*4*5-2.,.@
               >3-:|
           >6-:|
       >8-:|
>~"D"-:|
       $   $   $   $
           \   \
       1   1   1   1
       -   -   +   +
           \   \
^      <   <   <   <

echo 'UUDLLUU' | ./befungee.py ../man salidas 2√13 (en realidad, la implementación parece tener problemas con el ASCII extendido).

Joel Bosveld
fuente
0

Matlab, 51 caracteres

Mi presentación de Matlab, funciona solo con letras cautivas. ¡Esto fue divertido! La parte más difícil fue convertir la cadena en una matriz de números complejos para sumar.

Función:

f=@(s)abs(sum(fix((s-76.5)/8.5)+((s-79)*i/3).^-99))

Uso:

>> f=@(s)abs(sum(fix((s-76.5)/8.5)+((s-79)*i/3).^-99))
>> f('UURDL')
ans =

     1
>>
Hannesh
fuente
0

Javascript, 136

function z(a){var x=a.split('u').length-a.split('d').length;var y=a.split('r').length-a.split('l').length;return Math.sqrt(x*x+y*y)*2;};
document.write(z('uuuudrrrwl'));
7.211102550927978
Xin
fuente
0

JavaScript, 89

function f(a){U=D=L=R=0;for(d in a)eval(a[d]+'++');return 2*Math.sqrt((U-=D)*U+(L-=R)*L)}

Ejemplo:

<script>
document.write(f(['U', 'U', 'U', 'U', 'D', 'R', 'R', 'R', 'L']));
</script>

>7.211102550927978
Boann
fuente
0

C, 120

float d(char *p){int v=0,h=0;while(*p){v+=*p=='U'?1:*p=='D'?-1:0,h+=*p=='R'?1:*p=='L'?-1:0,++p;}return 2*sqrt(v*v+h*h);}

d("LULUURRRRURD") -> 8.485281

Warrenm
fuente
0

JavaScript (sin ES6, sin evaluación) - 131

f=function(h){for(i=0,a=[0,,0,0,0];i<h.length;++i)++a[(h.charCodeAt(i)>>2)-25];x=a[0]-a[4];y=a[2]-a[3];return Math.sqrt(x*x+y*y)*2}

Prueba:

console.log(f('uuuudrrrl'));     // 7.211102550927978 
console.log(f('luluurrrrurd'));  // 8.48528137423857
iefserge
fuente