DEV Community

chenge
chenge

Posted on • Edited on

My Solutions for Perfect Number in Several Languages

There's a warm discuss in post Write a script to find "Perfect Numbers" . Here's my solutions.

Ruby

def sum_divisions(n)
  (1...n).select{|i| n % i == 0}.sum
end

def perfect_number?(n)
  n == sum_divisions(n)
end

(1..10_000).each do |i|
  puts "#{i} is perfect" if perfect_number?(i)
end

Enter fullscreen mode Exit fullscreen mode

Node

const sum = (accumulator, currentValue) => accumulator + currentValue;

function range(size, startAt = 0) {
  return [...Array(size).keys()].map(i => i + startAt);
}

function sumDivisions(n){
  arr = range(n-1, startAt=1).filter(x => n % x == 0)
  return arr.reduce(sum, 0);
}

function is_perfect_number(n){
  return sumDivisions(n) == n
}

range(10000, 1).forEach(function(x){
  if(is_perfect_number(x)){
    console.log(x);
  }
})
Enter fullscreen mode Exit fullscreen mode

Go

package main

import (
  "fmt"
)

func sum_divisions(n int) int {
  sum := 0
  for i := 1; i < n; i++ {
    if n % i == 0 {
      sum += i
    }
  }
  return sum
}

func is_perfect(n int) bool {
  return n == sum_divisions(n)
}

func main() {
  for i := 1; i <= 10000; i++ {
    if is_perfect(i) {
      fmt.Println(i)
    }
  }
}

Enter fullscreen mode Exit fullscreen mode

Rust


fn main(){
  let perfects = (1..10_000).filter(|x| is_perfect(*x) );
  for x in perfects {
    println!("{}", x)
  }
}

fn is_perfect(n: i32) -> bool{
  n == sum_divisions(n)
}

fn sum_divisions(n: i32) -> i32{
  (1..n).filter(|x| n % x == 0).sum()
}

Enter fullscreen mode Exit fullscreen mode

Elixir

defmodule Play do
  def perfect?(n) do
    n == sum_divisions(n)
  end

  defp sum_divisions(n) do
    Enum.filter(1..(n-1), fn(x) -> rem(n, x) == 0 end)
    |> Enum.sum
  end
end

Enum.each(2..10_000, fn(x) -> if Play.perfect?(x), do: IO.puts(x) end)

Enter fullscreen mode Exit fullscreen mode

Clojure


(defn sum_divisions [x]
  (apply + 
    (filter #(= 0 (rem x %)) (range 1 x))))

(defn is_perfect [x]
  (= x (sum_divisions x)))

(doseq [i (range 1 10000)] 
  (if (is_perfect i) (println i)))
Enter fullscreen mode Exit fullscreen mode

v2, thanks @jcsvveiga

...
(doseq [ i (range 1 10000)
        :when (is_perfect i) ] 
  (println i) )

Enter fullscreen mode Exit fullscreen mode

End

I'm new to Node, Go, Rust, Elixir and Clojure, if you have better code, welcome comment.

Happy playing!

Top comments (4)

Collapse
 
grayjack profile image
GrayJack • Edited

In rust, there 2 idiomatic way to do the main()

Your version is idiomatic, but there also this way:

fn main(){
  (1..10_000).filter(|x| is_perfect(*x)).for_each(|x| println!("{}", x));
}

For something simple like this, I would use this version

Collapse
 
chenge profile image
chenge

This is like Ruby, nice.

Collapse
 
jcsvveiga profile image
João Veiga

In the Clojure example, you can move the if into :when clojuredocs.org/clojure.core/doseq...

Collapse
 
chenge profile image
chenge

thanks, that's better.