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.