Sto camminando per Manhattan, quanto sono lontano dal mio hotel?


27

La storia inutile e contorta

Sto camminando per Manhattan, blocco per blocco, i miei piedi si sono stancati e voglio tornare a casa.

Il traffico è piuttosto scarso, ma per fortuna sono molto ricco e ho un elicottero in standby in hotel. Ma ho bisogno che sappiano quanto carburante mettere in valigia per il volo e per questo devono conoscere la mia distanza diretta dall'hotel. Ho ricordato quali blocchi ho camminato e posso dire loro quale percorso ho preso. Questa distanza deve essere precisa, tuttavia, se sono troppo corti non ce la faremo indietro, troppo a lungo e ho comprato carburante che non posso usare.

Puoi scrivermi un programma per convertirlo nella distanza che dovranno percorrere sul loro volo per prendermi?

Specifica:

Scrivimi una funzione che:

  1. Accetta un elenco o una stringa di blocchi percorsi rispetto a una griglia arbitraria:
    • U p, D propria, L EFT e R ight.
    • Può essere maiuscolo o minuscolo, ad es. se è più corto da usare uinvece di Uandare avanti.
    • Una direzione non valida ha un comportamento indefinito, ad es. una direzione di X può causare un errore.
  2. Restituisce un float / decimale / doppio che è il doppio della distanza in linea retta dal punto di origine.

Per illustrazione e chiarimento:

Il mio viaggio

Il mio viaggio avrebbe potuto essere registrato altrettanto facilmente come "luluu..."o ['l','u','l'...]ma deve essere registrato come Su, Giù, Sinistra, Destra.


15
Sei abbastanza ricco per avere un elicottero ma ti importa se viene acquistato del carburante extra? : O
Fez Vrasta,

8
@fezvrasta perché sono avaro.

7
Modo di scherzare con la mia testa non facendo questo sulla distanza di Manhattan.
Kendall Frey,

25
La risposta corretta è "Non importa. Sei un ragazzo ricco, quindi ti metti una mano in tasca, tiri fuori una mazzetta di $ 20 e la saluti in aria per attirare l'attenzione di un cabby; sei poi assalito da un gruppo di teppisti dell'asilo che ti derubano e ti picchiano in una polpa insanguinata. Sei quindi arrestato per sporcizia e vagabondaggio pubblico, accusato di terrorismo per aver tentato di provocare panico di massa e una pandemia diffondendo la tua melma corporea attraverso un pubblico marciapiede, condannato, mandato in prigione e rinchiuso con un compagno di cella soprannominato Bruto che ha una vera simpatia per te. Benvenuto a New York! "
Bob Jarvis - Ripristina Monica il

2
@McKay lo interpreto comunque come indicazioni su una mappa (altrimenti sarebbe probabilmente "avanti" e "indietro"), e la misura della distanza è piuttosto inequivocabile "due volte la distanza in linea retta dal punto di origine", quindi no distanza di manhattan).
FireFly

Risposte:


32

J, 17 caratteri

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

Usa il fatto, che i poteri di jrappresentano le giuste direzioni.

  • 'urdl'i. prende la stringa e calcola gli indici (0 per 'u', 1 per 'r', ...)
  • 0j1^si trasforma nella direzione nel piano complesso usando la potenza corrispondente di j.
  • +/ riassume i singoli passaggi
  • 2*| due volte il modulo

Esempio:

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

5
Bel lavoro. Conoscenza matematica per la vittoria. :-)
Gareth

Crea questo ASCII "non esteso" e poi ha solo 15 byte (perché non usi l'ottavo bit).
Timtech,

11

Python 2.7 56 58 56 51 48

Con il numero uno rubato da Scrooge McDuck , ho fatto fortuna e ora ho più ricchezza di Scrooge.

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

Python 2.7 - 61 53 50 (senza distinzione tra maiuscole e minuscole)

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

Implementazione

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

Sto ottenendo IndexError: list index out of range. Quale forma deve avere l'input?
plannapus,

@plannapus: ho aggiunto una sezione di implementazione
Abhijit,

Ah ed è stato %5non %8. Ok, ora ha più senso :)
plannapus,

5

APL (29)

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

per esempio

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

Spiegazione:

  • +/'URDL'∘.=⍵: vedi con quale frequenza si URDLverificano i caratteri nell'argomento
  • -⌿2 2⍴: sottrai il Uvalore dal Dvalore e il Rvalore dal Lvalore
  • 2 0j2×: moltiplica il valore verticale per 2e il valore orizzontale per2i
  • +/: somma
  • |: magnitudo

4

Ruby 1.9+ (67)

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

Esempio

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

3

perl6: 44 caratteri

2*abs [+] i <<**>>%(<U R D L>Z ^4){get.comb}
  • get.comb ottiene una riga di input e si divide in caratteri
  • <U R L D> è un elenco di parole, caratteri in questo caso
  • (1,2,3) Z (4,5,6)== (1,2), (2,5), (3,6), quindi comprime 2 elenchi l'uno nell'altro, creando un elenco di pacchi che %()si trasforma in un hash
  • <<**>>fa in coppia **, estendendo l'elenco più corto per adattarsi al più lungo. L'elenco più breve sembra essere soloi
  • [+]somma tutti gli elementi di un elenco, absprende il modulo per numeri complessi

Sì, ho rimosso tutti gli spazi possibili.


2

Python 2.7 - 65

Bello e corto, utilizza numeri complessi per attraversare l'aereo:

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

Props to DSM e Abhijit in altre domande che mi hanno mostrato l'uso di 1jper calcolare questo.


Può 1jessere scritto come j, -1jcome -j? Inoltre, gestisce l'input superiore e inferiore o solo quello superiore?
DavidC,

1
Zio Scrooze , ti odio. Dovresti almeno lasciare dei soldi per i tuoi nipoti.
Abhijit,

1
@DavidCarraher: No, non puoi. Sarebbe impossibile distinguere tra la variabile je l'unità immaginariaj
Abhijit,

Non hai detto che doveva produrre il doppio della distanza? quando provo con UUUUDRRRL ottengo 3.606 con questa funzione invece di 7.21.
plannapus,

4
Puoi salvare altri 2 caratteri, moltiplicando le costanti 2invece di moltiplicare il risultato finale.
Abhijit,

2

Mathematica 92 49

Calle merita pieno credito per la semplificazione del codice.

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

Esempio

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

7,2111


1
Farai molto lavoro che non è richiesto dall'OP, f@l_ := 2 N@Norm[Tr[l /. {"r" -> 1, "l" -> -1, "u" -> I, "d" -> -I}]]sarà sufficiente.

Ottengo 2 Norm[(2. + 2. I) + "U" + "X"]come output per il tuo codice.
DavidC,

1
Sì, ma l'OP dice che va bene fallire con tale input. È così che io e tutti gli altri lo interpretiamo. Non riesco a leggere queste altre lingue, ma vedrai che spesso sono hardcode per u, r, le d.

Ok. Fatto. Grazie per la segnalazione.
DavidC,

Se sostituisci due restanti coppie di parentesi con @s otterrai altri due caratteri in meno.
Shrx

2

PHP, 67

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

Esempio:

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

>float(7.211102550928)

2

Julia, 45 anni

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

Ho rubato il itrucco ai poteri. Inoltre, tutti i caratteri tranne d hanno valori che funzionano come poteri accettabili per i.


1

J, 29 caratteri

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

Funziona solo con il caso le indicazioni più bassi e caratteri diversi r, u,l , e dfarà sì che per dare una risposta sbagliata.

Uso:

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

Spiegazione:

'ruld'i.'uuuudrrrl'La forma diadica di i.trova l'indice degli elementi dall'argomento destro nell'argomento sinistro. In questo caso:

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

/:~ ordina questo elenco in ordine crescente:

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

#/.~ conta il numero di occorrenze di ciascun numero:

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

_2[\ lo taglia in 2 file:

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

-/ sottrae il fondo dall'alto

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

+&.*:prende in prestito un trucco da un'altra risposta di J che ho visto stamattina , e piazza gli oggetti, quindi li somma, quindi esegue una radice quadrata. Vedi sotto&. documentazione:

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

+: raddoppia il risultato:

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

1

R, 86 74 56 caratteri

Ok, in realtà è molto più breve con numeri immaginari davvero:

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

Vecchia soluzione a 74 caratteri con 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

Accetta input come stdin, deve essere minuscolo e separato da spazio. Usa le coordinate xy a partire da (0,0).


1

k ( 50 49)

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

Esempio

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

Supponevo che ogni "U" fosse "1 in su", quindi due unità in su sarebbero "UU"

Modifica: scambiato per 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);}}

Spostato per iteratore

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

Non accetta più input come stringa, piuttosto array di direzioni

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

La mia comprensione del brief era che hai solo bisogno di una funzione, non di un intero programma.
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 è la stringa di input di tipo varchar (max)


1

ES6, 77 69

Definizione:

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
  • Accetta stringa OR array (lettere minuscole)
  • Non usa numeri immaginari
  • Non sarebbe stato possibile solo 3 giorni prima che OP avesse pubblicato la domanda ; cioè funziona solo con Firefox 27+ (e forse anche Chrome con roba sperimentale abilitata, non ho testato :) !!

(Ispirato parzialmente dalla risposta di Boann.)


Voglio davvero fare qualcosa di complicato per sbarazzarmi del ritorno, come trasformare il tutto in un'espressione booleana che viene appena valutata e restituita automagicamente, ma non sono sicuro che ci sia un modo per farlo a meno che non riesca a sostituire l' foraffermazione con alcuni espressione (un corpo di funzione freccia contenente istruzioni richiede le parentesi e il ritorno esplicito, i corpi che sono solo espressioni no) ..
Noyo

1

JavaScript - 142 caratteri - no 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}

dove a è una stringa come 'uudrrl'

usare così -

a='uudrrl'
r(a)

Test nella console del browser.

var x = "luluurrrrurd"
r(x)
8.48528137423857

1

C # - 90 caratteri

Fresco di 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();

Dove input è una stringa valida.

>string input = "LULUURRRRURD";

>8.48528137423857

0

Befunge-93 (65)

Ha 65 caratteri non bianchi (217 con spazi bianchi, sebbene ciò possa essere ridotto da un layout più compatto (per 69/176 caratteri)). Ci vuole un po 'di liberalità con il formato di output, ma è innegabilmente accurato. Non sembra valere la pena di implementare / rubare un'implementazione di radice quadrata.

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

echo 'UUDLLUU' | ./befungee.py ../man output 2√13 (tuttavia l'implementazione sembra avere problemi con l'ASCII esteso).


0

Matlab, 51 caratteri

La mia presentazione Matlab, funziona solo con lettere in cattività. Questo è stato divertente! La parte più difficile è stata la conversione della stringa in una matrice di numeri complessi da sommare.

Funzione:

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

Esempio:

<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 (no ES6, no eval) - 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}

Test:

console.log(f('uuuudrrrl'));     // 7.211102550927978 
console.log(f('luluurrrrurd'));  // 8.48528137423857
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.