Ich gehe durch Manhattan, wie weit bin ich von meinem Hotel entfernt?

27

Die unnötige und verworrene Geschichte

Ich gehe Block für Block durch Manhattan und meine Füße sind müde geworden und wollen nach Hause zurück.

Der Verkehr ist ziemlich schlecht, aber zum Glück bin ich sehr reich und ich habe einen Hubschrauber im Hotel in Bereitschaft. Aber sie müssen wissen, wie viel Treibstoff sie für den Flug einpacken müssen, und dafür müssen sie meine direkte Entfernung zum Hotel kennen. Ich habe mich daran erinnert, welche Blöcke ich gegangen bin und kann ihnen sagen, welchen Weg ich genommen habe. Dieser Abstand muss jedoch präzise sein. Wenn sie zu kurz sind, schaffen wir es nicht, zu lange zurückzukehren, und ich habe Kraftstoff gekauft, den ich nicht verwenden kann.

Können Sie mir ein Programm schreiben, um das in die Entfernung umzuwandeln, die sie auf ihrem Flug zurücklegen müssen, um mich abzuholen?

Spezifikation:

Schreiben Sie mir eine Funktion, die:

  1. Akzeptiert eine Liste oder eine Folge von Blöcken, die relativ zu einem beliebigen Raster ablaufen:
    • U p, D own, L eft und R ight.
    • Kann entweder Groß- oder Kleinschreibung sein - z. Wenn es kürzer zu benutzen ist, uanstatt Uweiterzumachen.
    • Eine ungültige Richtung hat undefiniertes Verhalten - z. Eine Richtung von X kann einen Fehler verursachen.
  2. Gibt ein Gleitkomma / Dezimal / Doppel zurück, das dem doppelten Abstand der geraden Linie vom Ursprungspunkt entspricht.

Zur Veranschaulichung und Verdeutlichung:

Meine Reise

Meine Reise hätte genauso einfach aufgezeichnet werden können wie "luluu..."oder ['l','u','l'...]aber sie muss als Auf, Ab, Links, Rechts aufgezeichnet werden.


quelle
15
Sie sind reich genug, um einen Hubschrauber zu haben, aber es interessiert Sie, ob Sie zusätzlichen Treibstoff kaufen? : O
Fez Vrasta
8
@fezvrasta weil ich geizig bin.
7
Weg, um mit meinem Kopf durcheinander zu kommen, indem ich das nicht über Manhattans Entfernung mache.
Kendall Frey
25
Die richtige Antwort lautet: "Es spielt keine Rolle. Sie sind ein reicher Typ. Greifen Sie in Ihre Tasche, ziehen Sie ein Bündel mit 20 Dollar heraus und schwenken Sie es in die Luft, um die Aufmerksamkeit eines Taxis auf sich zu ziehen. Sie sind es." Dann werden Sie von einer Gruppe von Kindergarten-Schlägern angeklagt, die Sie ausrauben und zu blutigem Brei schlagen. Dann werden Sie verhaftet, weil Sie versuchten, Massenpanik und eine Pandemie auszulösen, indem Sie Ihren Schlamm über ein Publikum verteilen Gehweg, verurteilt, ins Gefängnis geschickt und mit einem Mithäftling Spitznamen Brutus eingesperrt, der eine nimmt reale Sie starke Vorliebe. Willkommen in New York!“
Bob Jarvis - Reinstate Monica
2
@McKay Ich interpretiere es sowieso als Richtungen auf einer Karte (andernfalls wäre es wahrscheinlich "vorwärts" und "rückwärts"), und das Entfernungsmaß ist ziemlich eindeutig "doppelt so groß wie die Entfernung auf der Geraden vom Ursprungspunkt", also nein Manhattan Entfernung).
FireFly

Antworten:

32

J, 17 Zeichen

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

Nutzt die Tatsache, dass die Befugnisse jdie richtigen Richtungen darstellen.

  • 'urdl'i. nimm einen String und berechne Indizes (0 für 'u', 1 für 'r', ...)
  • 0j1^transformiert mit der entsprechenden Potenz von in die Richtung in der komplexen Ebene j.
  • +/ fasst die einzelnen Schritte zusammen
  • 2*| zweifacher Modul

Beispiel:

> 2*|+/0j1^'urdl'i.'uuuudrrrl'
7.2111
Howard
quelle
5
Gute Arbeit. Mathematikwissen für den Sieg. :-)
Gareth
Machen Sie dieses "nicht-erweiterte" ASCII und dann sind es nur 15 Bytes (weil Sie das achte Bit nicht verwenden).
Timtech
11

Python 2.7 56 58 56 51 48

Mit dem gestohlenen Number One Dime von Scrooge McDuck habe ich mein Vermögen gemacht und bin jetzt reicher als Scrooge.

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

Python 2.7 - 61 53 50 (Groß- und Kleinschreibung wird nicht berücksichtigt)

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

Implementierung

>>> 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
Abhijit
quelle
Ich bekomme IndexError: list index out of range. Welche Form soll die Eingabe haben?
Plannapus
@plannapus: Ich habe einen Implementierungsabschnitt hinzugefügt
Abhijit
Ah und es war %5nicht %8. Ok, es macht jetzt mehr Sinn :)
Plannapus
5

APL (29)

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

z.B

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

Erläuterung:

  • +/'URDL'∘.=⍵: Sehen Sie, wie oft die Zeichen URDLim Argument vorkommen
  • -⌿2 2⍴: subtrahiere den UWert vom DWert und den RWert vom LWert
  • 2 0j2×: multipliziere den vertikalen Wert mit 2und den horizontalen Wert mit2i
  • +/: Summe
  • |: Größe
Marinus
quelle
4

Ruby 1.9+ (67)

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

Beispiel

f["DRUULULLULL"] => 10.0
f["UUUUDRRRL"] => 7.211102550927978
daniero
quelle
3

perl6: 44 Zeichen

2*abs [+] i <<**>>%(<U R D L>Z ^4){get.comb}
  • get.comb Ruft eine Eingabezeile ab und teilt sie in Zeichen auf
  • <U R L D> ist eine Liste von Wörtern, in diesem Fall Zeichen
  • (1,2,3) Z (4,5,6)== (1,2), (2,5), (3,6), also packt es 2 Listen ineinander und erstellt eine Liste von Paketen, die %()sich in einen Hash verwandelt
  • <<**>>wird paarweise ausgeführt **, wobei die kürzere Liste um die längere erweitert wird. Kürzere Liste ist zufällig nuri
  • [+]summiert alle Elemente einer Liste, absnimmt den Modul für komplexe Zahlen

Ja, ich habe alle möglichen Leerzeichen entfernt.

Ayiko
quelle
2

Python 2.7 - 65

Schön und kurz, dies verwendet komplexe Zahlen, um durch die Ebene zu springen:

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

Requisiten an DSM und Abhijit in anderen Fragen, die mir die Verwendung von zeigten 1j, um dies zu berechnen.


quelle
Kann 1jgeschrieben werden als j, -1jals -j? Behandelt dies auch obere und untere Eingabe oder nur obere?
DavidC
1
Onkel Scrooze , ich hasse dich. Sie sollten zumindest etwas Geld für Ihre Neffen hinterlassen.
Abhijit
1
@ DavidCarraher: Nein, kannst du nicht. Es wäre unmöglich, zwischen der Variablen jund der imaginären Einheit zu unterscheidenj
Abhijit
Haben Sie nicht gesagt, es sollte die doppelte Entfernung ausgeben ? Wenn ich es mit UUUUDRRRL versuche, erhalte ich 3,606 mit dieser Funktion anstelle von 7,21.
Plannapus
4
Sie können 2 weitere Zeichen speichern, indem Sie die Konstanten mit 2multiplizieren, anstatt das Endergebnis zu multiplizieren.
Abhijit
2

Mathematica 92 49

Calle verdient die volle Anerkennung für die Rationalisierung des Codes.

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

Beispiel

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

7.2111

DavidC
quelle
1
Sie erledigen eine Menge Arbeit, die das OP nicht benötigt, f@l_ := 2 N@Norm[Tr[l /. {"r" -> 1, "l" -> -1, "u" -> I, "d" -> -I}]]wird ausreichen.
Ich bekomme 2 Norm[(2. + 2. I) + "U" + "X"]als Ausgabe für deinen Code.
DavidC
1
Ja, aber das OP sagt, dass es in Ordnung ist, mit solchen Eingaben zu scheitern. So interpretiere ich und alle anderen es. Ich kann diese anderen Sprachen nicht lesen, aber Sie werden sehen, dass sie oft hart für u, r, l und d codieren.
Okay. Ich habs. Vielen Dank für den Hinweis.
DavidC
Wenn Sie zwei verbleibende Klammerpaare durch @s ersetzen, erhalten Sie zwei weitere Zeichen weniger.
shrx
2

PHP, 67

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

Beispiel:

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

>float(7.211102550928)
Boann
quelle
2

Julia, 45 Jahre alt

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

Hat den iTrick mit den to powers gestohlen . Außerdem haben alle Zeichen außer d Werte, die als akzeptable Potenzen für funktionieren i.

gggg
quelle
1

J 29 Zeichen

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

Dies funktioniert nur mit Kleinbuchstaben Richtungen und alle anderen Zeichen als r, u, l, und des wird dazu führen , eine falsche Antwort zu geben.

Verwendung:

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

Erläuterung:

'ruld'i.'uuuudrrrl'Die dyadische Form von i.findet den Index der Elemente aus dem rechten Argument im linken Argument. In diesem Fall:

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

/:~ sortiert diese Liste in aufsteigender Reihenfolge:

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

#/.~ zählt die Anzahl der Vorkommen jeder Zahl:

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

_2[\ schneidet es in 2 Reihen:

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

-/ subtrahiert die Unterseite von der Oberseite

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

+&.*:leiht sich einen Trick von einer anderen Antwort, die ich heute Morgen gesehen habe , und quadriert die Gegenstände, summiert sie dann und führt dann eine Quadratwurzel aus. Siehe unter&. Dokumentation:

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

+: verdoppelt das Ergebnis:

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

R, 86 74 56 Zeichen

Ok, es ist tatsächlich viel kürzer mit imaginären Zahlen:

2*Mod(sum(sapply(scan(,""),switch,u=1i,d=-1i,l=-1,r=1)))

Verwendung:

> 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

Alte Lösung bei 74 Zeichen mit xy-Koordinaten:

2*sqrt(sum(rowSums(sapply(scan(,""),switch,u=0:1,d=0:-1,l=-1:0,r=1:0))^2))

Verwendung:

> 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

Nimmt die Eingabe als stdin, muss klein geschrieben und durch Leerzeichen getrennt sein. Verwenden Sie xy-Koordinaten ab (0,0).

Plannapus
quelle
1

k ( 50 49)

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

Beispiel

{2*sqrt x$x:0 0f+/("udlr"!(1 0;-1 0;0 -1;0 1))@x}"uuuudrrrl"
7.211103
Skeevey
quelle
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);}}

Ich habe angenommen, dass jedes "U" "1 up" ist, also wären zwei Einheiten "UU"

Bearbeiten: Schalter gegen Wenn ausgetauscht

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

Für Iterator verschoben

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

Nimmt keine Eingabe mehr als Zeichenfolge, sondern als Array von Richtungen

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);}}
James Webster
quelle
Mein Verständnis für den Auftrag war, dass Sie nur eine Funktion benötigen, nicht ein ganzes Programm.
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))

Das @s ist die Eingabezeichenfolge vom Typ varchar (max)

duanxn
quelle
1

ES6, 77, 69

Definition:

f=s=>{u=d=l=r=0;for(c of s)eval(c+'++');return 2*Math.hypot(u-d,l-r)}

Verwendung:

>>> f('uuuudrrrl')
7.211102550927979
>>> f( 'uuuudrrrl'.split('') )
7.211102550927979
  • Akzeptiert Zeichenfolge ODER Array (Kleinbuchstaben)
  • Verwendet keine imaginären Zahlen
  • Wäre nur 3 Tage, bevor OP die Frage gestellt hat, nicht möglich gewesen ; Das heißt, es läuft nur in Firefox 27+ (und vielleicht auch in Chrome mit aktiviertem experimentellen Material, noch nicht getestet :) !!

(Teilweise inspiriert von Boanns Antwort.)

Noyo
quelle
Ich möchte wirklich etwas heikles tun, um die Rückgabe loszuwerden, wie das Ganze in einen booleschen Ausdruck zu verwandeln, der nur automatisch ausgewertet und zurückgegeben wird, aber ich bin mir nicht sicher, ob es einen Weg gibt, dies zu tun, es sei denn, ich kann die forAnweisung durch eine andere ersetzen Ausdruck (ein Pfeil Funktionskörper mit Anweisungen erfordert die Klammern und die explizite Rückgabe, Körper, die nur Ausdrücke sind, nicht) ..
Noyo
1

JavaScript - 142 Zeichen - keine Bewertung ()

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}

wo ist ein String wie 'uudrrl'

Verwenden Sie wie folgt -

a='uudrrl'
r(a)

Test in der Browserkonsole.

var x = "luluurrrrurd"
r(x)
8.48528137423857
rahulroy9202
quelle
1

C # - 90 Zeichen

Frisch von 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();

Wobei die Eingabe eine gültige Zeichenfolge ist.

>string input = "LULUURRRRURD";

>8.48528137423857
tdink
quelle
0

Befunge-93 (65)

Es hat 65 Nicht-Leerzeichen (217 mit Leerzeichen, obwohl dies durch ein kompakteres Layout (für 69/176 Zeichen) reduziert werden kann). Das Ausgabeformat erfordert eine gewisse Liberalität, ist jedoch unbestreitbar genau. Scheint die Mühe nicht wert zu sein, eine Quadratwurzelimplementierung zu implementieren / zu stehlen.

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

echo 'UUDLLUU' | ./befungee.py ../man Ausgänge 2√13 (tatsächlich scheint die Implementierung jedoch ein Problem mit dem erweiterten ASCII zu haben).

Joel Bosveld
quelle
0

Matlab, 51 Zeichen

Mein Matlab-Beitrag funktioniert nur mit Großbuchstaben. Das war ein Spaß! Am schwierigsten war es, die Zeichenfolge in ein Array komplexer Zahlen umzuwandeln, die summiert werden sollten.

Funktion:

f=@(s)abs(sum(fix((s-76.5)/8.5)+((s-79)*i/3).^-99))

Verwendung:

>> f=@(s)abs(sum(fix((s-76.5)/8.5)+((s-79)*i/3).^-99))
>> f('UURDL')
ans =

     1
>>
Hannesh
quelle
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
Xin
quelle
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)}

Beispiel:

<script>
document.write(f(['U', 'U', 'U', 'U', 'D', 'R', 'R', 'R', 'L']));
</script>

>7.211102550927978
Boann
quelle
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

warrenm
quelle
0

JavaScript (kein ES6, keine Auswertung) - 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}

Prüfung:

console.log(f('uuuudrrrl'));     // 7.211102550927978 
console.log(f('luluurrrrurd'));  // 8.48528137423857
iefserge
quelle