빔이 맞습니까?


31

레이저는로 표시된 네 개의 직교 방향 중 하나로 직선 빔을 촬영합니다 <>^v. O직사각형 그리드 에서 대상 을 칠 것인지 결정합니다 .

이들 각각은 (참)에 도달합니다.

.....
...O.
.....
...^.
.....

>O.
...

v....
O....

...........
...........
O.........<
...........

이것들은 (False) 놓칠 것입니다 :

......
......
.^..O.

......
.....>
O.....
......
......


.O.
...
.v.

.....<.
..O....

입력 :. 크기가 2x2 이상인 직사각형 그리드로 , 정확히 하나의 대상 O과 하나의 레이저로 구성 <>^v됩니다. 줄은 문자열 목록, 2D 배열 또는 중첩 된 문자 목록 또는 선택적인 후행 줄 바꿈이있는 단일 줄 바꿈으로 구분 된 문자열 일 수 있습니다.

출력 : 레이저 빔이 목표물에 부딪 치면 일관된 진실한 값, 그리고 놓치면 일관된 거짓 값

정규 표현식 (또는 내장 패턴 기반 문자열 일치)을 별도의 범주로 사용하지 않는 제출을 고려할 것입니다. 당신이 넣으면 (no regex)언어 이름 뒤에, 당신의 대답은 리더 보드에 별도로 표시됩니다.



6
나는 당신이 거울을 포함 할 것 기대했다 /하고 \ . 다른 질문이있을 수도 있습니다.
vsz

2
@Mego ...이 도전은 훨씬 간단하고 매우 다른 접근 방식을 허용합니다.
Martin Ender

2
@Mego 동의하지 않습니다. 이러한 논리에 따르면 일반 Hello World 과제는 동시에 수십 가지 다른 과제와 중복됩니다. 어쨌든, 이제 코드 골프 과제를 닫거나 다시 열어야하는 힘에 대해 알려 주셔서 감사합니다.
aditsu

5
@ Mego이 질문은 다른 질문의 특별한 경우이지만 답변이 완전히 다른 접근법을 사용하기 때문에 속임수라고 생각하지 않습니다. 이 질문에서 그들은 모두 광선이 걸리는 경로를 계산합니다. 포털은 경로를 어디에서나 지름길로 이동할 수있는 곳으로 이동할 수 있으며 반사기는 다루기가 까다 롭습니다. 여기에 대한 답변은 대부분 입력 문자열의 일부 속성을 확인하거나 일치시킵니다. 물론, 다른 챌린지에서 경로 추적 답변을 복사하고 추가 비트를 제거 할 수 있지만이 방법은 너무 과도하며 불필요한 솔루션을 제공합니다.
xnor

답변:


27

달팽이 , 19 바이트

\>|\<l|\^u|\vd).,\O

이것에 대한 사양은 가능한 한 문자 그대로 구현 될 수 있으며 생각할 필요가 없습니다.


6
작동 방식에 대한 설명을 추가 할 수 있습니까?
기금 모니카의 소송

5
@QPaysTaxes feersum이 다가올 때까지 이것이 도움이 될 것입니다. 달팽이는 2D 패턴 일치 언어입니다. udlr달팽이의 방향을 위 / 아래 / 왼쪽 / 오른쪽으로 설정하십시오. |정규 정규식에서와 같이 작동 )하며 일치하는 열린 괄호가 필요하지 않습니다. 따라서 코드는 "중 하나를 찾아서 v<>^방향을 적절하게 설정 한 다음 해당 방향으로 O를 찾으십시오 "로 직접 변환됩니다 .
FryAmTheEggman

그래, 에그 맨이 한 말 유일한 다른 것은 정규식 ,과 같습니다 *.
feersum

13

레티 나, 56 52 42 38 31 30 바이트

@ MartinBüttner 덕분에 1 바이트 절약

O.*<|>.*O|[vO](.*¶)[^O]*[O^]\1

사각형의 속성을 남용합니다. 입력에 후행 줄 바꿈이 있어야합니다.

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

설명

이것은 세 부분으로 작동합니다.

  • 어울리는 >
  • 어울리는 <
  • 일치 ^v의 논리 때문입니다 ^그리고 v, 정말 문자 동일합니다.

검증 <

이것은 간단하다 :

O.*<

이것은 O선택적으로 개행 문자 이외의 문자 와 일치 하고<

검증 >

이것은 다른 방법을 제외하고는 이전 방법과 거의 동일합니다. 먼저 a >가 일치하고O

검증 ^v

이것은 골프하기가 어려웠으며 항상 유효한 입력을 광고했습니다. 먼저, 우리는 그것이이든 v또는 O:

[vO]

인 경우 ^첫 번째 문자는 O입니다. 따라서 이것은 일치하는 첫 번째 문자와 일치합니다. 다음으로 .개행까지 s 의 양을 계산합니다 .

(.*\n)

다음으로 두 부분으로 나눌 수 있습니다. 첫 번째 부분을 다룰 것입니다.

먼저 다음 O을 사용하여 다음과 일치합니다 .

[^O]*O

이것은 선택적으로 Oa O가 나타날 때까지 모든 비 문자 와 일치합니다. 성공하면 계속되고 ... 그렇지 않으면 다음이 발생합니다.

이제 다음을 ^사용하여 찾으려고 시도합니다 .

[^^]*\^

^정규 표현식의 특수 문자이므로 이스케이프해야합니다. [^^]를 제외한 모든 문자와 일치 ^하며 위와 동일하게 작동하며, 성공하면 다음과 같은 일이 발생합니다.

이제 위 중 하나가 성공적으로 일치 \1하는지 확인하고 이전의 캡처 그룹 이 있는지 확인 (.*\n)하고이 캡처 그룹 은 이전 또는 .이후 의 s 의 양을 저장 했으므로 이제는 점의 양이 같은.vO\1


대신에 를 사용하여 바이트를 절약 할 수 있습니다 \n(Retina는 ISO 8859-1에서 소스 코드를 처리 할 수 ​​있음)
Martin Ender

@ MartinBüttner 는 \ n 교체품에 불과 하다고 생각 했습니다. 팁을 주셔서 감사합니다!
Downgoat

소스 코드의 어느 곳에서도 작동하지 않습니다. 파일을 줄로 나눈 후 Retina가 수행하는 첫 번째 작업은 추가 구문 분석을 수행하기 전에 모든 곳을 교체하는 것 입니다.
마틴 엔더

9

자바 (정규식 없음) 413 412 246 242 212 211 209 198 바이트

자바를 사용하여 골프 도전에 경쟁하는 것은 자전거를 타고 포뮬러 1 경주에 참여하는 것보다 덜 의미가 있지만, 항상 어떤 생각을하는 것은 아닙니다.

여기 내 매우 긴 자바 솔루션 골프 버전이 있습니다.

boolean l(char[][]w){int[]t={},l={};for(int y=0;y<w.length;y++)for(int x=0;x<w[0].length;x++){if(w[y][x]=='O')t=new int[]{x,y};if(w[y][x]=='<')l=new int[]{x,y,1};if(w[y][x]=='>')l=new int[]{x,y,2};if(w[y][x]=='v')l=new int[]{x,y,3};if(w[y][x]=='^')l=new int[]{x,y,4};};return(l[2]==1&&l[1]==t[1]&&l[0]>t[0])||(l[2]==2&&l[1]==t[1]&&l[0]<t[0])||(l[2]==3&&l[0]==t[0]&&l[1]<t[1])||(l[2]==4&&l[0]==t[0]&&l[1]>t[1]);}

그리고 ungolfed

boolean l(char[][] w) {
    int[] t = {}, l = {};
    for (int y = 0; y < w.length; y++)
        for (int x = 0; x < w[0].length; x++) {
            if (w[y][x] == 'O')
                t = new int[] { x, y };
            if (w[y][x] == '<')
                l = new int[] { x, y, 1 };
            if (w[y][x] == '>')
                l = new int[] { x, y, 2 };
            if (w[y][x] == 'v')
                l = new int[] { x, y, 3 };
            if (w[y][x] == '^')
                l = new int[] { x, y, 4 };
        }
    ;
    return (l[2] == 1 && l[1] == t[1] && l[0] > t[0])
            || (l[2] == 2 && l[1] == t[1] && l[0] < t[0])
            || (l[2] == 3 && l[0] == t[0] && l[1] < t[1])
            || (l[2] == 4 && l[0] == t[0] && l[1] > t[1]);
}

내 전체 개념이 잘못 된 것 같습니다. 여기 더 짧은 해결책이 있습니다.

boolean z(char[][]w){int x=0,y=0,i=0,a=w.length,b=w[0].length;for(;w[y][x]!=79;)if(++y==a){y=0;x++;}for(;i<(a<b?b:a);)if(i<b&w[y][i]==(i<x?62:60)|i<a&w[i][x]==(i++<y?'v':94))return 1<2;return 1>2;}

ungolfed 버전

oolean z(char[][] w) {
        int x = 0, y = 0, i = 0, a = w.length, b = w[0].length;
        for (; w[y][x] != 79;)
            if (++y == a) {
                y = 0;
                x++;
            }
        for (; i < (a < b ? b : a);)
            if (i < b & w[y][i] == (i < x ? 62 : 60) | i < a
                    & w[i][x] == (i++ < y ? 'v' : 94))
                return 1 < 2;
        return 1 > 2;
    }

편집 'O'를 찾기 위해 코드를 다시 작성했습니다. 이제 단일 루프가 훨씬 짧아지고 @Frozn 제안을 사용하여 일부 문자를 ASCII 값으로 바꿉니다.

결과적으로 다른 30 바이트가 먼지를 물었습니다.

@Frozn의 또 다른 제안은 Python 솔루션에 몇 바이트 더 가깝습니다.

다른 하나는 하나의 루프를 삭제하고 두 개의 if 문을 결합합니다.


1
하나는 당신 사이의 공간을 제거 할 수 있습니다 return(하지만, 바이트를 저장합니다. 반환 값이 괄호 안에 있거나 문자열에 따옴표가 있으면 공백이 필요하지 않습니다. Java 코드 골프 팁의 소스.
케빈 크루이 센

@KevinCruijssen 많이 절약하지 않지만 감사합니다 :)
user902383

모든 작은 비트 (또는 바이트를 말해야 함)는 추측하는 데 도움이됩니다. ;) 게다가, 나는 자바가 어쨌든 코드 골프 도전을 이길 것이라고 생각하지 않는다. 그래도 Java에서 코드 골프 문제를 좋아합니다. 특히 현재 직장에서 Java를 사용하고 있기 때문에 특히 그렇습니다.
Kevin Cruijssen

당신은 자신의 ASCII 값으로 문자를 대체 할 수있다 : 'O' = 79, '>' = 62, '<' = 60, '^' = 94. 'v'의 경우 118이지만 코드가 단축되지 않습니다.
Frozn

모든 바이트 수에서 Kevin이 말한 것처럼 @Frozn.
user902383

7

MATL (정규식 없음), 26 25 24 22 바이트

'>v<^'XJymfX!tZpYswJm)

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

모든 테스트 사례에 대한 수정 된 버전

설명

        % Implicitly grab input
'>v<^'  % String literal indicating the direction chars
XJ      % Store in the J clipboard
y       % Copy the input from the bottom of the stack
m       % Check to see which of the direction chars is in the input. The
        % result is a 1 x 4 logical array with a 1 for the found direction char
f       % Get the 1-based index into '>v<^' of this character
X!      % Rotate the input board 90 degrees N times where N is the index. This
        % Way we rotate the board so that, regardless of the direction char,
        % the direction char should always be BELOW the target in the same column
t       % Duplicate
Zp      % Determine if any elements are prime ('O' is the only prime)
Ys      % Compute the cumulative sum of each column
w       % Flip the top two stack elements
J       % Grab '>v<^' from clipboard J
m       % Create a logical matrix the size of the input where it is 1 where
        % the direction char is and 0 otherwise
)       % Use this to index into the output of the cumulative sum. If the 
        % direction char is below 'O' in a column, this will yield a 1 and 0 otherwise
        % Implicitly display the result

@LuisMendo 이제 어떻게 제거하는 방법을 알아 J
내려고

MATL을 모르므로 이것은 어리석은 질문 일 수 있지만 왜 0이 소수입니까?
Neil

3
@Neil 'O'숫자가 아닌 문자 0입니다. 문자의 ASCII 코드 'O'79
Luis Mendo

어쨌든, 당신이 대신에 홀수를 찾고 있다면 나는 여전히 바보 같았을 것입니다.
Neil

5

CJam (정규식 없음), 25

이전 버전이 잘못되었으므로 지금 당장 수행해야합니다.

q~_z]{'.-HbI%}f%[HF].&~+,

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

설명:

q~         read and evaluate the input (given as an array of strings)
_z         copy and transpose
]          put the original grid and transposed grid in an array
{…}f%      map the block to each grid (applying it to each string in each grid)
  '.-      remove all dots (obtaining a string of 0 to 2 chars)
  Hb       convert to base H=17, e.g. ">O" -> 62*17+79=1133
  I%       calculate modulo I=18
[HF]       make an array [17 15]
.&         set-intersect the first array (mapped grid) with 17 and 2nd one with 15
~+         dump and concatenate the results
,          get the array length

나는 "좋은"문자열과 "나쁜"문자열을 구별하기 위해 몇 가지 수학 공식을 시도했으며 각 유형의 공식에 대해 다양한 숫자를 꽂았습니다. 나는 HbI%위와 함께 끝났다 .

원래 그리드의 "good"문자열은 "> O"및 "O <"이며 결과는 17
입니다. 조옮김 된 그리드의 "good"문자열은 "vO"및 "O ^"이며 결과는
"bad"입니다. 두 그리드의 문자열은 ">", "<", "^", "v", "O", "", "O>", "Ov", "<O", "^ O"입니다. 결과 8, 6, 4, 10, 7, 0, 1, 3, 1, 3


3

Python 3 (정규식 없음), 184 바이트

평가 해킹을위한 만세!

def f(a,o=0,d={},q=''):
 for r in a:
  i=0
  for c in r:d[c]=o,i;i+=1;q=(c,q)[c in'O.']
  o+=1
 z,y=d['O'];e,j=d[q];return eval("z%se and y%sj"%(('><'[q<'v'],'=='),('==',q))[q in'><'])

3

TSQL (sqlserver 2012) (정규식 없음), 358 바이트

DECLARE @ varchar(1000)=
'......'+ CHAR(13)+CHAR(10)+
'......'+ CHAR(13)+CHAR(10)+
'...0..'+ CHAR(13)+CHAR(10)+
'...^..'+ CHAR(13)+CHAR(10)
;

WITH C as(SELECT
number n,SUBSTRING(@,number,1)a,1+min(IIF(SUBSTRING(@,number,1)=char(13),number,99))over()m
FROM master..spt_values
WHERE'P'=type and
SUBSTRING(@,number,1)in('>','<','^','v','0',char(13)))SELECT
IIF(c.n%c.m=d.n%c.m and c.a+d.a in('0^','v0')or
c.n/c.m=d.n/c.m and c.a+d.a in('>0','0<'),1,0)FROM c,c d
WHERE c.n<d.n and char(13)not in(c.a,d.a)

선언에서 펑키 한 줄 바꿈을 사용하여 온라인 버전에서 강제로 실행해야했습니다 (입력 변수에 값을 할당해도 길이 계산에는 영향을 미치지 않습니다)

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



2

자바 스크립트 (ES6), 78 바이트

s=>s.match(`>.*O|O.*<|(?=v)([^]{${l=s.search`\n`+1}})+O|(?=O)([^]{${l}})+\\^`)

물론 정규식. 루비의 대답과 원칙적으로 비슷하다는 것이 밝혀졌습니다.


2

루비, 71 55 54 바이트

정규식 솔루션은 아마도 Retina 또는 Perl에 의해 쉽게 이길 수 있음을 의미합니다.

일치하는 인덱스 번호 (거실)를 반환합니다.

이제 @Downgoat Retina 답변과 유사한 트릭을 사용하여 동시에 하향 및 상향 빔을 일치시킵니다.

->m{m=~/>\.*O|O\.*<|(?=[vO])(.{#{??+m=~/\n/}})+[O^]/m}

2

JavaScript (ES6) (정규식 없음), 126 바이트

s=>([n,o,l,r,u,d]=[..."\nO<>^"].map(c=>1+s.indexOf(c)),l>o&l-o<n&l%n>o%n||r&&r<o&o-r<n&r%n<o%n||u>o&u%n==o%n||d&&d<o&d%n==o%n)

어디 \n리터럴 개행 문자를 나타냅니다.


2

Clojure (정규식 없음), 293 바이트

(defn z[f](let[v(sort(keep-indexed(fn[i v](if(some #{v}[\v\>\<\^\O])[(if(= v\O)\& v)i]))f))l(+(.indexOf f"\n")1)d((nth v 1)0)q((nth v 1)1)p((nth v 0)1)r(=(quot p l)(quot q l))i(> q p)](cond(= d\^)(and i(=(mod(- q p)l)0))(= d\v)(and(not i)(=(mod(- p q)l)0))(= d\>)(and(not i)r):else(and i r))))

기분이 좋지 않습니다. 간단한 솔루션으로 해당 문자의 색인을 찾아 같은 줄에 있는지 계산합니다.

당신은 여기에 그것을 시도 할 수 있습니다 https://ideone.com/m4f2ra


2

파이썬 (정규식 없음), 105 바이트

def f(s):t=s.strip('.\n');return not['\n'in t,len(t)%(s.find('\n')+1)!=1,1]['>O<vO^'.find(t[0]+t[-1])//3]

True 또는 False를 반환

먼저 '.'을 제거합니다. 끝에서 '\ n'을 사용하여 관심있는 문자 '0 <> v ^'이 첫 번째 문자와 마지막 문자가되도록합니다.

'>O<vO^'.find(t[0]+t[-1])//3-문자가 유효한 배열인지 확인합니다. '> O'또는 'O <'의 경우 0, 'vO'또는 'O ^'의 경우 1, 기타 항목의 경우 -1로 평가됩니다.

'\n'in t-문자가 다른 행에
len(t)%(s.find('\n')+1)!=1있는지 확인- 문자가 다른 열에 있는지 확인
1-기본값

not소위 반전은 결과의리스트로부터 선택된 return식 동등하다 :

t[0]+t[-1] in '>0<' and '\n' not in t or t[0]+t[-1] in 'vO^' and len(t)%(s.find('\n')+1)==1

2

줄리아 (정규식 없음), 98

a->(c=rotr90(a,findlast("i1Q/",sum(a-46)));
    f(n)=find(any(c.!='.',n));b=c[f(2),f(1)];
    (b'*b)[1]==97)

문자 배열에서 작동하고 회전으로 정규화하고 범위 색인으로 점만 포함하는 행과 열을 제거하고 마지막으로 b가 행렬 곱셈을 사용하여 열 또는 행 벡터인지를 고려하여 'O'의 위치를 ​​확인하는 함수입니다.

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


1

Python 2 (정규식 없음), 268 바이트

import numpy
def q(i):
 s=numpy.asmatrix(i)
 for n in s:
  n=n.tolist()[0]
  try:
   a=n.index("0")
   if n.index(">")<a or n.index("<")>a:return 1
  except:0
 for n in range(len(i)):
  c=[x[0] for x in s[:,n].tolist()]
  try:
   a=c.index("0")
   if c.index("v")<a or c.index("^")>a:return 1
  except:0
 return 0

함수가 반환 한 Truthy 및 Falsy 값은 각각 1과 0입니다.

아직 골프를 타지 못했습니다. 솔직히, 나는 이것에 대해 너무 희망적이지 않습니다 ...

어떤 제안이라도 대단히 감사하겠습니다!


1

C # (No Regex), 282 바이트

bool F(char[,]b){int k=0,l=1,m=1,n=0,o=0;for(int x=0;x<b.GetLength(0);x++)for(int y=0;y<b.GetLength(1);y++){char i=b[x,y];if(i=='O'){k=x;l=y;}if(new[]{'<','>','^','v'}.Contains(i)){m=x;n=y;o=i;}}return(o==60&&k==m&&l<n)||(o==62&&k==m&&l>n)||(o==94&&l==n&&k<m)||(o==118&&l==n&&k>m);}

자바 버전처럼 작동하지만 번역 및 축소

확장 (설명 포함) :

bool F(char[,] b)
{
    // declare variables for goal x, goal y, laser x, laser y, and laser direction respectively (laser direction is char code for directions)
    int k = 0, l = 0, m = 0, n = 0, o = 0;
    // go through each cell
    for (int x = 0; x < b.GetLength(0); x++)
    {
        for (int y = 0; y < b.GetLength(1); y++)
        {
            // get cell contents
            char i = b[x, y];
            // set goal position if goal
            if (i == 'O')
            {
                k = x;
                l = y;
            }
            // set laser position and direction if laser
            if (new[]{ '<', '>', '^', 'v' }.Contains(i))
            {
                m = x;
                n = y;
                o = i;
            }
        }
    }
    // check everything is on the same line and in right direction
    return (o == 60 && k == m && l < n) ||
           (o == 62 && k == m && l > n) ||
           (o == 94 && l == n && k < m) ||
           (o == 118 && l == n && k > m);
}

0

C (ANSI) (정규식 없음), 237 바이트

#define l b[1][i]
main(i,b,c,d,x,y,z,p)char **b;{for(y=z=i=0,x=1;z<2&&(l==10?x=0,++y:1);i++,x++)if(l>46){if(l!=79)p=l;if(!z++)c=x,d=y;}i--;x--;z=(c==x)*((p=='v')*(l==79)+(p==94)*(l==p))+(d==y)*((p==60)*(l==p)+(p==62)*(l==79));return z;}

넓히는:

#define l b[1][i]
main(i,b,c,d,x,y,z,p)char **b;{
    for(y=z=i=0,x=1;z<2&&(l==10?x=0,++y:1);i++,x++)
        if(l>46){if(l!=79)p=l;if(!z++)c=x,d=y;}
    i--;x--;
    z=(c==x)*((p=='v')*(l==79)+(p==94)*(l==p))+(d==y)*((p==60)*(l==p)+(p==62)*(l==79));
    printf("%i\n",z);
    return z;
}

Java 또는 C # 구현과 비교하여 여기에서 상당히 다른 접근법을 취했다고 생각합니다. 'O'와 화살표 ((c, d)와 (x, y))의 좌표를 얻은 다음 화살표가 올바른 방향을 가리키고 있는지 비교했습니다.

거짓이면 0을, 참이면 1을 반환


0

Grime v0.1 , 31 바이트

n`\>.*a|a.*\<|\v/./*/a|a/./*/\^

매우 흥미로운 해결책은 아닙니다. 1진실한 예와 거짓된 예를 위해 인쇄 0합니다. 온라인으로 사용해보십시오!

설명

입력 사각형을 검색하여 레이저와 대상을 올바른 순서로 포함하는 최소 크기 (n × 1 또는 1 × n) 패턴을 검색합니다. n`플래그는 인터프리터는 항상 대부분의 일에있을 것입니다있는 경기의 수를 인쇄 할 수 있습니다. 나머지 행은- |문자로 구분 된 4 개의 패턴으로 구성되며 , 논리 OR을 의미합니다. 사각형이 패턴 중 하나와 일치하면 사각형이 일치합니다. 패턴은 다음과 같이 작동합니다.

\>.*a    Literal ">", horizontal row of any chars, one alphabetic char
a.*\<    One alphabetic char, horizontal row of any chars, literal "<"
\v/./*/a Literal "v", on top of vertical column of any chars, on top of one alphabetic char
a/./*/\^ One alphabetic char, on top of vertical column of any chars, on top of literal "^"
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.