Estou andando por Manhattan, a que distância estou do meu hotel?


27

A história desnecessária e complicada

Estou andando por manhattan, quarteirão por quarteirão, e meus pés se cansaram e querem voltar para casa.

O tráfego é muito ruim, mas felizmente sou muito rico e tenho um helicóptero em espera no hotel. Mas preciso que eles saibam quanto combustível levar para o voo e para isso precisam saber a minha distância direta do hotel. Lembrei-me de quais quarteirões andei e posso dizer a eles qual caminho eu segui. Porém, essa distância precisa ser precisa; se forem muito curtas, não voltaremos por muito tempo e comprei combustível que não posso usar.

Você pode me escrever um programa para converter isso na distância que eles terão que viajar no voo para me buscar?

Especificação:

Escreva-me uma função que:

  1. Aceita uma lista ou sequência de blocos percorridos em relação a uma grade arbitrária:
    • L p, D próprio, L eft e R ight.
    • Pode ser maiúscula ou minúscula - por exemplo. se for mais curto para usar em uvez de Useguir em frente.
    • Uma direção inválida tem um comportamento indefinido - por exemplo. uma direção de X pode causar uma falha.
  2. Retorna um ponto flutuante / decimal / duplo que é o dobro da distância da linha reta do ponto de origem.

Para ilustração e esclarecimento:

Minha viagem

Minha viagem pode ter sido tão facilmente gravada quanto "luluu..."ou, ['l','u','l'...]mas deve ser gravada como Cima, Baixo, Esquerda, Direita.


15
Você é rico o suficiente para ter um helicóptero, mas se importa se comprar algum combustível extra? : O
Fez Vrasta

8
@fezvrasta porque sou mesquinho.

7
Maneira de mexer com minha cabeça, não fazendo isso sobre a distância de Manhattan.
Kendall Frey

25
A resposta correta é: "Não importa. Você é um cara rico, então enfia a mão no bolso, tira um maço de US $ 20 e balança no ar para atrair a atenção de um taxista; você é então, é atacado por um grupo de bandidos do jardim de infância que o roubam e o espancam até uma polpa ensanguentada.Você é preso por desordem e vadiagem pública, acusado de terrorismo por tentar causar pânico em massa e uma pandemia, espalhando sua lama corporal por um público calçada, condenado, enviado para a prisão, e trancou-se com um companheiro de cela apelidado Brutus que leva um verdadeiro gosto forte para você. Bem-vindo ao New York!"
Bob Jarvis - Restabelece Monica

2
@McKay Eu interpreto como direções em um mapa (de qualquer forma (provavelmente seria "para frente" e "para trás"), e a medida da distância é bastante clara "duas vezes a distância da linha reta do ponto de origem", então não distância de manhattan).
FireFly

Respostas:


32

J, 17 caracteres

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

Usa o fato de que os poderes de jrepresentam as direções apropriadas.

  • 'urdl'i. pegue a string e calcule os índices (0 para 'u', 1 para 'r', ...)
  • 0j1^transforma na direção no plano complexo usando a potência correspondente de j.
  • +/ resume as etapas únicas
  • 2*| duas vezes o módulo

Exemplo:

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

5
Bom trabalho. Conhecimento de matemática para a vitória. :-)
Gareth

Faça esse ASCII "não estendido" e então terá apenas 15 bytes (porque você não usa o oitavo bit).
Timtech

11

Python 2.7 56 58 56 51 48

Com o número dez centavos roubado de Scrooge McDuck , fiz minha fortuna e agora tenho mais riqueza do que Scrooge.

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

Python 2.7 - 61 53 50 (não diferencia maiúsculas de minúsculas)

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

Implementação

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

Eu estou recebendo IndexError: list index out of range. Que forma a entrada deve ter?
plannapus

@ plannapus: eu adicionei uma seção de implementação
Abhijit

Ah e foi %5não %8. Ok, faz mais sentido agora :)
plannapus

5

APL (29)

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

por exemplo

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

Explicação:

  • +/'URDL'∘.=⍵: veja com que frequência os caracteres URDLocorrem no argumento
  • -⌿2 2⍴: subtraia o Uvalor do Dvalor e o Rvalor do Lvalor
  • 2 0j2×: multiplique o valor vertical por 2e o valor horizontal por2i
  • +/: soma
  • |: magnitude

4

Ruby 1.9+ (67)

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

Exemplo

f["DRUULULLULL"] => 10.0
f["UUUUDRRRL"] => 7.211102550927978

3

caracteres perl6: 44

2*abs [+] i <<**>>%(<U R D L>Z ^4){get.comb}
  • get.comb obtém uma linha de entrada e se divide em caracteres
  • <U R L D> é uma lista de palavras, caracteres neste caso
  • (1,2,3) Z (4,5,6)== (1,2), (2,5), (3,6), para que ele junte 2 listas, criando uma lista de pacotes que se %()transformam em hash
  • <<**>>emparelhado **, estendendo a lista mais curta para caber mais. A lista mais curta passa a ser apenasi
  • [+]soma todos os elementos de uma lista, abspega o módulo para números complexos

Sim, removi todos os espaços possíveis.


2

Python 2.7 - 65

Bom e curto, ele usa números complexos para percorrer o avião:

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

Adereços para DSM e Abhijit em outras perguntas que me mostraram o uso de 1jpara calcular isso.


Pode 1jser escrito como j, -1jcomo -j? Além disso, isso lida com as entradas superior e inferior, ou apenas superior?
DavidC

1
Tio Scrooze , eu te odeio. Você deveria pelo menos deixar algum dinheiro para seus sobrinhos.
Abhijit

1
@DavidCarraher: Não, você não pode. Seria impossível diferenciar entre a variável je a unidade imagináriaj
Abhijit

Você não disse que deveria produzir duas vezes a distância? ao tentar com UUUUDRRRL, estou recebendo 3.606 com esta função em vez de 7.21.
plannapus

4
Você pode salvar mais 2 caracteres, multiplicando as constantes, em 2vez de multiplicar o resultado final.
Abhijit

2

Mathematica 92 49

Calle merece todo o crédito pela otimização do código.

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

Exemplo

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

7.2111


1
Você está fazendo muito trabalho que não é exigido pelo OP, f@l_ := 2 N@Norm[Tr[l /. {"r" -> 1, "l" -> -1, "u" -> I, "d" -> -I}]]será suficiente.

Recebo 2 Norm[(2. + 2. I) + "U" + "X"]como saída para o seu código.
6134

1
Sim, mas o OP diz que não há problema em falhar com essa entrada. É assim que eu e todos os outros interpretamos. Não consigo ler esses outros idiomas, mas você verá que eles frequentemente codificam para u, r, le d.

Está bem. Consegui. Obrigado por apontar isso.
6134

Se você substituir os dois pares restantes de parênteses por @s, obtém outros dois caracteres a menos.
shrx

2

PHP, 67

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

Exemplo:

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

Roubou o itruque dos poderes. Todos os caracteres, exceto d, também possuem valores que funcionam como poderes aceitáveis i.


1

J, 29 caracteres

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

Só funciona com direções minúsculas e quaisquer outros do que personagens r, u, l, e dfará com que ele para dar uma resposta errada.

Uso:

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

Explicação:

'ruld'i.'uuuudrrrl'A forma diádica de i.localiza o índice de itens do argumento correto no argumento esquerdo. Nesse caso:

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

/:~ classifica esta lista em ordem crescente:

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

#/.~ conta o número de ocorrências de cada número:

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

_2[\ divide em 2 linhas:

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

-/ subtrai a parte inferior do topo

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

+&.*:pede emprestado um truque de outra resposta J que vi hoje de manhã , encaixa os itens, soma os itens e executa uma raiz quadrada. Veja na&. documentação:

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

+: duplica o resultado:

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

1

R, 86 74 56 caracteres

Ok, é realmente muito mais curto com números imaginários:

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

Solução antiga com 74 caracteres com xy coords:

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 a entrada como stdin, precisa ser minúscula e separada por espaço. Use coordenadas xy iniciando em (0,0).


1

k ( 50 49)

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

Exemplo

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

Eu assumi que cada "U" era "1 up", então duas unidades acima seriam "UU"

Edit: troca de switch para 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 para o 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);}}

Não recebe mais a entrada como string, mas sim como um conjunto de direções

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

Meu entendimento do resumo foi que você só precisa de uma função, não de um programa inteiro.
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))

O @s é a sequência de entrada do tipo varchar (max)


1

ES6, 77 69

Definição:

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
  • Aceita string OR array (minúscula)
  • Não usa números imaginários
  • Não seria possível apenas três dias antes do OP postar a pergunta ; isto é, ele roda apenas no Firefox 27+ (e talvez também no Chrome com material experimental ativado, não testei :) !!

(Inspirado parcialmente pela resposta de Boann.)


Eu realmente quero fazer algo complicado para me livrar do retorno, como transformar tudo em uma expressão booleana que apenas é avaliada e retornada automaticamente, mas não tenho certeza de que haja uma maneira de fazer isso, a menos que eu possa substituir a fordeclaração por alguma expressão (um corpo da função seta que contém instruções exigem os suportes e o retorno explícita, órgãos que são apenas expressões não) ..
Noyo

1

JavaScript - 142 caracteres - sem avaliação ()

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}

onde a é uma string como 'uudrrl'

use assim -

a='uudrrl'
r(a)

Teste no console do navegador.

var x = "luluurrrrurd"
r(x)
8.48528137423857

1

C # - 90 caracteres

Recém-vindo do 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();

Onde input é uma sequência válida.

>string input = "LULUURRRRURD";

>8.48528137423857

0

Befunge-93 (65)

Possui 65 caracteres que não são espaços em branco (217 com espaços em branco, embora isso possa ser reduzido por um layout mais compacto (para 69/176 caracteres)). É preciso alguma liberalidade com o formato de saída, mas é inegavelmente preciso. Não parece valer o esforço para implementar / roubar uma implementação de raiz quadrada.

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

echo 'UUDLLUU' | ./befungee.py ../man resultados 2√13 (na verdade, a implementação parece ter problemas com o ASCII estendido).


0

Matlab, 51 caracteres

Minha inscrição no Matlab, funciona apenas com letras maiúsculas. Essa foi engraçada! A parte mais difícil foi converter a string em uma matriz de números complexos a serem somados.

Função:

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

Exemplo:

<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 (sem ES6, sem avaliação) - 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}

Teste:

console.log(f('uuuudrrrl'));     // 7.211102550927978 
console.log(f('luluurrrrurd'));  // 8.48528137423857
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.