Hộp nhạc 4 nốt của tôi có thể phát bài hát đó không?


51

Tôi có một hộp nhạc hoạt động bằng tay quay có thể chơi một loạt bốn nốt nhạc. Khi tôi xoay tay quay, nó sẽ cắm một trong bốn dây, tùy thuộc vào vị trí của tay quay và hướng quay. Khi quay tay quay về hướng bắc, hộp (với các chuỗi được đánh số từ 1 đến 4) trông như thế này:

1  |  2
   |
   O   

4     3

Từ đó, tôi có thể xoay tay quay theo chiều kim đồng hồ để nhổ dây số 2 và chỉ tay quay về hướng đông:

1     2

   O---   

4     3

Ngoài ra, tôi cũng có thể quay tay quay ngược chiều kim đồng hồ từ phía bắc để chơi chuỗi số 1 và kết thúc bằng một tay quay hướng về phía tây:

1     2

---O   

4     3

Tại bất kỳ thời điểm nào, sau đó, hộp có thể phát một trong hai nốt: nốt tiếp theo có sẵn theo chiều kim đồng hồ hoặc nốt tiếp theo theo hướng ngược chiều kim đồng hồ.

Thử thách

Thử thách của bạn là viết một chương trình hoặc chức năng chấp nhận một chuỗi các giá trị ghi chú không trống (nghĩa là các chữ số 1thông qua 4) và xác định xem có thể phát chuỗi ghi chú đó trên hộp nhạc không. Tạo ra một kết quả trung thực hoặc giả để chỉ ra khả năng phát hoặc không phát của đầu vào.

Một số lưu ý:

  • Đầu vào không có giả định về vị trí bắt đầu ban đầu. Các đầu vào 214(bắt đầu từ phía đông và di chuyển theo chiều ngược chiều kim đồng hồ) và 234(bắt đầu từ phía bắc và di chuyển đúng theo chiều kim đồng hồ) và cả hai đều hợp lệ.

  • Tay quay có thể di chuyển tự do theo một trong hai hướng sau mỗi nốt nhạc. Một loạt các ghi chú tương tự là có thể (ví dụ, 33333) bằng cách di chuyển qua lại trên một chuỗi. Sê- 1221441ri hoàn toàn có thể chơi được (bắt đầu từ phía tây, di chuyển theo chiều kim đồng hồ hai bước, sau đó ngược chiều kim đồng hồ ba bước, sau đó theo chiều kim đồng hồ hai bước).

Mẫu

Một số truetrường hợp:

1
1234
1221
3333
143332
22234
2234
22214
1221441
41233

Một số falsetrường hợp:

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  

Đầu vào có thể là chuỗi bao gồm cả dấu ngoặc kép?
Luis Mendo

@LuisMendo Chắc chắn, tôi sẽ cho phép nó - Tôi quan tâm đến thuật toán của bạn, không khiến bạn phải nhảy qua vòng để lấy đầu vào. Dù sao, có sự đồng thuận không chính thức của cộng đồng rằng nói chung là ổn: Chuỗi đầu vào có hoặc không có phiên bản?
apsillers

1
Tôi không biết điều đó. Cảm ơn các liên kết!
Luis Mendo

1
@AJMansfield Không, các giải pháp nên cho phép nhiều chu kỳ tùy ý. Tất nhiên, nếu một số đầu vào khiến mã của bạn vượt quá giới hạn trong trình thông dịch ngôn ngữ hoặc bộ nhớ máy tính của bạn, thì tốt thôi (vì nó chỉ bị giới hạn bởi nhiều bộ nhớ mà bạn có hoặc thông dịch viên cho phép), nhưng giải pháp của bạn không nên áp dụng các giới hạn bổ sung trên bao xa hoặc bao nhiêu lần quây di chuyển.
apsillers

1
Thử thách này đã chiến thắng hạng mục Không đơn giản như vẻ ngoài của Best of PPCG 2016. Thật không may, chúng tôi không thể đưa tiền thưởng cho các thử thách, nhưng Zgarb đã viết một thử thách để vinh danh bạn . Xin chúc mừng!
Martin Ender

Câu trả lời:


9

Bình thường, 30 27 byte

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

Đây là ý tưởng:

 1.5  1  0.5

  2       0

 2.5  3  3.5

Tay quay luôn ở vị trí nửa nguyên c. Ở mỗi bước, chúng tôi phản ánh nó qua ghi chú vị trí số nguyên nbằng cách cài đặt c = 2*n-c. Nếu nhợp lệ, cthay đổi theo ± 1 mod 8. Nếu nkhông hợp lệ, cthay đổi theo ± 3 mod 8. Chúng tôi giảm dần so với đầu vào để thu thập tất cả các giá trị của c, và sau đó xem liệu tất cả các ghi chú có hợp lệ không. Chúng tôi làm điều này cho mọi giá trị bắt đầu c, bởi vì nó ngắn hơn so với việc chỉ kiểm tra những giá trị liền kề với ghi chú đầu tiên.

Định dạng:

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

Bộ thử nghiệm .


18

CJam, 34 31 byte

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

Đã làm điều này trên điện thoại của tôi, vì vậy tôi sẽ phải đưa ra một lời giải thích sau. Đầu ra là nonempty iff thật.

Dùng thử trực tuyến | Bộ kiểm tra

Giải trình

Mã mới thay đổi bố cục một chút:

2    3    4

1    .    5

0/8  7    6

Số chẵn tương ứng với vị trí chuỗi và số lẻ tương ứng với vị trí quây.

Đây là những gì xảy ra:

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

Ngăn xếp sau đó được tự động in ở cuối. Bất kỳ vị trí kết thúc có thể nào sẽ nằm trong đầu ra, ví dụ như đầu vào 1là đầu ra 31, điều đó có nghĩa là tay quay có thể kết thúc quay mặt sang trái hoặc lên.

Nếu chỉ có CJam có bộ lọc với tham số phụ ...


Chỉnh sửa: Tạm thời quay lại trong khi tôi tự thuyết phục bản thân rằng 29 byte này hoạt động:

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

37
Mỗi khi ai đó trả lời bằng một số ngôn ngữ khó như cjam và nói "đã làm điều này trên điện thoại của tôi", tôi chết một chút bên trong
Dennis van Gils

2
Có lẽ anh ta có nghĩa là văn bản được xuất ra bằng điện thoại, nhưng nó đã được thực hiện trong đầu anh ta.
Nelson

7

Haskell, 93 88 87 byte

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

Điều này ước tính cho một hàm ẩn danh nhận một chuỗi và trả về một boolean. Bộ thử nghiệm ở đây.

Giải trình

Ý tưởng là lambda ở bên phải ánh xạ một số atới [[a,a+1],[a+1,a]], hai "bước di chuyển" có thể đưa quây qua số đó, theo sơ đồ sau:

  1 (2) 2

(1/5)  (3)

  4 (4) 3

Trong hàm ẩn danh chính, trước tiên chúng ta thực hiện mapM((...).read.pure), chuyển đổi từng ký tự thành một số nguyên, áp dụng lambda ở trên cho nó và chọn một trong hai di chuyển, trả về danh sách tất cả các chuỗi di chuyển kết quả. Sau đó, chúng tôi kiểm tra xem có bất kỳ chuỗi nào trong số này có thuộc tính rằng số thứ hai của mỗi lần di chuyển bằng số thứ nhất của modulo 4 tiếp theo hay không, có nghĩa là đó là chuỗi có thể thực hiện được. Để làm điều này, chúng tôi ziptừng chuỗi di chuyển với nó tail, kiểm tra điều kiện cho allcác cặp và xem nếu anytrình tự ước tính True.



6

Võng mạc , 127 109 byte

^((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))*$

Điều này in 0hoặc 1, theo đó.

Hãy thử trực tuyến! (Đây là phiên bản sửa đổi một chút, đánh dấu tất cả các kết quả khớp trong đầu vào thay vì in 0hoặc 1.)

Tôi đã thử đưa ra một thuật toán tao nhã, nhưng vài lần thử đầu tiên của tôi không thể tránh được việc quay lại ... và việc thực hiện quay lui rất khó chịu ... vì vậy tôi đã sử dụng một ngôn ngữ để quay lại cho tôi khi tôi chỉ cần mã hóa giải pháp hợp lệ. Thật không may, mã hóa khá dài dòng và khá dư thừa ... Tôi chắc chắn rằng điều này có thể được rút ngắn.

Trong khi tôi cố gắng tìm ra một cái gì đó gọn gàng hơn, nếu bất cứ ai muốn sắp xếp cách thức hoạt động của nó, đây là một phiên bản dễ đọc hơn:

^
(
    (?<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)
)*
$

Và đây là một gợi ý:

1  a  2

d  O  b

4  c  3

6

MATL , 57 55 byte

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

Điều này sử dụng bản phát hành hiện tại (10.2.1) , sớm hơn thử thách này.

EDIT (17 tháng 1 năm 2017): do sự thay đổi trong ngôn ngữ,v nhu cầu được thay thế bằng &v, và tL3$)bởi Y)(ngoài ra, một số cải tiến khác có thể được thực hiện). Liên kết sau bao gồm hai sửa đổi

Hãy thử trực tuyến!

Giải trình

Điều này dựa trên hai trong số các công cụ yêu thích của tôi cho môn đánh gôn: lực lượng vũ phutích chập .

Mã xác định đường dẫn theo sau bởi tay quay theo tọa độ 0.5, 1.5v.v ... Mỗi số cho biết vị trí của tay quay giữa các ghi chú. Mã trước tiên xây dựng một mảng đường dẫn với tất cả các đường dẫn có thể bắt đầu bằng ghi chú đầu tiên của chuỗi đầu vào. Mỗi đường dẫn là một cột trong mảng này. Đây là thành phần lực lượng vũ phu .

Từ mảng đường dẫn này, một mảng ghi chú được lấy, trong đó mỗi cột là một chuỗi các ghi chú đã phát. Ví dụ, chuyển động từ vị trí 0.5để 1.5tạo ra một ghi chú 1. Điều này bao gồm lấy trung bình giữa các vị trí và sau đó áp dụng thao tác modulo 4. Trung bình chạy dọc theo mỗi cột được thực hiện với tích chập 2D .

Cuối cùng, chương trình kiểm tra xem có bất kỳ cột nào của mảng ghi chú trùng với đầu vào không.

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

Bình thường, 43

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

Phòng thử nghiệm

Đây có lẽ là rất có thể chơi được và cũng không phải là thuật toán tối ưu để chơi gôn (tôi hy vọng việc liệt kê tất cả các đường sẽ ngắn hơn?) ... Dù sao, nếu bạn tìm thấy bất kỳ lỗi nào với thuật toán, hãy cho tôi biết, tôi nghĩ nó nên hoạt động nhưng tôi Trước đây đã sai!

Tôi sẽ giải thích thuật toán của tôi bằng cách sử dụng đầu vào ví dụ của 1221. Chương trình này trước tiên ánh xạ các chữ số chống lại người kế nhiệm của họ, như vậy : [[1,2],[2,2],[2,1]]. Sau đó, nó nhận được sự khác biệt của họ 4(Pyth nhận được kết quả phù hợp với dấu hiệu của đối số đúng %, vì vậy điều này luôn luôn tích cực) : [3,0,1]. Sau đó, các kết quả được phân chia 0và đã 2trừ đi từ mỗi trong số chúng : [[1],[-1]].

Bây giờ việc thiết lập đã hoàn tất, chúng tôi tạo một danh sách [-1,1,-1...]và phủ định của nó [1,-1,...], cả hai cùng độ dài với mảng kết quả từ trước đó. Sau đó, đối với mỗi danh sách này, hãy thực hiện phép trừ giữa các thành phần của danh sách và danh sách được tạo ở bước trước. Sau đó, nếu một trong hai kết quả chỉ chứa danh sách trống, chúng tôi xuất ra đúng.


Bạn có ý nghĩa gì bởi "kết quả được chia thành 0"? Cụ thể, bạn sẽ nhận được gì 12212211221441?
Neil

1
@Neil 1221221là sai và 1221441cho tổng thể đúng, nhưng nếu tôi hiểu bạn muốn kết quả sau bước đó trong thuật toán? Nếu đó là trường hợp nó đưa ra: từ [3, 0, 1, 3, 0, 1]đến [[3], [1, 3], [1]][3, 0, 1, 1, 0, 3]đến [[3], [1, 1], [3]]. Hãy cho tôi biết nếu bạn muốn giải thích điều gì khác :)
FryAmTheEggman

Tôi nghĩ rằng tôi bối rối hơn trước, vì vậy bạn có thể vui lòng hoàn thành hai ví dụ đó để giải thích kết quả (chính xác) đạt được như thế nào không?
Neil

1
@Neil Chắc chắn, không có vấn đề gì :) Từ đó, chúng tôi thực hiện phép trừ để có được: [[1], [-1, 1], [-1]][[1], [-1, -1], [1]]từ đây, bạn có thể thấy rằng danh sách đầu tiên không có danh sách xen kẽ giữa -11trong khi danh sách khác thực hiện, đưa ra kết quả cuối cùng. Thuật toán hơi khó hiểu, nhưng về cơ bản, ánh xạ sẽ thay đổi 0hướng và hướng +/-1, sau đó kiểm tra xem không có bước nhảy nào được thực hiện và hướng có ý nghĩa.
FryAmTheEggman

Ồ, vì vậy, phần tôi bị thiếu là mỗi danh sách phân tách phải bao gồm cùng một giá trị và các giá trị đó phải thay thế. Cảm ơn!
Neil

4

Matlab, 279 180 byte

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

Khá là một giải pháp lười biếng, nhưng ngắn nhất tôi đã có thể đưa ra. Tôi đã tạo ra ma trận đặc biệt: Khi bạn mã hóa trạng thái của plucker và chuỗi cuối cùng sẽ được gảy, nó sẽ trả về một vectơ, mã hóa vị trí mới của plucker, và liệu lần nhổ trước đó có khả thi hay không. Bây giờ chúng tôi chỉ cần lặp lại tất cả các ghi chú từ hai vị trí bắt đầu có thể và xem liệu một trong số chúng có dẫn đến giai điệu có thể chơi được không. Có lẽ có thể được chơi golf nhiều hơn nữa.

Nguồn mở rộng và giải thích:

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 byte

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

Chỉnh sửa: Đã lưu 4 byte nhờ @DigitalTrauma.

Đây là một bản viết lại hoàn chỉnh vì cách tiếp cận trước đây của tôi là thiếu sót.

Tôi bắt đầu bằng cách giảm tất cả các chữ số xuống còn 1 hoặc 2 tùy thuộc vào việc có một số lẻ hay số chẵn trong quá trình chạy. Sau đó tôi tìm kiếm tất cả các kết hợp bất hợp pháp:

  • 13|24|31|42 (cạnh đối diện)
  • 3[24]{2}1như 32213441là bất hợp pháp
  • tương tự cho 4xx2, 1xx32xx4nơi xlà một trong các chữ số còn thiếu
  • (.).\1vì những thứ như 121là bất hợp pháp ( 111đã được giảm xuống 1trước đó)

Nếu không có cặp hoặc "bộ ba" bất hợp pháp thì toàn bộ chuỗi là hợp pháp (bằng chứng cảm ứng được để lại như một bài tập vì đêm muộn ở đây).

Tôi đã cố gắng đơn giản hóa 3[24]{2}1|1[24]{2}3bằng cách sử dụng một xác nhận nhìn tiêu cực nhưng hóa ra nó dài hơn theo cách đó.


f("1122") => true@DigitalTrauma
Conor O'Brien

@ CᴏɴᴏʀO'Bʀɪᴇɴ Tôi thấy không có gì sai với điều đó. Mặt khác, tôi đã nhận ra rằng đưa f("1221221")ra câu trả lời sai, vì vậy tôi sẽ phải suy nghĩ lại.
Neil

Thật tuyệt khi bao gồm một bộ thử nghiệm, '43221' không thành công: jsbin.com/vafitotequ/1/edit?js,console
Pavlo

@Pavlo Rất tiếc, tôi đã golfed [24][24]đến (2|4)\1nhưng tôi đã không kiểm tra đầy đủ. Xin lỗi vì điều đó.
Neil

Can bạn golf [24][24]để [24]{2}?
Chấn thương kỹ thuật số

2

JavaScript (ES6), 80 byte

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

Giải trình

i%4 là vị trí tay quay hiện tại:

    1 (i%4 == 1) 2   

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

    4 (i%4 == 3) 3   

Thụt lề và bình luận

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

Kiểm tra

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>


Hoàn thành tốt Bạn sẽ giải thích làm thế nào |hoạt động trong trường hợp này?
Pavlo

1
@pavlo Cảm ơn. Đó là một cách viết ngắn hơn (x.map(...),v). Nó hoạt động vì mảng mà maptrả về phôi 00|v == v.
dùng81655

2

Lua , 146 142 108 162 159 149 144 135 132 118 113 byte

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

Trả về đúng hoặc sai với một chuỗi các số từ 1 đến 4. (Không xử lý không có dữ liệu hoặc ngoài số phạm vi.

Đơn giản chỉ cần theo dõi chuyển động cuối cùng là gì và kiểm tra xem chuyển động này có phải là sự đảo ngược của chuyển động cuối cùng (IE, 121 hoặc 12221) hoặc nếu khoảng cách di chuyển nhiều hơn có thể.

CHỈNH SỬA 1 :

Đã lưu 6 byte. Tôi quên rằng if (int) thentrả về true nếu int là số không.

Do vậy:

if t~=0 then

thay đổi:

if t then

Cũng lưu một vài byte bằng cách tái cấu trúc.

EDIT 2 :

Tôi đang dần hiểu ra điều này. Tôi đã đọc tài liệu ở đây: http://www.lua.org/pil/ Và một trong những trang hữu ích hơn để chơi golf là http://www.lua.org/pil/3.3.html

Đặc biệt, điều này rất hữu ích:

Giống như các cấu trúc điều khiển, tất cả các toán tử logic đều coi false và nil là false và mọi thứ khác là true.

Điều này có nghĩa với tôi là tôi có thể tiếp tục và xóa tuyên bố của mình cho q ( ban đầu được đặt thành 0 ) vì nó sẽ được coi là "sai" cho đến khi được đặt. Vì vậy, tôi tiết kiệm thêm một vài byte thông qua điều này.

Một điều đáng nói nữa, mặc dù tôi không sử dụng nó, là nếu bạn muốn trao đổi giá trị trong Lua, bạn có thể chỉ cần làm a,b=b,a mà không cần một biến tạm thời.

CHỈNH SỬA 3

Vì vậy, thông qua một số tái tạo thông minh cũng như một chức năng mới, tôi đã đếm được thêm 9 byte nữa.

Chế độ tốt nhất để nhận đầu vào

Nếu bạn cần đọc một danh sách các số và thực hiện từng thao tác trên từng số một, bạn có thể sử dụng:

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

Khi so sánh với thay thế của bạn bằng cách sử dụng chuỗi: phụ, bạn có thể thấy giá trị cho golf (hoặc sử dụng chung):

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

Tái cấu trúc các hàm hoặc chuỗi

Điều thứ hai, nếu bạn có nhiều khai báo trên một dòng và một trong các giá trị là hàm hoặc bạn có một điều kiện để bạn so sánh một số với kết quả của một hàm như sau:

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

if math.abs(x)==2 then

bằng cách cấu trúc lại nó để dấu ngoặc đơn đóng là ký tự cuối cùng trong điều kiện hoặc khai báo, bạn có thể cắt bỏ một ký tự như vậy:

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

Trả về các Điều kiện tương đương với Đúng hoặc Sai thay vì 'Đúng' hoặc 'Sai'

Tôi tìm thấy một cách thú vị để giảm số lượng byte của tôi xuống hơn nữa. Nếu bạn cần trả về true hoặc false, bạn có thể trả về một câu lệnh tương đương với true hoặc false có ít ký tự hơn "true" hoặc "false".

Chẳng hạn, so sánh:

return true
return false

Đến:

return 2>1
return 1>2

121nên xuất sai.
lirtosiast

À, đừng bận tâm. Tôi hiểu rồi. Sẽ khắc phục trong thời gian ngắn
Skyl3r

Bạn có thể quan tâm đến việc thêm một số lời khuyên Lua đó vào Mẹo chơi gôn ở Lua nếu bạn chưa thấy chúng được liệt kê ở đó.
apsillers

2

MATL, 49 byte (không cạnh tranh 1 )

1. Câu trả lời (ab) sử dụng việc lập chỉ mục ít nghiêm ngặt hơn cho các phiên bản MATL mới hơn và sẽ không hoạt động tại thời điểm thử thách này được đăng.

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

Hãy thử trực tuyến! .

Tôi đã thấy thử thách này tại giải Best of PPCG 2016 và nhận ra rằng điều này có thể sử dụng toán tử yêu thích của tôi :

d

Hoặc, difftrong MATLAB / Octave (tôi sẽ tự do sử dụng thuật ngữ MATLAB / Octave trong phần giải thích của tôi, vì nó dễ đọc hơn cho con người). Lệnh này tính toán sự khác biệt về phần tử trong một vectơ hoặc, trong trường hợp này, trong một mảng ký tự.

Đối với vấn đề này, sự khác biệt thể hiện một mô hình thú vị. Lưu ý rằng

Thay đổi hướng phải có nghĩa là một nốt nhạc được phát hai lần .

Đối với mẫu khác biệt (bỏ qua 1-4chuyển đổi ngay bây giờ), điều này có nghĩa là

Một thay đổi trong đăng nhập diff(input)phải có một số 0 số lẻ ở giữa. Ngược lại, dấu hiệu không được phép thay đổi sau một số 0 chẵn .


Tôi đã thực hiện điều này bằng cách, cho mỗi mảng, tìm số 0 đầu tiên. Tôi cắt số không, và nhân tất cả các phần tử sau nó với nó -1. Đối với kết quả cuối cùng, điều này có nghĩa là tất cả các yếu tố phải có cùng một dấu hiệu. Tất nhiên, có một vấn đề nhỏ của việc -3cân bằng +1, và 2không được phép nói chung. Tôi đã giải quyết vấn đề này bằng cách lấy tập hợp kết quả với [1 -3]và kiểm tra xem đây có phải là cỡ 2 không (nghĩa là không có phần tử không được phép 'nhập' tập hợp thông qua liên kết). Lặp lại [-1 3]và kiểm tra xem một trong hai (hoặc cả hai, trong trường hợp đầu vào 1 độ dài) có đúng không.

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 Cảm ơn. Tôi thực sự cần phải đọc lên M, lần trước tôi đã thử nó, nó hoạt động khác với dự kiến ​​vì vậy tôi chỉ bỏ qua nó trong thời gian này. Có đúng không khi nói rằng nó cần phải 3Mbởi vì sau đó tôi nhận được đầu vào không ), :nhưng không phải q(bỏ qua wvì nó không phải là một chức năng bình thường )?
Chiếm

Đúng chính xác. wbị bỏ qua vì nó không phải là một chức năng bình thường. Các chức năng bình thường không có đầu vào cũng sẽ bị bỏ qua
Luis Mendo

2

Python (3.5) 160 151 150 byte

Một giải pháp đệ quy

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

Ungolfed mà không có lambda

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

Tôi xoay tất cả các hộp thay vì quây. Vị trí quây là giữa ký tự thứ nhất và thứ hai của chuỗi c. Tôi cần phải kiểm tra tất cả vị trí bắt đầu của tay quay.

Thủ thuật sử dụng để xoay chuỗi

Cách thông thường để xoay một chuỗi trong python ( s[i:]+s[:i]) cần lặp lại cả chỉ mục và chuỗi. Trong trường hợp này, tôi nhân đôi chuỗi và cắt các ký tự đầu tiên.

(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

Các trường hợp thử nghiệm

[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
Bạn có thể loại bỏ không gian tại 3"[i:]) for.
Erik the Outgolfer

@EriktheOutgolfer cảm ơn tôi xóa nó.
Erwan


1

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

15 byte được lưu bởi Neil! Phiên bản gốc chưa được chỉnh sửa:

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
}

Các xét nghiệm: https://jsbin.com/cuqicajuko/1/edit?js,console


1
Bạn đã tiết kiệm được 17 byte:(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

Vẫn không ngắn như câu trả lời của @ user81655.
Neil

1

Mã máy Turing, 395 byte

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

Hãy thử trực tuyến!

Về cơ bản, đây là một cách tiếp cận dựa trên nhà nước:

  • Trạng thái ban đầu là 0.
  • a, b, c, Và dlà "tiểu bang chưa quyết định" đó chỉ xảy ra ngay từ đầu
  • N, E, S, Và Wlà những "tiểu bang quyết định", rõ ràng là đứng cho NOrth, East, South, và West.

1

Thứ ba, 203 byte

Tôi không thể nghĩ làm thế nào để chơi golf xa hơn.

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<

Nếu trình tự ghi chú là có thể, sẽ xuất ra hướng kết thúc, nếu không thì đầu ra sẽ trống.


1

Prolog (SWI) , 117 byte

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,_).

Xác định một vị từ pthành công trên các đầu vào có thể phát (được đưa ra dưới dạng danh sách các số nguyên) và không thành công trên các số nguyên. Hãy thử trực tuyến!

Giải trình

axác định một mối quan hệ kề giữa Nvị trí ghi chú và tay quay P. Chúng tôi xác định vị trí p nằm giữa các ghi chú pp + 1 . Do đó, một vị trí liền kề để lưu ý Niff

  • nó bằng N( P=N); hoặc là
  • ghi chú là 1 và vị trí là 4 ( N=1,P=4); hoặc là
  • trường hợp trên không đúng ( !) và vị trí bằng N-1( P is N-1).

mlấy một danh sách các ghi chú và cố gắng tạo một danh sách các vị trí sẽ phát các ghi chú đó. Alà nốt nhạc vừa chơi, Blà nốt nhạc sắp được phát; Xlà vị trí quây hiện tại, Ylà vị trí quây tiếp theo. Một động thái là hợp lệ

  • ghi chú vừa chơi nằm liền kề với vị trí quây hiện tại ( a(A,X));
  • lưu ý sắp được phát cũng liền kề với vị trí quay tay hiện tại ( a(B,X));
  • ghi chú sắp được chơi nằm liền kề với vị trí quây tiếp theo ( a(B,Y)); và
  • hai vị trí quây không bằng nhau ( X\=Y).

Nếu tất cả những thứ này giữ lại, tái diễn. Nếu chúng tôi thành công xuống bất kỳ một ghi chú ( m([_],_)), chuỗi ghi chú có thể phát được.

Đối với câu hỏi này, chúng tôi chỉ quan tâm liệu một chuỗi di chuyển có tồn tại hay không, vì vậy chúng tôi xác định pđể gọi mvà loại bỏ danh sách các vị trí quay được tạo.

Xem phiên bản chưa được chỉnh sửa và xác minh tất cả các trường hợp thử nghiệm tại đây .

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.