Я иду по Манхэттену, как далеко я от моего отеля?

27

Ненужная и запутанная история

Я гуляю по Манхэттену, блок за блоком, и мои ноги устали и хочу вернуться домой.

Движение довольно плохое, но, к счастью, я очень богат, и у меня есть вертолет в режиме ожидания в отеле. Но мне нужно, чтобы они знали, сколько топлива нужно собрать для полета, и для этого им нужно знать мое прямое расстояние от отеля. Я помню, по каким кварталам я ходил, и могу сказать им, по какому маршруту я пошел Это расстояние должно быть точным, хотя, если они слишком короткие, мы не вернемся слишком долго, и я купил топливо, которое не смогу использовать.

Можете ли вы написать мне программу, чтобы преобразовать это в расстояние, которое им придется путешествовать во время полета, чтобы забрать меня?

Спецификация:

Напишите мне функцию, которая:

  1. Принимает список или строку блоков, пройденных относительно произвольной сетки:
    • У р, Д собственное, л EFT и R РАВ.
    • Может быть в верхнем или нижнем регистре - например. если его короче использовать uвместо того, чтобы Uидти вперед.
    • Недопустимое направление имеет неопределенное поведение - например, направление X может вызвать сбой.
  2. Возвращает число с плавающей запятой / десятичное число / двойное число, которое в два раза больше расстояния по прямой линии от точки происхождения.

Для иллюстрации и пояснения:

Моя поездка

Моя поездка могла быть записана так же легко, как "luluu..."и, ['l','u','l'...]но она должна быть записана как Вверх, Вниз, Влево, Вправо.


источник
15
Вы достаточно богаты, чтобы иметь вертолет, но вам небезразлично, если купить дополнительное топливо? : O
Фес Враста
8
@fezvrasta, потому что я скуп.
7
Способ возиться с моей головой, не делая это о расстоянии Манхэттена.
Кендалл Фрей,
25
Правильный ответ: «Это не имеет значения. Ты богатый парень, поэтому ты лезешь в свой карман, достаешь пачку 20 долларов и машешь им в воздухе, чтобы привлечь внимание водителя; затем на группу бандитов из детского сада, которые грабят вас и избивают до кровавой мякоти, а затем вас арестовывают за мусор и публичное бродяжничество, обвиняют в терроризме за попытку вызвать массовую панику и пандемию, распространяя ваши телесные слизи по общественности тротуар, осужденный, в тюрьму, и заперли с сокамерником по кличке Брут , который берет реальную сильную симпатию к вам. Добро пожаловать в Нью - Йорк!»
Боб Джарвис - Восстановить Монику
2
@McKay Я все равно интерпретирую это как указания на карте (иначе это, вероятно, будет «вперед» и «назад»), и мера расстояния довольно однозначна, «вдвое больше расстояния по прямой линии от точки происхождения», поэтому нет Манхэттенское расстояние).
FireFly

Ответы:

32

J, 17 символов

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

Использует тот факт, что полномочия jпредставляют правильные направления.

  • 'urdl'i. взять строку и вычислить индексы (0 для «u», 1 для «r», ...)
  • 0j1^превращается в направлении в комплексной плоскости с использованием соответствующей степени j.
  • +/ подводит итоги отдельных шагов
  • 2*| два раза модуль

Пример:

> 2*|+/0j1^'urdl'i.'uuuudrrrl'
7.2111
Говард
источник
5
Хорошая работа. Математические знания для победы. :-)
Гарет
Сделайте этот «нерасширенный» ASCII, и тогда он будет всего 15 байтов (потому что вы не используете восьмой бит).
Timtech
11

Python 2,7 56 58 56 51 48

С украденной копейкой номер один от Скруджа Макдака я разбогател, и теперь у меня больше богатства, чем у Скруджа.

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

Python 2.7 - 61 53 50 (без учета регистра)

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

Реализация

>>> 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
источник
Я получаю IndexError: list index out of range. Какую форму должен иметь ввод?
plannapus
@plannapus: я добавил раздел реализации
Abhijit
Ах, и это %5не было %8. Хорошо, теперь это имеет смысл :)
plannapus
5

APL (29)

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

например

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

Объяснение:

  • +/'URDL'∘.=⍵: посмотрите, как часто символы URDLвстречаются в аргументе
  • -⌿2 2⍴: вычесть Uзначение из Dзначения, а Rзначение из Lзначения
  • 2 0j2×: умножить вертикальное значение на 2и горизонтальное значение на2i
  • +/: сумма
  • |: величина
Мэринус
источник
4

Рубин 1.9+ (67)

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

пример

f["DRUULULLULL"] => 10.0
f["UUUUDRRRL"] => 7.211102550927978
daniero
источник
3

perl6: 44 символа

2*abs [+] i <<**>>%(<U R D L>Z ^4){get.comb}
  • get.comb получает одну строку ввода и разбивается на символы
  • <U R L D> это список слов, символы в этом случае
  • (1,2,3) Z (4,5,6)== (1,2), (2,5), (3,6), поэтому он объединяет 2 списка друг в друга, создавая список посылок, который %()превращается в хеш
  • <<**>>делает попарно **, расширяя более короткий список, чтобы соответствовать длиннее. Короче список бывает толькоi
  • [+]суммирует все элементы списка, absпринимает модуль для комплексных чисел

Да, я удалил все возможные пробелы.

Ayiko
источник
2

Python 2.7 - 65

Хороший и короткий, он использует комплексные числа, чтобы пройти через плоскость:

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

Реквизиты для DSM и Abhijit в других вопросах, которые показали мне использование 1jдля вычисления этого.


источник
Можно 1jзаписать как j, -1jкак -j? Кроме того, это обрабатывает верхний и нижний ввод, или только верхний?
DavidC
1
Дядя Скруз , я ненавижу тебя. Вы должны хотя бы оставить немного денег для своих племянников.
Абхиджит
1
@DavidCarraher: Нет, ты не можешь. Было бы невозможно провести различие между переменной jи мнимой единицейj
Абхиджит
Разве вы не сказали, что он должен был вывести дважды больше расстояния? при попытке с UUUUDRRRL я получаю 3.606 с этой функцией вместо 7.21.
plannapus
4
Вы можете сохранить еще 2 символа, умножив константы 2вместо умножения конечного результата.
Абхиджит
2

Mathematica 92 49

Калле заслуживает полного уважения за упорядочение кода.

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

пример

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

7,2111

DavidC
источник
1
Вы делаете много работы, которая не требуется ОП, f@l_ := 2 N@Norm[Tr[l /. {"r" -> 1, "l" -> -1, "u" -> I, "d" -> -I}]]будет достаточно.
Я получаю 2 Norm[(2. + 2. I) + "U" + "X"]в качестве вывода для вашего кода.
DavidC
1
Да, но ОП говорит, что с таким вводом ничего не получится. Вот как я и все остальные интерпретируем это. Я не могу читать эти другие языки, но вы увидите, что они часто жестко кодируют u, r, l и d.
Хорошо. Понял. Спасибо что подметил это.
DavidC
Если вы замените две оставшиеся пары скобок на @s, вы получите еще на два символа меньше.
Shrx
2

PHP, 67

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

Пример:

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

>float(7.211102550928)
Boann
источник
2

Юлия, 45

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

Украл iуловку. Также все символы, кроме d, имеют значения, которые работают как допустимые полномочия i.

GGGG
источник
1

J, 29 символов

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

Работает только с более низкими направлениями дел и любыми другими символами , чем r, u, l, иd заставит его дать неправильный ответ.

Использование:

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

Объяснение:

'ruld'i.'uuuudrrrl'Диадическая форма i.находит индекс элементов из правого аргумента в левом аргументе. В этом случае:

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

/:~ сортирует этот список в порядке возрастания:

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

#/.~ подсчитывает количество вхождений каждого числа:

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

_2[\ нарезать его на 2 ряда:

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

-/ вычитает дно сверху

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

+&.*:заимствует трюк из другого J-ответа, который я видел сегодня утром , и возводит в квадрат элементы, затем суммирует их, затем выполняет квадратный корень. Смотрите в&. документации:

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

+: удваивает результат:

   +:+&.*:/-/_2[\#/.~/:~'ruld'i.'uuuudrrrl'
7.2111
Gareth
источник
1

R, 86 74 56 символов

Хорошо, это на самом деле намного короче с мнимыми числами:

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

Использование:

> 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

Старое решение на 74 символов с координатами xy:

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

Использование:

> 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

Принимает ввод как stdin, должен быть в нижнем регистре и через пробел. Используйте координаты xy, начиная с (0,0).

plannapus
источник
1

к ( 50 49)

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

пример

{2*sqrt x$x:0 0f+/("udlr"!(1 0;-1 0;0 -1;0 1))@x}"uuuudrrrl"
7.211103
skeevey
источник
1

Ява, 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);}}

Я предполагал, что каждое «U» было «1 вверх», поэтому на две единицы вверх будет «UU»

Редактировать: замена переключателя для 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);}}

Перемещено для итератора

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

Больше не воспринимает ввод как строку, а как массив направлений

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);}}
Джеймс Вебстер
источник
В моем понимании краткости было то, что вам нужна только функция, а не целая программа.
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 - это строка ввода типа varchar (max)

duanxn
источник
1

ES6, 77 69

Определение:

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

Использование:

>>> f('uuuudrrrl')
7.211102550927979
>>> f( 'uuuudrrrl'.split('') )
7.211102550927979
  • Принимает строку ИЛИ массив (нижний регистр)
  • Не использует мнимые числа
  • Было бы невозможно за 3 дня до того, как ОП разместил вопрос ; то есть он работает только в Firefox 27+ (и, возможно, также в Chrome с включенным экспериментальным материалом, не тестировал :) !!

(Отчасти вдохновлено ответом Боанна.)

Noyo
источник
Я действительно хочу сделать что-то хитрое, чтобы избавиться от возврата, например, превратить все это в логическое выражение, которое просто вычисляется и возвращается автоматически, но я не уверен, что есть способ сделать это, если я не смогу заменить forвыражение некоторым выражение (тело функции стрелки, содержащее операторы, требует скобок и явного возврата, тела, которые являются просто выражениями, не нужны) ..
Noyo
1

JavaScript - 142 символа - нет 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}

где a строка типа 'uudrrl'

использовать как это -

a='uudrrl'
r(a)

Тест в консоли браузера.

var x = "luluurrrrurd"
r(x)
8.48528137423857
rahulroy9202
источник
1

C # - 90 символов

Только что из 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();

Где input - допустимая строка.

>string input = "LULUURRRRURD";

>8.48528137423857
tdink
источник
0

Befunge-93 (65)

В нем 65 символов без пробелов (217 с пробелами, хотя это можно уменьшить с помощью более компактного макета (для 69/176 символов)). Это требует некоторой либеральности с форматом вывода, но, несомненно, является точным. Кажется, не стоит усилий по реализации / краже реализации с квадратным корнем.

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

echo 'UUDLLUU' | ./befungee.py ../man выводит 2√13 (хотя на самом деле реализация имеет проблемы с расширенным ASCII).

Джоэл Босвелд
источник
0

Matlab, 51 символов

Моя подача Matlab, работает только с заглавными буквами. Это было весело! Сложнее всего было преобразовать строку в массив комплексных чисел для суммирования.

Функция:

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

Использование:

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

     1
>>
Hannesh
источник
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
источник
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)}

Пример:

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

>7.211102550927978
Boann
источник
0

С, 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
источник
0

JavaScript (нет ES6, нет 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}

Тест:

console.log(f('uuuudrrrl'));     // 7.211102550927978 
console.log(f('luluurrrrurd'));  // 8.48528137423857
iefserge
источник