Bisakah kotak musik 4-note saya memutar lagu itu?

51

Saya memiliki kotak musik yang dioperasikan engkol yang dapat memainkan serangkaian empat catatan. Ketika saya memutar engkol, itu memutar salah satu dari empat senar, tergantung pada posisi engkol dan arah putaran. Ketika engkol diputar ke utara, kotak (dengan senar bernomor 1 hingga 4) terlihat seperti ini:

1  |  2
   |
   O   

4     3

Dari sana, saya bisa memutar engkol searah jarum jam untuk memetik senar # 2 dan mengarahkan engkol ke timur:

1     2

   O---   

4     3

Sebagai alternatif, saya juga bisa memutar engkol berlawanan arah jarum jam dari utara untuk memainkan string # 1 dan mengakhiri dengan engkol yang menunjuk ke barat:

1     2

---O   

4     3

Maka, pada waktu tertentu, kotak itu dapat memainkan salah satu dari dua not: not berikutnya tersedia dalam arah searah jarum jam atau not berikutnya dalam arah berlawanan arah jarum jam.

Tantangan

Tantangan Anda adalah menulis program atau fungsi yang menerima string nilai not yang tidak kosong (yaitu, angka yang 1dilewati 4) dan menentukan apakah mungkin untuk memainkan urutan not pada kotak musik. Menghasilkan hasil yang benar atau salah untuk menunjukkan kemampuan memutar atau tidak dapat dimainkannya input.

Beberapa catatan:

  • Masukan tidak membuat asumsi tentang posisi awal awal. Input 214(mulai ke timur dan bergerak sangat berlawanan arah jarum jam) dan 234(mulai ke utara dan bergerak dengan ketat searah jarum jam) dan keduanya valid.

  • Engkol dapat bergerak bebas ke kedua arah setelah setiap nada. Serangkaian catatan yang sama dimungkinkan (misalnya, 33333) dengan bergerak bolak-balik melintasi satu string. Serial 1221441ini dapat dimainkan dengan sempurna (mulai barat, bergerak searah jarum jam dua langkah, lalu berlawanan arah tiga langkah, lalu searah jarum jam dua langkah).

Sampel

Beberapa truekasus:

1
1234
1221
3333
143332
22234
2234
22214
1221441
41233

Beberapa falsekasus:

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  
apsillers
sumber
Bisakah input menjadi string termasuk kutipan?
Luis Mendo
@LuisMendo Tentu, saya akan mengizinkannya - Saya tertarik dengan algoritme Anda, tidak membuat Anda melompat melewati lingkaran untuk mendapatkan input. Lagi pula, ada konsensus komunitas tidak resmi yang pada umumnya baik-baik saja: Masukan string dengan atau tanpa ""?
apsillers
1
Saya tidak tahu itu. Terima kasih untuk tautannya!
Luis Mendo
1
@AJMansfield Tidak, solusi harus memungkinkan untuk banyak siklus sewenang-wenang. Tentu saja, jika beberapa input menyebabkan kode Anda melebihi batas dalam penerjemah bahasa Anda atau memori komputer Anda, tidak apa-apa (karena itu hanya dibatasi oleh seberapa banyak memori yang Anda miliki secara fisik atau memungkinkan penerjemah Anda), tetapi solusi Anda tidak boleh memaksakan batasan tambahan pada seberapa jauh atau berapa kali engkol bergerak.
apsillers
1
Tantangan ini telah memenangkan kategori Tidak semudah kelihatannya di Best of PPCG 2016. Sayangnya, kami tidak dapat memberikan hadiah untuk tantangan, tetapi Zgarb telah menulis tantangan untuk kehormatan Anda . Selamat!
Martin Ender

Jawaban:

9

Pyth, 30 27 byte

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

Inilah idenya:

 1.5  1  0.5

  2       0

 2.5  3  3.5

Engkol selalu pada posisi setengah bilangan bulat c. Pada setiap langkah, kami merefleksikannya pada nota posisi integer ndengan menetapkan c = 2*n-c. Jika nvalid, cubah dengan ± 1 mod 8. Jika ntidak valid, cubah dengan ± 3 mod 8. Kami secara kumulatif mengurangi input untuk mengumpulkan semua nilai c, dan kemudian melihat apakah semua catatan valid. Kami melakukan ini untuk setiap nilai awal c, karena lebih pendek daripada memeriksa hanya yang berdekatan dengan catatan pertama.

Diformat:

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

Suite uji .

lirtosiast
sumber
18

CJam, 34 31 byte

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

Apakah ini di ponsel saya, jadi saya harus memberikan penjelasan nanti. Output tidak kosong jika jujur.

Cobalah online | Suite uji

Penjelasan

Kode baru sedikit mengubah tata letak:

2    3    4

1    .    5

0/8  7    6

Angka genap sesuai dengan posisi string dan angka ganjil sesuai dengan posisi engkol.

Inilah yang terjadi:

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

Tumpukan kemudian dicetak secara otomatis di bagian akhir. Setiap posisi akhir yang mungkin ada dalam output, misalnya untuk input 1output 31, yang berarti engkol dapat berakhir menghadap ke kiri atau ke atas.

Kalau saja CJam memiliki filter dengan parameter tambahan ...


Sunting: Sementara memutar kembali sementara saya meyakinkan diri sendiri bahwa 29-byte ini berfungsi:

8,q{~2*f{_@-_7b1#@@+8,=|}W-}/
Sp3000
sumber
37
Setiap kali seseorang menjawab dengan bahasa yang sulit seperti Kim dan mengatakan "lakukan ini di ponsel saya" Saya mati sedikit di dalam
Dennis van Gils
2
Dia mungkin berarti teks itu dikeluarkan menggunakan telepon, tetapi itu dilakukan di kepalanya.
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)

Ini mengevaluasi ke fungsi anonim yang mengambil string dan mengembalikan boolean. Test suite di sini.

Penjelasan

Idenya adalah bahwa lambda di sebelah kanan peta nomor ake [[a,a+1],[a+1,a]], dua kemungkinan "bergerak" yang mengambil engkol lebih jumlah itu, menurut diagram berikut:

  1 (2) 2

(1/5)  (3)

  4 (4) 3

Dalam fungsi anonim utama, pertama-tama kita lakukan mapM((...).read.pure), yang mengubah setiap karakter menjadi bilangan bulat, menerapkan lambda di atasnya, dan memilih salah satu dari dua gerakan, mengembalikan daftar semua urutan langkah yang dihasilkan. Kemudian, kami memeriksa apakah ada dari sekuens ini yang memiliki properti bahwa jumlah kedua dari setiap gerakan sama dengan jumlah pertama dari modulo 4 berikutnya, yang berarti bahwa itu adalah urutan yang memungkinkan secara fisik. Untuk melakukan ini, kita zipmasing-masing memindahkan urutan dengan tail, memeriksa kondisi untuk allpasangan, dan melihat apakah anyurutan mengevaluasi True.

Zgarb
sumber
7

Retina, 50 byte

A`13|31|24|42|(.)(?!\1)(.)(\2\2)*(\1|\2(?!\1|\2).)

Saya pikir ini berhasil?

Coba di sini.

jimmy23013
sumber
6

Retina , 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))*$

Ini mencetak 0atau 1, sesuai.

Cobalah online! (Ini adalah versi yang sedikit dimodifikasi yang menandai semua kecocokan dalam input alih-alih mencetak 0atau 1.)

Saya mencoba membuat algoritma yang elegan, tetapi beberapa upaya pertama saya tidak dapat menghindari backtracking ... dan menerapkan backtracking itu mengganggu ... jadi saya menggunakan bahasa yang melakukan backtracking untuk saya di mana saya hanya perlu menyandikan solusi yang valid. Sayangnya, pengkodeannya cukup bertele-tele dan cukup berlebihan ... Saya yakin ini bisa dipersingkat.

Sementara saya mencoba mencari tahu sesuatu yang lebih rapi, jika ada yang ingin memilah cara kerjanya, ini adalah versi yang lebih mudah dibaca:

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

Dan ini adalah sebuah petunjuk:

1  a  2

d  O  b

4  c  3
Martin Ender
sumber
6

MATL , 57 55 byte

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

Ini menggunakan rilis saat ini (10.2.1) , yang lebih awal dari tantangan ini.

EDIT (17 Januari, 2017): karena perubahan bahasa,v perlu diganti oleh &v, dan tL3$)oleh Y)(selain itu, beberapa perbaikan lain dapat dilakukan). Tautan berikut mencakup dua modifikasi tersebut

Cobalah online!

Penjelasan

Ini didasarkan pada dua alat favorit saya untuk golf kode: brute force dan convolution .

Kode mendefinisikan jalur diikuti oleh engkol dalam hal koordinat 0.5, 1.5dll. Setiap angka memberitahu posisi engkol antara catatan. Kode pertama kali membangun larik lintasan dengan semua lintasan yang mungkin yang dimulai dengan nada pertama dari string input. Setiap jalur adalah kolom dalam array ini. Ini adalah komponen brute force .

Dari larik lintasan ini, larik catatan diperoleh, di mana setiap kolom adalah urutan catatan yang dimainkan. Misalnya, pindah dari posisi 0.5ke 1.5menghasilkan catatan 1. Ini terdiri dari mengambil rata-rata antara posisi dan kemudian menerapkan operasi modulo 4. Rata-rata berjalan di sepanjang setiap kolom dilakukan dengan konvolusi 2D .

Akhirnya, program memeriksa apakah ada kolom array catatan yang bertepatan dengan input.

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
Luis Mendo
sumber
5

Pyth, 43

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

Test Suite

Ini mungkin sangat golfable, dan juga bukan algoritma yang optimal untuk golf (saya berharap menghitung semua jalur akan lebih pendek?) ... Lagi pula, jika Anda menemukan kesalahan dengan algoritma tolong beri tahu saya, saya pikir itu harus bekerja tetapi saya pernah salah sebelumnya!

Saya akan menjelaskan algoritma saya menggunakan contoh input 1221. Program ini pertama memetakan angka melawan penerus mereka, seperti: [[1,2],[2,2],[2,1]]. Kemudian mendapat perbedaan mereka mod 4(Pyth mendapat hasil yang cocok dengan tanda argumen yang tepat %, jadi ini selalu positif): [3,0,1]. Kemudian hasilnya dibagi pada 0dan telah 2dikurangi dari masing-masing: [[1],[-1]].

Sekarang setelah setup selesai, kami membuat daftar [-1,1,-1...]dan negasinya [1,-1,...], sama panjangnya dengan array yang dihasilkan dari sebelumnya. Kemudian, untuk masing-masing daftar ini, lakukan pengurangan setwise antara elemen daftar dan daftar yang dihasilkan pada langkah sebelumnya. Kemudian, jika salah satu dari hasil hanya berisi daftar kosong, kami menampilkan true.

FryAmTheEggman
sumber
Apa yang Anda maksud dengan "hasilnya dibagi 0"? Khususnya, untuk apa Anda 1221221dan 1221441?
Neil
1
@ Neil 1221221adalah palsu dan 1221441memberikan benar secara keseluruhan, tetapi jika saya mengerti Anda ingin hasilnya setelah langkah itu dalam algoritma? Jika itu adalah kasus memberikan: dari [3, 0, 1, 3, 0, 1]ke [[3], [1, 3], [1]]dan [3, 0, 1, 1, 0, 3]ke [[3], [1, 1], [3]]. Beri tahu saya jika Anda ingin sesuatu yang lain dijelaskan :)
FryAmTheEggman
Saya pikir saya lebih bingung dari sebelumnya, jadi bisakah Anda menyelesaikan dua contoh itu untuk menjelaskan bagaimana hasil (benar) tercapai?
Neil
1
@Neil Tentu, tidak ada masalah :) Dari sana, kami melakukan pengurangan untuk mendapatkan: [[1], [-1, 1], [-1]]dan [[1], [-1, -1], [1]]dari sini, Anda dapat melihat bahwa yang pertama tidak memiliki daftar yang bergantian antara -1dan 1sementara daftar lainnya, memberikan hasil akhir. Algoritma ini agak tumpul, tetapi pada dasarnya memetakan perubahan 0arah dan arah sebagai +/-1, kemudian memeriksa bahwa tidak ada lompatan dibuat dan arah masuk akal.
FryAmTheEggman
Oh, jadi bit yang saya lewatkan adalah bahwa setiap daftar split harus terdiri dari nilai yang sama, dan nilai-nilai itu harus bergantian. Terima kasih!
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

Solusi yang cukup malas, tetapi yang terpendek yang bisa saya lakukan. Saya membuat matriks khusus: Ketika Anda mengkodekan keadaan pemetik dan string terakhir yang akan dipetik, ia mengembalikan vektor, yang mengkodekan posisi baru pemetik , dan apakah pemetik sebelumnya dimungkinkan sama sekali. Sekarang kita hanya mengulang semua catatan dari dua posisi awal yang memungkinkan dan melihat apakah salah satunya menghasilkan melodi yang dapat dimainkan. Mungkin bisa bermain golf lebih banyak.

Sumber diperluas dan dijelaskan:

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

Sunting: Disimpan 4 byte berkat @DigitalTrauma.

Ini adalah penulisan ulang yang lengkap karena pendekatan saya sebelumnya cacat.

Saya mulai dengan mengurangi semua run digit menjadi 1 atau 2 tergantung pada apakah ada angka ganjil atau genap dalam menjalankan. Saya kemudian mencari semua kombinasi ilegal:

  • 13|24|31|42 (sisi berlawanan)
  • 3[24]{2}1sebagai 3221dan 3441ilegal
  • sama untuk 4xx2, 1xx3dan di 2xx4mana xsalah satu dari digit yang hilang
  • (.).\1karena hal-hal seperti 121ilegal ( 111telah dikurangi menjadi 1sebelumnya)

Jika tidak ada pasangan ilegal atau "tiga kali lipat" maka seluruh string sah (bukti dengan induksi dibiarkan sebagai latihan karena sudah larut malam di sini).

Saya mencoba untuk menyederhanakan 3[24]{2}1|1[24]{2}3menggunakan pernyataan lookahead negatif tetapi ternyata lebih lama seperti itu.

Neil
sumber
f("1122") => true@DigitalTrauma
Conor O'Brien
@ CᴏɴᴏʀO'Bʀɪᴇɴ Saya tidak melihat ada yang salah dengan itu. Di sisi lain saya telah menyadari bahwa f("1221221")menghasilkan jawaban yang salah, jadi saya harus memikirkan kembali.
Neil
Selalu menyenangkan untuk menyertakan test suite, '43221' gagal: jsbin.com/vafitotequ/1/edit?js,console
Pavlo
@Pavlo Whoops, aku golfed [24][24]ke (2|4)\1tapi aku tidak diuji secara memadai. Maaf soal itu.
Neil
Bisa Anda golf [24][24]ke [24]{2}?
Trauma Digital
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

Penjelasan

i%4 adalah posisi engkol saat ini:

    1 (i%4 == 1) 2   

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

    4 (i%4 == 3) 3   

Diindentasi dan Dikomentari

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

Uji

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>

pengguna81655
sumber
Bagus sekali. Apakah Anda akan menjelaskan cara |kerjanya dalam kasus ini?
Pavlo
1
@ pavlo Terima kasih. Ini cara menulis yang lebih pendek (x.map(...),v). Ia bekerja karena larik yang mapdikembalikan ke 0dan 0|v == v.
user81655
2

Lua , 146 142 108 162 159 149 135 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

Mengembalikan benar atau salah diberi string angka antara 1 dan 4. (Tidak menangani data atau di luar angka jangkauan.

Cukup melacak apa gerakan terakhir itu dan memeriksa apakah gerakan ini adalah pembalikan dari gerakan terakhir (IE, 121 atau 12221) atau jika jarak bergerak lebih dari mungkin.

EDIT 1 :

Disimpan 6 byte. Saya lupa bahwa if (int) thenmengembalikan true jika int bukan nol.

Jadi:

if t~=0 then

perubahan ke:

if t then

Juga menghemat beberapa byte dengan restrukturisasi.

EDIT 2 :

Saya perlahan mencari tahu ini. Saya telah membaca dokumentasi di sini: http://www.lua.org/pil/ Dan salah satu halaman yang lebih berguna di sana untuk bermain golf adalah http://www.lua.org/pil/3.3.html

Secara khusus, ini sangat membantu:

Seperti struktur kontrol, semua operator logis menganggap false dan nil sebagai false dan yang lainnya benar.

Apa artinya ini bagi saya adalah bahwa saya dapat melanjutkan dan menghapus deklarasi saya untuk q ( yang awalnya ditetapkan ke 0 ) karena akan dianggap sebagai "salah" sampai ditetapkan. Jadi saya menyimpan beberapa byte lagi melalui ini.

Hal lain yang layak disebut, meskipun saya tidak menggunakannya, adalah jika Anda ingin menukar nilai dalam Lua, Anda bisa melakukannya a,b=b,a tanpa perlu variabel sementara.

EDIT 3

Jadi, melalui beberapa rekonstruksi pintar serta fungsi baru, saya punya hitungan mundur 9 oleh lebih.

Mode Terbaik untuk Menerima Input

Jika Anda perlu membaca daftar angka dan melakukan operasi satu per satu, Anda dapat menggunakan:

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

Jika dibandingkan dengan alternatif Anda menggunakan string: sub, Anda dapat melihat nilai untuk golf (atau penggunaan umum):

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

Merestrukturisasi Fungsi atau String

Hal kedua, jika Anda memiliki banyak deklarasi pada satu baris dan salah satu nilainya adalah fungsi atau Anda memiliki kondisi di mana Anda membandingkan angka dengan hasil fungsi seperti ini:

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

if math.abs(x)==2 then

dengan menata ulang sehingga tanda kurung penutup adalah karakter terakhir dalam kondisi atau deklarasi, Anda dapat memotong karakter seperti:

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

Mengembalikan Kondisi yang Menyamakan Benar atau Salah, bukan 'Benar' atau 'Salah'

Saya menemukan cara yang agak lucu untuk mengurangi jumlah byte saya lebih jauh. Jika Anda perlu mengembalikan benar atau salah, Anda dapat mengembalikan pernyataan yang sama dengan benar atau salah yang memiliki karakter kurang dari "benar" atau "salah" sendiri.

Misalnya, bandingkan:

return true
return false

Untuk:

return 2>1
return 1>2
Skyl3r
sumber
121seharusnya output salah.
lirtosiast
Ah, tidak apa-apa. Saya melihat. Akan segera diperbaiki
Skyl3r
Anda mungkin tertarik untuk menambahkan beberapa tips Lua ke Tips untuk bermain golf di Lua jika Anda belum melihat mereka terdaftar di sana.
apsillers
2

MATL, 49 byte (tidak bersaing 1 )

1. Jawabannya (ab) menggunakan pengindeksan yang lebih ketat dari versi MATL yang lebih baru, dan tidak akan berfungsi pada saat tantangan ini diposting.

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

Cobalah online! .

Saya melihat tantangan ini di Best of PPCG 2016 , dan berpikir bahwa ini bisa menggunakan operator favorit saya :

d

Atau, diffdalam MATLAB / Octave (saya akan dengan bebas menggunakan terminologi MATLAB / Octave dalam penjelasan saya, karena lebih mudah dibaca untuk manusia). Perintah ini menghitung perbedaan elemen-bijaksana dalam vektor atau, dalam hal ini, dalam array karakter.

Untuk masalah ini, perbedaannya menunjukkan pola yang menarik. Catat itu

Perubahan arah harus berarti bahwa not dimainkan dua kali .

Untuk pola perbedaan (mengabaikan 1-4transisi untuk saat ini), ini artinya

Perubahan saat masuk diff(input)harus memiliki angka nol yang ganjil di antaranya. Sebaliknya, tanda tidak diizinkan untuk berubah setelah angka nol genap .


Saya menerapkan ini dengan, untuk setiap array, menemukan nol pertama. Saya memangkas nol, dan melipatgandakan semua elemen setelahnya -1. Untuk hasil akhirnya, ini berarti semua elemen harus memiliki tanda yang sama. Tentu saja, ada masalah kecil -3penyamaan +1, dan 2ditolak secara umum. Saya memecahkan ini dengan membawa set gabungan hasil dengan [1 -3], dan memeriksa apakah ini adalah ukuran 2 (yaitu, tidak ada elemen yang tidak diizinkan 'memasuki' set melalui serikat). Ulangi untuk [-1 3], dan periksa apakah salah satu (atau keduanya, dalam hal input 1-panjang) benar.

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. 
Sanchises
sumber
@LuisMendo Terima kasih. Saya benar-benar perlu membaca M, terakhir kali saya mencobanya, itu bekerja berbeda dari yang diharapkan jadi saya mengabaikannya untuk sementara waktu. Apakah benar mengatakan bahwa itu perlu 3Mkarena saya mendapatkan input bukan ), bukan :tetapi q(melewatkan wkarena itu bukan fungsi normal )?
Sanchises
Ya persis. wdilewati karena itu bukan fungsi normal. Fungsi normal yang tidak mengambil input akan dilewati juga
Luis Mendo
2

Python (3.5) 160 151 150 byte

Solusi rekursif

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

Tidak disatukan tanpa 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)])

Saya memutar semua kotak, bukan engkol. Posisi engkol adalah antara karakter pertama dan kedua dari string c. Saya perlu menguji semua posisi awal engkol.

Trik digunakan untuk memutar string

Cara biasa untuk memutar string dalam python ( s[i:]+s[:i]) perlu mengulangi baik indeks dan string. Dalam hal ini saya menduplikasi string dan memotong karakter pertama.

(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

Uji kasus

[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]
Erwan
sumber
1
Anda dapat menghapus ruang di 3"[i:]) for.
Erik the Outgolfer
@EriktheOutgolfer terima kasih saya hapus.
Erwan
2

Python 2 , 65 byte

n=15
for c in input():k=2**int(c);n=n*17/k%4*5/2%4*k%15
print n>0

Cobalah online!

Tidak
sumber
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 disimpan oleh Neil! Versi asli ungolfed:

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
}

Pengujian: https://jsbin.com/cuqicajuko/1/edit?js,console

Pavlo
sumber
1
Menyelamatkan Anda 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
Masih tidak sesingkat jawaban user81655.
Neil
1

Kode mesin 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

Cobalah online!

Ini pada dasarnya adalah pendekatan berbasis negara:

  • Keadaan awal adalah 0.
  • a, b, c, Dan dadalah "ragu-ragu menyatakan" bahwa hanya terjadi pada awal
  • N, E, S, Dan Wadalah "negara memutuskan", jelas berdiri untuk North, East, Selatan, dan West.
Biarawati Bocor
sumber
1

Thue, 203 byte

Saya tidak bisa memikirkan bagaimana cara bermain golf ini lebih jauh.

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<

Jika urutan note dimungkinkan, akan menampilkan arah akhir, jika tidak maka output akan kosong.

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

Menentukan predikat pyang berhasil pada input yang dapat diputar (diberikan sebagai daftar bilangan bulat) dan gagal pada yang tidak dapat dimainkan. Cobalah online!

Penjelasan

amendefinisikan hubungan kedekatan antara catatan Ndan posisi engkol P. Kami mendefinisikan posisi p berada di antara catatan p dan p + 1 . Dengan demikian, suatu posisi berbatasan dengan note Niff

  • itu sama dengan N( P=N); atau
  • catatannya adalah 1 dan posisinya adalah 4 ( N=1,P=4); atau
  • kasus di atas tidak benar ( !) dan posisinya sama dengan N-1( P is N-1).

mmengambil daftar catatan dan mencoba menghasilkan daftar posisi yang akan memainkan catatan itu. Aadalah not yang baru saja diputar, Bapakah not akan segera dimainkan; Xadalah posisi engkol saat ini, Yadalah posisi engkol berikutnya. Suatu langkah sah jika iff

  • not yang baru saja diputar berbatasan dengan posisi engkol saat ini ( a(A,X));
  • nada yang akan dimainkan juga berdekatan dengan posisi engkol saat ini ( a(B,X));
  • nada yang akan diputar berbatasan dengan posisi engkol berikutnya ( a(B,Y)); dan
  • dua posisi engkol tidak sama ( X\=Y).

Jika semua ini bertahan, kambuh. Jika kami berhasil masuk ke salah satu catatan ( m([_],_)), urutan catatan dapat diputar.

Untuk pertanyaan ini, kami hanya peduli apakah ada urutan pergerakan, jadi kami menetapkan puntuk memanggil mdan membuang daftar posisi engkol yang dihasilkan.

Lihat versi yang tidak dipisahkan dan verifikasi semua kasus uji di sini .

DLosc
sumber