Sekwencja odległości na Manhattanie

9

Myślałem, że będzie to dobre wyzwanie: http://adventofcode.com/2016/day/1

Opis zadania

Biorąc pod uwagę sekwencję obrotów i odległości zgodnie ze wzorem (L | R) [1-9] [0-9] *, podaj manhattan odległość między punktem początkowym a końcowym, czyli minimalną liczbę ruchów w pionie i poziomie siatka.

Przykłady

Na przykład, jeśli założymy, że zacząłeś wychodzić na północ:

Po R2, L3 pozostawia ci 2 bloki na wschód i 3 bloki na północ lub 5 bloków dalej. R2, R2, R2 pozostawiają ci 2 bloki na południe od pozycji początkowej, która jest 2 bloki dalej. R5, L5, R5, R3 pozostawia ci 12 bloków.

Szczegóły techniczne

Możesz wybrać separator między ruchami (np .: „\ n”, „,” lub „,”). Musisz podać odpowiedź jako liczbę całkowitą w bazie 10.

Nie duplikat!

Nie jest to duplikat z wielu powodów:

  • Ruchy nie są takie same. Tutaj są rotacje , a nie kierunki.
  • Chcę odległości na Manhattanie, a nie euklidesa.
Labo
źródło
3
W pytaniu należy podać opis odległości na Manhattanie. Samo opublikowanie linku jest dość tandetne.
Gabriel Benamy,
2
To bardzo różne ! Mamy tylko rotacje!
Labo
1
@Labo Zgadzam się. Nie chodzi tylko o to, że odpowiedź jest tutaj w odległości na Manhattanie, podczas gdy druga jest w odległości euklidesowej. Ma to ruch w stylu żółwia, podczas gdy drugi określa kierunki kompasu NSEW (fakt, że nazywa je UDLR, nie ma znaczenia).
Level River St
2
Użyj Sandbox w przyszłości, aby uzyskać informacje zwrotne na temat swoich wyzwań, zanim opublikujesz je na głównej stronie.
Mego
2
@Labo W porządku, nie oczekujemy, że nowi użytkownicy od razu poznają wszystkie szczegóły tej witryny. To tylko delikatna sugestia na następny raz. :)
Mego

Odpowiedzi:

4

Python 3, 109 99 104 101 bajtów

Jest to prosta odpowiedź, która używa liczb zespolonych, z wejściem jako ciąg rozdzielany spacjami lub ciąg rozdzielany znakiem nowej linii. Zapraszamy do gry w golfa!

Edycja: -13 bajtów dzięki Labo. +5 bajtów do konwersji na liczbę całkowitą.

d=p=0
for r in input().split():d+=1-2*(r<'R');p+=1j**d*int(r[1:])
print(int(abs(p.real)+abs(p.imag)))

Ungolfing

def manhattan_rotation(seq, nsew=0, pos = 0):
    for rot in seq.split():
        # change direction
        if rot[0] == "L":
            nsew += -1 
        else:
            nsew += 1
        # move in that direction rot[1:] times
        pos += 1j ** nsew * int(rot[1:])
    return int(abs(pos.real)+abs(pos.imag))
Sherlock9
źródło
1-2 * (r [0] <'R') pozwoli Ci zaoszczędzić 2 bajty :)
Labo
Nie rób funkcji, czytanie z wejścia pozwala zaoszczędzić więcej znaków!
Labo,
Przypisz 2 zmienne w tym samym wierszu, aby zapisać 2 bajty: d = p = 0
Labo
Ponownie grałem w golfa twoją odpowiedź i daje 99 znaków! pastie.org/private/hm7lejqosdqnkgo000u7q
Labo
2
@Labo Nie jestem pewien, czy możesz edytować specyfikację w sposób, który unieważniałby istniejące odpowiedzi, ale pozwól, że zapytam o niektóre mody.
Sherlock9
2

PHP, 93 bajty

while($m=$argv[++$i])${chr(80|3&$d+=(P<$m)-(M>$m))}+=substr($m,1);echo abs($P-$R)+abs($Q-$S);

awaria

while($m=$argv[++$i])       // loop through arguments:
    ${                      // 5. use as variable name
        chr(                // 4. cast to character (P,Q,R,S) 
        80|                 // 3. add 80
        3&                  // 2. modulo 4
        $d+=(P<$m)-(M>$m)   // 1. change direction depending on letter
    )}+=substr($m,1);       // 6. add number to variable
echo abs($P-$R)+abs($Q-$S); // calculate distance, print
Tytus
źródło
2

Python 2, 86 bajtów

x=y=0
for d in input().split():c=cmp(d,'M');x,y=int(d[1:])-y*c,x*c
print abs(x)+abs(y)

Śledzi prąd xi ywspółrzędne. Podczas obracania zamiast aktualizować kierunek, obraca bieżącą wartość, dzięki czemu ruch jest zawsze w kierunku dodatnim x. Liczby zespolone były zbyt kosztowne, aby wyodrębnić współrzędne.

xnor
źródło
1

Python 2, 103 102 bajtów

l=c=0
for i in input().split():c+=cmp(i[0],'N');l+=1j**c*int(i[1:])
print int(abs(l.imag)+abs(l.real))

repl.it

Dane wejściowe to ciąg kierunków rozdzielanych spacjami, np "R5 L5 R5 R3".
Drukuje odległość Manhattanu między miejscem początkowym a miejscem docelowym.

W jaki sposób?

Zaczyna się od początku płaszczyzny złożonej l=0;

Z skumulowanej ćwierćfinałowym skręt w prawo blatu c=0;

Dla każdej instrukcji iobrót jest analizowany przez porównanie pierwszego znaku kierunku z znakiem 'N'i cjest odpowiednio dostosowywany.

Odległość do przebycia jest analizowana, int(i[1:])a instrukcja jest wprowadzana w życie, wykonując tyle kroków wielkości bloku w kierunku podanym, przyjmując cmoc 0+1jz 1j**c.

Ostateczna odległość na Manhattanie jest sumą absolutnych odległości od miejsca początkowego w dwóch kierunkach - urojonym i rzeczywistym; osiągnięte dziękiabs(l.imag)+abs(l.real)

Jonathan Allan
źródło
1
@ Sherlock9 - Och, zbieżność odpowiedzi. Zaoszczędź 2 bajty, przełączając się na Python 2 i używając cmppodobnej do mojej odpowiedzi, daj mi znać, a usunę.
Jonathan Allan,
0

JavaScript (ES2016), 98 100

2 bajty zaoszczędzone dzięki @Neil

d=>d.replace(/.(\d+)/g,(d,l)=>(o+=d>'M'||3,l*=~-(o&2),o&1?x-=l:y+=l),x=y=o=0)&&(x*x)**.5+(y*y)**.5

100 bajtów dla ES6

d=>d.replace(/.(\d+)/g,(d,l)=>(o+=d>'M'||3,l*=~-(o&2),o&1?x-=l:y+=l),x=y=o=0)&&(x>0?x:-x)+(y>0?y:-y)

Mniej golfa

d => d.replace(/.(\d+)/g,
  (d,l)=>( // L or R in d, distance in l
    o += d>'M' || 3, // orientation in o, used %4
    l *= ~-(o&2), // convert to number and change sign if needed
    o&1 ? x -= l : y += l // move based on orientation
  ), x = y = o = 0)
&& (x>0?x:-x) + (y>0?y:-y)

Test (ES6)

F=
d=>d.replace(/.(\d+)/g,(d,l)=>(o+=d>'M'||3,l*=~-(o&2),o&1?x-=l:y+=l),x=y=o=0)&&(x>0?x:-x)+(y>0?y:-y)

function update() {
  O.textContent=F(I.value)
}

update()
<input id=I value='R5, L5, R5, R3' oninput='update()'><pre id=O></pre>

edc65
źródło
1
Moja odpowiedź na ES6 wynosiła pierwotnie 106 bajtów; skopiowanie zmiennej pośredniej pozwoliło mi zaoszczędzić 3 bajty; przełączenie z dopasowania na zastąpienie pozwoliło mi zaoszczędzić 2 bajty, a jednoczesne skopiowanie przetwarzania i kierunku pozwoliło mi zaoszczędzić ostatni bajt, w wyniku czego: s=>s.replace(/.(\d+)/g,(c,n)=>(d+=c<'R'||3,n*=~-(d&2),d&1?x+=n:y+=n),x=y=d=0)&&(x<0?-x:x)+(y<0?-y:y)który jest teraz o dwa bajty krótszy niż odpowiedź ES6, dzięki c<'R'||3i n*=~-(d&2)sztuczkom .
Neil,