Skip to content

Instantly share code, notes, and snippets.

@mzemel
Last active August 29, 2015 14:10
Show Gist options
  • Save mzemel/ab79da7fb07520956b25 to your computer and use it in GitHub Desktop.
Save mzemel/ab79da7fb07520956b25 to your computer and use it in GitHub Desktop.
Problem 3 in Project Euler
(ns clojure-euler.core
(:gen-class))
;The prime factors of 13195 are 5, 7, 13 and 29.
;What is the largest prime factor of the number 600851475143 ?
(defn divides_cleanly
"[arg1 arg2] True if the remainder of arg1 / arg2 is 0"
[arg1 arg2]
(= 0 (mod arg1 arg2)))
(defn fits
"[[el & coll]] Makes sure el is not divisible by anything in collection, excluding self
e.g. [5 2 3 4 5] ;=> true"
[[ el & coll]]
(not (some #(and (divides_cleanly el %) (not (= el %))) coll)))
(defn massage
"[v] Will sort vector and select elements which cannot be divided by any other number
e.g. [2, 3, 4, 5, 6] => [2, 3, 5]"
[v]
(into [] (filter #( fits (into [%] v)) v)))
(defn factors
"[t] Returns vector of all factors for target, not unique or ordered"
[t]
(loop [primes []
highest t
iteration 2]
(if (< highest iteration)
(apply max (massage primes))
(do
(if (divides_cleanly t iteration)
(recur (concat primes [iteration (/ t iteration)]) (/ t iteration) (inc iteration))
(recur primes t (inc iteration)))))))
(factors 600851475143)
; => 6857
# The prime factors of 13195 are 5, 7, 13 and 29.
# What is the largest prime factor of the number 600851475143 ?
defmodule ProblemThree do
def primes_for(n) do
Enum.filter(1..n, fn(x) -> rem(n,x) == 0 end)
end
def is_prime?(n) do
length(primes_for n) == 2
end
def prime_factors_for(n) do
Enum.filter(1..round(n/2), fn(x) -> is_prime? x end)
end
end
IO.puts Enum.max ProblemThree.prime_factors_for 600851475143
# The prime factors of 13195 are 5, 7, 13 and 29.
# What is the largest prime factor of the number 600851475143 ?
class FactorSet
include Enumerable
attr_accessor :arr
def initialize(init = nil)
self.arr = []
arr.push(init) if init
end
def permits?(arg)
arr[1..-1].each do |el|
break nil if ( arg % el == 0)
end
end
def push(arg)
arr.push(arg)
end
def last
arr.last
end
end
class ProblemSolver
attr_accessor :small, :large, :bignum
def initialize(bignum)
self.small = FactorSet.new(1)
self.large = FactorSet.new(bignum)
self.bignum = bignum
end
def perform
iterate
puts answer
end
def iterate
(2..bignum).each do |i|
break if i > large.last
rem = bignum % i
if rem == 0
quotient = bignum / i
large.push(quotient)
small.push(i) if small.permits?(i)
end
end
end
def answer
large.arr.select{|el| small.permits?(el)}.first || small.last
end
end
p = ProblemSolver.new(6008514751433)
p.perform
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment