试图解决Project Euler问题119:
数字512很有意思,因为它等于它的数字加到某个幂的总和:5 + 1 + 2 = 8,而8 ^ 3 = 512.具有此属性的数字的另一个例子是614656 = 28 ^ 4。
我们将a定义为该序列的第n个术语,并坚持数字必须包含至少两个数字才能得到总和。
您被给予a2 = 512和a10 = 614656。
找到a30。
问题:找到答案的方法是否比检查每个号码更有效,直到找到a30为止?
我的代码
int currentNum = 0;
long value = 0;
for (long a = 11; currentNum != 30; a++){ //maybe a++ is inefficient
int test = Util.sumDigits(a);
if (isPower(a, test)) {
currentNum++;
value = a;
System.out.println(value + ":" + currentNum);
}
}
System.out.println(value);
isPower检查a是否是测试的力量。 Util.sumDigits:
public static int sumDigits(long n){
int sum = 0;
String s = "" + n;
while (!s.equals("")){
sum += Integer.parseInt("" + s.charAt(0));
s = s.substring(1);
}
return sum;
}
程序已经运行了大约30分钟(可能会长时间溢出)。输出(到目前为止):
81:1
512:2
2401:3
4913:4
5832:5
17576:6
19683:7
234256:8
390625:9
614656:10
1679616:11
17210368:12
34012224:13
52521875:14
60466176:15
205962976:16
612220032:17
答案 0 :(得分:5)
解决方案是一个15位数字。祝你运气好,足以使运行速度足以检查每一个数字。
解决问题。数字的总和是一个相对较低的数字(最多9×数字的位数),功率也相对较低(即使是15位数也不需要很大的功率)
所以循环求和和幂,计算总数(你可以在内部循环中保持一个运行总数乘以,甚至不需要功率计算)然后将其数字相加以查看它是否与你的循环相匹配变量
数字不符合规定,因此计算得比您需要的多,并对结果进行排序。
应该在大约一秒钟内运行。
答案 1 :(得分:3)
关于那个数字总和......这里有一些重要的事实:
0% Scenario{vm=java, trial=0, benchmark=NaiveDigitSum} 542.90 ns; σ=11.00 ns @ 10 trials
50% Scenario{vm=java, trial=0, benchmark=BetterDigitSum} 42.13 ns; σ=1.42 ns @ 10 trials
benchmark ns linear runtime
NaiveDigitSum 542.9 ==============================
BetterDigitSum 42.1 ==
测试代码:
import com.google.caliper.Runner;
import com.google.caliper.SimpleBenchmark;
public class Performance extends SimpleBenchmark {
public void timeNaiveDigitSum(int reps) {
for (int r = 0; r < reps; r++) sumDigits(r + 1_000_000);
}
public void timeBetterDigitSum(int reps) {
for (int r = 0; r < reps; r++) sumDigitsBetter(r + 1_000_000);
}
public static int sumDigits(long n){
int sum = 0;
String s = "" + n;
while (!s.equals("")){
sum += Integer.parseInt("" + s.charAt(0));
s = s.substring(1);
}
return sum;
}
static int sumDigitsBetter(long n) {
int sum = 0;
for (; n != 0; sum += n % 10, n /= 10);
return sum;
}
public static void main(String... args) {
Runner.main(Performance.class, args);
}
}
(已删除扰流板解决方案,可通过编辑历史记录获取)