Де я зараз?


21

Де я зараз?

Давши рядок d, що містить лише літери NSWE, визначте координати, якими я подорожував (зліва направо, жадібно споживаючи) та кінцеву координату, де я проживаю.

Правила зчитування координат зліва направо:

  • Якщо наступним символом є NабоS :
    • Якщо персонаж після Nабо Sє іншим NабоS :
      • Споживайте лише перший Nабо S.
      • Вихід [0,1] дляN
      • Вихід [0,-1]дляS
    • Якщо символ після Nабо Sє WабоE :
      • Споживайте як Nабо, так Sі Wабо E.
      • Вихід [1,1]або [-1,1]для NEі NW, відповідно.
      • Вихід [1,-1]або [-1,-1]для SEі SW, відповідно.
  • Якщо символ є Eабо Wне передує SабоN :
    • Споживайте Eабо W.
    • Вихід [1,0]для E.
    • Вихід [-1,0]для W.

Приклад роботи

NSWE

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

Зверніть увагу, це може бути в будь-якому форматі, ось інші приклади дійсного виводу:

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

І т.д. ...


Більше прикладів

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]

Правила

  • Ви можете виводити в будь-якому зручному форматі, який не порушує лазівки.
  • Ви повинні споживати жадібно, NWEніколи N,W,E, це завжди NW,E.
    • Це відноситься до: SW*, SE*, NW*, NE*.
    • Ви спокійно споживаєте зліва направо.
  • Це , виграє найменший байт.

"визначте координати, якими я подорожував" : я не впевнений, чи відповідає це дійсно описаному згодом. Це більше схоже на "визначте вектори всіх моїх рухів" . Тільки кінцевий вихід - це фактичні координати.
Арнольд

1
Тестовий випадок, який ходить до цього [4, 3]чи іншого, полегшив би побачити, що відбувається у вихідному тесті.
Лінн

3
Чи складні числа форматуються як 1, -1jі (-1+1j)т.д., дійсний вихідний формат?
Лінн

2
Виходячи з відсутності цього випадку і в наведених правилах, і в прикладах, я припускаю, що введення String ніколи не закінчиться на "N" або "S"?
Кевін Круїйсен

1
Чи споживає жадібність насправді інше, ніж ні? Оскільки NEце просто N+Eне повинно мати значення?
Пшеничний майстер

Відповіді:


7

Python 2 , 116 байт

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

Спробуйте в Інтернеті!

З виходом як [(3+4j), 1, -1j, …], 91 байт

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

Спробуйте в Інтернеті!

Ця лямбда повертає список цілих чисел Гаусса : перше - це кінцева координата, а всі інші - кроки, необхідні для того, щоб потрапити туди.


5

Attache , 80 байт

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

Спробуйте в Інтернеті!

Це анонімна функція, яка бере один аргумент рядка.

Пояснення

Перше завдання - реалізувати етап розбору цього питання. Я вважаю найкоротшим використання простого Regex для розбору вводу ( _):

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

Це відповідає всім явищам виразів [NS][WE]|., як це видно в багатьох інших відповідях. Це жадібно дає запитувані вказівки.

Тепер ми будемо застосовувати хеш-функцію до кожного директора. Беремо кодові точки кожного напрямку та підсумовуємо їх. Це дає таке відображення:

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

Спробуємо відобразити ці значення в меншій області; модуль для цього корисний, і ми можемо продемонструвати, що найменший модуль, який призводить до унікальних значень для всіх заданих входів, становить 11. Сортування за залишками, це дає нам наступну таблицю:

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

Тепер ми маємо вхідну кореспонденцію як кодування за Sum@Ords=>[...]%11. Далі ми повинні перетворити ці залишки в точки. Ми спробуємо отримати інше відображення, яке означає, що введення "значень розрідженого заповнення" в хеші, які не відповідають вказівкам, буде корисним:

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]

Наразі у нас є ряд точок, які можуть дати список, індексується хешем:

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

Тепер ми будемо стискати це, бачачи, як складається лише його -1s, 0s та 1s. Оскільки список представляє пари, ми можемо вирівняти список, не втрачаючи даних. Потім, якщо взяти кожне число xі обчислити 1-x, ми отримаємо такий список:

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

Ми можемо перетворити це в базове 3 число:

20101101002212111102213

Перетворення на базу 10:

20101101002212111102213 ≡ 2226044618810

Підводячи підсумок, ми взяли наші пункти, з'єднали їх, взяли кожен елемент, який віднімали 1, і перетворили з бази 3, давши нам 22260446188. Ми можемо декомпресувати як таке:

  1. Перетворити в базу 3: ToBase[22260446188,3]
  2. Візьміть кожне число, віднімане від одного (самообернене): 1-ToBase[22260446188,3]
  3. Перепаріруйте список: Chop[1-ToBase[22260446188,3],2]

Це дає нам наш оригінальний набір пар. Тоді ми можемо виконати вищезгадане індексування так:

(chopped value)[hashes]

Оскільки в Attache індексація масивом повертає всі елементи, що відповідають цим індексам. (Отже,. [1,2,3,4][ [0,0,-1,1] ] = [1,1,4,2]) Тепер ми маємо напрямки шляху, яким пройшла ОП. Залишилося розрахувати суму.

Отже, ми фіксуємо цей результат у лямбда {...}і ставимо його як першу функцію у складі функції ( a##b), а друга є V#Sum. Це виделка, яка, враховуючи введення даних x, розширюється як:

V[x, Sum[x]]

Sum, коли дається 2D масив, трапляється підсумовувати кожен стовпець у масиві (в результаті векторизованого підсумовування). Отже, це поєднує напрямки з кінцевим пунктом призначення, і ми маємо свій остаточний результат.


4

JavaScript (ES6), 102 байти

Повертає рядок.

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]

Спробуйте в Інтернеті!


Мені подобається використання функцій шаблону! : D
Conor O'Brien

@ ConorO'Brien Так, вони тут дуже зручні. Усі чарівні чарівні чари, які я закликав до цього часу, принаймні трохи довші.
Арнольд

4

MATL , 45 байт

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

Спробуйте в Інтернеті! Або перевірити всі тестові випадки .

Пояснення (з прикладом)

Розглянемо вклад 'NSWE'як приклад.

'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

4

Java (JDK 10) , 171 байт

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

Спробуйте в Інтернеті!

Пояснення

Завдяки c=~-s[i]/6%4, зроблено наступне відображення:

'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
  • NSперевіряється c<2і відображається +1/ -1використовується для використання 1-c*2;
  • EWперевіряється c>1і відображається на +1/ -1використовує c*2-5.

Кредити


Ах, ви написали свою відповідь на Java, поки я набирав свої пояснення. :) Оскільки ми обидва використовуємо зовсім інший підхід, я покину мою. Занадто погані змінні, що використовуються в лямбдах, повинні бути ефективно остаточними, інакше ви могли б повернути рядок замість списку для збереження байтів.
Кевін Кройсейсен

Спасибі, це врятувало лише кілька байтів (4), але це краще, ніж нічого;)
Олів'є Грегоар

@KevinCruijssen Спасибі, спочатку це здавалося доволі очевидним, але я працював над іншим підходом, який скоротив міркування байтів більш ніж на 30. "Розбір" одного, а не "відповідний".
Олів'є Грегоар


1
@KevinCruijssen Вибачте, це неприємність, що інтегрує ваші зміни ... Мене взяли на роботу, і я забуваю оновити цю сторінку ... Дякую за все-таки ^^ 'Кількість кредитів, швидше за все, нижче вашого фактичного кредиту. Вибачте і за це: s
Олів'є Грегоар

3

Сітківка 0,8,2 , 93 байти

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

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

Спробуйте в Інтернеті! Пояснення:

.+
$&¶$&

Скопіюйте введення.

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

Розділіть перший примірник на напрямки.

G`.

Видаліть сторонні порожні рядки, створені вищевказаним процесом.

W
J

Перейдіть Wна Jтак, щоб він сортував між Eі N. (Перехід Eміж ними, Sа Wтакож працюватиме.)

%O`.

Сортуйте кожен рядок у порядку.

+`EJ|NS

Видаліть пари протилежних напрямків (це стосується лише останнього рядка курсу).

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

Порахуйте кількість горизонтальних і вертикальних рухів, додаючи знаки, де це необхідно.

Ті з вас, хто знає відмінності між Retina 0.8.2 та Retina 1, хочу сказати, що я можу зберегти 2 байти в Retina 1, оскільки він використовує *замість $*. Поки я був там, я намагався спростити процес розбиття, але мені не вдалося далі зменшити кількість байтів, я міг лише зрівнятись із цим:

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

3

Java 10, 269 265 243 байт

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

Однозначно не потрібна мова для цього завдання.

Спробуйте в Інтернеті.

Пояснення:

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

1
Відповіді Java отримують бали, хоча всі отримують їх :).
Чарівна восьминога урна

@MagicOctopusUrn Правда. :) І мені все одно подобається гольф на Java, навіть якщо ти ніколи не будеш найкоротшим. Якщо тільки ти єдиний не відповів (отримав два прийнятих відповіді на Java .. XD). Однак на цей виклик відповідь Java від OlivierGrégoire приблизно на 70 байт коротша, тому більшість оновлених даних повинні надходити до нього.
Кевін Кройсейсен


2

JavaScript (ES6), 102 байти

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

Повертає рядок.


1

Рубін , 75 71 байт

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

Спробуйте в Інтернеті!

-4 байти завдяки benj2240.

Оскільки повернення складних чисел виглядає як прийнятний вихідний формат, я думаю, що він не отримає багато гольфіста, ніж просто зробити порт дуже гарної відповіді Лінни .


Дуже хороша. Ви можете зберегти кілька байт, пропустивши внутрішній map, передавши його блок безпосередньо sum: Спробуйте в Інтернеті!
benj2240

1

F # (моно) , 269 байт

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]

Спробуйте в Інтернеті!


Привіт, Ласкаво просимо до PPCG. На жаль, вам не вистачає останнього пункту вашого результату, який повинен бути позицією, де ви закінчилися. Так що для NSWEвас в даний момент виводиться (0,1), (-1,-1), (1,0), а четвертий вихід повинен бути сума цих координат, тому (0,0)(тому 0+-1+1 = 0і 1+-1+0 = 0).
Кевін Круїссен

@KevinCruijssen Добре, я цього не зрозумів. Зробив оновлення.
Генрік Хансен

1
Зараз, здається, працює чудово, тому +1 від мене. Насолодитися перебуванням! :) І якщо ви цього ще не бачили, Поради щодо гольфу у F # та Поради щодо гольфу на <всіх мовах> можуть бути цікавими для прочитання.
Кевін Круїссен

1

sed, 125

У вольності з форматом виведення версії:

Оцінка включає +1 для -rпараметра 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

Спробуйте в Інтернеті .

Вихід такий:

  • елементи координат розділені комами
  • кожен набір координат розділений TAB
  • остаточна координата знаходиться на новій прямій
  • усі числа є ℤ-унарними:
    • рядок A символів представляє ціле число + velen(string)
    • рядок a символів представляє ціле число -ve-len(string)
    • порожній рядок являє собою 0

Наприклад:

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

sed 4.2.2, включаючи розширення GNU exec , 147

Розумний формат виведення версії:

Оцінка включає +1 для -rпараметра 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

Вихідні дані задаються у вигляді розділених пробілом координат, по одному на рядок. Між передостанньою та кінцевою множинами координат є додаткова нова лінія - не впевнений, проблематично це чи ні.

Спробуйте в Інтернеті!


0

PHP, 153 байти

нехай регулярний вираз робить розщеплення; прокручуйте сірники, друкуйте та підсумовуйте проміжні результати:

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

Запустіть як трубу -nRабо спробуйте в Інтернеті .


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.