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.


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

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

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

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

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.


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.


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


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)

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.


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

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


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

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

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)


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


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

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

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


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

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

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

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


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
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.