Esercizio in Haskell

Messaggioda Michele/96 » 13/09/2019, 11:56

Salve a tutti,

recentemente, studiando per un esame, mi sono imbattuto nel seguente esercizio in Haskell:

Un numero naturale n si dice perfetto se la somma dei suoi divisori (incluso n) è pari a 2n.
Escluso lo 0 (che non è perfetto per convenzione) i primi tre numeri perfetti sono 6, 28 e
496. Senza usare list comprehension o funzioni della libreria standard, definire una funzione
Codice:
perfetto:: Int => Bool

che, applicata a n, determina se n è perfetto.

ovviamente la limitazione circa l' uso di funzioni della libreria standard non comprende +,- o altre funzioni con nome simbolico.
Quello che non capisco è: esiste un modo per iterare su una lista senza usare head, tail o list comprehension? Ho provato con l' operatore !!, tuttavia non vi è modo(che io sappia) di determinare se l' elemento al quale si tenta di accedere esista, a meno che non si compari l'indice con length che, tuttavia, è comunque una funzione della libreria standard.

Saluti.
Michele/96
New Member
New Member
 
Messaggio: 35 di 70
Iscritto il: 22/10/2016, 12:24

Re: Esercizio in Haskell

Messaggioda apatriarca » 13/09/2019, 16:56

Puoi semplicemente usare la ricorsione. Per esempio, per sommare tutti i divisori di un numero:
Codice:
sommaDivisori n = sommaDivisori' n n 0
sommaDivisori' _ 0 s = s
sommaDivisori' n i s = sommaDivisori' n (i-1) s'
  where s' = if n `mod` i == 0 then s + i else s

Il codice assume gli venga passato un numero positivo e va in loop infinito altrimenti (dovresti forse modificarlo in modo che funzioni correttamente..). Ma spero che l'idea sia chiara.
apatriarca
Moderatore
Moderatore
 
Messaggio: 5297 di 10435
Iscritto il: 08/12/2008, 20:37
Località: Madrid

Re: Esercizio in Haskell

Messaggioda claudio86 » 14/09/2019, 22:49

Michele/96 ha scritto:Quello che non capisco è: esiste un modo per iterare su una lista senza usare head, tail o list comprehension? Ho provato con l' operatore !!, tuttavia non vi è modo(che io sappia) di determinare se l' elemento al quale si tenta di accedere esista, a meno che non si compari l'indice con length che, tuttavia, è comunque una funzione della libreria standard.


Pattern matching e ricorsione?

Codice:
f :: [a] -> Int
f (x:xs) = 1 + f xs -- La lista ha almeno un elemento
f [] = 0            -- La lista è vuota


O anche pattern guards

Codice:
f :: [a] -> Int
f (x:xs)
  | x == 0       = 1 + f xs -- La lista ha almeno un elemento, che è uguale a zero
  | x > 0        = 1 + f xs -- La lista ha almeno un elemento, che è maggiore di zero
  | otherwise    = 1 + f xs -- La lista ha almeno un elemento, che è minore di zero
f [] = 0                    -- La lista è vuota
"This theorem, as many others, is proven by writing zero in a creative way…"
claudio86
Senior Member
Senior Member
 
Messaggio: 525 di 1130
Iscritto il: 09/01/2011, 15:12


Torna a Informatica

Chi c’è in linea

Visitano il forum: Nessuno e 1 ospite