英文:
Unable to use .to() operator on Long data type
问题
The code you provided is in Scala and seems to have an issue with the to()
method, which expects an Int
as the upper bound. To work with a Long
range, you can use the to
method with Long
ranges. Here's a corrected version of your code:
@main def m(): Unit = {
var largest = 0L;
val num = 600851475143L;
(2L to num - 1).foreach(arg =>
if (num % arg == 0 && largest < arg) {
var flag = true;
(2L to arg - 1).foreach(arg2 =>
if (arg % arg2 == 0) flag = false
);
if (flag) largest = arg;
}
)
println(largest);
}
By using 2L
and arg.to(arg - 1)
for Long ranges, you should be able to avoid the error related to the Long datatype.
英文:
The question is:
The prime factors of 13195 are 5, 7, 13 and 29.
What is the largest prime factor of the number 600851475143?
I have written a code for it but it gives an error.The code is written in Scala.
@main def m(): Unit = {
var largest = 0L;
val num = 600851475143L;
2.to(num - 1).foreach(arg =>
if num % arg == 0 && largest < arg then
var flag = true;
2.to(arg - 1).foreach(arg2 =>
if arg % arg2 == 0 then flag = false);
if flag then largest = arg;
)
println(largest);
}
The code gives an error of:
Found: Long
Required: Int
2.to(num - 1).foreach(arg =>
How can we use .to() operator for Long datatype? It seems like we are only allowed to use Int.
I tried type casting the long to the Int but it resulted in the answer getting 0.
答案1
得分: 4
以下是您要翻译的内容:
"While number in a Range
can be Long
s, they cannot contain more than Int.MaxValue
values (docs):
Any method that could require a collection of over
Int.MaxValue
length to be created, or could be asked to index beyondInt.MaxValue
elements will throw an exception.
You can create a lazy Iterator
that spans all numbers from 2L
to a Long
greater than Int.MaxValue
as follows:
Iterator.iterate(2L)(_ + 1).takeWhile(_ < max)
So in your code this would be the following:
@main def m(): Unit = {
var largest = 0L;
val num = 600851475143L;
Iterator.iterate(2L)(_ + 1).takeWhile(_ < (num - 1)).foreach(arg =>
if num % arg == 0 && largest < arg then
var flag = true;
Iterator.iterate(2L)(_ + 1).takeWhile(_ < (arg - 1)).foreach(arg2 =>
if arg % arg2 == 0 then flag = false);
if flag then largest = arg;
)
println(largest);
}
A few additional notes:
- you can drop the semicolons if you want, they are not needed in Scala
- producing the range lazily is a bit of a mouthful, it's probably best to give it a name
- you can use
for
-comprehensions as a way to express looping (what you are achieving withforeach
)
Given this, one way to re-write your program could be the following:
def range(from: Long, to: Long, step: Long = 1) = {
require(from < to)
Iterator.iterate(from)(_ + step).takeWhile(_ < to)
}
var largest = 0L;
val num = 600851475143L;
for (arg <- range(from = 2L, to = num - 1)) {
if num % arg == 0 && largest < arg then
var flag = true
for (arg2 <- range(from = 2L, to = arg - 1)) {
if arg % arg2 == 0 then flag = false
}
if flag then largest = arg
}
println(largest)
The for
-comprehension above is entirely equivalent to a foreach
. They are particularly useful when you need to nest multiple flatMap
s and close with a map
or a foreach
to make the code less nested and possibly easier to read. You can read more about them in the documentation.
You can play around with this code here on Scastie. Maybe consider giving your variables names more meaningful than arg
, arg2
and flag
as well to improve the readability.
As a final note, more important than anything, your algorithm can probably be improved in terms of time complexity, but that's something you want to spent some time on by yourself.
英文:
While number in a Range
can be Long
s, they cannot contain more than Int.MaxValue
values (docs):
> Any method that could require a collection of over Int.MaxValue
length to be created, or could be asked to index beyond Int.MaxValue
elements will throw an exception.
You can create a lazy Iterator
that spans all numbers from 2L
to a Long
greater than Int.MaxValue
as follows:
Iterator.iterate(2L)(_ + 1).takeWhile(_ < max)
So in your code this would be the following:
@main def m(): Unit = {
var largest = 0L;
val num = 600851475143L;
Iterator.iterate(2L)(_ + 1).takeWhile(_ < (num - 1)).foreach(arg =>
if num % arg == 0 && largest < arg then
var flag = true;
Iterator.iterate(2L)(_ + 1).takeWhile(_ < (arg - 1)).foreach(arg2 =>
if arg % arg2 == 0 then flag = false);
if flag then largest = arg;
)
println(largest);
}
A few additional notes:
- you can drop the semicolons if you want, they are not needed in Scala
- producing the range lazily is a bit of a mouthful, it's probably best to give it a name
- you can use
for
-comprehensions as a way to express looping (what you are achieving withforeach
)
Given this, one way to re-write your program could be the following:
def range(from: Long, to: Long, step: Long = 1) = {
require(from < to)
Iterator.iterate(from)(_ + step).takeWhile(_ < to)
}
var largest = 0L;
val num = 600851475143L;
for (arg <- range(from = 2L, to = num - 1)) {
if num % arg == 0 && largest < arg then
var flag = true
for (arg2 <- range(from = 2L, to = arg - 1)) {
if arg % arg2 == 0 then flag = false
}
if flag then largest = arg
}
println(largest)
The for
-comprehension above is entirely equivalent to a foreach
. They are particularly useful when you need to nest multiple flatMap
s and close with a map
or a foreach
to make the code less nested and possibly easier to read. You can read more about them in the documentation.
You can play around with this code here on Scastie. Maybe consider giving your variables names more meaningful than arg
, arg2
and flag
as well to improve the readability.
As a final note, more important than anything, your algorithm can probably be improved in terms of time complexity, but that's something you want to spent some time on by yourself.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论