Search code examples
scalafunctional-programmingfactors

Finding common factors in Scala


We need to find all common factors for a list of integers:

val b = List(4, 8, 12)
b: List[Int] = List(4, 8, 12)

Getting the minimum value in the list:

val min_b = b.min
min_b: Int = 4

Iterating through the range from 1 to min_b and checking if every element in b is divisible by the iterator's current value works, but the output contains empty AnyVals:

val factors_of_b = (1 to min_b)
  .map { x => if (b.forall{ z => z % x == 0 }) x }

Results in:

factors_of_b: scala.collection.immutable.IndexedSeq[AnyVal] = Vector(1, 2, (), 4)

Yielding zeros in place of inapplicable factors and filtering the result for zeros is one workaround, but maybe there exists a cleaner, more Scala-esque solution?

val factors_of_b = (1 to min_b)
  .map { x => if(b.forall{ z => z % x == 0 }) x else 0 }
  .filterNot(_ == 0)

Results in:

factors_of_b: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 4)

Solution

  • What you want is a filter:

    scala> val b = List(4, 8, 12)
    b: List[Int] = List(4, 8, 12)
    
    scala> (1 to b.max).filter { x => b.forall{ z => z % x == 0 } }
    res3: scala.collection.immutable.IndexedSeq[Int] = Vector(1, 2, 4)
    

    Also, I'm not sure why are you iterating until b.max instead of b.min, since the common factor won't be greater than any of the numbers.