Verifica una soluzione della Torre di Hanoi


29

Se non sai cos'è la Torre di Hanoi , te lo spiego brevemente: ci sono tre aste e alcuni dischi, ognuno dei quali ha dimensioni diverse. All'inizio tutti i dischi si trovano sulla prima torre, in ordine: il più grande è in fondo, il più piccolo in alto. L'obiettivo è portare tutti i dischi alla terza asta. Sembra facile? Ecco il problema: non è possibile posizionare un disco sopra un disco più piccolo dell'altro disco; puoi tenere solo un disco alla mano per spostarlo su un'altra asta e puoi posizionare il disco solo su aste, non sul tavolo, bastardo subdolo.

Esempio di soluzione ascii:

  A      B      C
  |      |      |      
 _|_     |      |      
__|__    |      |


  A      B      C
  |      |      |      
  |      |      |      
__|__   _|_     |


  A      B      C
  |      |      |      
  |      |      |      
  |     _|_   __|__


  A      B      C
  |      |      |      
  |      |     _|_     
  |      |    __|__      

Sfida

Ci sono tre aste chiamate A, B e C. (Puoi anche chiamarle 1,2 e 3 rispettosamente se questo aiuta) All'inizio tutti e n i dischi sono sull'asta A (1).

La tua sfida è verificare una soluzione per la torre di Hanoi. Dovrai assicurarti che:

  1. Alla fine tutti e n i dischi sono sull'asta C (3).
  2. Per ogni dato disco in qualsiasi dato stato non c'è un disco più piccolo sotto di esso.
  3. Nessun errore evidente come il tentativo di prendere i dischi da un'asta vuota o di spostare i dischi su aste inesistenti.

(la soluzione non deve essere ottimale.)

Ingresso

Il tuo programma riceverà due input:

  1. Il numero di dischi n (un numero intero)
  2. Le mosse che sono prese, che consisterà in una serie di tuple di: (torre per prendere il disco attualmente più in alto da), (torre per prendere questo disco in) dove ogni tupla si riferisce a una mossa. Puoi scegliere come sono rappresentati. Ad esempio qualcosa come i seguenti modi di rappresentare la soluzione per n = 2 che ho disegnato in ASCII sopra. (Userò il primo nei casi di test, perché è facile per gli occhi):

    "A-> B; A-> C; B-> C"

    [( "A", "B"), ( "A", "C"), ( "B", "C")]

    [(1,2), (1,3), (2,3)]

    "ABACBC"

    [1,2,1,3,2,3]

Produzione

  • Sinceramente, se le condizioni che si possono trovare sotto "sfida" valgono.

  • Falsy, se non lo fanno.

Casi test:

Vero:

n=1, "A->C"

n=1, "A->B ; B->C"

n=2, "A->B ; A->C ; B->C"

n=2, "A->C ; C->B ; A->C ; B->C"

n=2, "A->C ; A->B ; C->B ; B->A ; B->C ; A->C"

n=3, "A->C ; A->B ; C->B ; A->C ; B->A ; B->C ; A->C"

n=4, "A->B ; A->C ; B->C ; A->B ; C->A ; C->B ; A->B ; A->C ; B->C ; B->A ; C->A ; B->C ; A->B ; A->C ; B->C"

falso:

3 ° suggerito da @MartinEnder, 7 ° da @Joffan

n=1, "A->B"

n=1, "C->A"

n=2, "A->C ; A->B ; C->B ; A->C ; B->A ; B->C ; A->C"

n=2, "A->B ; A->C ; C->B"

n=2, "A->C ; A->B ; C->B ; B->A"

n=2, "A->C ; A->C"

n=3, "A->B ; A->D; A->C ; D->C ; A->C"

n=3, "A->C ; A->C ; A->B ; C->B ; A->C ; B->A ; B->C ; A->C"

n=3, "A->C ; A->B ; C->B ; A->B ; B->C ; B->A ; B->C ; A->C"

n=3, "A->C ; A->B ; C->B ; A->C ; B->A ; B->C ; C->B"

n=4, "A->B ; A->C ; B->C ; A->B ; C->A ; C->B ; A->B ; A->C ; B->C ; B->A ; C->A ; B->C ; A->B ; A->C"

n=4, "A->B ; A->B ; A->B ; A->C ; B->C ; B->C ; B->C"

Questo è code-golf , vince la soluzione più breve. Si applicano regole standard e scappatoie. Nessuna batteria inclusa.


E 'anche bene se il 2 ° ingresso può essere rappresentata utilizzando il metodo, ma utilizzando i numeri al posto delle lettere (ad esempio A=1, B=2, C=3, etc.)?
R. Kap,

1
Posso azzerare gli input?
Rohan Jhunjhunwala,

1
Va bene se viene generato un errore quando un disco viene prelevato da un'asta vuota o inesistente?
R. Kap,

1
Possiamo presumere che non ci saranno non-mosse come A->A?
Martin Ender,

2
@Kobi devi controllare moving discs to nonexistant rods.quindi ovviamente sì, è aD
edc65

Risposte:


7

Retina , 84 80 byte

-5 byte grazie a Martin Ender

~
 ~$'
$
ABC
{`^(.)(.*)( ~+)\1
$3$2$1
}`^(\W+)(\w)(.*)(?<=\1~+|\w)\2
$3$1$2
^AB 

Provalo online! (più 5 byte per i test riga per riga)

Il codice simula un gioco completo.

  • L'input è dato come ACABCBACBABCAC~~~.
    ~~~significa tre dischi.
  • Le prime quattro linee convertono l'ingresso nel formato di gioco: ACABCBACBABCAC ~~~ ~~ ~ABC.
    All'inizio l'asta A ha tutti e 3 i dischi e le aste B e C sono vuote.
  • Successivamente abbiamo un ciclo di due passaggi:
    • Prendi la prima lettera nella riga, che indica la barra della fonte successiva. Trova questa asta e inserisci l'ultimo disco. Rimuovi la lettera e sposta il disco a fondo (raccoglilo).
      Nell'esempio, dopo il primo passo, il testo sarà simile: ~CABCBACBABCAC ~~~ ~~ABC.
    • Nel secondo stadio troviamo l'asta bersaglio e spostiamo lì il disco. Convalidiamo l'asta è vuota, o ha un disco grande in alto: ABCBACBABCAC ~~~ ~~AB ~C.
  • Infine confermiamo che le aste A e B sono vuote - questo significa che tutti i dischi sono in C (c'è uno spazio extra nell'ultima riga).

Wow, è impressionante
Rohan Jhunjhunwala il

17

Retina , 167 165 157 150 123 byte

Questa sembra totalmente una sfida che dovrebbe essere risolta con una sola regex ... (nonostante l'intestazione che dice "Retina", questa è solo una regex .NET vaniglia, che corrisponde a input validi).

^(?=\D*((?=(?<3>1+))1)+)((?=A(?<1-3>.+)|B(?<1-4>.+)|C(?<1-5>.+)).(?=A.*(?!\3)(\1)|B.*(?!\4)(\1)|C.*(?!\5)(\1)).)+(?!\3|\4)1

Il formato di input è l'elenco di istruzioni del modulo AB, seguito da nunario utilizzando la cifra 1. Non ci sono separatori. L'output è 1valido e 0non valido.

Provalo online! (I primi due caratteri abilitano una suite di test separata da avanzamento riga.)

Soluzione alternativa, stesso conteggio byte:

^(?=\D*((?=(?<3>1+))1)+)((?=A(?<1-3>.+)|B(?<1-4>.+)|C(?<1-5>.+)).(?=A.*(?!\3)(\1)|B.*(?!\4)(\1)|C.*(?!\5)(\1)).)+(?<-5>1)+$

Questo può eventualmente essere abbreviato usando 1, 11e 111invece di A, Be Cdovrò esaminarlo più avanti. Potrebbe anche essere più breve dividere il programma in più fasi, ma dov'è la sfida in questo? ;)

Spiegazione

Questa soluzione fa ampio uso dei gruppi di bilanciamento di .NET. Per una spiegazione completa, vedere il mio post su Stack Overflow , ma l'essenza è che i gruppi di acquisizione in .NET sono stack, in cui ogni nuova acquisizione spinge un'altra sottostringa e dove è anche possibile eseguire nuovamente il pop-up da tale stack. Ciò consente di contare varie quantità in una stringa. In questo caso ci consente di implementare le tre aste direttamente come tre diversi gruppi di acquisizione in cui ogni disco è rappresentato da una cattura.

Per spostare i dischi tra le aste usiamo una strana stranezza della (?<A-B>...)sintassi. Normalmente, questo fa scattare una cattura dallo stack Be spinge in pila Ala stringa tra quella cattura scoppiata e l'inizio di questo gruppo. Così (?<A>a).(?<B-A>c)abbinato contro abclascerebbe Avuoto e Bcon b(al contrario di c). Tuttavia, grazie ai lookbehind di lunghezza variabile .NET è possibile che le acquisizioni di (?<A>...)e si (?<B-A>...)sovrappongano. Per qualsiasi motivo, in tal caso, l' intersezione dei due gruppi viene spinta B. Ho dettagliato questo comportamento nella "sezione avanzata" sui gruppi di bilanciamento in questa risposta .

Passiamo alla regex. Canne A, Be Ccorrispondono a gruppi 3, 4e 5nella regex. Iniziamo inizializzando rod A:

^                 # Ensure that we start at the beginning of the input.
(?=               # Lookahead so that we don't actually move the cursor.
  \D*             # Skip all the instructions by matching non-digit characters.
  (               # For each 1 at the end of the input...
    (?=(?<3>1+))  # ...push the remainder of the string (including that 1)
                  # onto stack 3.
  1)+
)

Quindi, ad esempio, se l'ingresso termina con 111, il gruppo 3 / rod Aora conterrà l'elenco delle acquisizioni [111, 11, 1](la parte superiore si trova sulla destra).

Il prossimo bit del codice ha la seguente struttura:

(
  (?=A...|B...|C...).
  (?=A...|B...|C...).
)+

Ogni iterazione di questo ciclo elabora un'istruzione. La prima alternanza tira un disco dall'asta data (su un gruppo temporaneo), la seconda alternanza mette quel disco sull'altra asta data. Vedremo tra poco come funziona e come ci assicuriamo che la mossa sia valida.

Innanzitutto, togliendo un disco dall'asta della sorgente:

(?=
  A(?<1-3>.+)
|
  B(?<1-4>.+)
|
  C(?<1-5>.+)
)

Questo utilizza lo strano comportamento di intersezione di gruppo che ho descritto sopra. Si noti che gruppo 3, 4e 5sarà sempre tenere sottostringhe 1s alla fine della stringa cui corrisponde alle dimensioni del disco lunghezza. Ora usiamo (?<1-N>.+)per estrarre il disco superiore dallo stack Ne spingere l'intersezione di questa sottostringa con la corrispondenza .+sullo stack 1. Dato che .+copre sempre necessariamente l'intera cattura spuntata N, sappiamo che questo sposta semplicemente la cattura.

Quindi, inseriamo questo disco dallo stack 1allo stack corrispondente alla seconda asta:

(?=
  A.*(?!\3)(\1)
|
  B.*(?!\4)(\1)
|
  C.*(?!\5)(\1)
)

Nota che non è necessario ripulire lo stack 1, possiamo semplicemente lasciare il disco lì, poiché ne inseriremo uno nuovo prima di riutilizzarlo. Ciò significa che possiamo evitare la (?<A-B>...)sintassi e semplicemente copiare la stringa con (\1). Per garantire che la mossa sia valida utilizziamo il lookahead negativo (?!\N). Questo assicura che, dalla posizione in cui vogliamo abbinare il disco corrente, sia impossibile abbinare il disco già in pila N. Questo può succedere solo se a) \Nnon corrisponderà mai perché lo stack è completamente vuoto oppure b) the disc on top of stackN is larger than the one we're trying to match with\ 1`.

Infine, tutto ciò che rimane è garantire che a) abbiamo abbinato tutte le istruzioni eb) aste Ae che Bsiano vuote, in modo che tutti i dischi siano stati spostati C.

(?!\3|\4)1

Abbiamo semplicemente accertare l'assenza \3\4può abbinare (che è solo il caso se entrambi sono vuoti, perché ogni disco effettivo sarebbe abbinare) e che possono poi abbinare un 1modo che non abbiamo omesso alcuna istruzione.


14

Java "solo" 311 272 263 261 260 259 256 byte

Hai salvato 39 innumerevoli byte grazie a @Frozn che ha notato una vecchia funzionalità di debug e alcuni trucchi da golf intelligenti.

Versione golfizzata

int i(int n,int[]m){int j=0,k=0,i=n;Stack<Integer>t,s[]=new Stack[3];for(;j<3;)s[j++]=new Stack();for(;i-->0;)s[0].push(i);for(;k<m.length;k+=2)if((t=s[m[k+1]]).size()>0&&s[m[k]].peek()>t.peek())return 0;else t.push(s[m[k]].pop());return s[2].size()<n?0:1;}

non rigato di spiegazioni e pile piuttosto stampate ad ogni passo

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package codegolf;

/**
 *
 * @author rohan
 */
import java.util.Arrays;
import java.util.Stack;
public class CodeGolf {
    //golfed version
    int i(int n,int[]m){int j=0,k=0,i=n;Stack<Integer>[] s=new Stack[3];for(;j<3;j++)s[j]=new Stack();for(;i-->0;)s[0].push(i);for(;k<m.length;System.out.println(Arrays.toString(s)),k+=2)if(!s[m[k+1]].isEmpty()&&s[m[k]].peek()>s[m[k+1]].peek())return 0;else s[m[k+1]].push(s[m[k]].pop());return s[2].size()==n?1:0;}
    /** Ungolfed
        * 0 as falsy 1 as truthy
        * @param n the number of disks
        * @param m represents the zero indexed stacks in the form of [from,to,from,to]
        * @return 0 or 1 if the puzzle got solved, bad moves result in an exception
        */
    int h(int n, int[] m) {
        //declarations
        int j = 0, k = 0, i = n;
        //create the poles
        Stack<Integer>[] s = new Stack[3];
        for (; j < 3; j++) {
            s[j] = new Stack();
        }
        //set up the first tower using the "downto operator
        for (; i-- > 0;) {
            s[0].push(i);
        }
    //go through and perform all the moves
        for (; k < m.length; System.out.println(Arrays.toString(s)), k += 2) {
            if (!s[m[k + 1]].isEmpty() && s[m[k]].peek() > s[m[k + 1]].peek()) {
                return 0;//bad move
            } else {
                s[m[k + 1]].push(s[m[k]].pop());
            }
        }
        return s[2].size() == n ? 1 : 0;// check if all the disks are done
    }
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
    //test case
        System.out.println( new CodeGolf().h(3,new int[]{0,2,0,1,2,1,0,2,1,0,1,2,0,2})==1?"Good!":"Bad!");
    }

}

La versione ungolfed ha una funzione in cui stamperà come appaiono gli stack ad ogni passaggio in questo modo ...

[[2, 1], [], [0]]
[[2], [1], [0]]
[[2], [1, 0], []]
[[], [1, 0], [2]]
[[0], [1], [2]]
[[0], [], [2, 1]]
[[], [], [2, 1, 0]]
Good!

Cosa fa System.out.println(Arrays.toString(s))?
Frozn,

Stamperà piuttosto le pile. In questo modo [[2,1,0], [] []]
Rohan Jhunjhunwala,

Whoops @Frozn che era una funzionalità di debug che rimuove ora
Rohan Jhunjhunwala,

Lo so, mi chiedo solo perché sia ​​lì :) Puoi anche sostituirlo &&con &.
Frozn,

@Frozn Non posso sostituirlo tristemente perché facevo affidamento sul comportamento in corto circuito per evitare di cercare di sbirciare uno stack vuoto. Grazie per la riduzione di 39 byte
Rohan Jhunjhunwala,

9

Python 2, 186 167 158 135 127 115 110 102 102 byte

n,m=input()
x=[range(n),[],[]]
for a,b in m:p=x[a].pop();e=x[b];e and 1/(p>e[-1]);e+=p,
if x[0]+x[1]:_

Accetta input su STDIN nel seguente formato:

(1,[(0,1),(1,2)])

Cioè, una tupla Python del numero di dischi e un elenco di tuple Python (from_rod,to_rod). Come in Python, le parentesi circostanti sono opzionali. Le aste sono a indice zero.

Ad esempio, questo caso di test:

n=2; "A->B ; A->C ; B->C"

sarebbe dato come:

(2,[(0,1),(0,2),(1,2)])

Se la soluzione è valida, non emette nulla ed esce con un codice di uscita pari a 0. Se non è valida, genera un'eccezione ed esce con un codice di uscita pari a 1. Lancia un IndexErrorse si sposta su un'asta inesistente o tenta di estrarre un disco da asta che non contiene dischi, aZeroDivisionError se un disco è posizionato sopra un disco più piccolo o a NameErrorse sono rimasti dei dischi sulla prima o sulla seconda all'estremità.

Risparmiato 13 byte grazie a @KarlKastor!

8 byte salvati grazie a @xnor!


1
Il controllo che ogni pila sia ordinata sembra troppo complicato. Non puoi semplicemente verificare che il disco spostato sia più grande del disco superiore della pila su cui è stato spostato?
xnor

@xnor Grazie, dovrebbe funzionare. Aggiungendolo ora.
Copper,

5

Python 2.7, 173 158 138 130 127 123 byte:

r=range;a,b=input();U=[r(a,0,-1),[],[]]
for K,J in b:U[J]+=[U[K].pop()]if U[J]<[1]or U[K]<U[J]else Y
print U[-1]==r(a,0,-1)

Accetta input tramite lo stdin nel formato in (<Number of Discs>,<Moves>)cui<Moves> è indicato come un array contenente tuple corrispondenti a ciascuna mossa, che contengono ciascuna una coppia di numeri separati da virgola. Ad esempio, il caso di test:

n=3, "A->C ; A->B ; C->B ; A->C ; B->A ; B->C ; A->C" 

dato nel post sarebbe dato come:

(3,[(0,2),(0,1),(2,1),(0,2),(1,0),(1,2),(0,2)]) 

al mio programma. Emette un IndexErrorse la terza condizione non è soddisfatta, a NameErrorse la seconda condizione non è soddisfatta e Falsese la prima condizione non è soddisfatta. Altrimenti uscite True.


due cose: la variabile Ynon è mai definita nel tuo codice (penso che dovrebbe essere J) ed U[J]+=[Y,[U[K].pop()]][U[J]<[1]or U[K]<U[J]]è più corta di 3 caratteri che ilstmt1 if cond else stmt2
jermenkoo,

@jermenkoo Bene, io uso quella Yvariabile in questo modo per aumentare NameErrorogni volta che la seconda condizione non è soddisfatta. Se dovessi passare Ya J, allora NameErrornon verrebbe sollevato. Per questo motivo, anche io non posso farlo U[J]+=[Y,[U[K].pop()]][U[J]<[1]or U[K]<U[J]]perché questo aumenterebbe NameError continuamente , non solo quando la seconda condizione non è soddisfatta.
R. Kap,

va bene, grazie per la tua spiegazione!
jermenkoo,

5

VBA, 234 217 213 196 byte

Function H(N,S)
ReDim A(N)
While P<Len(S)
P=P+2:F=1*Mid(S,P-1,1):T=1*Mid(S,P,1)
E=E+(T>2):L=L+T-F
For i=1 To N
If A(i)=F Then A(i)=T:Exit For
E=E+(A(i)=T)+(i=N)
Next
Wend
H=L+9*E=2*N
End Function

Il formato di input per gli spostamenti è una stringa con un numero pari di cifre (012). La chiamata è in foglio di calcolo, = H ([numero di dischi], [sposta stringa])

L'array A mantiene la posizione dell'asta dei vari dischi. Una mossa sta semplicemente aggiornando la prima occorrenza del numero di asta "Da" nel numero di asta "A". Se incontri prima un disco con asta "A" o nessun disco con asta "Da", è una mossa non valida. Il "valore dell'asta" totale di A è tenuto in L, che deve terminare a 2N. Gli errori vengono accumulati come conteggio negativo in E.

In comune con altre soluzioni, non è proibito "spostare" un disco da una torre alla stessa torre. Potrei vietarlo per altri 6 byte.

risultati

Risultato della funzione nella prima colonna (l'ultimo caso n = 3 è la mia aggiunta usando una barra aggiuntiva).

TRUE    1   02
TRUE    1   0112
TRUE    2   010212
TRUE    2   02210212
TRUE    2   020121101202
TRUE    3   02012102101202
TRUE    4   010212012021010212102012010212

FALSE   1   01
FALSE   1   20
FALSE   2   02012102101202
FALSE   2   010221
FALSE   2   02012110
FALSE   2   0202
FALSE   3   0202012102101202
FALSE   3   0201210112101202
FALSE   3   02012102101221
FALSE   3   0103023212
FALSE   4   0102120120210102121020120102
FALSE   4   01010102121212

2

php, 141 byte

<?php $a=$argv;for($t=[$f=range($a[++$i],1),[],[]];($r=array_pop($t[$a[++$i]]))&&$r<(end($t[$a[++$i]])?:$r+1);)$t[$a[$i]][]=$r;echo$t[2]==$f;

Script da riga di comando, accetta input come altezza, quindi una serie di indici di array (0 indicizzati), ad es. 1 0 2 o 2 0 1 0 2 1 2 per i casi di test più brevi di 1 o 2 altezza.
Echos 1 su casi veri e niente su quelli falsi.
Fornisce 2 avvisi e 1 avviso, pertanto è necessario eseguirli in un ambiente in grado di silenziarli.


1

JavaScript (ES6), 108

n=>s=>!s.some(([x,y])=>s[y][s[y].push(v=s[x].pop())-2]<v|!v,s=[[...Array(s=n)].map(_=>s--),[],[]])&s[2][n-1]

Formato di input: funzione con 2 argomenti

  • arg 1, numerico, numero di squilli
  • arg 2, array di stringhe, ogni stringa 2 caratteri '0', '1', '2'

Uscita: restituisce 1 se ok, 0 se non valido, eccezione se asta inesistente

Meno golfato e spiegato

n=>a=>(
  // rods status, rod 0 full with an array n..1, rod 1 & 2 empty arrays
  s = [ [...Array(t=n)].map(_=>t--), [], [] ],
  // for each step in solution, evaluate function and stop if returns true
  err = a.some( ([x,y]) => {
    v = s[x].pop(); // pull disc from source rod
    // exception is s[x] is not defined
    if (!v) return 1; // error source rod is empty
    l = s[y].push(v); // push disc on dest rod, get number of discs in l
    // exception is s[y] is not defined
    if(s[y][l-2] < v) return 1; // error if undelying disc is smaller
  }),
  err ? 0 // return 0 if invalid move
  : s[2][n-1]; // il all moves valid, ok if the rod 2 has all the discs
)

Nota del test : la prima riga della funzione Test è necessaria per convertire il formato di input indicato nella domanda nell'input previsto dalla mia funzione

F=
n=>s=>!s.some(([x,y])=>s[y][s[y].push(v=s[x].pop())-2]<v|!v,s=[[...Array(s=n)].map(_=>s--),[],[]])&s[2][n-1]

Out=x=>O.textContent+=x+'\n'

Test=s=>s.split`\n`.map(r=>[+(r=r.match(/\d+|.->./g)).shift(),r.map(x=>(parseInt(x[0],36)-10)+''+(parseInt(x[3],36)-10))])
.forEach(([n,s],i)=>{
  var r
  try {
    r = F(+n)(s);
  } 
  catch (e) {
    r = 'Error invalid rod';
  }
  Out(++i+' n:'+n+' '+s+' -> '+r)
})

Out('OK')
Test(`n=1, "A->C"
n=1, "A->B ; B->C"
n=2, "A->B ; A->C ; B->C"
n=2, "A->C ; C->B ; A->C ; B->C"
n=2, "A->C ; A->B ; C->B ; B->A ; B->C ; A->C"
n=3, "A->C ; A->B ; C->B ; A->C ; B->A ; B->C ; A->C"
n=4, "A->B ; A->C ; B->C ; A->B ; C->A ; C->B ; A->B ; A->C ; B->C ; B->A ; C->A ; B->C ; A->B ; A->C ; B->C"`)

Out('\nFail')
Test( `n=1, "A->B"
n=1, "C->A"
n=2, "A->C ; A->B ; C->B ; A->C ; B->A ; B->C ; A->C"
n=2, "A->B ; A->C ; C->B"
n=2, "A->C ; A->B ; C->B ; B->A"
n=2, "A->C ; A->C"
n=3, "A->B ; A->D; A->C ; D->C ; A->C"
n=3, "A->C ; A->C ; A->B ; C->B ; A->C ; B->A ; B->C ; A->C"
n=3, "A->C ; A->B ; C->B ; A->B ; B->C ; B->A ; B->C ; A->C"
n=3, "A->C ; A->B ; C->B ; A->C ; B->A ; B->C ; C->B"
n=4, "A->B ; A->C ; B->C ; A->B ; C->A ; C->B ; A->B ; A->C ; B->C ; B->A ; C->A ; B->C ; A->B ; A->C"
n=4, "A->B ; A->B ; A->B ; A->C ; B->C ; B->C ; B->C"`)
<pre id=O></pre>

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.