4
\$\begingroup\$

I am trying to implement ugly number sequence generation in Scala.

Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15...

I have implemented using var keyword like java implementation and it is working fine. Here is the ideone link of complete code.

Can someone suggest better of implementing it using Scala idioms and without using mutable values?

/**
 * Ugly numbers are numbers whose only prime factors are 2, 3 or 5. The sequence
 * 1, 2, 3, 4, 5, 6, 8, 9, 10, 12, 15,
 * shows the first 11 ugly numbers. By convention, 1 is included.
 * Write a program to find and print the 150th ugly number.
 *
 */
object UglyNumbers extends App {
 var uglyNumbers = List(1)
 val n = 11
 var i2 = 0;
 var i3 = 0;
 var i5 = 0;
 // initialize three choices for the next ugly numbers
 var next_multiple_2 = uglyNumbers(i2) * 2;
 var next_multiple_3 = uglyNumbers(i3) * 3;
 var next_multiple_5 = uglyNumbers(i5) * 5;
 for (i <- 0 to n) {
 val nextUglyNumber = min(next_multiple_2, next_multiple_3, next_multiple_5)
 uglyNumbers = uglyNumbers :+ nextUglyNumber
 if (nextUglyNumber == next_multiple_2) {
 i2 = i2 + 1
 next_multiple_2 = uglyNumbers(i2) * 2
 }
 if (nextUglyNumber == next_multiple_3) {
 i3 = i3 + 1
 next_multiple_3 = uglyNumbers(i3) * 3
 }
 if (nextUglyNumber == next_multiple_5) {
 i5 = i5 + 1
 next_multiple_5 = uglyNumbers(i5) * 5
 }
 }
 for (uglyNumber <- uglyNumbers)
 print(uglyNumber + " ")
 def min(a: Int, b: Int, c: Int): Int = (a, b, c) match {
 case _ if (a <= b && a <= c) => a
 case _ if (b <= a && b <= c) => b
 case _ => c
 }
}
Jamal
35.2k13 gold badges134 silver badges238 bronze badges
asked Mar 24, 2014 at 4:45
\$\endgroup\$
1
  • \$\begingroup\$ I got very good response here. pls check this link to my cross-post on Stack Overflow \$\endgroup\$ Commented Mar 24, 2014 at 12:12

1 Answer 1

1
\$\begingroup\$

First off, I'd like to mention, that my Scala experience is limited, so please do point out any errors.

You should implement your algorithm in it's own class implementing an appropriate interface/trait (probably Iterator, but there may be better ones).

That would also avoid having the awkward hard-coded limit to 11 elements in the main algorithm.

I'm not a fan of the repeated code for the three base numbers. Off the top of my head I'm not sure how to avoid it, but would assume it would include using case classes.

You should also have a look at your variable names. You have a mixture of short cryptic names (n, i3, etc.) and two different styles (camel case and underlines). You should always use descriptive names (maxIterations, index3) and use a single style (preferably camel case as this is the convention for Scala).

BTW, List has a min method, so there is no need to roll your own:

val nextUglyNumber = List(next_multiple_2, next_multiple_3, next_multiple_5).min;
answered Mar 24, 2014 at 11:29
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.