martedì 22 novembre 2022

Prova del 9 in linguaggio C

Ritornando con la mente ai tempi delle elementari (ai miei tempi si chiamavano così, non "primaria" come oggi) mi è venuta la voglia di implementare la prova del 9 in linguaggio C. 

Per chi non lo sapesse, la prova del 9 è un sistema per verificare la correttezza del risultato della moltiplicazione fra due operandi; in realtà il superamento di questa prova non certifica che il risultato sia corretto, infatti ci sono degli errori (come lo scambio di posizione delle cifre) che non possono essere rilevati.

Volendo utilizzare il procedimento corretto (confesso che non me lo ricordavo) e la terminologia appropriata, ho fatto qualche ricerca su Internet. 

Innanzitutto il procedimento è spiegato molto bene su wikipedia https://it.wikipedia.org/wiki/Prova_del_nove: l'implementazione della sequenza si trova nella funzione ProvaDel9() in cui eseguo anche una stampa a video della croce in cui, per consuetudine, si inseriscono i valori calcolati.

La somma delle cifre di un numero si chiama radice numerica (vedi https://it.wikipedia.org/wiki/Radice_numerica): in pratica bisogna sommare fra di loro tutte le cifre del numero e procedere ricorsivamente finchè non rimaniamo con un'unica cifra (ovvero un valore da 0 a 9). Il calcolo della radice numerica è implementato nella funzione RadiceNumerica() che riceve in input il valore e restituisce come risultato la radice numerica calcolata. La funzione avrebbe potuto sfruttare la ricorsività, ovvero richiamare se stessa se il risultato ottenuto è composto da più di una cifra ma, sebbene forse meno elegante, ho preferito implementarla con un semplice ciclo while.

Qui sotto il programma completo... Buon divertimento!!!


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

int RadiceNumerica(int val)
{
    int sum;

    if (val < 0)            // determina valore assoluto (elimina segno)
        val = -val;

    while (val >= 10)        // il ciclo viene eseguito finchè non rimane una sola cifra    
    {
        sum = 0;
        while (val > 0)        // calcola la somma di tutte le cifre
        {
            sum += val % 10;
            val = val / 10;
        }
        val = sum;        
    }
    return val;
}

int ProvaDel9(int a, int b, int p)
{
    int c;
    int ra;
    int rb;
    int rc;
    int rp;

    ra = RadiceNumerica(a);
    rb = RadiceNumerica(b);

    c = ra*rb;
    rc = RadiceNumerica(c);

    rp = RadiceNumerica(p);

    printf("\n %5d | %5d", ra, rb);
    printf("\n       |      ");
    printf("\n ------+------");
    printf("\n       |      ");
    printf("\n %5d | %5d", rc, rp);
    printf("\n");

    if (rc == rp)
        return 1;
    else
        return 0;
}

int InputInt(char *message)
{
    int val = 0;
    char buff[128];

    printf(message);
    
    strcpy(buff, "");
    if(fgets(buff, 128, stdin))
        val = atoi(buff);

    return val;
}

int main(int argc, char **argv)
{
    int a;
    int b;
    int p;

    a = InputInt("\nInserisci il moltiplicando:");
    b = InputInt("\nInserisci il moltiplicatore:");
    p = InputInt("\nInserisci il prodotto:");

    if( ProvaDel9(a, b, p) )
        printf("\nVerifica OK");
    else
        printf("\nVerifica KO");

    return 0;
}


martedì 27 settembre 2022

Crivello di Eratostene in Python

Con un po' di tempo libero a disposizione mi sono cimentato nell'implementazione del famoso Crivello di Eratostene, per la ricerca dei numeri primi, utilizzando il linguaggio Python.

Sono partito dall'algoritmo, sviluppato con GW-BASIC, presente in questo articolo https://www.sebcosta.altervista.org/joomla/articles/30-crivello-di-erastotene-in-gw-basic.html

Ecco qui il programma:

import math

def Eratostene(n):
# prepara il setaccio con una lista da a[1] a a[n] (a[0] viene ignorato)
# la lista viene creata con tutti valori a 0
a = [0] * (n+1)

max = int(math.sqrt(n)) # determina fine setacciatura
for i in range(2, max + 1):
j = i + i # i*2
while j <= n:
a[j] = 1 # marchia j come "non primo"
j = j + i # i*3,i*4,i*5,...

# crea lista in output
primi = []
for i in range(2, n + 1):
if a[i] == 0:
primi.append(i)

return primi

n=int(input("Inserisci N="))
primi = Eratostene(n)
print(primi)

Rispetto alla versione GW-BASIC, la versione Python è senz'altro molto più leggibile!

Alcune note:
- l'array per il "setaccio" viene implementato tramite una lista
- l'indice 0 della lista "setaccio" non viene utilizzato (in realtà, nella pratica, neanche l'indice 1 viene utilizzato)
- la fase di "setacciatura" avviene senza eseguire alcuna moltiplicazione, ma semplicemente eseguendo addizioni ripetute.
- la funzione Eratostene(n) ritorna una lista dei numeri primi trovati, quindi alla fine della funzione si scorre il setaccio per determinare i valori che non hanno divisori.

Ecco un esempio di esecuzione:

Inserisci N=100
[2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

Sarebbe per me molto interessante riscrivere l'ultima parte, in cui si crea la lista di numeri primi, in un modo più pythonico: al momento non ho trovato alcuna alternativa... se qualcuno ha qualche suggerimento mi faccia sapere!!!

giovedì 24 ottobre 2019

La ricorsione

Qualche settimana fa sono stato contattato da un nuovo amico di nome Simone che mi chiedeva se potevo fornirgli maggiori spiegazioni sull'algoritmo di ricerca delle combinazioni che ho presentato qui https://sebcosta.altervista.org/joomla/articles/4-algoritmo-per-la-ricerca-delle-combinazioni.html.
Per spiegare questo algoritmo sono partito da una spiegazione di come funziona la ricorsione.

mercoledì 27 marzo 2019

Sostituzione di stringhe in C

Ho scritto in C una funzione simile alla String.Replace() di C#: purtroppo la libreria standard del linguaggio C non fornisce tale funzionalità che quindi va implementata in proprio.
Come prototipo ho deciso di utilizzare qualcosa del genere:

int StrReplace(char *str, int maxstr, char *pattern, char *replace);

dove str è la stringa da modificare, maxstr la dimensione allocata per tale stringa, pattern la stringa da ricercare e replace la stringa da utilizzare in sostituzione.
La String.Replace() di C# sostituisce tutte le occorrenze che trova mentre la mia funzione, per semplicità, si limita alla prima occorrenza. Per lavorare come la String.Replace() è possibile sfruttare il valore di ritorno che sarà 1 nel caso di sostituzione avvenuta o 0 se non c'è stata alcuna sostituzione (o <0 in caso di errore), permettendoci quindi di scrivere 

while( StrReplace(...) == 1 ) {};

Qui di seguito presento il codice completo e le spiegazioni.

mercoledì 6 marzo 2019

Potenze ricorsive in GW-BASIC

In questo post riporto un semplice esempio di programma GW-BASIC: si tratta del calcolo del potenza con il metodo delle potenze ricorsive.

Per maggiori informazioni sull'algoritmo potete partire dalla spiegazione che trovate qui.

L'implementazione è iterativa (non ricorsiva) e fa uso del solo costrutto IF (si poteva usare un WHILE/WEND, qui sostituito da un IF+GOTO).


sabato 2 marzo 2019

Python course

Da un vecchio post su Google+, riporto il link ad un sito con vari tutorial su Python: a me è stato molto utile la parte su Tkinter https://www.python-course.eu/