Il mio carillon a 4 note può riprodurre quella canzone?


51

Ho un carillon a manovella che può suonare una serie di quattro note. Quando giro la pedivella, pizzica una delle quattro stringhe, a seconda della posizione della pedivella e della direzione della svolta. Quando la pedivella viene girata verso nord, la scatola (con le sue stringhe numerate da 1 a 4) si presenta così:

1  |  2
   |
   O   

4     3

Da lì, posso girare la manovella in senso orario per pizzicare la corda n. 2 e puntare la manovella verso est:

1     2

   O---   

4     3

In alternativa, avrei anche potuto girare la pedivella in senso antiorario da nord per suonare la corda n. 1 e terminare con una manovella che punta verso ovest:

1     2

---O   

4     3

In qualsiasi momento, quindi, la casella può suonare una delle due note: la nota successiva disponibile in senso orario o la nota successiva in senso antiorario.

Sfida

La sfida è quella di scrivere un programma o una funzione che accetta una stringa non vuota di valori di note (ad esempio, numeri 1attraverso 4) e determinare se è mai possibile giocare quella sequenza di note sul carillon. Produrre un risultato veritiero o falso per indicare la giocabilità o la non giocabilità dell'input.

Alcune note:

  • L'ingresso non fa ipotesi sulla posizione iniziale iniziale. Gli ingressi 214(che iniziano a est e si muovono rigorosamente in senso antiorario) e 234(che iniziano a nord e si muovono rigorosamente in senso orario) ed entrambi sono validi.

  • La pedivella può muoversi liberamente in entrambe le direzioni dopo ogni nota. Una serie della stessa nota è possibile (ad es. 33333) Spostandosi avanti e indietro su una stringa. La serie 1221441è perfettamente giocabile (partendo da ovest, muovendosi in senso orario di due passi, quindi in senso antiorario di tre passi, quindi in senso orario di due passi).

Campioni

Alcuni truecasi:

1
1234
1221
3333
143332
22234
2234
22214
1221441
41233

Alcuni falsecasi:

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  

L'input può essere la stringa comprese le virgolette?
Luis Mendo,

@LuisMendo Certo, lo permetterò - Sono interessato al tuo algoritmo, non ti faccio saltare attraverso i cerchi per ottenere l'input. Ad ogni modo, c'è un consenso non ufficiale della comunità sul fatto che in genere va bene: input di stringhe con o senza “”?
apsillers,

1
Non lo sapevo. Grazie per il link!
Luis Mendo,

1
@AJMansfield No, le soluzioni dovrebbero consentire arbitrariamente molti cicli. Naturalmente, se alcuni input fanno sì che il tuo codice superi un limite nell'interprete della tua lingua o nella memoria del tuo computer, va bene (poiché è semplicemente limitato dalla quantità di memoria che hai fisicamente o l'interprete lo consente), ma la tua soluzione non dovrebbe imporre ulteriori limitazioni su quanto o quante volte si muove la pedivella.
apsillers,

1
Questa sfida ha vinto la categoria Non è così semplice come sembra in Best of PPCG 2016. Sfortunatamente, non possiamo dare taglie alle sfide, ma Zgarb ha scritto una sfida in tuo onore . Congratulazioni!
Martin Ender,

Risposte:


9

Pyth, 30 27 byte

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

Ecco l'idea:

 1.5  1  0.5

  2       0

 2.5  3  3.5

La pedivella è sempre in una posizione di mezzo intero c. Ad ogni passaggio, lo riflettiamo su una nota di posizione intera nimpostando c = 2*n-c. Se nè valido, ccambia di ± 1 mod 8. Se nnon è valido, ccambia di ± 3 mod 8. Riduciamo cumulativamente l'input per raccogliere tutti i valori di c, quindi vediamo se tutte le note erano valide. Lo facciamo per ogni valore iniziale di c, perché è più breve di controllare solo quelli adiacenti alla prima nota.

formattato:

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

Suite di test .


18

CJam, 34 31 byte

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

Ho fatto questo sul mio telefono, quindi dovrò presentare una spiegazione in seguito. L'output è vuoto se vero.

Provalo online | Suite di test

Spiegazione

Il nuovo codice sposta leggermente il layout:

2    3    4

1    .    5

0/8  7    6

I numeri pari corrispondono alle posizioni delle stringhe e i numeri dispari corrispondono alle posizioni della pedivella.

Ecco cosa succede:

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

La pila viene quindi automaticamente stampata alla fine. Eventuali posizioni finali possibili saranno nell'uscita, ad es. Per l'ingresso che è 1l'uscita 31, il che significa che la manovella può terminare rivolta verso sinistra o verso l'alto.

Se solo CJam avesse un filtro con parametro extra ...


Modifica: Ripristino temporaneo mentre mi convinco che questo 29 byte funziona:

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

37
Ogni volta che qualcuno risponde con un linguaggio difficile come cjam e dice "ho fatto questo sul mio telefono" muoio un po 'dentro
Dennis van Gils,

2
Probabilmente intendeva che il testo veniva emesso usando un telefono, ma era stato fatto nella sua testa.
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)

Ciò restituisce una funzione anonima che accetta una stringa e restituisce un valore booleano. Suite di test qui.

Spiegazione

L'idea è che la lambda sulla destra associ un numero aa [[a,a+1],[a+1,a]], le due possibili "mosse" che prendono la manovella su quel numero, secondo il seguente diagramma:

  1 (2) 2

(1/5)  (3)

  4 (4) 3

Nella principale funzione anonima, lo facciamo prima mapM((...).read.pure), che converte ogni carattere in un numero intero, applica il lambda sopra ad esso e sceglie una delle due mosse, restituendo l'elenco di tutte le sequenze di mosse risultanti. Quindi, controlliamo se una di queste sequenze ha la proprietà che il secondo numero di ogni mossa sia uguale al primo numero del modulo 4 successivo, il che significa che è una sequenza fisicamente possibile. Per fare questo, zipognuno di noi sposta la sequenza con la sua tail, controlliamo la condizione per allle coppie e vediamo se la anysequenza valuta True.



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

Questo stampa 0o 1, di conseguenza.

Provalo online! (Questa è una versione leggermente modificata che segna tutte le corrispondenze nell'input invece di stampare 0o 1.)

Ho provato a elaborare un algoritmo elegante, ma i miei primi tentativi non sono stati in grado di eludere il backtracking ... e l'implementazione del backtracking è fastidiosa ... quindi ho usato un linguaggio che fa il backtracking per me dove ho solo bisogno di codificare un soluzione valida. Sfortunatamente, la codifica è abbastanza dettagliata e abbastanza ridondante ... Sono sicuro che questo può essere abbreviato.

Mentre provo a capire qualcosa di più ordinato, se qualcuno vuole capire come funziona, ecco una versione un po 'più leggibile:

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

Ed ecco un suggerimento:

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

Questo utilizza l' attuale versione (10.2.1) , che è precedente a questa sfida.

EDIT (17 gennaio 2017): a causa di cambiamenti nella lingua,v deve essere sostituito da &ve tL3$)da Y)(inoltre, potrebbero essere apportati altri miglioramenti ). Il seguente link include queste due modifiche

Provalo online!

Spiegazione

Questo si basa su due dei miei strumenti preferiti per il golf del codice: la forza bruta e la convoluzione .

Il codice definisce il percorso seguito dalla pedivella in termini di coordinate 0.5, 1.5ecc. Ogni numero indica la posizione della pedivella tra le note. Il codice crea innanzitutto un array di percorsi con tutti i possibili percorsi che iniziano con la prima nota della stringa di input. Ogni percorso è una colonna in questo array. Questo è il componente della forza bruta .

Da questo array di percorsi, si ottiene un array di note , in cui ogni colonna è una sequenza realizzabile di note suonate. Ad esempio, il movimento dalla posizione 0.5a 1.5produce una nota 1. Ciò consiste nel prendere la media tra le posizioni e quindi applicare un'operazione modulo 4. La media corrente lungo ciascuna colonna viene eseguita con una convoluzione 2D .

Infine, il programma verifica se qualsiasi colonna dell'array note coincide con l'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

5

Pyth, 43

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

Test Suite

Questo è probabilmente molto giocabile, e non è anche l'algoritmo ottimale per giocare a golf (mi aspetto che enumerare tutti i percorsi sarà più breve?) ... Comunque, se trovi qualche errore con l'algoritmo, fammi sapere, penso che dovrebbe funzionare, ma io ho sbagliato prima!

Spiegherò il mio algoritmo usando l'input di esempio di 1221. Questo primo programma associa le cifre contro i loro successori, in questo modo: [[1,2],[2,2],[2,1]]. Poi si fa loro differenze mod 4(Pyth ottiene il risultato che corrisponde al segno del diritto argomento %, quindi questo è sempre positivo): [3,0,1]. Poi i risultati sono divisi su 0e hanno 2sottratto da ciascuno di essi: [[1],[-1]].

Ora che l'installazione è terminata, creiamo un elenco di [-1,1,-1...]e la sua negazione [1,-1,...], entrambe della stessa lunghezza dell'array risultante da prima. Quindi, per ciascuno di questi elenchi, eseguire la sottrazione tra gli elementi dell'elenco e l'elenco generato nel passaggio precedente. Quindi, se uno dei risultati contiene solo elenchi vuoti, viene generato true.


Cosa intendi con "i risultati sono divisi su 0"? In particolare, cosa vorresti ottenere 1221221e 1221441?
Neil,

1
@Neil 1221221è falso e 1221441dà il vero in generale, ma se ho capito che vuoi il risultato dopo quel passaggio dell'algoritmo? Se questo è il caso che dà: da [3, 0, 1, 3, 0, 1]a [[3], [1, 3], [1]]e [3, 0, 1, 1, 0, 3]a [[3], [1, 1], [3]]. Fammi sapere se vuoi qualcos'altro spiegato :)
FryAmTheEggman,

Penso di essere più confuso di prima, quindi potresti per favore finire quei due esempi per spiegare come si ottengono i risultati (corretti)?
Neil,

1
@Neil Certo, nessun problema :) Da lì, facciamo la sottrazione per ottenere: [[1], [-1, 1], [-1]]e [[1], [-1, -1], [1]]da qui, puoi vedere che il primo non ha elenchi che si alternano tra -1e 1mentre l'altro lo fa, dando il risultato finale. L'algoritmo è un po 'ottuso, ma fondamentalmente sta mappando i cambiamenti di 0direzione e direzione come +/-1, quindi controllando che non vengano fatti salti e che le direzioni abbiano un senso.
FryAmTheEggman,

Oh, quindi il bit che mi mancava era che ciascuna lista divisa doveva essere dello stesso valore e quei valori devono alternarsi. Grazie!
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

Piuttosto una soluzione pigra, ma la più breve che sono riuscito a trovare. Ho creato speciale matrice: Quando si codifica lo stato del Plucker e l'ultima stringa che deve essere colto, restituisce un vettore, che codifica la nuova posizione del Plucker, e se il precedente coraggio è stato possibile a tutti. Ora passiamo in rassegna tutte le note delle due possibili posizioni iniziali e vediamo se una di esse risulta in una melodia suonabile. Probabilmente si può giocare a golf molto di più.

Fonte ampliata e spiegata:

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

Modifica: salvato 4 byte grazie a @DigitalTrauma.

Questa è una riscrittura completa poiché il mio approccio precedente era imperfetto.

Comincio riducendo tutte le serie di cifre a 1 o 2 a seconda che ci sia stato un numero pari o dispari nella serie. Quindi cerco tutte le combinazioni illegali:

  • 13|24|31|42 (lati opposti)
  • 3[24]{2}1come 3221e 3441sono illegali
  • in modo simile per 4xx2, 1xx3e 2xx4dove xè una delle cifre mancanti
  • (.).\1poiché cose come 121sono illegali ( 111è stato ridotto a 1prima)

Se non ci sono coppie illegali o "triple", l'intera stringa è legale (la prova per induzione viene lasciata come un esercizio perché è notte fonda qui).

Ho cercato di semplificare 3[24]{2}1|1[24]{2}3usando un'asserzione negativa, ma si è rivelato più lungo in quel modo.


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

@ CᴏɴᴏʀO'Bʀɪᴇɴ Non vedo nulla di male in questo. D'altra parte ho capito che f("1221221")produce la risposta sbagliata, quindi dovrò ripensare.
Neil,

È sempre bello includere una suite di test, "43221" non riesce: jsbin.com/vafitotequ/1/edit?js,console
Pavlo,

@Pavlo Whoops, avevo giocato [24][24]a golf (2|4)\1ma non avevo testato adeguatamente. Mi dispiace per quello.
Neil,

Sai giocare [24][24]a golf [24]{2}?
Trauma digitale

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

Spiegazione

i%4 è l'attuale posizione della pedivella:

    1 (i%4 == 1) 2   

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

    4 (i%4 == 3) 3   

Rientrato e commentato

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

Test

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>


Ben fatto. Spiegheresti come |funziona in questo caso?
Pavlo,

1
@pavlo Grazie. È un modo più breve di scrivere (x.map(...),v). Funziona perché l'array su cui viene maprestituito cast 0e 0|v == v.
user81655,

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

Restituisce vero o falso dato una stringa di numeri tra 1 e 4. (Non gestisce dati o numeri fuori intervallo.

Tiene semplicemente traccia dell'ultimo movimento e controlla se questo movimento è un'inversione dell'ultimo movimento (IE, 121 o 12221) o se lo spostamento della distanza è più che possibile.

MODIFICA 1 :

6 byte salvati. Ho dimenticato che if (int) thenritorna vero se int è diverso da zero.

Così:

if t~=0 then

cambia in:

if t then

Inoltre ha salvato alcuni byte ristrutturando.

MODIFICA 2 :

Sto lentamente capendo questo. Ho letto la documentazione qui: http://www.lua.org/pil/ E una delle pagine più utili per il golf è http://www.lua.org/pil/3.3.html

In particolare, questo è molto utile:

Come le strutture di controllo, tutti gli operatori logici considerano falso e zero falso e qualsiasi altra cosa vera.

Ciò significa per me che posso andare avanti e rimuovere la mia dichiarazione per q ( che inizialmente era impostata su 0 ) poiché sarà considerata "falsa" fino a quando non viene impostata. Quindi risparmio qualche byte in più attraverso questo.

Un'altra cosa degna di nota, anche se non la utilizzo, è se si desidera scambiare valori in Lua, si può semplicemente fare a a,b=b,a meno della necessità di una variabile temporanea.

MODIFICA 3

Quindi, attraverso una ricostruzione intelligente e una nuova funzione, ho il conto alla rovescia di byte di altri 9.

Modalità migliore per ricevere input

Se devi leggere un elenco di numeri ed eseguire operazioni su di essi uno alla volta, puoi utilizzare:

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

Rispetto alla tua alternativa usando string: sub, puoi vedere il valore per il golf (o l'uso generale):

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

Ristruttura funzioni o stringhe

In secondo luogo, se hai più dichiarazioni su una riga e uno dei valori è una funzione o hai una condizione in cui confronti un numero con il risultato di una funzione come questa:

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

if math.abs(x)==2 then

ristrutturandolo in modo che le parentesi di chiusura siano l'ultimo carattere nella condizione o nella dichiarazione, è possibile ritagliare un carattere in questo modo:

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

Condizioni di ritorno equivalenti a Vero o Falso anziché "Vero" o "Falso"

Ho trovato un modo semi divertente per ridurre ulteriormente il mio conto alla rovescia. Se è necessario restituire true o false, è possibile restituire un'istruzione che equivale a true o false con meno caratteri rispetto a "true" o "false" stessi.

Ad esempio, confronta:

return true
return false

Per:

return 2>1
return 1>2

121dovrebbe generare false.
lirtosiast,

Ah, non importa. Vedo.
Risolverà a

Potresti essere interessato ad aggiungere alcuni di questi consigli Lua a Suggerimenti per giocare a golf a Lua se non li vedi già elencati lì.
apsillers,

2

MATL, 49 byte (non concorrenti 1 )

1. La risposta (ab) utilizza l'indicizzazione meno rigorosa delle versioni più recenti di MATL e non avrebbe funzionato al momento della pubblicazione della sfida.

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

Provalo online! .

Ho visto questa sfida al meglio di PPCG 2016 e ho pensato che potesse usare il mio operatore preferito :

d

Oppure, diffin MATLAB / Octave (userò liberamente la terminologia MATLAB / Octave nella mia spiegazione, poiché è più facile da leggere per gli umani). Questo comando calcola la differenza dal punto di vista degli elementi in un vettore o, in questo caso, in una matrice di caratteri.

Per questo problema, le differenze mostrano uno schema interessante. Nota che

Un cambio di direzione deve significare che una nota viene suonata due volte .

Per il modello di differenza (ignorando la 1-4transizione per ora), ciò significa che

Una modifica di accesso diff(input)deve avere un numero dispari di zero tra. Al contrario, il segno non è consentito cambiare dopo un anche il numero di zeri.


Ho implementato questo, per ogni array, trovando il primo zero. Rifilo lo zero e moltiplico tutti gli elementi dopo di esso -1. Per il risultato finale, ciò significa che tutti gli elementi devono avere lo stesso segno. Certo, c'è il piccolo problema -3dell'eguaglianza +1e del 2fatto che non è consentito in generale. Ho risolto questo problema prendendo l'unione dell'insieme del risultato [1 -3]e verificando se questa è di dimensione 2 (cioè, nessun elemento non consentito "è entrato" nell'insieme attraverso l'unione). Ripetere l'operazione [-1 3]e verificare se uno (o entrambi, nel caso di un input di 1 lunghezza) è vero.

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 Grazie. Ho davvero bisogno di leggere M, l'ultima volta che l'ho provato, ha funzionato diversamente dal previsto, quindi per il momento l'ho ignorato. È corretto dire che deve essere 3Mperché poi ottengo l'input di non ), non :ma di q(saltando wperché non è una funzione normale )?
Sanchises,

Si, esattamente. wviene ignorato perché non è una funzione normale. Anche le normali funzioni che non accettano input verrebbero ignorate
Luis Mendo il

2

Python (3.5) 160 151 150 byte

Una soluzione ricorsiva

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

Ruoto tutta la scatola invece della pedivella. La posizione di manovella è tra il primo e il secondo carattere della stringa c. Devo testare tutte le posizioni iniziali della pedivella.

Uso del trucco per ruotare la stringa

Il solito modo per ruotare una stringa in python ( s[i:]+s[:i]) deve ripetere troppo sia l'indice che la stringa. In questo caso duplico la stringa e ritaglio i primi caratteri.

(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

Casi test

[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
È possibile rimuovere lo spazio in 3"[i:]) for.
Erik the Outgolfer,

@EriktheOutgolfer grazie lo rimuovo.
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 salvati da Neil! Versione originale non golfata:

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
}

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


1
Ti ho salvato 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,

Non è ancora breve come la risposta di @ user81655.
Neil,

1

Codice macchina di 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

Provalo online!

Questo è fondamentalmente un approccio basato sullo stato:

  • Lo stato iniziale è 0.
  • a, b, c, E dsono "stati indecisi" che si verificano solo all'inizio
  • N, E, S, E Wsono gli "stati decisi", ovviamente in piedi per NOrth, East, South, e West.

1

Quindi, 203 byte

Non riesco a pensare a come giocare a golf così lontano.

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<

Se la sequenza delle note è possibile, verrà emessa la direzione finale, altrimenti l'uscita sarà vuota.


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

Definisce un predicato pche riesce su input giocabili (dato come un elenco di numeri interi) e fallisce su input non giocabili. Provalo online!

Spiegazione

adefinisce una relazione di adiacenza tra la nota Ne la posizione della pedivella P. Definiamo la posizione p tra le note p e p + 1 . Pertanto, una posizione è adiacente per notare Niff

  • è uguale a N( P=N); o
  • la nota è 1 e la posizione è 4 ( N=1,P=4); o
  • il caso precedente non è vero ( !) e la posizione è uguale a N-1( P is N-1).

mprende un elenco di note e cerca di generare un elenco di posizioni che suonerà quelle note. Aè la nota appena suonata, Bè la nota che sta per essere suonata; Xè la posizione corrente della pedivella, Yè la posizione successiva della pedivella. Una mossa è valida iff

  • la nota appena suonata è adiacente all'attuale posizione di manovella ( a(A,X));
  • la nota che sta per essere suonata è anche adiacente all'attuale posizione di manovella ( a(B,X));
  • la nota che sta per essere suonata è adiacente alla successiva posizione di manovella ( a(B,Y)); e
  • le due posizioni della pedivella non sono uguali ( X\=Y).

Se tutto ciò vale, ricorrere. Se arriviamo con successo a una qualsiasi nota ( m([_],_)), la sequenza di note è riproducibile.

Per questa domanda, ci importa solo se esiste una sequenza di mosse, quindi definiamo pdi chiamare me scartare l'elenco generato di posizioni di manovella.

Guarda una versione non controllata e verifica tutti i casi di test qui .

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.