Di mana saya sekarang?

21

Di mana saya sekarang?

Diberikan string d, yang hanya berisi surat-surat NSWE, menentukan koordinat yang telah saya tempuh (dari kiri ke kanan, mengonsumsi rakus) dan koordinat terakhir tempat saya tinggal.

Aturan untuk membaca koordinat dari kiri ke kanan:

  • Jika karakter selanjutnya adalah NatauS :
    • Jika karakter setelah Natau Syang lain NatauS :
      • Hanya mengkonsumsi yang pertama Natau S.
      • Output [0,1] untukN
      • Output [0,-1]untukS
    • Jika karakter setelah Natau Sadalah WatauE :
      • Mengkonsumsi baik Natau Sdan Watau E.
      • Output [1,1]atau [-1,1]untuk NEdan NW, masing-masing.
      • Output [1,-1]atau [-1,-1]untuk SEdan SW, masing-masing.
  • Jika karakternya adalah Eatau Wtidak didahului oleh SatauN :
    • Mengkonsumsi Eatau W.
    • Output [1,0]untuk E.
    • Output [-1,0]untuk W.

Contoh yang berhasil

NSWE

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

Catatan ini bisa dalam format apa pun, berikut adalah contoh lain dari output yang valid:

[[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"

Dll ...


Lebih banyak contoh

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]

Aturan

  • Anda dapat menampilkan dalam format apa pun yang nyaman yang tidak melanggar celah.
  • Anda harus mengkonsumsi dengan rakus, NWEtidak pernah N,W,E, selalu NW,E.
    • Hal ini berlaku untuk: SW*, SE*, NW*, NE*.
    • Anda mengkonsumsi dari kiri ke kanan, rakus.
  • Ini adalah , byte-count terendah yang menang.
Guci Gurita Ajaib
sumber
"tentukan koordinat yang telah saya tempuh" : Saya tidak yakin apakah itu benar-benar cocok dengan apa yang dijelaskan sesudahnya. Ini lebih seperti "menentukan vektor semua gerakan saya" . Hanya hasil akhir yang merupakan koordinat aktual.
Arnauld
1
Sebuah test case yang berjalan ke [4, 3]atau lebih akan membuatnya sedikit lebih mudah untuk melihat apa yang terjadi pada output test.
Lynn
3
Apakah bilangan kompleks diformat sebagai 1, -1j, (-1+1j)dll format output yang valid?
Lynn
2
Berdasarkan tidak adanya kasus ini baik dalam aturan dan contoh yang diberikan saya menganggap input-String tidak akan pernah berakhir dengan 'N' atau 'S'?
Kevin Cruijssen
1
Apakah mengkonsumsi dengan rakus sebenarnya berbeda dari tidak? Karena NEhanya N+Etidak itu tidak masalah?
Wheat Wizard

Jawaban:

7

Python 2 , 116 byte

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

Cobalah online!

Dengan output sebagai [(3+4j), 1, -1j, …], 91 byte

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

Cobalah online!

Lambda ini mengembalikan daftar bilangan bulat Gaussian : yang pertama adalah koordinat terakhir, dan semua yang lain adalah langkah-langkah yang diperlukan untuk sampai di sana.

Lynn
sumber
5

Attache , 80 byte

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

Cobalah online!

Ini adalah fungsi anonim yang mengambil satu argumen string.

Penjelasan

Tugas pertama adalah mengimplementasikan fase parsing dari pertanyaan ini. Saya merasa terpendek untuk menggunakan Regex sederhana untuk mengurai input ( _):

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

Ini cocok dengan semua kemunculan regex [NS][WE]|., seperti terlihat pada banyak jawaban lainnya. Ini dengan rakus menghasilkan arah yang diminta.

Sekarang, kita akan menerapkan fungsi hash untuk setiap direciton. Kami mengambil codepoint dari setiap arah dan menjumlahkannya. Ini memberikan pemetaan berikut:

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

Kami akan mencoba memetakan nilai-nilai ini ke domain yang lebih kecil; modulo berguna untuk ini, dan kami dapat menunjukkan bahwa modulo terkecil yang menghasilkan nilai unik untuk semua input yang diberikan adalah 11. Mengurutkan berdasarkan sisa, ini memberi kita tabel berikut:

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

Sekarang, kami memiliki korespondensi input, sebagai penyandian oleh Sum@Ords=>[...]%11. Selanjutnya, kita harus mengubah sisa ini menjadi poin. Kami akan mencoba untuk menurunkan pemetaan lain, yang berarti memasukkan "nilai pengisian jarang" ke hash yang tidak sesuai dengan arah akan berguna:

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]

Saat ini kami memiliki serangkaian poin, yang dapat memberikan daftar diindeks oleh hash:

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

Sekarang, kita akan mengompres ini, mengingat bagaimana ini hanya terdiri dari -1s, 0s, dan 1s. Karena daftar mewakili pasangan, kami dapat meratakan daftar tanpa kehilangan data. Kemudian, jika kita mengambil setiap angka xdan menghitung 1-x, kita mendapatkan daftar berikut:

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

Kami dapat mengonversinya menjadi nomor basis 3:

20101101002212111102213

Konversi ke basis 10:

20101101002212111102213 ≡ 2226044618810

Untuk meringkas, kami telah mengambil poin kami, un-berpasangan, mengambil setiap elemen dikurangi 1, dan dikonversi dari basis 3, memberi kami 22260446188. Kita dapat mendekompres seperti itu:

  1. Konversikan ke basis 3: ToBase[22260446188,3]
  2. Ambil setiap angka yang dikurangi dari satu (terbalik sendiri): 1-ToBase[22260446188,3]
  3. Pasangkan kembali daftar: Chop[1-ToBase[22260446188,3],2]

Ini memberi kita set pasangan asli kita. Kemudian, kita dapat melakukan pengindeksan yang disebutkan di atas seperti ini:

(chopped value)[hashes]

Karena, di Attache, pengindeksan oleh array mengembalikan semua elemen yang sesuai dengan indeks tersebut. (Jadi [1,2,3,4][ [0,0,-1,1] ] = [1,1,4,2],.) Sekarang, kita memiliki arah jalan yang dilalui OP. Yang tersisa adalah menghitung jumlah.

Jadi kami menangkap hasil ini dalam lambda {...}dan menempatkannya sebagai fungsi pertama dalam komposisi fungsi ( a##b), dengan yang keduaV#Sum . Ini adalah garpu, yang, diberi input x, diperluas menjadi:

V[x, Sum[x]]

Sum, ketika diberi array 2D, terjadi untuk menjumlahkan setiap kolom dalam array (sebagai hasil penjumlahan vektor). Jadi, ini memasangkan arah dengan tujuan akhir, dan kami memiliki hasil akhir kami.

Conor O'Brien
sumber
4

JavaScript (ES6), 102 byte

Mengembalikan string.

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]

Cobalah online!

Arnauld
sumber
Saya suka menggunakan fungsi template! : D
Conor O'Brien
@ ConorO'Brien Ya, mereka sangat berguna di sini. Semua mantra sihir hashing yang aku panggil sejauh ini setidaknya sedikit lebih lama.
Arnauld
4

MATL , 45 byte

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

Cobalah online! Atau verifikasi semua kasus uji .

Penjelasan (dengan contoh)

Pertimbangkan input 'NSWE'sebagai contoh.

'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
sumber
4

Java (JDK 10) , 171 byte

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

Cobalah online!

Penjelasan

Berkat c=~-s[i]/6%4, pemetaan berikut dilakukan:

'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
  • NSdiperiksa dengan c<2dan dipetakan ke +1/ -1menggunakan 1-c*2;
  • EWdiperiksa dengan c>1dan dipetakan ke +1/ -1menggunakan c*2-5.

Kredit

Olivier Grégoire
sumber
Ah, Anda memposting jawaban Java Anda saat saya mengetik penjelasan saya. :) Karena kami berdua menggunakan pendekatan yang sama sekali berbeda, aku akan meninggalkan milikku untuk saat ini. Variabel yang terlalu buruk yang digunakan dalam lambdas harus final secara efektif, jika tidak, Anda bisa mengembalikan sebuah String alih-alih Daftar untuk menyimpan byte.
Kevin Cruijssen
Terima kasih, ini hanya menghemat beberapa byte (4), tetapi lebih baik daripada tidak sama sekali;)
Olivier Grégoire
@KevinCruijssen Terima kasih, pada awalnya tampak agak jelas, tetapi saya sedang mengerjakan pendekatan lain yang mengurangi jumlah byte saya lebih dari 30. Yang "parsing", bukan yang "cocok".
Olivier Grégoire
1
Huh .. 172 byte
Kevin Cruijssen
1
@KevinCruijssen Maaf, ini adalah kekacauan yang mengintegrasikan perubahan Anda ... Saya sedang bekerja dan saya lupa untuk me-refresh halaman ini ... Terima kasih untuk semua, ^^ 'Hitungan kredit sangat mungkin di bawah kredit Anda yang sebenarnya. Maaf untuk itu juga: s
Olivier Grégoire
3

Retina 0.8.2 , 93 byte

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

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

Cobalah online! Penjelasan:

.+
$&¶$&

Gandakan input.

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

Bagi salinan pertama menjadi arah.

G`.

Hapus garis kosong asing yang dibuat oleh proses di atas.

W
J

Ubah Wmenjadi Jsedemikian rupa sehingga antara Edan N. (Pindah Eke antara Sdan Wjuga akan bekerja.)

%O`.

Urutkan setiap baris ke dalam urutan.

+`EJ|NS

Hapus pasangan dari arah yang berlawanan (ini hanya mempengaruhi baris terakhir saja).

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

Hitung jumlah gerakan horisontal dan vertikal, tambahkan tanda jika perlu.

Anda yang mengetahui perbedaan antara Retina 0.8.2 dan Retina 1 ingin menunjukkan bahwa saya dapat menyimpan 2 byte di Retina 1 karena menggunakan *alih-alih $*. Sementara saya di sana saya mencoba untuk menyederhanakan proses pemisahan tetapi saya tidak dapat mengurangi jumlah byte lebih lanjut, saya hanya dapat menyamakannya dengan ini:

L$`$(?<=(.*))|[NS]?[EW]?
$&$1
Neil
sumber
3

Java 10, 269 265 243 byte

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

Jelas bukan bahasa yang tepat untuk tantangan ini ..

Cobalah online.

Penjelasan:

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
sumber
1
Jawaban Java mendapatkan poin karena semua orang mendapatkannya :).
Magic Gurita Guci
@MagicOctopusUrn Benar. :) Dan saya masih menikmati golf di Jawa, meskipun Anda tidak akan pernah menjadi yang terpendek .. Kecuali Anda satu-satunya yang menjawab (mendapat dua jawaban Java yang diterima .. XD). Namun untuk tantangan ini, jawaban Java oleh OlivierGrégoire adalah sekitar 70 byte lebih pendek, sehingga sebagian besar upvotes harus pergi kepadanya.
Kevin Cruijssen
2

Perl 5 -n , 94 byte

$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

Cobalah online!

Xcali
sumber
2

JavaScript (ES6), 102 byte

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

Mengembalikan string.

Neil
sumber
1

Ruby , 75 71 byte

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

Cobalah online!

-4 byte terima kasih kepada benj2240.

Karena mengembalikan bilangan kompleks tampaknya merupakan format output yang dapat diterima, saya kira itu tidak akan jauh lebih golf daripada hanya membuat port jawaban Lynn yang sangat bagus .

Kirill L.
sumber
Sangat bagus. Anda dapat menyimpan beberapa byte dengan melewatkan bagian dalam map, meneruskan bloknya secara langsung ke sum: Coba online!
benj2240
1

F # (Mono) , 269 byte

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]

Cobalah online!

Henrik Hansen
sumber
Hi, selamat datang untuk PPCG. Sayangnya Anda kehilangan item terakhir dari output Anda, yang seharusnya menjadi posisi di mana Anda berakhir. Jadi untuk NSWEAnda saat keluaran (0,1), (-1,-1), (1,0), tapi output keempat harus menjadi jumlah dari koordinat, sehingga (0,0)(karena 0+-1+1 = 0dan 1+-1+0 = 0).
Kevin Cruijssen
@KevinCruijssen OK, saya tidak menangkapnya. Membuat pembaruan.
Henrik Hansen
1
Tampaknya bekerja dengan baik sekarang, jadi +1 dari saya. Selamat menikmati! :) Dan jika Anda belum melihatnya, Tips untuk bermain golf di F # dan Tips untuk bermain golf di <semua bahasa> mungkin menarik untuk dibaca.
Kevin Cruijssen
1

sed, 125

The mengambil kebebasan dengan format output versi:

Skor termasuk +1 untuk -rparameter untuk 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

Cobalah online .

Output adalah sebagai berikut:

  • elemen koordinat dipisahkan oleh koma
  • setiap set koordinat dipisahkan oleh TAB
  • koordinat terakhir ada di jalur baru
  • semua nomor dalam ℤ-unary:
    • string Akarakter mewakili + ve integerlen(string)
    • serangkaian akarakter mewakili -ve integer-len(string)
    • mewakili string kosong 0

Sebagai contoh:

  • , adalah [0,0]
  • ,AA adalah [0,2]
  • aaa, adalah [-3,0]

sed 4.2.2 termasuk ekstensi GNU exec , 147

The masuk akal format output versi:

Skor termasuk +1 untuk -rparameter untuk 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

Output diberikan sebagai koordinat yang dipisahkan ruang, satu per baris. Ada baris baru ekstra antara kedua dari belakang dan set akhir dari koordinat - tidak yakin apakah itu bermasalah atau tidak.

Cobalah online!

Trauma Digital
sumber
0

PHP, 153 byte

biarkan regex melakukan pemisahan; mengulangi pertandingan, mencetak dan meringkas hasil antara:

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";

Jalankan sebagai pipa dengan -nRatau coba online .

Titus
sumber
0

C (gcc) , 173 byte

Sangat menarik melakukan ini dalam bahasa tanpa dukungan regex!

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

Cobalah online!

ErikF
sumber
164 byte
ceilingcat