Oppure

Loading
07/01/20 23:33
AldoBaldo
Piacerebbe anche a me che ci si potesse scambiare le risoluzioni senza troppi patemi, ma così non è. Magari un giorno si rivedrà quest'impostazione, non so, ma al momento il regolamento lo vieta. Io l'ho buttata lì, hai visto mai... :heehee:
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
07/01/20 23:45
AldoBaldo
Per trattare i casi nei quali le stringhe non hanno lunghezza pari a una potenza del tre ho fatti ricorso a questo procedimento (i frammenti di codice si possono condividere).

int cantor_calcola_lunghezza_settori( int lStr, int l[] ) {
    l[0] = lStr/3;  // la lunghezza del settore di sinistra
    l[1] = l[0];    // la lunghezza del settore centrale
    l[2] = l[0];    // la lunghezza del settore di destra
    
    // inizialmente, i tre settori hanno la stessa lunghezza; la loro somma, per
    // via dei troncamenti determinati dall'uso di valori di tipo intero, puo'
    // essere minore rispetto a quanto indicato dal parametro lStr. Per questo...

    if( 0 != l[0] ) { // ... se i settori non hanno lunghezza nulla
        int r;  // r: resto

        if( (r=lStr%3) ) { // se sono state "tagliate" delle parti...
            if( 1==r ) {        // se si e' "avanzato" solo un 1,
                l[1]++;         // lo aggiungiamo alla parte centrale
            }
            else if( 2==r ) {   // se invece l'avanzo e' 2,
                l[0]++;         // ne aggiungiamo meta' al settore di sinistra
                l[2]++;         // e meta' al settore di destra
            }
        }

        return 1;   // restituiamo 1 per indicare che
                    // i settori hanno lunghezza valida
    }

    return 0;       // restituiamo 0 per indicare che
                    // i settori NON hanno lunghezza valida
}


Sicuramente esistono metodi più efficaci/meno banali, però questo funziona e m'è venuto facile metterlo insieme...
Ultima modifica effettuata da AldoBaldo 07/01/20 23:51
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
07/01/20 23:59
Goblin
però ... visto il crosspost e la risoluzione in un altro forum ...... :rofl::rofl::rofl:

Questa la mia soluzione che estrae risultati uguali a quelli di AldoBaldo, in pascal spero di non aver scritto troppe cavolate.

Function cantor(var str: String; posizioneInizioStringa, DimStringa: Integer): String;
Var i: Integer;
    nDim: Integer;
    nDummy: Integer;
begin
  // dummy mi serve per prendere più o meno di parte centrale
  // in base al resto della divisione
  // ovviamente a potenza di 3 è nullo e tutto resta normale
  nDummy := 0;
  if (DimStringa mod 3) < 0 then  // meno di 3
    nDim := 0
  else if (DimStringa mod 3) = 1 then  // resto 1
  begin
    nDim := DimStringa DIV 3;
    nDummy := 1;
  end
  else if (DimStringa mod 3) = 2 then  // resto 2
  begin
    nDim := round(DimStringa / 3);
    nDummy := -1;
  end
  else
    nDim := DimStringa DIV 3;  // divisione secca

  if nDim = 0 then
    Result := str
  else
  begin
    // prima parte
    Cantor(str, posizioneInizioStringa, nDim);
    // scrivo parte centrale nulla
    For i := posizioneInizioStringa + nDim To posizioneInizioStringa + (nDim * 2) - 1 + nDummy do
      str[i] := '.';
    // terza parte
    Cantor(str, posizioneInizioStringa + (nDim * 2) + nDummy, nDim);
    Result := str;
  end;
end;

procedure TForm23.Button1Click(Sender: TObject);
Var ss: String;
  I: Integer;  // stringhe di test
  x: Integer; // dummy per inizializzare la stringa ...
  s: String;   // stringa di supporto per '0' formattazione output
begin
  memo1.Lines.Clear;
  for I := 1 to 300 do
  begin
// doppio begin per inserire solo potenze di 3
    begin
      SetLength(ss, I);
      s := '0';
      for x := 1 to I do
        ss[x] := '#';  // inizializzo tutto pieno ... potrei fare un fillChar ... ma ... lascio ai posteri il lavoro
      // non mi ricordo più il PADL .... scusatemi faccio casareccio
      if i>=10 then
        s := '';
      memo1.Lines.Add(s + I.ToString + ' char: ' + Cantor(ss, 1, I))
    end;
  end;
end;


il codice è Delphi Pascal, il click del bottone aggiunge i risultati in un memo, è molto spartano e buttato giù in qualche minuto .. scusate eventuali errori
G.
Ibis redibis non morieris in bello
08/01/20 17:28
AldoBaldo
A mala pena leggiucchio il pascal un po' alla mia maniera, però da quel che intuisco hai usato un sistema diverso da quello che ho usato io. Mi vien voglia di tentare una "traduzione" letterale in C. Anzi, lo faccio (e mi ci divertirò pure)!
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
08/01/20 19:59
AldoBaldo
La "traduzione" l'ho fatta, ma mi dà risultati diversi da quelli che mi sarei aspettato, con raggruppamenti di '#' e '.' diversi da quelli della mia soluzione.

Ho visto che tu hai inizializzato la stringa con tutti '#', per poi andare a modificare gli '#' con '.' dove hai ritenuto necessario. Io ho preferito una strada diversa: non ho inizializzato per niente la stringa iniziale, e poi ho usato una funzione con questo prototipo:

int cantor( char str[], int lStr, char chrEst, char chrInt );

Ho passato cioè negli ultimi due parametri il carattere "esterno" (che nel nostro caso è '#') e il carattere "interno" (che nel nostro caso è '.'). E' poi cantor() a decidere quale dei due usare in ogni parte della stringa della quale vengono passati l'indirizzo e la lunghezza. Ad ogni chiamata ricorsiva, ovviamente, vengono passati indirizzi e lunghezze diverse, corrispondenti alle varie "porzioni" della stringa da trattare. La funzione che ho ideato non è interessata a sapere a che livello di "profondità" si trova, semplicemente tratta la "sua" stringa come se fosse l'unica, continuando a chiamare nuovi cantor() fino a che la lunghezza della stringa da trattare è 0 (a quel punto ritorna, chiudendo il ciclo delle ricorsioni).
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
08/01/20 20:59
Goblin
Facciamo il giochino inverso, credo di masticare il "C" al tuo livello di pascal ... dunque metti la tua soluzione e io la converto in pascal ... vediamo quello che esce :)
Nell'immagine a sx il mio a dx il tuo.

EDIT: come ho scritto, ho buttato giù il codice in 5/10 minuti, forse non è molto ottimizzato e molto basilare, ma al momento funzionava, e non sono stato tanto x il sottile, ma sono veramente curioso di vedere la tua versione
Ultima modifica effettuata da Goblin 08/01/20 21:10
Ibis redibis non morieris in bello
08/01/20 21:09
AldoBaldo
Ah! Guardando l'immagine mi risulta OVVIO che ho "cannato" la traduzione... e di brutto! :)

Comunque sia, sperando di non far inquietare i moderatori, vediamo cosa succede quando la traduzione la tenti TU! :heehee:

#include <stdio.h>
#include <stdlib.h>

int cantor_calcola_lunghezza_settori( int lStr, int l[] ) {
    l[0] = lStr/3;
    l[1] = l[0];
    l[2] = l[0];

    if( 0 != l[0] ) {
        int r;

        if( (r=lStr%3) ) {
            if( 1==r ) {
                l[1]++;
            }
            else if( 2==r ) {
                l[0]++;
                l[2]++;
            }
        }

        return 1;
    }

    return 0;
}

int cantor( char str[], int lStr, char chrEst, char chrInt ) {
    int i, l[3];

    if( cantor_calcola_lunghezza_settori(lStr,l) ) {
        int e = cantor( str, l[0], chrEst, chrInt );
        for( i=0; i<l[1]; ++i ) (str+l[0])[i] = chrInt;
        e += cantor( str+l[0]+l[1], l[2], chrEst, chrInt );
        return 2 == e;
    }
    else {
        for( i=0; i<lStr; ++i )
            str[i] = chrEst;
        return 0;
    }
}

int main() {
    char *s = NULL;
    unsigned int l;

    do {
        printf( "Quanti caratteri deve avere la tua stringa? " );
        scanf( "%u", &l );
        while( '\n' != getchar() );

        if( (s=calloc(l+1,sizeof(*s))) ) {
            cantor( s, l, '#', '.' );
            printf( "\n%s\n\n", s );
            free( s ); s = NULL;
        } else puts( "\nErrore: memoria non allocata.\n" );
    } while( 0 != l );

    return 0;
}
ATTENZIONE! Sono un hobbista e l'affidabilità delle mie conoscenze informatiche è molto limitata. Non prendere come esempio il codice che scrivo, perché non ho alcuna formazione accademica e rischieresti di apprendere pratiche controproducenti.
08/01/20 21:17
Goblin
Postato originariamente da AldoBaldo:

Ah! Guardando l'immagine mi risulta OVVIO che ho "cannato" la traduzione... e di brutto! :)

Comunque sia, sperando di non far inquietare i moderatori, vediamo cosa succede quando la traduzione la tenti TU! :heehee:



Credo che ormai sia diventato un giochino tra di noi, ho visto la soluzione che hanno dato nell'altro forum
#include <stdio.h>
#define N 27

void cantor(char[], int, int);

int main() {
    char v[N+1];
    int i;
    for(i = 0; i<N; i++){
        v[i] = 'a';
    }
    v[i] = '
Postato originariamente da AldoBaldo:

Ah! Guardando l'immagine mi risulta OVVIO che ho "cannato" la traduzione... e di brutto! :)

Comunque sia, sperando di non far inquietare i moderatori, vediamo cosa succede quando la traduzione la tenti TU! :heehee:



Credo che ormai sia diventato un giochino tra di noi, ho visto la soluzione che hanno dato nell'altro forum
#include <stdio.h>
#define N 27

void cantor(char[], int, int);

int main() {
    char v[N+1];
    int i;
    for(i = 0; i<N; i++){
        v[i] = 'a';
    }
    v[i] = '{parsed_message}';
    cantor(v, 0, N-1);
    printf("%s\n", v);
    
    return 0;
}

void cantor(char str[], int posInStr, int posFinStr){
    int a = (posFinStr+1-posInStr)/3;
    int i;
    if((posFinStr - posInStr) >= 2){
        for(i=posInStr; i < posInStr + a; i++){
            str[i] = '#';
        }
        for(i = posInStr + a; i < posInStr + 2*a; i++){
            str[i] = '.';
        }
        for(i = posInStr + 2*a; i < posFinStr+1; i++){
            str[i] = '#';
        }
        cantor(str, posInStr, posInStr+a-1);
        cantor(str, posInStr+2*a, posFinStr);
    }
}



e.....
EDIT: :rofl::rofl::rofl::rofl: meno male che non hai postato prima la tua soluzione.... credo che se come soluzione avesse portato la tua nemmeno il prof l'avrebbe capita, hai usato una tecnica veramente avanzata, e peccato che non ci lavori con il codice .... il mondo software sarebbe migliore, i miei complimenti ... spero di essere all'altezza della traduzione pascal'; cantor(v, 0, N-1); printf("%s\n", v); return 0; } void cantor(char str[], int posInStr, int posFinStr){ int a = (posFinStr+1-posInStr)/3; int i; if((posFinStr - posInStr) >= 2){ for(i=posInStr; i < posInStr + a; i++){ str[i] = '#'; } for(i = posInStr + a; i < posInStr + 2*a; i++){ str[i] = '.'; } for(i = posInStr + 2*a; i < posFinStr+1; i++){ str[i] = '#'; } cantor(str, posInStr, posInStr+a-1); cantor(str, posInStr+2*a, posFinStr); } }


e.....
EDIT: :rofl::rofl::rofl::rofl: meno male che non hai postato prima la tua soluzione.... credo che se come soluzione avesse portato la tua nemmeno il prof l'avrebbe capita, hai usato una tecnica veramente avanzata, e peccato che non ci lavori con il codice .... il mondo software sarebbe migliore, i miei complimenti ... spero di essere all'altezza della traduzione pascal
Ultima modifica effettuata da Goblin 08/01/20 21:31
Ibis redibis non morieris in bello