1votos

AutoNumeros (selfNumbers) en Haskell en Clojure

por josejuan hace 3 años

Algo mejor con el array mutable, pero las computaciones siguen siendo lazy y sigue siendo lento.

Realizar el ejercicio acorde a los planteamientos dados en lenguaje de programación Haskell

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
(defn digitToInt [c] (- (int c) 48)) 
 
(defn d [n] (+ n (reduce + (map digitToInt (str n))))) 
 
(defn noSelf [v i n] 
    (if (<= i n) 
        (do (aset-boolean v i true) 
            (noSelf v (d i) n)))) 
 
(defn selfs [n] 
    (let [v (boolean-array (+ 1 n))] 
         (for [i (range 1 (+ 1 n)) 
                 :when (do (noSelf v (d i) n) 
                           (not (aget v i)))] 
              i))) 
 
(defn upTo [n] (reverse (take 20 (reverse (sort (selfs n)))))) 
 
(print (with-out-str (time (println (upTo 9999))))) 
2 comentarios
0votos

Escrito por josejuan hace 3 años

Para percibir un "curioso efecto Clojurano" sustitúyase:
                 :when (do (noSelf v (d i) n) 
                           (not (aget v i)))] 

por
                 :when (do (not (aget v i))
                           (noSelf v (d i) n))] 

(NOTA: el efecto obviamente es por lazy, mi referencia en twitter es a la impureza de la función `noSelf`)
0votos

Escrito por josejuan hace 3 años

Vale, esperar que me va a costar sacar la pata de tan profundo que la he metido:
                 :when (let [x (not (aget v i))]
                           (noSelf v (d i) n)
                           x)] 

¡Pero el `unsafe` sigue intácto!

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.