내 4 노트 뮤직 박스가 그 노래를 재생할 수 있습니까?


51

크랭크로 작동되는 뮤직 박스에 일련의 4 개의 음표를 연주 할 수 있습니다. 크랭크를 돌리면 크랭크의 위치와 회전 방향에 따라 네 줄 중 하나를 뽑습니다. 크랭크를 북쪽으로 돌리면 상자의 문자열 번호가 1-4입니다.

1  |  2
   |
   O   

4     3

거기에서 크랭크를 시계 방향으로 돌려 # 2 스트링을 뽑아 크랭크를 동쪽으로 가리킬 수 있습니다.

1     2

   O---   

4     3

또는 크랭크를 북쪽에서 시계 반대 방향으로 돌려 # 1 현을 연주하고 크랭크가 서쪽을 가리키는 것으로 끝낼 수도 있습니다.

1     2

---O   

4     3

주어진 시간에 상자는 두 가지 음 중 하나를 재생할 수 있습니다. 다음 음은 시계 방향으로 사용 가능하고 다음 음은 반 시계 방향으로 사용 가능합니다.

도전

당신의 도전은 비어 있지 않은 음 값의 문자열을 받아들이는 프로그램이나 함수를 작성하는 것입니다 (즉, 숫자 1부터 4~ 까지 ). 입력의 재생 가능성 또는 재생 불가능 성을 나타 내기 위해 진실되거나 거짓된 결과를 생성합니다.

몇 가지 참고 사항 :

  • 입력은 초기 시작 위치에 대한 가정을하지 않습니다. 입력은 214(동쪽으로 시작하고 시계 반대 방향으로 엄격하게 이동) 및 234(북쪽에서 시작하고 시계 방향으로 엄격하게 이동) 두 가지 모두 유효합니다.

  • 크랭크는 각 음마다 한 방향으로 자유롭게 움직일 수 있습니다. 33333한 줄을 가로 질러 앞뒤로 움직여서 같은 음표가 연속적으로 가능합니다 (예 :). 이 시리즈 1221441는 완벽하게 재생할 수 있습니다 (서부에서 시작하여 시계 방향으로 2 단계 이동 한 다음 시계 반대 방향으로 3 단계 이동 한 다음 시계 방향으로 2 단계 이동).

시료

어떤 true경우에는 :

1
1234
1221
3333
143332
22234
2234
22214
1221441
41233

어떤 false경우에는 :

13     (note 3 is never available after note 1)
1224   (after `122`, the crank must be north, so 4 is not playable)
121    (after `12` the crank is east; 1 is not playable)
12221  (as above, after `1222` the crank is east)
43221  

입력 값이 따옴표를 포함한 문자열 일 수 있습니까?
Luis Mendo 2016 년

@LuisMendo 물론, 나는 그것을 허용 할 것입니다-나는 알고리즘에 관심이 있습니다. 입력을 얻기 위해 농구대를 뛰어 넘지 마십시오. 어쨌든, 비공식 커뮤니티의 합의가 일반적으로 괜찮다는 것입니다 : “”의 유무에 관계없이 문자열 입력?
apillers

1
나는 몰랐다. 링크 주셔서 감사합니다!
Luis Mendo 2016 년

1
@AJMansfield 아니요, 솔루션은 임의로 많은 사이클을 허용해야합니다. 물론 일부 입력으로 인해 코드가 언어의 인터프리터 또는 컴퓨터 메모리의 한계를 초과하는 경우 괜찮습니다 (물리적으로 가지고 있거나 많은 인터프리터가 허용하는 메모리에 의해 제한되기 때문에).하지만 솔루션에 추가 제한이 없어야합니다. 크랭크가 얼마나 멀리 또는 몇 번 움직이는 지
apillers

1
이 도전 과제는 Best of PPCG 2016의 단순한 외형 이 아닙니다. 불행히도, 우리는 도전에 대한 바운티 를 줄 수 없지만 Zgarb는 귀하의 명예에 도전했습니다 . 축하합니다!
마틴 엔더

답변:


9

Pyth, 30 27 바이트

f!-aVJ.u%-ysYN8zTtJ,1 7cR2T

아이디어는 다음과 같습니다.

 1.5  1  0.5

  2       0

 2.5  3  3.5

크랭크는 항상 반정 수 위치에 c있습니다. 각 단계에서을 n설정 하여 정수 위치 메모 에 반영 합니다 c = 2*n-c. n유효한 경우 c± 1 mod 8 씩 변경됩니다. n유효하지 않은 경우 c± 3 mod 8만큼 변경됩니다. 모든 값을 수집하기 위해 입력을 누적하여 줄이고 c모든 음표가 유효한지 확인합니다. c첫 번째 노트에 인접한 값만 확인하는 것보다 짧기 때문에 모든 시작 값에 대해이 작업을 수행합니다 .

형식화 :

f
  ! -
      aV J .u
              % -
                  y s Y
                  N
                8
              z
              T
         t J
      ,
        1 
        7
  cR2 T

테스트 스위트 .


18

CJam, 34 31 바이트

8,q{~2*f{_@-_zF8b&,@@+8,=*}0-}/

휴대폰에서이 작업을 수행 했으므로 나중에 설명을 작성해야합니다. 사실은 출력이 비어 있지 않습니다.

온라인으로 사용해보십시오 | 테스트 스위트

설명

새 코드는 레이아웃을 약간 변경합니다.

2    3    4

1    .    5

0/8  7    6

짝수는 문자열 위치에 해당하고 홀수는 크랭크 위치에 해당합니다.

다음과 같은 일이 발생합니다.

8,           Create the range [0 1 .. 7] of possible starting positions
             We can leave the string positions [0 2 4 6] in since it doesn't matter
q{ ... }/    For each character in the input...
  ~2*          Evaluate as integer and double, mapping "1234" -> [2 4 6 8]
  f{ ... }     Map over our possible current crank positions with the string
               position as an extra parameter
    _@-          Calculate (string - crank), giving some number in [-7 ... 7]
    _z           Duplicate and absolute value
    F8b          Push 15 base 8, or [1 7]
    &,           Setwise intersection and get length. If (string - crank) was in
                 [-7 -1 1 7] then the move was valid and this evaluates to 1, otherwise 0
    @@+          Calculate ((string - crank) + string)
    8,=          Take modulo 8, giving the new crank position. x%y in Java matches the
                 sign of x, so we need to do ,= (range + index) to get a number in [0 .. 7]
    *            Multiply the new crank position by our previous 0 or 1
  0-           Remove all 0s, which correspond to invalid positions

그런 다음 마지막에 스택이 자동으로 인쇄됩니다. 예를 들어 1, 출력이 31인 경우 출력이 종료 위치에있을 수 있습니다. 즉, 크랭크가 왼쪽 또는 위를 향하게 될 수 있습니다.

CJam에만 추가 매개 변수가있는 필터가있는 경우 ...


편집 :이 29 바이트가 작동한다고 스스로 확신하면서 일시적으로 롤백합니다.

8,q{~2*f{_@-_7b1#@@+8,=|}W-}/

37
때마다 누군가가 cjam 같은 몇 가지 어려운 언어로 응답하고 "이것은 내 전화 않았다"나는 내부의 작은 다이 말한다
데니스 반 GILS

2
그는 아마도 텍스트가 전화를 사용하여 출력되었다는 것을 의미했지만, 그의 머리에서 이루어졌습니다.
Nelson

7

하스켈, 93 88 87 바이트

any(all(\(a,b:c)->1>mod(a!!1-b)4).(zip=<<tail)).mapM((\a->[[a,a+1],[a+1,a]]).read.pure)

이것은 문자열을 가져와 불리언을 리턴하는 익명 함수로 평가됩니다. 여기에서 테스트 스위트.

설명

아이디어는 오른쪽의 람다 는 다음 다이어그램에 따라 숫자를 크랭크로 가져갈 수있는 두 가지 "움직임"에 숫자 a를 매핑하는 것입니다 [[a,a+1],[a+1,a]].

  1 (2) 2

(1/5)  (3)

  4 (4) 3

기본 익명 함수에서는 먼저 mapM((...).read.pure)각 문자를 정수로 변환하고 위의 람다를 적용하고 두 동작 중 하나를 선택하여 모든 결과 이동 시퀀스 목록을 반환합니다. 그런 다음 각 시퀀스의 두 번째 숫자가 다음 모듈로 4의 첫 번째 숫자와 동일한 속성을 갖는지 확인합니다. 이는 물리적으로 가능한 시퀀스임을 의미합니다. 이를 위해 zip각 시퀀스를로 이동 하고 쌍 tail의 조건을 확인하고 시퀀스가로 평가 all되는지 확인합니다 .anyTrue



6

망막 , 127 109 바이트

^((1|2)|(2|3)|(3|4)|(4|1))((?<2-5>1)|(?<5-2>1)|(?<3-2>2)|(?<2-3>2)|(?<4-3>3)|(?<3-4>3)|(?<5-4>4)|(?<4-5>4))*$

이 인쇄 0또는 1이에 따라,.

온라인으로 사용해보십시오! (이것은 약간의 수정 된 버전으로 인쇄 0또는 대신 입력에서 모든 일치 항목을 표시합니다 1.)

나는 우아한 알고리즘을 생각해 보았지만 처음 몇 번의 시도는 역 추적을 우회 할 수 없었고 역 추적을 구현하는 것은 성가신 일입니다. 유효한 솔루션. 불행히도, 인코딩은 상당히 장황하고 상당히 중복 적입니다 ... 이것이 단축 될 수 있다고 확신합니다.

내가 더 깔끔한 것을 알아 내려고 노력하는 동안 누군가가 어떻게 작동하는지 정렬하려면 다음과 같이 좀 더 읽기 쉬운 버전이 있습니다.

^
(
    (?<a>1|2)
  | (?<b>2|3)
  | (?<c>3|4)
  | (?<d>4|1)
)
(
    (?<a-d>1) | (?<d-a>1)
  | (?<b-a>2) | (?<a-b>2)
  | (?<c-b>3) | (?<b-c>3)
  | (?<d-c>4) | (?<c-d>4)
)*
$

그리고 여기 힌트가 있습니다 :

1  a  2

d  O  b

4  c  3

6

MATL , 57 55 바이트

1t_hjnZ^!t1tL3$)2_/wvG1)UGnl2$Ov+Ys.5tv3X53$Y+4X\G!U=Aa

이 문제보다 빠른 현재 릴리스 (10.2.1)를 사용합니다 .

EDIT (2017년 1월 17일)에 의한 언어의 변화는v 필요 에 의해 대체 될 &v, 그리고 tL3$)에 의해 Y)(추가로, 다른 개선 할 수 할 수). 다음 링크에는이 두 가지 수정 사항이 포함되어 있습니다.

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

설명

이것은 코드 골프를 위해 내가 좋아하는 두 가지 도구 인 brute forceconvolution을 기반으로 합니다.

코드는 정의 경로 좌표의 관점에서 크랭크이어서 0.5, 1.5등 각 숫자는 음의 크랭크의 위치를 알 수있다. 이 코드는 먼저 입력 문자열의 첫 번째 메모로 시작하는 가능한 모든 경로로 경로 배열 을 만듭니다 . 각 경로는이 배열의 열입니다. 이것이 무차별 대입 구성 요소입니다.

이 경로 배열에서 음표 배열 을 얻습니다. 여기서 각 열은 연주 가능한 음표의 시퀀스입니다. 예를 들어, 위치에서 이동 하면 메모 0.51.5생성 1됩니다. 이것은 위치 간 평균을 취한 다음 모듈로 4 연산을 적용하는 것으로 구성됩니다. 각 열의 누적 평균은 2D 컨벌루션으로 수행됩니다 .

마지막으로, 프로그램은 노트 배열의 열이 입력과 일치하는지 확인합니다.

1t_h        % row array [1, -1]
j           % input string
nZ^!        % Cartesian power of [1, -1] raised to N, where "N" is length of string
t           % duplicate
1tL3$)      % extract first row
2_/         % divide by -2
wv          % attach that modified row to the top of Cartesian power array
G1)U        % first character of input string converted to number, "x"
Gnl2$O      % column array of N-1 zeros, where N is length of input
v           % concat vertically into column array [x;0;0...;0]
+           % add with singleton expansion
Ys          % cumulative sum along each column. Each column if this array is a path
.5tv        % column array [.5;.5]
3X5         % predefined string 'same' (for convolution)
3$Y+        % 2D convolution of path array with [.5;.5]
4X\         % modified modulo operation. This gives note array with values 1,2,3,4
G!U         % column array of input string characters converted to numbers
=Aa         % true if any column of the note array equals this

5

피스, 43

Km-R2sMdc`M%R4-VJjQTtJ`0|Fm!s-VKdCm_B^_1dlK

테스트 스위트

이것은 아마도 매우 골프 타기 가능하며 골프를위한 최적의 알고리즘이 아닙니다 (모든 경로를 열거하는 것이 더 짧을 것으로 예상됩니까?) ... 어쨌든 알고리즘에 오류가 있으면 알려주십시오. 작동해야한다고 생각합니다. 전에 잘못했습니다!

예제 입력을 사용하여 알고리즘을 설명하겠습니다 1221. 이 프로그램은 먼저 다음과 같이 숫자를 해당 후속 작업에 매핑합니다 [[1,2],[2,2],[2,1]]. 그런 다음 차이점 mod를 얻습니다 4(Pyth는의 올바른 인수의 부호와 일치하는 결과를 얻으 %므로 항상 긍정적입니다) [3,0,1]. 그런 다음 결과에 분할 0하고있다 2그들 각각에서 차감 : [[1],[-1]].

설정이 완료 [-1,1,-1...]되었으므로 [1,-1,...]이전의 결과 배열과 동일한 길이 의 목록 과 해당 부정을 작성합니다 . 그런 다음 각 목록에 대해 목록의 요소와 이전 단계에서 생성 된 목록 사이에서 설정 차감을 수행하십시오. 그런 다음 결과 중 하나에 빈 목록 만 포함 된 경우 true를 출력합니다.


"결과가 0으로 나뉩니다"는 무슨 뜻입니까? 특히, 당신은 무엇을 얻을 것입니다 12212211221441?
Neil

1
@ Neil 1221221은 거짓이며 1221441전반적으로 사실이지만, 이해한다면 알고리즘에서 해당 단계 이후의 결과를 원하십니까? 에서 : 그게주는 경우 경우 [3, 0, 1, 3, 0, 1][[3], [1, 3], [1]][3, 0, 1, 1, 0, 3]에가 [[3], [1, 1], [3]]. 다른 설명이 필요하면 알려주세요 :)
FryAmTheEggman

나는 이전보다 더 혼란스러워 생각하기 때문에 (올바른) 결과가 어떻게 달성되는지 설명하기 위해이 두 가지 예를 끝내시겠습니까?
Neil

1
@Neil 물론, 아무 문제 : 거기에서, 우리가 얻을 수있는 뺄셈을 수행 [[1], [-1, 1], [-1]]하고 [[1], [-1, -1], [1]]여기에서, 당신은 처음이리스트 사이의 대체가 발생하지 않는 것을 볼 수 있습니다 -11다른 목록이하는 동안, 최종 결과를 제공합니다. 알고리즘은 약간 애매하지만 기본적으로 방향 변경 0과 방향을로 매핑 +/-1한 다음 점프하지 않고 방향이 올바른지 확인합니다.
FryAmTheEggman

아, 그래서 누락 된 비트는 각 분할 목록이 동일한 값으로 구성되어야하고 해당 값이 번갈아 가야한다는 것입니다. 감사!
Neil

4

Matlab, 279180 바이트

o=eye(4);a=input('')-'0';M=[o,o(:,[4,1:3]);o(:,[2:4,1:4,1])];x=2;for p=[a(1),mod(a(1),4)+1];for k=a;i=find(M*[o(:,k);o(:,p)]>1);if i;p=mod(i-1,4)+1;else;x=x-1;break;end;end;end;x>0

꽤 게으른 해결책이지만 가장 짧은 해결책을 찾았습니다. 나는 특별한 행렬을 만들었습니다 : plucker의 상태와 뜯어 낼 마지막 문자열을 인코딩하면 plucker의 새로운 위치를 인코딩하는 벡터를 반환하고 이전 뜯기 가 가능 했는지 여부를 반환 합니다. 이제 우리는 두 가지 가능한 시작 위치에서 모든 음을 반복하고 그 중 하나가 연주 가능한 멜로디가 있는지 확인합니다. 아마 더 많이 골프를 칠 수 있습니다.

확장 및 설명 소스 :

o=eye(4);
a=input('')-'0';

% encoding of plucker/notes
%      1
%   1     2
%4           2
%   4     3
%      3
%

M=[...
%12 3 4 1 2 3 4 <
1,0,0,0,0,1,0,0; %1  k = current note
0,1,0,0,0,0,1,0; %2  
0,0,1,0,0,0,0,1; %3  
0,0,0,1,1,0,0,0; %4  
0,0,0,1,0,0,0,1; %1  p = current position of plucker
1,0,0,0,1,0,0,0; %2
0,1,0,0,0,1,0,0; %3
0,0,1,0,0,0,1,0];%4
% the vector we multiply with this matrix has following structure,
% the k-th and the p+4 th entries are 1, the rest 0
% when we multiply this vecotr with this matrix, we get a vector with an
% entry of value 2 IF this is a valid move ( mod(positionOfThe2 -1,4)+1 is
% the position of the plucker now)
% or only entries less than 2 it is impossible
x=2;  %number of "chances" to get it right
for p=[a(1),mod(a(1),4)+1] %check both starting values;
    for k=a;                %loop throu the notes
        size(M);

        c = M * [o(:,k);o(:,p)];
        i=find(c>1);               %did we find a 2?
        if i;
           p=mod(i-1,4)+1;         %if yes, valid move
        else;
            x=x-1;                 %if no, invalid, 
            break;
        end 
    end
end
x=x>0 %if we failed more than once, it is not possible

4

ES6, 104 100 바이트

s=>!/13|24|31|42|3[24]{2}1|4[13]{2}2|1[24]{2}3|2[13]{2}4|(.).\1/.test(s.replace(/(.)(\1\1)+/g,"$1"))

편집 : @DigitalTrauma 덕분에 4 바이트가 절약되었습니다.

이것은 이전의 접근 방식에 결함이 있었으므로 완전히 다시 작성되었습니다.

런에 홀수인지 짝수인지에 따라 모든 자릿수를 1 또는 2로 줄이는 것으로 시작합니다. 그런 다음 모든 불법 조합을 찾습니다.

  • 13|24|31|42 (반대면)
  • 3[24]{2}132213441불법
  • 유사위한 4xx2, 1xx3그리고 2xx4어디에서 x누락 된 숫자 중 하나입니다
  • (.).\1같은 일이 같은 121불법 ( 111감소 된 1이전 버전)

불법적 인 짝이나 "트리플"이 없다면, 끈 전체가 합법적입니다.

3[24]{2}1|1[24]{2}3부정적인 lookahead 어설 션을 사용하여 단순화하려고 시도했지만 더 길었습니다.


f("1122") => true@DigitalTrauma
코너 오브라이언

@ CᴏɴᴏʀO'Bʀɪᴇɴ 그것도 아무 문제가 없습니다. 반면에 나는 f("1221221")잘못된 답변 을 출력 한다는 것을 깨달았 으므로 다시 생각해야합니다.
Neil

그것은 테스트 스위트를 포함하도록 항상 곁에 좋은 데요, '43221'은 실패 jsbin.com/vafitotequ/1/edit?js,console
파블로

@Pavlo Whoops, 나는 골프 [24][24](2|4)\1쳤지 만 제대로 테스트하지 않았습니다. 미안합니다.
Neil

당신의 골프 수 [24][24][24]{2}?
Digital Trauma

2

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

s=>[r=0,1,2,3].map(i=>[...s].map(n=>n-1-i%4?n%4-i%4?v=0:i+=3:i++,v=1)|v?r=1:0)|r

설명

i%4 현재 크랭크 위치입니다.

    1 (i%4 == 1) 2   

(i%4 == 0) (i%4 == 2)

    4 (i%4 == 3) 3   

들여 쓰기 및 주석 처리

s=>
  [r=0,1,2,3].map(i=> // i = crank position, test for i starting at 0 to 3, r = result
    [...s].map(n=>    // for each note n
      n-1-i%4?        // if n is not at the position after i
        n%4-i%4?      // if n is not at the position before i
          v=0         // set the result of this test to invalid
        :i+=3         // else i-- (+3 used because i%4 would break for negative values)
      :i++,           // else i++
      v=1             // v = result of test, initialise to 1 (valid)
    )
    |v?r=1:0          // if the test returned true, set the result to true
  )
  |r                  // return the result

테스트

var solution = s=>[r=0,1,2,3].map(i=>[...s].map(n=>n-1-i%4?n%4-i%4?v=0:i+=3:i++,v=1)|v?r=1:0)|r
<input type="text" value="1221441" oninput="result.textContent=solution(this.value)" />
<pre id="result"></pre>


잘 했어요 |이 경우 어떻게 작동 하는지 설명해 주시겠습니까 ?
Pavlo

1
@pavlo 감사합니다. 더 짧은 작성 방법입니다 (x.map(...),v). map반환 된 배열이 0및 로 캐스팅 되기 때문에 작동합니다 0|v == v.
user81655

2

루아 , 146142108162159149144135132118113113 바이트

z,q,s=0,0,io.read()for i in s:gmatch'.'do t=i-z if 2==math.abs(t)or t==q then return''end q=-t z=i end return 2>1

1에서 4 사이의 숫자 문자열이 제공되면 true 또는 false를 반환합니다. 데이터를 처리하지 않거나 범위를 벗어난 숫자를 처리하지 않습니다.

마지막 움직임을 추적하고이 움직임이 마지막 움직임의 반전인지 (IE, 121 또는 12221) 또는 거리 이동이 가능한 이상인지 확인합니다.

편집 1 :

6 바이트를 저장했습니다. if (int) thenint가 0이 아닌 경우 true 를 반환하는 것을 잊었습니다 .

그러므로:

if t~=0 then

로 변경 :

if t then

또한 구조 조정을 통해 몇 바이트를 절약했습니다.

편집 2 :

천천히 알아내는 중입니다. 나는 여기에서 설명서를 읽었습니다 : http://www.lua.org/pil/ 그리고 골프를 위해 거기에서 더 유용한 페이지 중 하나는 http://www.lua.org/pil/3.3.html입니다

특히 이것은 매우 도움이됩니다.

제어 구조와 마찬가지로 모든 논리 연산자는 false와 nil을 false로 간주하고 다른 것을 true로 간주합니다.

이것이 나에게 의미하는 것은 q 가 설정 될 때까지 "false"로 간주되므로 q에 대한 선언을 제거 할 수 있다는 것입니다 ( 처음 0 으로 설정 됨). 그래서 이것을 통해 몇 바이트를 더 절약합니다.

언급하지 않아도 될 또 다른 것은 루아에서 값을 바꾸고 싶다면 임시 변수없이 간단히 할 수 a,b=b,a 있다는 것입니다.

편집 3

따라서 새로운 기능뿐만 아니라 영리한 재구성을 통해 바이트 수가 9로 줄었습니다.

입력 수신을위한 최상의 모드

숫자 목록을 읽고 한 번에 하나씩 숫자를 조작해야하는 경우 다음을 사용할 수 있습니다.

for x in string:gmatch('.') do
    print(x) --This is our number
end

string : sub를 사용하는 대안과 비교할 때 golf (또는 일반적인 용도)의 가치를 볼 수 있습니다.

for x=1,string:len() do
    print(string:sub(x,x)) --This is our number
end

함수 또는 문자열 재구성

두 번째로, 한 줄에 여러 선언이 있고 값 중 하나가 함수이거나 숫자를 다음과 같이 함수 결과와 비교하는 조건이있는 경우 :

x,y,z=io.read(),0,0 print('test')

if math.abs(x)==2 then

닫는 괄호가 조건 또는 선언의 마지막 문자가되도록 재구성하여 다음과 같이 문자를 잘라낼 수 있습니다.

y,z,x=0,0,io.read()print('test') --Notice no space

if 2==math.abs(x)then --If we put the '2' first in the conditional statement, we can now remove a space character

'True'또는 'False'대신 True 또는 False에 해당하는 반환 조건

바이트 카운트를 줄이려면 반 재미있는 방법을 찾았습니다. true 또는 false를 리턴해야하는 경우 "true"또는 "false"자체보다 문자가 적은 true 또는 false와 같은 명령문을 리턴 할 수 있습니다.

예를 들어 다음을 비교하십시오.

return true
return false

에:

return 2>1
return 1>2

121false를 출력해야합니다.
lirtosiast

아, 신경 쓰지 마 내가 참조. 곧 고칠 것입니다
Skyl3r

루아 골프 팁 에 해당 루아 팁을 아직 추가하지 않은 경우 루아 골프 팁 에 추가하는 것이 좋습니다.
apillers

2

MATL, 49 바이트 (비경쟁 1 )

1. 대답 (ab)은 최신 버전의 MATL에 대해 덜 엄격한 색인을 사용하며이 문제가 게시 된 시점에는 효과가 없었습니다.

dt~aX`tt~f1)q:)w3MQJh)_ht~a]tT-3hX|n2=wT_3hX|n2=+

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

나는 Best of PPCG 2016 에서이 도전을 보았고 이것이 내가 가장 좋아하는 연산자를 사용할 수 있다고 생각했습니다 .

d

또는 diffMATLAB / Octave에서 (인간이 읽기 쉽기 때문에 설명에 MATLAB / Octave 용어를 자유롭게 사용할 것입니다). 이 명령은 벡터 또는 문자 배열에서 요소 별 차이를 계산합니다.

이 문제의 경우 차이점이 흥미로운 패턴을 나타냅니다. 참고

방향으로 변화 해야한다 메모가 재생되는 것을 의미 두 번 .

차이 패턴의 경우 ( 1-4현재 전환은 무시 )

로그인 변경은 사이에 홀수 의 0 diff(input)이 있어야합니다 . 반대로, 짝수 의 제로 후에 부호를 변경할 수 없습니다 .


각 배열마다 첫 번째 0을 찾아서 구현했습니다. 나는 0을 다듬고 그 뒤에 모든 요소를 ​​곱합니다 -1. 결과적으로 모든 요소의 부호가 동일 해야합니다 . 물론, 작은 문제가 -3같게 +1하고, 2일반적으로 허용되는가. 로 결과의 합집합을 취하고 [1 -3]이것이 2 크기인지 여부를 확인 하여이 문제를 해결했습니다 (즉, 허용되지 않은 요소가 합집합을 통해 집합에 '입력'되지 않았습니다). 에 대해 반복하고 [-1 3]어느 한쪽 (1 길이 입력의 경우 둘 다)이 참인지 확인합니다.

d                                % Difference of input
 t~a                             % Check if any element equals 0
    X`                     t~a]  % Start while loop, ending in the same check
       t~                           % Get a new vector, logical negated to find zeroes.
          f1)                       % Find the position of the first zero. 
      t         q:)                 % Decrement by 1, to index all elements before that zero.
                   w3MQJh)          % Push the result of 'find', but increment to get all elements after.
                         _h         % Multiply the second half by -1, and concatenate horizontally.

  T-3hX|n2=                      % Check if set union with [1 -3] is size 2
 t        wT_3hX|n2=             % Check if set union with [-1 3] is size 2
                    +            % Logical OR. 

@LuisMendo 감사합니다. 나는 실제로 그것을 읽을 필요가있다 M. 마지막으로 시도했을 때, 예상과 다르게 작동했기 때문에 당분간 그것을 무시했다. 그것이 될 필요가 있음이 올바른지 대답 3M내가하지의 입력 도착 후하기 때문에 ),하지 :만의 q(생략 w그것이 아니다으로 정상 기능)?
Sanchises

예, 정확히 w정상적인 기능이 아니기 때문에 건너 뜁니다. 입력을받지 않는 일반 기능도 건너 뜁니다.
Luis Mendo

2

파이썬 (3.5) 160 151 150 바이트

재귀 솔루션

def f(s):g=lambda s,c:s==''or g(s[1:],(c[:4]*2)[(s[0]==c[0])*2+1:])if s==''or s[0]in c[:2]else 0;return any([g(s,"1234123"[i:])for i in range(4)])

람다가없는 언 골프

def f(s):
    def g(s,c):
        if s=='' or s[0] in c[:2] :
            return s=='' or g(s[1:],(c[:4]*2)[(s[0]==c[0])*2+1:])
        else:
            return False
    return any([g(s,"1234123"[i:]) for i in range(4)])

크랭크 대신 모든 상자를 회전시킵니다. 크랭크 위치는 c 문자열의 첫 번째와 두 번째 문자 사이입니다. 크랭크의 모든 시작 위치를 테스트해야합니다.

줄을 회전하는 데 사용하는 간계

파이썬 ( s[i:]+s[:i]) 에서 문자열을 회전시키는 일반적인 방법 은 색인과 문자열을 모두 반복해야합니다. 이 경우 문자열을 복제하고 첫 문자를 자릅니다.

(c*2)                        # duplicate the string
     [(s[0]==c[0])*2+1       # test that return 1 if firsts characters match 3 instead 
                      :]     
                        [:4] # crop again to have a 4 characters string

테스트 사례

[f(i) for i in ["1", "1234", "1221", "3333", "143332", "22234", "2234", "22214", "1221441", "41233", "13", "1224", "121", "12221", "43221"]]
[True, True, True, True, True, True, True, True, True, True, False, False, False, False, False]

1
에서 공간을 제거 할 수 있습니다 3"[i:]) for.
Outgolfer Erik

@EriktheOutgolfer 고마워요.
Erwan


1

자바 스크립트 (ES2015) 110 95

p=(s,d)=>(h=s[0],t=s.slice(1),g=t[0],!g||(d?g==h?p(t,-d):g%4==(h-d)%4&&p(t,d):p(s,1)||p(s,-1)))

Neil이 15 바이트를 절약했습니다! 풀리지 않은 원본 버전 :

p = (s, d) => {
  h = s[0]
  t = s.substr(1)

  if (!t[0]) return true
  if (!d) return p(s, 1) || p(s, -1)
  if (t[0] == h) return p(t, d*-1)
  if (t[0] == (h-d > 4 ? 1 : h-d || 4)) return p(t, d)

  return false
}

테스트 : https://jsbin.com/cuqicajuko/1/edit?js,console


1
17 바이트 절약 :(s,d)=>(h=s[0],t=s.slice(1),g=t[0],!g||(d?g==h?p(t,-d):g%4==(h-d)%4&&p(t,d):p(s,1)||p(s,-1)))
Neil

그래도 @ user81655의 대답만큼 짧지는 않습니다.
Neil

1

튜링 머신 코드, 395 바이트

0 1 _ r a
0 2 _ r b
0 3 _ r c
0 4 _ r d
a 1 _ r a
a 2 _ r E
a 3 _ r h
a 4 _ r S
b 1 _ r W
b 2 _ r b
b 3 _ r S
b 4 _ r h
c 1 _ r h
c 2 _ r N
c 3 _ r c
c 4 _ r W
d 1 _ r N
d 2 _ r h
d 3 _ r E
d 4 _ r d
N 1 _ r W
N 2 _ r E
N _ _ r r
N * _ r h
E 2 _ r N
E 3 _ r S
E _ _ r r
E * _ r h
S 3 _ r E
S 4 _ r W
S _ _ r r
S * _ r h
W 4 _ r S
W 1 _ r N
W _ _ r r
W * _ r h
h _ 0 r halt
h * _ r h
r _ 1 r halt

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

이것은 기본적으로 상태 기반 접근 방식입니다.

  • 초기 상태는 0입니다.
  • a, b, c, 및 d시작에 불과 발생 "미정 상태"이다
  • N, E, S, 그리고 W분명히을 위해 서 "결정 상태"이다 N노스, EAST, SOUTH 및 W동부 표준시.

1

목요일, 203 바이트

나는 이것을 더 멀리 골프하는 법을 생각할 수 없다.

0::=:::
>11::=>1
>22::=>2
>33::=>3
>44::=>4
>12::=b
>21::=d
>14::=c
>41::=a
>23::=c
>32::=a
>34::=d
>43::=b
a1::=d
a2::=b
b2::=a
b3::=c
c3::=b
c4::=d
d4::=c
d1::=a
a<::=~n
b<::=~e
c<::=~s
d<::=~w
::=
>0<

음표 순서가 가능하면 종료 방향을 출력하고 그렇지 않으면 출력이 비어 있습니다.


1

프롤로그 (SWI) 117 바이트

a(N,P):-P=N;N=1,P=4,!;P is N-1.
m([A,B|C],[X,Y|Z]):-a(A,X),a(B,X),a(B,Y),X\=Y,m([B|C],[Y|Z]).
m([_],_).
p(N):-m(N,_).

p재생 가능한 입력에서 성공하고 (정수 목록으로 제공) 재생할 수없는 입력에서 실패 하는 술어 를 정의합니다 . 온라인으로 사용해보십시오!

설명

a노트 N와 크랭크 위치 사이의 인접 관계를 정의합니다 P. 우리는 위치 p 를 음표 pp + 1 사이에 있도록 정의 합니다. 따라서 위치는 Niff

  • 그것은 N( P=N) 와 같다 ; 또는
  • 음표는 1이고 위치는 4 ( N=1,P=4)입니다. 또는
  • 위의 경우는 (사실이 아니다 !)과 위치가 동일 N-1( P is N-1).

m음표를 가져 와서 음표를 연주 할 위치 목록을 생성하려고 시도합니다. A방금 연주 한 음이 연주 B될 음입니다. X현재 크랭크 위치이고 Y다음 크랭크 위치입니다. 움직임은 유효합니다

  • 방금 연주 한 음이 현재 크랭크 위치 ( a(A,X))에 인접 해 있습니다 .
  • 연주 될 음은 또한 현재 크랭크 위치 ( a(B,X))에 인접하고 ;
  • 연주 될 음은 다음 크랭크 위치 ( a(B,Y))에 인접하고 ; 과
  • 두 크랭크 위치가 동일하지 않습니다 ( X\=Y).

이 모든 것이 유지되면 재귀하십시오. 하나의 음표 ( m([_],_)) 로 성공적으로 내려 가면 음표 순서를 재생할 수 있습니다.

이 질문에서는 일련의 동작이 존재하는지 여부 만 신경 쓰므로 생성 된 크랭크 위치 목록 p을 호출 m하고 삭제하도록 정의 합니다 .

ungolfed 버전을보고 여기에서 모든 테스트 사례를 확인 하십시오 .

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