Contatore meccanico

di il
4 risposte

Contatore meccanico

Salve ragazzi sono nuovo del forum quindi se c'è qualche problema col post non esitate a farmelo notare.

Scrivo perché devo fare un programmino per un esame di programmazione ma mi manca l'idea di base da cui partire, non voglio la soluzione ma soltanto l'impostazione del problema e come ragionarci su. Vi incollo il testo

Problema 1: il contatore che può cambiare una sola cifra alla volta

Si consideri un contatore meccanico, come quello che misura l'acqua o il gas in casa, o i chilometri percorsi in un'automobile. Questo è formato da n cilindri, ognuno dei quali rappresenta una cifra, usualmente espressa in base b = 10.

Nel normale utilizzo di un contatore, questo enumera tutte le possibili bn combinazioni di cifre, partendo da 0,0,0,... e arrivando a b-1,b-1,b-1,.... Nell'enumerazione, il numero rappresentato dalla sequenza di cifre viene incrementato di una unità alla volta. Ogni incremento può modificare l'intero contatore di un numero di cifre variabile a seconda di quante cifre finali b-1 sono già presenti (ovvero, di quanti riporti servono).

Vi si chiede di scrivere un programma Java che, dati b,n enumeri tutte le possibili combinazioni di cifre, in un qualunque ordine che rispetti quanto segue.

Ogni possibile combinazione di cifre deve apparire una ed una sola volta. (In totale, ci devono essere esattamente bn combinazioni, tutte distinte)
L'enumerazione deve partire da 0,0,0,....
Nell'enumerazione, tra una combinazione e la successiva ci deve essere esattamente una cifra diversa.
Il numero di cifre è un naturale qualunque (quindi, maggiore o uguale a zero). La base b è un intero maggiore o uguale a 2 e minore o uguale a 10.

Esempio

Per un input base 5, con 2 cifre:

5 2
un possibile risultato che deve essere calcolato e salvato nel file output1.txt potrebbe essere:

00 01 02 03 04 14 13 12 11 10 20 21 22 23 24 34 33 32 31 30 40 41 42 43 44



Come già detto non voglio la soluzione al problema, ma solo un indirizzamento verso la retta via

Grazie a chi spenderà del tempo per aiutarmi

4 Risposte

  • Re: Contatore meccanico

    Esercitazione interessante ..... Innanzitutto, se non lo sapevi e giusto come background, esiste un codice binario particolare chiamato Codice "Gray" che ha proprio la stessa proprietà che hai descritto, ovvero da una combinazione alla successiva c'è sempre e solo una singola cifra di differenza. Come ho detto è un codice binario, quindi si applica alla base 2. Ma il concetto è sicuramente generalizzabile.
    Vedi: https://it.wikipedia.org/wiki/Codice_Gra

    Generalizzare il discorso, per un qualunque numero di cifre e soprattutto per una qualunque base è sicuramente possibile e richiede un po' (un minimo) di ragionamento ma anche di osservazione.

    Tanto per fare qualche ragionamento sulla sequenza che hai riportato tu (00 01 02 03 04 14 13 12 11 10 20 21 22 23 24 34 33 32 31 30 40 41 42 43 44): che cosa riesci a notare? Scrivi ciascuna combinazione su una riga e poi separa a blocchi di 5 combinazioni. Cosa noti? Osserva come progredisce la cifra di sinistra ma soprattutto quella di destra.
  • Re: Contatore meccanico

    Ciao,

    anche io devo fare questo progetto, ho provato a buttare giù un po di codice, ma riesco a farlo funzionare solo per n=2.

    Risucite a darmi due dritte per farlo funzionare con n che sia qualsiasi numero?

    Ho provato diverse cose ma non riesco.

    Grazie infinite!!!
  • Re: Contatore meccanico

    Indicazioni pratiche:

    Una soluzione è mantenere le informazioni minime per rappresentare una combinazione e poi farla "progredire" di volta in volta andando avanti finché si arriva all'ultima combinazione possibile. Per fare questo, il minimo necessario è tenere un array int[] poiché il numero n di cifre è richiesto come "arbitrario", oltre al fatto che anche la base è arbitraria (e un int è assolutamente sufficiente ... anzi, anche troppo ma è ok).

    Su come strutturare il codice, mi vengono in mente 2 soluzioni: un grosso ciclo al cui interno c'è tutto (logica, stampa dei dati, ecc...) oppure la gestione in stile a "iteratore".
    Un grosso ciclo con tutto quanto dentro non è di per sé sbagliato ma è meno bello dal punto di vista del design (c'è tutto mescolato dentro, logica, stampe, ecc...) oltre al fatto che non è (facilmente) riutilizzabile.
    Una alternativa è incapsulare la logica in una classe apposita e poi offrire il modo per avanzare nelle combinazioni usando lo stile degli "iteratori". A livello pratico un uso finale di questo tipo:
    GrayCounter grayCounter = new GrayCounter(3, 4);    // base 3, n.cifre=4
    
    while (grayCounter.hasNext()) {
        int[] combinazione = grayCounter.next();
    
        // usa la combinazione (stampa ecc..)....
    }
    Questo è decisamente più pulito e interessante.

    Riguardo la logica per far progredire le combinazioni, a me viene in mente di ragionare su come le singole cifre debbano incrementarsi o decrementarsi. Questo sarebbe sicuramente utile nello scenario della classe che funziona "a iteratore", poiché c'è da mantenere uno "stato" su come le combinazioni devono evolvere.

    Basta osservare la sequenza già postata: 00 01 02 03 04 14 13 12 11 10 20 21 22 23 24 34 33 32 31 30 40 41 42 43 44

    La cifra di destra, prima si incrementa da 0 a 4, poi quando quella di sinistra si incrementa di 1, quella di destra si decrementa da 4 a 0, poi quando quella di sinistra si incrementa di nuovo quella di destra torna ad incrementarsi da 0 a 4 ecc...

    Provate a scrivere "a mano" le combinazioni con base 3 e con 3 o 4 cifre. Se osservate come avvengono gli incrementi e decrementi, scoprirete la regola generale.

    Dovessi farlo io (e senza indicazioni o imposizioni particolari), lo farei nello stile a "iteratore" e all'interno della classe manterrei le seguenti informazioni: a) la base (ovviamente), b) un array int[n] e c) un array boolean[n]. Eventualmente (dovrei ragionare se è strettamente necessario) la indicazione se le combinazioni sono terminate oppure non ancora.

    A che serve l'array di boolean? Io lo userei per indicare se una colonna (cifra) si deve incrementare o decrementare. E la logica per stabilirlo è deducibile osservando come avvengono gli incrementi/decrementi in uno scenario come quello descritto poco fa.
  • Re: Contatore meccanico

    Dopo l'ultimo messaggio che hai inviato, @andbin, ho avuto l'illuminazione e finalmente ho capito come funziona, l'idea del vettore di boolean è stata la chiave di volta

    Grazie ancora
Devi accedere o registrarti per scrivere nel forum
4 risposte