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.