Gdzie teraz jestem?

21

Gdzie teraz jestem?

Biorąc pod uwagę ciąg znaków d, zawierający tylko litery NSWE, określ współrzędne, które podróżowałem (od lewej do prawej, pochłaniając zachłannie) i ostateczną współrzędną, w której przebywam.

Reguły odczytu współrzędnych od lewej do prawej:

  • Jeśli następnym znakiem jest NlubS :
    • Jeśli znak po Nlub Sjest inny NlubS :
      • Spożywać tylko pierwszy Nlub S.
      • Wyjście [0,1] dlaN
      • Wyjście [0,-1]dlaS
    • Jeśli znak po Nalbo Sjest WalboE :
      • Spożywać oba Nlub Si Wlub E.
      • Dane wyjściowe [1,1]lub odpowiednio [-1,1]dla NEi NW.
      • Dane wyjściowe [1,-1]lub odpowiednio [-1,-1]dla SEi SW.
  • Jeśli znak jest Elub Wnie poprzedzone SlubN :
    • Spożywać Elub W.
    • Wyjście [1,0]dla E.
    • Wyjście [-1,0]dla W.

Przykład działania

NSWE

[0,1]   (North      N)
[-1,-1] (South-west SW)
[1,0]   (East       E)
[0,0]   (N+SW+E = Didn't actually move)

Uwaga: może to być dowolny format, oto inne przykłady prawidłowych danych wyjściowych:

[[0,1],[-1,-1],[1,0],[0,0]]


[[[0,1],[-1,-1],[1,0]],[0,0]]


"0,1\n0,-1\n-1,0\n1,0\n0,0"

Itp...


Więcej przykładów

SWSENNESWNE

[-1,-1]
[1,-1]
[0,1]
[1,1]
[-1,-1]
[1,1]
[1,0]

NNEESESSWWNW

[0,1]
[1,1]
[1,0]
[1,-1]
[0,-1]
[-1,-1]
[-1,0]
[-1,1]
[0,0]

NENENEE

[1,1]
[1,1]
[1,1]
[1,0]
[4,3]

NEN

[1,1]
[0,1]
[1,2]

EEE

[1,0]
[1,0]
[1,0]
[3,0]

Zasady

  • Możesz drukować w dowolnym dogodnym formacie, który nie narusza luk.
  • Musisz jeść łapczywie, NWEnigdy N,W,Enie jest, zawsze jest NW,E.
    • Dotyczy to: SW*, SE*, NW*, NE*.
    • Chciwie pochłaniasz od lewej do prawej.
  • Jest to , wygrywa najmniej bajtów.
Urna Magicznej Ośmiornicy
źródło
„określ współrzędne, które przejechałem” : nie jestem pewien, czy to naprawdę pasuje do tego, co opisano później. To bardziej jak „określ wektory wszystkich moich ruchów” . Tylko końcowy wynik to rzeczywiste współrzędne.
Arnauld
1
Przypadek testowy, który do niego podchodzi, [4, 3]ułatwiłby nieco zobaczenie, co się dzieje w wyniku testu.
Lynn
3
Są liczbami zespolonymi sformatowany jako 1, -1j, (-1+1j)etc poprawny format wyjściowy?
Lynn
2
Opierając się na braku tego przypadku zarówno w podanych regułach, jak i przykładach, zakładam, że ciąg wejściowy nigdy nie zakończy się na „N” lub „S”?
Kevin Cruijssen
1
Czy spożywanie zachłannie tak naprawdę jest inne niż nie? Bo NEczy to N+Enie powinno mieć znaczenia?
Kreator pszenicy,

Odpowiedzi:

7

Python 2 , 116 bajtów

import re
a=[(int(s,35)%5-3,('N'in s)-('S'in s))for s in re.findall('[NS][EW]?|.',input())]
print a,map(sum,zip(*a))

Wypróbuj online!

Z wyjściem jako [(3+4j), 1, -1j, …], 91 bajtów

lambda x:[sum(1j**(ord(c)%8%5)for c in s)for s in[x]+re.findall('[NS][EW]?|.',x)]
import re

Wypróbuj online!

Ta lambda zwraca listę liczb całkowitych Gaussa : pierwsza to ostatnia współrzędna, a wszystkie pozostałe to kroki niezbędne do jej osiągnięcia.

Lynn
źródło
5

Attache , 80 bajtów

V#Sum##{Chop[1-ToBase[22260446188,3],2][Sum@Ords=>MatchAll[_,/"[NS][WE]|."]%11]}

Wypróbuj online!

Jest to anonimowa funkcja, która pobiera jeden argument ciągu.

Wyjaśnienie

Pierwszym zadaniem jest wdrożenie etapu analizy tego pytania. Najkrótsze okazało się użycie prostego wyrażenia regularnego do analizy danych wejściowych ( _):

MatchAll[_,/"[NS][WE]|."]

To pasuje do wszystkich wystąpień wyrażenia regularnego [NS][WE]|., jak widać w wielu innych odpowiedziach. To łapczywie daje żądane wskazówki.

Teraz zastosujemy funkcję skrótu do każdego direcitonu. Bierzemy punkty kodowe każdego kierunku i sumujemy je. Daje to następujące mapowanie:

Direction       Ord-sum
E               69
N               78
S               83
W               87
NE              147
SE              152
NW              165
SW              170

Spróbujemy zmapować te wartości na mniejszą domenę; modulo jest do tego przydatne, a my możemy wykazać, że najmniejszym modułem, który daje unikalne wartości dla wszystkich podanych danych wejściowych, jest 11. Sortowanie według reszty, daje nam następującą tabelę:

Direction       Ord-sum         % 11
NW              165             0
N               78              1
E               69              3
NE              147             4
SW              170             5
S               83              6
SE              152             9
W               87              10

Teraz mamy korespondencję wejściową, jako kodowanie przez Sum@Ords=>[...]%11. Następnie musimy przekształcić te resztki w punkty. Postaramy się uzyskać inne mapowanie, co oznacza, że ​​przydatne będzie wstawienie „wartości wypełniania rzadkiego” do skrótów, które nie odpowiadają kierunkom:

Direction       Hash        Coordinates
NW              0           [-1, 1]
N               1           [0, 1]
--             (2)          [0, 0]
E               3           [1, 0]
NE              4           [1, 1]
SW              5           [-1, -1]
S               6           [0, -1]
--             (7)          [0, 0]
--             (8)          [0, 0]
SE              9           [1, -1]
W               10          [-1, 0]

Obecnie mamy szereg punktów, które mogą dać listę indeksowaną przez skrót:

[-1, 1] [0, 1] [0, 0] [1, 0] [1, 1] [-1, -1] [0, -1] [0, 0] [0, 0] [1, -1] [-1, 0]

Teraz skompresujemy to, widząc, jak składa się tylko z -1s, 0s i 1s. Ponieważ lista reprezentuje pary, możemy spłaszczyć listę bez utraty danych. Następnie, jeśli weźmiemy każdą liczbę xi obliczymy 1-x, otrzymamy następującą listę:

2 0 1 0 1 1 0 1 0 0 2 2 1 2 1 1 1 1 0 2 2 1

Możemy przekonwertować to na podstawową liczbę 3:

20101101002212111102213

Konwersja do bazy 10:

20101101002212111102213 ≡ 2226044618810

Podsumowując, wzięliśmy nasze punkty, sparowaliśmy je, wzięliśmy każdy element odejmowany 1i przekształcaliśmy z bazy 3, dając nam 22260446188. Możemy dekompresować jako taki:

  1. Konwertuj na bazę 3: ToBase[22260446188,3]
  2. Weź każdą liczbę odjętą od jednego (samo odwrotność): 1-ToBase[22260446188,3]
  3. Ponownie sparuj listę: Chop[1-ToBase[22260446188,3],2]

To daje nam nasz oryginalny zestaw par. Następnie możemy wykonać wyżej wymienione indeksowanie w następujący sposób:

(chopped value)[hashes]

Ponieważ w Attache indeksowanie według tablicy zwraca wszystkie elementy odpowiadające tym indeksom. (Tak więc [1,2,3,4][ [0,0,-1,1] ] = [1,1,4,2].) Teraz mamy wskazówki ścieżki, którą kroczył PO. Pozostało tylko obliczyć sumę.

Przechwytujemy więc ten wynik w lambda {...}i umieszczamy jako pierwszą funkcję w kompozycji funkcji ( a##b), przy czym drugą jest V#Sum. To jest rozwidlenie, które przy danych wejściowych xrozwija się jako:

V[x, Sum[x]]

Sum, gdy otrzyma tablicę 2D, sumuje każdą kolumnę w tablicy (w wyniku sumowania wektorowego). Tak więc łączy kierunki z ostatecznym miejscem docelowym i mamy nasz końcowy wynik.

Conor O'Brien
źródło
4

JavaScript (ES6), 102 bajty

Zwraca ciąg.

s=>s.replace(/[NS][EW]|./g,s=>(D=d=>!!s.match(d),x+=h=D`E`-D`W`,y+=v=D`N`-D`S`,[h,v]+`
`),x=y=0)+[x,y]

Wypróbuj online!

Arnauld
źródło
Lubię korzystać z funkcji szablonów! : D
Conor O'Brien
@ ConorO'Brien Tak, są tu całkiem przydatne. Wszystkie zaklęcia haszujące, które przywołałem do tej pory, są przynajmniej trochę dłuższe.
Arnauld
4

MATL , 45 bajtów

'NS' 'WE'Z*Z{2MhX{h'eklihfmj'X{YX9\3_2&YAqts

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .

Objaśnienie (z przykładem)

Rozważ dane wejściowe 'NSWE'jako przykład.

'NS' 'WE'  % Push these two strings
           % STACK: 'NS', 'WE'
Z*         % Cartesian product. Gives a 4×2 char matrix
           % STACK: ['NW'; 'NE'; 'SW'; 'SE']
Z{         % Cell array of rows (strings)
           % STACK: {'NW', 'NE', 'SW', 'SE'}
2M         % Push again the inputs of the second-last function call
           % STACK: {'NW', 'NE', 'SW', 'SE'}, 'NS', 'WE'
h          % Concatenate horizontally
           % STACK: {'NW', 'NE', 'SW', 'SE'}, 'NSWE'
X{         % Cell array of individual elements (chars)
           % STACK: {'NW', 'NE', 'SW', 'SE'}, {'N', 'S', 'W', 'E'}
h          % Concatenate horizontally
           % STACK: {'NW', 'NE', 'SW', 'SE', 'N', 'S', 'W', 'E'}
'eklihfmj' % Push this string
           % STACK: {'NW', 'NE', 'SW', 'SE', 'N', 'S', 'W', 'E'}, 'eklihfmj'
X{         % Cell array of individual elements (chars)
           % STACK: {'NW','NE','SW','SE','N','S','W','E'},{'e','k','l','i','h','f','m','j'}
YX         % Implicit input. Regexp replace: replaces 'NW' by 'e', then 'NE' by 'k', etc.
           % Note that the two-letter combinations are replaced first, which implements
           % the greediness; and the target letters do not appear in the source, which
           % avoids unwanted interactions between replacements
           % STACK: 'hlj'
9\         % Modulo 9 (of codepoints), element-wise
           % STACK: [5, 0, 7]
3_2&YA     % Convert to base 3 with 2 digits. Gives a 2-column matrix
           % STACK: [1, 2; 0, 0; 2, 1]
q          % Subtract 1, element-wise
           % STACK: [0, -1; -1, -1; 1, 0]
tXs        % Duplicate. Sum of each column
           % STACK: [0, -1; -1, -1; 1, 0], [0, 0]
           % Implicit display
Luis Mendo
źródło
4

Java (JDK 10) , 171 bajtów

s->{var r="";int i=0,l=s.length,c,x=0,y=0,Y,X;for(;i<l;X=c>1||i<l&&(c=~-s[i]/6%4)>1&&++i>0?c*2-5:0,r+=X+","+Y+" ",x+=X,y+=Y)Y=(c=~-s[i++]/6%4)<2?1-c*2:0;return r+x+","+y;}

Wypróbuj online!

Objaśnienia

Dzięki temu c=~-s[i]/6%4odbywa się następujące mapowanie:

'N' -> ascii: 78 -> -1 = 77 -> /6 = 12 -> %4 = 0
'S' -> ascii: 83 -> -1 = 83 -> /6 = 13 -> %4 = 1
'W' -> ascii: 87 -> -1 = 86 -> /6 = 14 -> %4 = 2
'E' -> ascii: 69 -> -1 = 68 -> /6 = 11 -> %4 = 3
  • NSjest sprawdzany c<2zi odwzorowywany na +1/ -1using 1-c*2;
  • EWjest sprawdzane za pomocą c>1i mapowane na +1/ -1using c*2-5.

Kredyty

Olivier Grégoire
źródło
Ach, opublikowałeś swoją odpowiedź Java, kiedy pisałem moje wyjaśnienie. :) Ponieważ oboje stosujemy zupełnie inne podejście, na razie zostawię moje. Szkoda, że ​​zmienne używane w lambdach muszą być skutecznie ostateczne, w przeciwnym razie mógłbyś zwrócić łańcuch zamiast listy, aby zapisać bajty.
Kevin Cruijssen
Dzięki, zaoszczędził tylko kilka bajtów (4), ale jest lepszy niż nic;)
Olivier Grégoire,
@KevinCruijssen Dzięki, na początku wydawało się to dość oczywiste, ale pracowałem nad innym podejściem, które zmniejszyło moją liczbę bajtów o ponad 30. „Analiza składniowa”, a nie „pasująca”.
Olivier Grégoire,
1
Westchnienie ... 172 bajty
Kevin Cruijssen
1
@KevinCruijssen Przepraszamy, to bałagan integrujący twoje zmiany ... Jestem zajęty pracą i zapomniałem odświeżyć tę stronę ... W każdym razie dziękuję ^^ 'Liczba punktów jest bardzo prawdopodobna poniżej rzeczywistej kwoty. Przepraszam również za to: s
Olivier Grégoire,
3

Retina 0.8.2 , 93 bajty

.+
$&¶$&
\G[NS]?[EW]?
$&¶
G`.
W
J
%O`.
+`EJ|NS

m`^((J)?[EJ]*)((S)?[NS]*)
$#2$*-$.1,$#4$*-$.3

Wypróbuj online! Wyjaśnienie:

.+
$&¶$&

Zduplikuj dane wejściowe.

\G[NS]?[EW]?
$&¶

Podziel pierwszą kopię na kierunki.

G`.

Usuń zbędne puste linie utworzone w powyższym procesie.

W
J

Zmień Wna, Jaby sortować pomiędzy Ei N. (Przejście Epomiędzy Si Wrównież by działało.)

%O`.

Sortuj każdą linię w kolejności.

+`EJ|NS

Usuń pary przeciwnych kierunków (wpływa to oczywiście tylko na ostatnią linię).

m`^((J)?[EJ]*)((S)?[NS]*)
$#2$*-$.1,$#4$*-$.3

Policz liczbę ruchów poziomych i pionowych, dodając znaki w razie potrzeby.

Ci z was, którzy znają różnice między Retina 0.8.2 i Retina 1, będą chcieli zaznaczyć, że mogę zapisać 2 bajty w Retina 1, ponieważ używa *zamiast niej $*. Podczas gdy tam byłem, próbowałem uprościć proces dzielenia, ale nie byłem w stanie dalej zmniejszyć liczby bajtów, byłem w stanie to zrównać z tym:

L$`$(?<=(.*))|[NS]?[EW]?
$&$1
Neil
źródło
3

Java 10, 269 265 243 bajtów

s->{var r="";int x=0,y=0,t,X,Y,a;for(;!s.isEmpty();r+=X+"|"+Y+" ",s=s.substring(++t),x+=X,y+=Y){a=s.charAt(t=0);if(s.matches("[SN][WE].*")){X=s.charAt(1)<70?1:-1;Y=1-a%2*2;t++;}else{X=a<70?1:a>86?-1:0;Y=a>69&a<87?1-a%2*2:0;}}return r+x+"|"+y;}

Zdecydowanie niewłaściwy język dla tego wyzwania.

Wypróbuj online.

Wyjaśnienie:

s->{                  // Method with String as both parameter and return-type
  var r="";           //  Result-String, starting empty
  int x=0,            //  Ending `x`-coordinate, starting at 0
      y=0,            //  Ending `y`-coordinate, starting at 0
      t,X,Y,a;        //  Temp-integers
  for(;!s.isEmpty()   //  Loop as long as the input-String is not empty yet
      ;               //    After every iteration:
       r+=X+"|"+Y+" ",//     Append the current steps to the result-String
       s=s.substring(t),
                      //     Remove the first `t` characters from the input-String
       x+=X,y+=Y){   //      Append the ending `x`,`y` coordinates with the steps
    a=s.charAt(0);   //    Set `a` to the first character of the input-String to save bytes
    t=1;             //    Set `t` to 1
    if(s.matches("[SN][WE].*")){
                     //   Else-if the input-String starts with N/S followed by E/W:
      X=s.charAt(1)<70?1:-1;
                     //    Set `X` to 1 if 'E', -1 if 'W'
      Y=1-a%2*2;     //    Set `Y` to 1 if 'N', -1 if 'S'
      t++;}          //    Increase `t` by 1
    else{            //   Else:
      X=a<70?1:a>86?-1:0;
                     //    Set `X` to 1 if 'E', -1 if 'W', 0 if 'N' or 'S'
      Y=a>69&a<87?1-a%2*2:0;}}
                     //    Set `Y` 1 if 'N', -1 if 'S', 0 if 'E' or 'W'
  return r+x+"|"+y;} //  Append the ending coordinates, and return the result-String
Kevin Cruijssen
źródło
1
Odpowiedzi Java zdobywają punkty, bo wszyscy je zdobywają :).
Magic Octopus Urn
@MagicOctopusUrn True. :) I nadal lubię grać w golfa w Javie, mimo że nigdy nie będziesz najkrótszy .. Chyba że jesteś jedyną osobą, która odpowiedziała (dostałem dwie zaakceptowane odpowiedzi Java .. XD). Jednak na to wyzwanie odpowiedź OlivieraGrégoire'a w języku Java jest o około 70 bajtów krótsza, więc większość entuzjastów powinna go skierować.
Kevin Cruijssen
2

Perl 5 -n , 94 bajtów

$x=$y=0;%X=qw/E ++ W --/;%Y=qw/N ++ S --/;s%(N|S)?(E|W)?%"say $X{$2}\$x.','.$Y{$1}\$y"if$&%gee

Wypróbuj online!

Xcali
źródło
2

JavaScript (ES6), 102 bajty

f=
s=>s.replace(/((N)|(S))?((E)|(W))?/g,(m,v,n,s,h,e,w)=>(x+=h=!w-!e,y+=v=!s-!n,m?[h,v]+`
`:[x,y]),x=y=0)
<input oninput=o.textContent=/[^NSEW]/.test(this.value)?``:f(this.value)><pre id=o>0,0

Zwraca ciąg.

Neil
źródło
1

Rubinowy , 75 71 bajtów

->x{[*x.scan(/[NS][EW]?|./),x].map{|s|s.chars.sum{|c|1i**(c.ord%8%5)}}}

Wypróbuj online!

-4 bajty dzięki benj2240.

Ponieważ zwracanie liczb zespolonych wydaje się być akceptowalnym formatem wyjściowym, myślę, że nie będzie dużo bardziej golfa niż tylko zrobienie portu bardzo ładnej odpowiedzi Lynn .

Kirill L.
źródło
Bardzo dobrze. możesz zaoszczędzić kilka bajtów, pomijając wewnętrzny map, przekazując jego blok bezpośrednio do sum: Wypróbuj online!
benj2240,
1

F # (mono) , 269 bajtów

let f s=
 let l,h=(string s).Replace("NW","A").Replace("NE","B").Replace("SW","C").Replace("SE","D")|>Seq.map(function 'N'->0,1|'S'->0,-1|'W'-> -1,0|'E'->1,0|'A'-> -1,1|'B'->1,1|'C'-> -1,-1|'D'->1,-1)|>Seq.mapFold(fun(x,y) (s,t)->(s,t),(x+s,y+t))(0,0)
 Seq.append l [h]

Wypróbuj online!

Henrik Hansen
źródło
Cześć, witamy w PPCG. Niestety brakuje ostatniego elementu wyjściowego, który powinien być miejscem, w którym zakończyłeś. Więc dla NSWEaktualnie wyprowadzanie (0,1), (-1,-1), (1,0), ale czwarte wyjście powinno być sumą tych współrzędnych, tak (0,0)(bo 0+-1+1 = 0a 1+-1+0 = 0).
Kevin Cruijssen
@KevinCruijssen OK, nie złapałem tego. Dokonano aktualizacji.
Henrik Hansen
1
Wygląda na to, że teraz działa świetnie, więc daj +1 ode mnie. Miłego pobytu! :) A jeśli jeszcze tego nie widziałeś, porady dotyczące gry w F # i wskazówki dotyczące gry w <wszystkie języki> mogą być interesujące do przeczytania.
Kevin Cruijssen
1

sed, 125

Korzystanie ze swobód w wersji formatu wyjściowego :

Wynik obejmuje +1 dla -rparametru do sed.

s/(N|S)(E|W)/\L\2,\1 /g
s/N|S/,& /g
s/E|W/&, /g
s/N|E/A/gi
s/S|W/a/gi
p
:
s/(\S*),(\S*) (\S*),(\S*)/\1\3,\2\4/
t
s/Aa|aA//
t

Wypróbuj online .

Dane wyjściowe są następujące:

  • elementy współrzędnych są oddzielone przecinkami
  • każdy zestaw współrzędnych jest oddzielony TAB
  • ostatnia współrzędna znajduje się na nowej linii
  • wszystkie liczby są w ary-unary:
    • ciąg Aznaków reprezentuje liczbę całkowitą + velen(string)
    • ciąg aznaków reprezentuje liczbę całkowitą -ve-len(string)
    • pusty ciąg reprezentuje 0

Na przykład:

  • , wynosi [0,0]
  • ,AA wynosi [0,2]
  • aaa, jest [-3,0]

sed 4.2.2, w tym rozszerzenie GNU exec , 147

Rozsądny format wersja:

Wynik obejmuje +1 dla -rparametru do sed.

s/(N|S)(E|W)/\L\2 \1\n/g
s/N|S/0 &\n/g
s/E|W/& 0\n/g
s/N|E/1/gi
s/S|W/-1/gi
p
:
s/(\S+) (\S+)\n(\S+) (\S+)/\1+\3 \2+\4/
t
s/\S+/$[&]/g
s/^/echo /e

Dane wyjściowe są podawane jako współrzędne rozdzielone spacjami, po jednym w wierszu. Istnieje dodatkowa nowa linia między przedostatnimi i ostatecznymi zbiorami współrzędnych - nie jestem pewien, czy jest to problematyczne, czy nie.

Wypróbuj online!

Cyfrowa trauma
źródło
0

PHP, 153 bajty

niech regex dokona podziału; przeglądaj mecze, drukuj i podsumowuj wyniki pośrednie:

preg_match_all("/[NS][EW]?|E|W/",$argn,$m);foreach($m[0]as$s){$x+=$p=strtr($s[-1],NEWS,1201)-1;$y+=$q=strtr($s[0],NEWS,2110)-1;echo"$p,$q
";}echo"$x,$y";

Uruchom jako potok z -nRlub spróbuj online .

Tytus
źródło
0

C (gcc) , 173 bajtów

Interesujące jest robienie tego w języku bez obsługi wyrażeń regularnych!

f(char*s){char*t="[%d,%d]\n";int x[4]={0},i;for(;*s;*x=x[1]=!printf(t,x[1],*x))for(i=-1;i<5;)if(*s=="S NW E"[++i]){x[i/3+2]+=x[i/3]=i%3-1;i+=2-i%3;s++;}printf(t,x[3],x[2]);}

Wypróbuj online!

ErikF
źródło
164 bajty
ceilingcat