빔이 맞습니까?


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.