나는 지금 어디에 있습니까?


21

나는 지금 어디에 있습니까?

d문자 만 포함 하는 문자열이 주어지면 NSWE내가 여행 한 좌표 (왼쪽에서 오른쪽으로 탐욕스럽게 소비)와 내가있는 최종 좌표를 결정합니다.

왼쪽에서 오른쪽으로 좌표를 읽는 규칙 :

  • 다음 문자 인 경우 N또는S :
    • 애프터 문자가있는 경우 N또는 S다른 있습니다 N또는S :
      • 첫 번째 N또는 만 사용하십시오 S.
      • 출력 [0,1] 에 대한N
      • 출력 [0,-1]에 대한S
    • N또는 뒤에있는 문자 SW또는E :
      • 모두 소비 NSWE.
      • 출력 [1,1]또는 [-1,1]for NENW.
      • 출력 [1,-1]또는 [-1,-1]for SESW.
  • 캐릭터는 경우 E또는 W가 선행되지 SN :
    • 소비 EW.
    • [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]

네네 니

[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*.
    • 당신은 탐욕스럽게 왼쪽에서 오른쪽으로 소비하고 있습니다.
  • 이것은 이며 가장 낮은 바이트 수입니다.

"내가 이동 한 좌표를 결정하십시오" : 나중에 설명 된 것과 실제로 일치하는지 확실하지 않습니다. "내 움직임의 벡터를 결정하는" 과 비슷 합니다. 최종 출력 만 실제 좌표입니다.
Arnauld

1
테스트 케이스로 [4, 3]이동하면 테스트 출력에서 ​​무슨 일이 일어나고 있는지 쉽게 알 수 있습니다.
Lynn

3
복잡한 숫자로 포맷 된 1, -1j, (-1+1j)등 유효한 출력 형식?
Lynn

2
주어진 규칙과 예제 모두 에서이 경우가 없으면 input-String이 절대 'N'또는 'S'로 끝나지 않는다고 가정합니다.
Kevin Cruijssen

1
탐욕스럽게 소비하는 것이 실제로 그렇지 않은 것과 다른가? 이후로는 NE그냥 N+E그것은 중요하지하지 않겠습니까?
밀 마법사

답변:


7

파이썬 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

첨부 , 80 바이트

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

온라인으로 사용해보십시오!

이것은 하나의 문자열 인수를 취하는 익명 함수입니다.

설명

첫 번째 과제는이 질문의 파싱 단계를 구현하는 것입니다. 입력 ( _) 을 구문 분석하기 위해 간단한 Regex를 사용하는 것이 가장 짧았습니다 .

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

이것은 [NS][WE]|.많은 다른 답변에서 볼 수 있듯이 모든 정규식 발생과 일치합니다 . 이것은 탐욕스럽게 요청 된 지시를 산출합니다.

이제 우리는 각 direciton에 해시 함수를 적용 할 것입니다. 우리는 각 방향의 코드 포인트를 가져와 합산합니다. 이것은 다음과 같은 매핑을 제공합니다.

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

요약하면, 우리는 우리의 요점을 취하고, 짝을 이루지 않았고, 각 요소를 빼고 1base 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].) 이제, 우리는 OP 걸어 그 경로의 방향이있다. 남은 것은 합계를 계산하는 것입니다.

따라서 우리는이 결과를 람다로 캡처 {...}하고 함수 구성 ( a##b) 의 첫 번째 함수로 두 번째를 씁니다 V#Sum. 이것은 입력 x이며 , 다음 과 같이 확장 되는 포크입니다 .

V[x, Sum[x]]

Sum는 2D 배열이 주어지면 배열의 모든 열을 합산합니다 (벡터화 된 합산의 결과). 따라서 이것은 최종 목적지와 길 찾기를 연결하며 최종 결과를 얻습니다.


4

자바 스크립트 (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 그래, 여기가 꽤 편리하다. 내가 지금까지 소환 한 모든 해싱 마법 주문은 조금 더 길다.
Arnauld

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

자바 (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 답변을 게시했습니다. :) 우리는 완전히 다른 접근법을 사용하기 때문에 지금은 내 것을 떠날 것입니다. 람다에 사용 된 너무 나쁜 변수는 효과적으로 최종이어야합니다. 그렇지 않으면 바이트 대신 저장하기 위해 List 대신 String을 반환 할 수 있습니다.
Kevin Cruijssen

고마워, 그것은 단지 몇 바이트 (4)를 절약하지만, 아무것도보다 낫다;)
올리비에 그레고리 르

@KevinCruijssen 고마워, 처음에는 다소 명백해 보였지만 바이트 수를 30 이상 줄이는 또 다른 접근법을 연구하고있었습니다. "일치하는"것이 아니라 "파싱하는 것"입니다.
Olivier Grégoire


1
@KevinCruijssen 죄송합니다. 변경 사항을 통합하는 엉망입니다 ... 직장에서 일을했는데이 페이지를 새로 고침하는 것을 잊었습니다 ... 어쨌든 고맙습니다 ^^ '크레딧 수는 실제 크레딧보다 낮습니다. 그것도 죄송합니다 : s
Olivier Grégoire

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사이에 SW도 작업을합니다.)

%O`.

각 줄을 순서대로 정렬하십시오.

+`EJ|NS

반대 방향 쌍을 삭제합니다 (마지막 줄에만 영향을 미침).

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

수평 및 수직 이동 횟수를 세어 필요한 곳에 표시를 추가하십시오.

Retina 0.8.2와 Retina 1의 차이점을 알고있는 사람들은 *대신 Retina 1에서 2 바이트를 절약 할 수 있음을 지적하고 싶을 것입니다 $*. 내가 거기있는 동안 분할 프로세스를 단순화하려고했지만 바이트 수를 더 줄일 수는 없었지만 다음과 같이 할 수있었습니다.

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

3

자바 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 답변은 모두가 점수를 얻지 만 점수를 얻습니다. :).
Magic Octopus Urn

@MagicOctopusUrn True. :) 그리고 나는 당신이 가장 짧은 결코 아니지만 Java에서 골프를 즐기고 있습니다. 그러나이 문제에 대해 OlivierGrégoire의 Java 답변은 약 70 바이트 더 짧으므로 대부분의 공감대가 그에게 가야합니다.
Kevin Cruijssen


2

자바 스크립트 (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)}}}

온라인으로 사용해보십시오!

benj2240 덕분에 -4 바이트.

복소수를 반환하는 것은 허용 가능한 출력 형식 인 것처럼 보이므로 아주 멋진 Lynn의 답변 포트를 만드는 것보다 골퍼가되지는 않을 입니다.


아주 좋아요 내부를 건너 뛰고 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)하지만 4 출력 정도로 그 좌표의 합이어야한다 (0,0)(인해 0+-1+1 = 0하고 1+-1+0 = 0).
Kevin Cruijssen

@KevinCruijssen 좋아, 나는 그것을 잡지 않았다. 업데이트했습니다.
Henrik Hansen

1
지금은 잘 작동하는 것 같습니다. +1 체류를 즐길 수! :) 그리고 아직 보지 못한 경우 F # 에서 골프 팁<모든 언어>에서 골프 팁 을 읽는 것이 흥미로울 수 있습니다.
Kevin Cruijssen

1

sed, 125

출력 형식으로 복용 자유 버전 :

점수 -r를 매길 매개 변수에 +1이 포함됩니다 .

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

온라인으로 사용해보십시오 .

출력은 다음과 같습니다.

  • 좌표 요소는 쉼표로 구분됩니다
  • 각 좌표 세트는 탭으로 구분됩니다.
  • 최종 좌표는 새로운 라인에 있습니다
  • 모든 숫자는 un 단항입니다.
    • 문자열은 A+ ve 정수를 나타냅니다.len(string)
    • 문자열은 a-ve 정수를 나타냅니다.-len(string)
    • 빈 문자열은 0

예를 들면 다음과 같습니다.

  • , [0,0]입니다
  • ,AA [0,2]입니다
  • aaa, [-3,0]입니다

sed 4.2.2 GNU exec 확장명 포함 , 147

분별 출력 포맷 버전 :

점수 -r를 매길 매개 변수에 +1이 포함됩니다 .

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하거나 온라인으로 사용해보십시오 .


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.