4 nota müzik kutum bu şarkıyı çalabilir mi?


51

Bir dizi dört nota çalabilecek krankla çalışan bir müzik kutum var. Krank çevirdiğimde, krankın konumuna ve dönüşün yönüne bağlı olarak dört dizeden birini tıkar. Krank nedeniyle kuzeye çevrildiğinde, kutu (1'den 4'e kadar olan dizeleri ile) şöyle görünür:

1  |  2
   |
   O   

4     3

Oradan, # 2 dizesini koparmak ve krankın doğuya doğrultmak için krankı saat yönünde çevirebilirim:

1     2

   O---   

4     3

Alternatif olarak, # 1 ipi çalmak için krankı saat yönünün tersine çevirip, krank işaretini batıya bakabilirdim:

1     2

---O   

4     3

Herhangi bir zamanda, kutu iki kutudan birini çalabilir: saat yönünde yönünde bulunan bir sonraki nota veya saat yönünün tersine bir sonraki nota.

Meydan okuma

Buradaki zorluk, boş olmayan bir not değerleri dizisini (yani sayılar 1arasında 4) kabul eden bir program veya işlev yazmak ve bu nota dizisini müzik kutusunda çalmanın mümkün olup olmadığını tespit etmektir. Girdinin oynanabilirliğini veya oynanabilirliğini belirtmek için bir gerçek veya sahte sonuç üretin.

Bazı notlar:

  • Giriş, başlangıç ​​başlangıç ​​konumu hakkında varsayımda bulunmaz. Girişler 214(doğudan başlayarak ve saat yönünün tersine tam olarak hareket eden) ve 234(kuzeyden başlayarak ve saat yönünde tam olarak saat yönünde hareket ederek) ve her ikisi de geçerlidir.

  • Krank, her nottan sonra her iki yönde de serbestçe hareket edebilir. Aynı nota bir dizi (örneğin, 33333) bir dize boyunca ileri geri hareket ettirilerek mümkündür . Seri 1221441mükemmel oynanabilir (batıdan başlayarak saat yönünde iki adım, sonra saat yönünün tersine üç adım, sonra saat yönünde iki adım).

Numuneler

Bazı truedurumlar:

1
1234
1221
3333
143332
22234
2234
22214
1221441
41233

Bazı falsedurumlar:

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  

Girdi, tırnak içeren dizge olabilir mi?
Luis Mendo

@LuisMendo Tabii, izin vereceğim - Algoritmanla ilgileniyorum, giriş elde etmek için size çemberin içinden atlamayın. Neyse, genel olarak tamam olduğuna dair resmi olmayan bir topluluk oybirliği var: “” ile veya onsuz string girişi?
apsillers

1
Bunu bilmiyordum. Bağlantı için teşekkürler!
Luis Mendo,

1
@AJMansfield Hayır, çözümler keyfi bir şekilde birçok devire izin vermelidir. Elbette, bazı girdiler kodunuzun dilinizin tercümanında veya bilgisayarınızın hafızasında bir sınırı aşmasına neden oluyorsa, sorun değil (çünkü fiziksel olarak sahip olduğunuz veya tercümanınız izin verdiği kadar hafıza ile sınırlıdır), ancak çözümünüz ekstra sınırlamalar getirmemelidir krankın ne kadar uzağa veya kaç kere hareket ettiği.
apsillers

1
Bu meydan okuma PPCG 2016'nın En İyisi kategorisinde göründüğü kadar basit değil . Maalesef, zorluklara ödül veremiyoruz , ama Zgarb şerefine bir meydan okuma yazdı . Tebrikler!
Martin Ender

Yanıtlar:


9

Pyth, 30 27 bayt

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

İşte fikir:

 1.5  1  0.5

  2       0

 2.5  3  3.5

Krank her zaman yarı-tamsayı pozisyonundadır c. Her adımda, onu bir tamsayı pozisyonu notuna nayarlayarak yansıtıyoruz c = 2*n-c. Eğer ngeçerliyse, c± 1 mod 8 ile değişir. nGeçersiz ise, c± 3 mod 8 ile değişir. Tüm değerleri toplamak için girdi üzerinde kümülatif olarak azalma yapar cve sonra tüm notların geçerli olup olmadığına bakarız. Bunu her başlangıç ​​değeri için yapıyoruz c, çünkü sadece ilk nota bitişik olanları kontrol etmekten daha kısa.

biçimlendirilmiş:

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

Test paketi .


18

CJam, 34 31 bayt

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

Telefonumda yaptım, bu yüzden daha sonra bir açıklama yapmak zorunda kalacağım. Çıktı boş değil iffet.

Çevrimiçi deneyin | Test odası

açıklama

Yeni kod düzeni biraz değiştiriyor:

2    3    4

1    .    5

0/8  7    6

Rakamlar bile ip pozisyonlarına ve tek rakamlar krank pozisyonlarına karşılık gelir.

İşte olanlar:

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

Yığın daha sonra otomatik olarak sonunda yazdırılır. Herhangi bir olası sonlandırma pozisyonu çıkışta olacaktır, örneğin 1çıkış için olduğu gibi 31, krank sola veya yukarı bakacak şekilde sona erebilir.

Keşke CJam ekstra parametreli filtrelerse ...


Düzenleme: Kendimi bu 29 baytın çalıştığına ikna ederken geçici olarak geri dönüyorum:

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

37
Ne zaman birisi cjam gibi zor bir dille cevap verir ve "bunu telefonumda yaptım" der, ben biraz içeride ölürüm
Dennis van Gils

2
Muhtemelen metnin bir telefon kullanılarak çıktısını alması anlamına geliyordu, fakat kafasında yapıldı.
Nelson

7

Haskell, 93 88 87 bayt

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

Bu, bir dize alan ve bir boole döndüren adsız bir işlevi değerlendirir. Burada test paketi.

açıklama

Fikir sağda lambda bir sayı eşler olmasıdır aiçin [[a,a+1],[a+1,a]]aşağıdaki şemaya göre, bu sayının üzerinde krank almak iki olası "hamle",:

  1 (2) 2

(1/5)  (3)

  4 (4) 3

Ana adsız işlevde, ilk önce mapM((...).read.pure)her karakteri bir tam sayıya dönüştüren ilk lambdayı ona uygular ve sonuçtaki tüm hareket dizilerinin listesini döndürerek iki hareketten birini seçeriz. Daha sonra, bu dizilerin herhangi birinin her bir hareketin ikinci sayısının bir sonraki modulo 4'ün ilk sayısına eşit olup olmadığını kontrol eder, bunun fiziksel olarak mümkün bir dizi olduğu anlamına gelir. Bunu yapmak için zipher bir diziyi onunla hareket ettiririz , çiftlerin taildurumunu kontrol ederiz allve anydizinin değerlendirilip değerlendirilmediğini kontrol ederiz True.



6

Retina , 127 109 bayt

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

Bu , 0veya 1buna göre yazdırır .

Çevrimiçi deneyin! (Bu yerine baskı girdi tüm eşleşmeleri işaretler biraz değiştirilmiş bir versiyonudur 0ya 1.)

Zarif bir algoritma geliştirmeye çalıştım, ancak ilk birkaç denemem geriye doğru izlemeyi engelleyemedi ... ve geri izlemeyi uygulamak can sıkıcıydı ... bu yüzden benim için geri izlemeyi yapan bir dil kullandım. geçerli bir çözüm Ne yazık ki, kodlama oldukça ayrıntılı ve oldukça gereksiz ... Bunun kısaltılabileceğine eminim.

Daha düzgün bir şey bulmaya çalışırken, eğer biri bunun nasıl çalıştığını çözmek isterse, işte biraz daha okunaklı bir sürüm:

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

Ve işte bir ipucu:

1  a  2

d  O  b

4  c  3

6

MATL , 57 55 bayt

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

Bu, bu zorluktan daha önceki olan geçerli sürümü (10.2.1) kullanır .

DÜZENLEME (17 Ocak 2017): nedeniyle dilinde değişikliklere,v ihtiyaç tarafından değiştirilmesi &vve tL3$)tarafından Y)(ek olarak diğer bazı iyileştirmeler olabilir yapılabilir). Aşağıdaki link bu iki değişikliği içermektedir.

Çevrimiçi deneyin!

açıklama

Bu kod golf için favori araçlarımdan ikisine dayanıyor: kaba kuvvet ve evrişim .

Kod , krankın takip ettiği yolu koordinatlar 0.5, 1.5vb. Cinsinden tanımlar . Her numara, krankın notlar arasındaki konumunu belirtir. Kod ilk önce giriş dizesinin ilk notu ile başlayan tüm olası yolları içeren bir yol dizisi oluşturur . Her yol bu dizideki bir sütundur. Bu kaba kuvvet bileşenidir.

Bu yol dizisinden, her bir sütunun çalınan notaların gerçekleştirilebilir bir dizisi olduğu bir not dizisi elde edilir. Örneğin, konumdan hareket 0.5etmek 1.5not üretir 1. Bu, konumlar arasında ortalamayı almak ve ardından bir modulo 4 işlemi uygulamaktan ibarettir. Her sütun boyunca akan ortalama, 2B evrişim ile yapılır .

Son olarak, program not dizisinin herhangi bir sütununun girişle çakışıp çakışmadığını kontrol eder.

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

Pyth, 43

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

Test odası

Bu muhtemelen çok golf oynamaktadır ve aynı zamanda golf oynamak için en uygun algoritma değildir (tüm yolların numaralandırılmasının daha kısa olacağını mı düşünüyorsunuz?) Daha önce yanılmışım!

Algoritmamın örnek girişini kullanarak açıklayacağım 1221. Bu program ilk önce rakamları haleflerine karşı eşler [[1,2],[2,2],[2,1]]. Sonra onların farklılıkları mod alır 4(Pyth sağ teriminin işaretini maçları sonucu alır %, bu yüzden bu her zaman pozitiftir): [3,0,1]. Sonra sonuçları üzerinde bölünür 0ve adres 2her biri çıkarılır: [[1],[-1]].

Şimdi kurulum yapıldığı için, daha önce elde edilen dizinin uzunluğu ile aynı uzunlukta olan bir liste [-1,1,-1...]ve olumsuzlama oluşturuyoruz [1,-1,...]. Ardından, bu listelerin her biri için, listenin öğeleriyle önceki adımda oluşturulan liste arasında ayarlanmış bir çıkarma yapın. Ardından, sonuçlardan herhangi biri yalnızca boş listeler içeriyorsa, doğru çıktısını alırız.


"Sonuçlar 0'a bölünmüştür" ile ne demek istiyorsunuz? Özellikle ne için 1221221ve ne elde edersiniz 1221441?
Neil

1
@Neil 1221221yanlıştır ve 1221441genel olarak doğru verir, ancak anlarsam algoritmanın bu adımdan sonra sonucunu ister misin? Eğer öyleyse, verdiği şey: [3, 0, 1, 3, 0, 1]ile [[3], [1, 3], [1]]ve [3, 0, 1, 1, 0, 3]arasında [[3], [1, 1], [3]]. Başka bir şeyin açıklanmasını istiyorsanız bana bildirin :)
FryAmTheEggman

Sanırım eskisinden daha fazla kafam karıştı, bu yüzden (doğru) sonuçların nasıl elde edildiğini açıklamak için bu iki örneği bitirebilir misiniz?
Neil

1
@Neil Tabii, sorun yok :) Oradan almak için çıkarma işlemini yapıyoruz: [[1], [-1, 1], [-1]]ve [[1], [-1, -1], [1]]buradan, ilk listenin, diğer liste ile arasında değişen -1ve 1nihai sonucu veren listelerin olmadığını görebilirsiniz . Algoritma biraz geniş, ama temelde yön değişiklikleri haritalama oluyor 0gibi yönünü +/-1o zaman hiçbir sıçramalar yaptı ve yön mantıklı olduğunu kontrol.
FryAmTheEggman

Oh, bu yüzden eksik olan bit, her bölünmüş listenin aynı değerden oluşması ve bu değerlerin değişmeli olmasıydı. Teşekkürler!
Neil

4

Matlab, 279 180 bayt

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

Oldukça tembel bir çözüm, ancak en kısa sürede bulabildim. Özel matris yarattım: Toplayıcı durumunu ve toplanacak son dizgiyi kodladığınızda, toplayıcının yeni konumunu kodlayan bir vektör döndürür ve toplayıcının yeni konumunu hiçbir zaman mümkün olup olmadığına bakar . Şimdi sadece iki olası başlangıç ​​konumundan gelen tüm notaları değiştiriyoruz ve bunlardan birinin oynanabilir bir melodi ile sonuçlanıp sonuçlanmadığını görüyoruz. Muhtemelen çok daha fazla golf olabilir.

Genişletilmiş ve açıklanmış kaynak:

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 bayt

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

Düzenleme: @ DigitalTrauma sayesinde 4 bayt kaydedildi.

Bu benim önceki yaklaşımım kusurlu olduğu için tam bir yeniden yazma.

Çalışmada tek veya çift bir sayı olup olmadığına bağlı olarak tüm basamak basamaklarını 1 veya 2'ye indirerek başlıyorum. Sonra tüm yasa dışı kombinasyonları ararım:

  • 13|24|31|42 (zıt taraflar)
  • 3[24]{2}1olarak 3221ve 3441yasadışı
  • Benzer için 4xx2, 1xx3ve 2xx4nerede xeksik basamak ya olduğu
  • (.).\1Gibi şeyler 121yasadışı olduğu gibi ( 111daha önce düşürüldü 1)

Yasadışı çiftler veya "üçler" yoksa, dizenin tamamı yasaldır (indüksiyonla ispat bir egzersiz olarak bırakılır, çünkü burada gece geç saattir).

3[24]{2}1|1[24]{2}3Olumsuz bir bakış açısı iddiası kullanarak basitleştirmeye çalıştım, ancak bu şekilde daha uzun olduğu ortaya çıktı.


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

@ CᴏɴᴏʀO'Bʀɪᴇɴ Bunda yanlış bir şey görmüyorum. Öte yandan f("1221221"), yanlış cevabı verdiğini farkettim , bu yüzden yeniden düşünmem gerekecek.
Neil


@Pavlo Whoops, golfed ediyorum [24][24]için (2|4)\1ama yeterince test edilmemişti. Bunun için üzgünüm.
Neil

Golf Can [24][24]için [24]{2}?
Dijital Travma,

2

JavaScript (ES6), 80 bayt

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

açıklama

i%4 Geçerli krank pozisyonu:

    1 (i%4 == 1) 2   

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

    4 (i%4 == 3) 3   

Girintili ve Yorumlu

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

Ölçek

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>


Güzel bitti. |Bu durumda nasıl çalıştığını açıklar mısınız?
Pavlo,

1
@pavlo Teşekkürler. Bu daha kısa bir yazı biçimi (x.map(...),v). Çalışır mapdöndürür dizisi 0ve attı çünkü 0|v == v.
user81655

2

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

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 ile 4 arasında bir sayı dizisi verildiğinde doğru veya yanlış döndürür.

Sadece son hareketin ne olduğunu izler ve bu hareketin son hareketin tersini mi (IE, 121 veya 12221) veya mesafenin hareket etmenin mümkün olup olmadığını kontrol eder.

EDIT 1 :

6 bayt kaydedildi. if (int) thenİnt sıfır değilse, bunun doğru olduğunu unuttum .

Böylece:

if t~=0 then

değişiklikleri:

if t then

Ayrıca yeniden yapılanarak birkaç bayt kurtardı.

EDIT 2 :

Bunu yavaşça çözüyorum. Buradaki belgeleri okudum: http://www.lua.org/pil/ Golf oynamak için daha kullanışlı sayfalardan biri http://www.lua.org/pil/3.3.html.

Özellikle, bu çok yardımcı olur:

Kontrol yapıları gibi, tüm mantıksal operatörler yanlış ve sıfır ile yanlış ve başka herhangi bir şeyin doğru olduğunu düşünür.

Bunun benim için anlamı, devam edecek ve ayarlanana kadar "yanlış" olarak kabul edileceği için q ( başlangıçta 0 olarak ayarlanmış ) bildirimi kaldırabilirim . Bu sayede birkaç bayttan tasarruf ediyorum.

Bahsetmeye değer başka bir şey, kullanmasam da, Lua'daki değerleri değiştirmek istiyorsanız, a,b=b,a geçici bir değişkene ihtiyaç duymadan kolayca yapabilirsiniz .

EDIT 3

Bu yüzden, yeni bir fonksiyonun yanı sıra akıllı bir yeniden yapılanma sayesinde, bayt sayısını 9 daha azalttım.

Giriş Almak için En İyi Mod

Bir numara listesini okumanız ve bunlara teker teker işlem yapmanız gerekiyorsa, şunları kullanabilirsiniz:

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

String: sub kullanarak alternatifinize kıyasla, golf (veya genel kullanım) için değeri görebilirsiniz:

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

Yeniden Yapılandırma İşlevleri veya Dizeleri

İkincisi, bir satırda birden fazla bildiriminiz varsa ve değerlerden biri bir işlevdir veya sayıyı aşağıdaki gibi bir işlevin sonucuyla karşılaştıracağınız bir koşul varsa:

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

if math.abs(x)==2 then

yeniden yapılandırarak kapanış parantezi koşul veya bildirimdeki son karakter olacak şekilde şöyle bir karakteri kesebilirsiniz:

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

'Doğru' veya 'Yanlış' yerine Doğru veya Yanlış'a Eşdeğer Dönüş Koşulları

Bayt sayımı daha da azaltmak için yarı eğlenceli bir yol buldum. Doğru veya yanlış döndürmeniz gerekirse, "doğru" veya "yanlış" öğesinden daha az karakter içeren doğru veya yanlış değerine karşılık gelen bir ifade döndürebilirsiniz.

Örneğin, karşılaştırın:

return true
return false

Kime:

return 2>1
return 1>2

121yanlış çıkmalı.
lirtosiast

Ah boşver. Anlıyorum. Kısa süre içinde tamir
edecektir

Bu Lua ipuçlarından bazılarını, Lua'da golf oynamak için İpuçları'na daha önce orada listelenenlerini görmüyorsanız eklemek isteyebilirsiniz .
apsillers

2

MATL, 49 bayt (yarışmayan 1 )

1. (ab) cevabı, MATL'ın daha yeni sürümlerinin daha az katı bir şekilde endekslenmesini kullanır ve bu zorluğun yayınlandığı tarihte işe yaramazdı.

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

Çevrimiçi deneyin! .

Bu zorluğu PPCG 2016'nın En İyisinde gördüm ve bunun en sevdiğim operatörü kullanabileceğini düşündüm :

d

Veya diffMATLAB / Octave (İnsanlarda okumak daha kolay olduğu için açıklamamda MATLAB / Octave terminolojisini serbestçe kullanacağım). Bu komut, bir vektördeki öğe bilgili farkı veya bu durumda bir karakter dizisini hesaplar.

Bu problem için farklılıklar ilginç bir desen sergiler. Bunu not et

Yöndeki değişiklik , bir notun iki kez çalınması anlamına gelmelidir .

Fark deseni için ( 1-4şu an için geçişi yok sayarak ), bunun anlamı

Oturum açmadaki bir değişiklik, aralarında tek sayıda sıfır diff(input)olmalıdır . Tersine, işaret sonrası değiştirmesine izin verilmez hatta sıfır sayısı.


Bunu, her bir dizi için ilk sıfırı bularak gerçekleştirdim. Sıfırı keserim ve ondan sonra tüm elemanları çarparım -1. Sonuçta bu, tüm öğelerin aynı işarete sahip olması gerektiği anlamına gelir . Tabii ki, -3eşitleme +1ve 2genel olarak izin verilmeyen küçük bir mesele var . Bunu sonucun set birleşimini alarak ve bunun [1 -3]2 büyüklüğünde olup olmadığını kontrol ederek çözdüm (yani, sete birleşme üzerinden izin verilmeyen öğelerin hiçbirine 'girmedi'). İçin tekrarlayın [-1 3]ve (veya her ikisi de 1 uzunluklu bir giriş durumunda) doğru olup olmadığını kontrol edin.

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 Teşekkürler. En Mson denediğimde, beklenenden farklı çalıştığı için okumaya ihtiyacım vardı, bu yüzden şimdilik sadece görmezden geldim. Olması gerektiğini doğruysa demek 3Mben girişini olsun o çünkü ), değil :ama q(atlama wo değil gibi normal bir fonksiyonu)?
17'de Sanchises

Evet kesinlikle. watlandı, çünkü normal bir işlev değil. Girdi almayan normal işlevler de atlanır
Luis Mendo

2

Python (3.5) 160 151 150 bayt

Özyinelemeli bir çözüm

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

Lambda olmadan Ungolfed

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

Krank yerine bütün kutuyu döndürdüm. Krank pozisyonu, c dizesinin birinci ve ikinci karakterleri arasındadır. Krankın başlangıç ​​konumunu test etmem gerekiyor.

Hile dizesini döndürmek için kullanın

Bir dizgeyi python ( s[i:]+s[:i]) dizininde döndürmenin genel yolu hem indeksi hem de dizgiyi tekrarlamak zorundadır . Bu durumda dizgeyi kopyalarım ve ilk karakterleri keserim.

(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

Test durumları

[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
Alanındaki boşluğu kaldırabilirsiniz 3"[i:]) for.
Outgolfer Erik,

@EriktheOutgolfer teşekkürler kaldırdım.
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)))

Neil tarafından 15 bayt kurtarıldı! Orijinal sürüm 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
}

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


1
17 bayt (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

Yine de @ user81655'in cevabı kadar kısa değil.
Neil

1

Turing makine kodu, 395 bayt

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

Çevrimiçi deneyin!

Bu temelde devlet temelli bir yaklaşımdır:

  • İlk durum 0'dır.
  • a, b, cVe dsadece başında meydana "kararsız eyaletler" dir
  • N, E, SVe Waçıkçası için ayakta "karar devletler" vardır North, East, South ve West.

1

Thue, 203 bayt

Daha uzağa nasıl golf oynayacağımı düşünemiyorum.

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<

Not dizisi mümkünse, bitiş yönünü çıkar, aksi takdirde çıkış boştur.


1

Prolog (SWI) , 117 bayt

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

pOynatılabilir girdilerde (tam sayıların bir listesi olarak verilir) başarılı olan ve okunamayan girişlerde başarısız olan bir yüklemi tanımlar . Çevrimiçi deneyin!

açıklama

aNot Nve krank pozisyonu arasındaki bitişik ilişkiyi tanımlar.P . Bu konum tanımlar p notları arasında olduğu p ve p + 1 . Böylece, bir pozisyon Niff notuna bitişiktir

  • eşittir N( P=N); veya
  • not 1 ve pozisyon 4 ( N=1,P=4); veya
  • yukarıdaki durum doğru değil (! ) ve pozisyon N-1( P is N-1) 'e eşittir .

m notların bir listesini alır ve bu notları çalacak pozisyonların bir listesini oluşturmaya çalışır. AYeni çalınan not, çalınacak Bnot; XGeçerli krank pozisyonu, Ybir sonraki krank pozisyonudur. Bir hareket geçerli ise iff

  • Yeni çalınan nota mevcut krank pozisyonuna ( a(A,X)) bitişiktir ;
  • Çalınacak nota aynı zamanda krank pozisyonuna bitişiktir ( a(B,X));
  • Çalınacak nota bir sonraki krank pozisyonuna bitişiktir ( a(B,Y)); ve
  • iki krank konumu eşit değil (X\=Y ).

Bunların hepsi tutarsa, tekrarlayın. Başarıyla herhangi bir nota indirirsek (m([_],_) ) inersek, not sırası oynanabilir.

Bu soru için, yalnızca bir dizi hareketin olup olmadığını önemsiyoruz, bu yüzden pm üretilen krank pozisyonları listesini çağırmayı ve atmayı .

Ungolfed sürümüne bakın ve tüm test durumlarını burada doğrulayın .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.