Project Euler 16 – 帮助解决问题

huangapple go评论105阅读模式
英文:

Project Euler 16 - Help in solving it

问题

我正在解决Project Euler问题16,我已经得到了一个可以逻辑上解决它的代码,但是由于溢出或其他原因无法处理。我尝试使用int64替换int,但它只打印0,0。如果我将幂改为30以下的任何值,它都可以工作,但是超过30就无法工作了。有人能指出我的错误吗?我认为它无法计算2^1000。

// PE_16项目 main.go
package main

import (
    "fmt"
)

func power(x, y int) int {
    var pow int
    var final int
    final = 1
    for pow = 1; pow <= y; pow++ {
        final = final * x
    }
    return final
}

func main() {
    var stp int
    var sumfdigits int
    var u, t, h, th, tth, l int
    stp = power(2,1000)
    fmt.Println(stp)
    u = stp / 1 % 10
    t = stp / 10 % 10
    h = stp / 100 % 10
    th = stp / 1000 % 10
    tth = stp / 10000 % 10
    l = stp / 100000 % 10
    sumfdigits = u + t + h + th + tth + l
    fmt.Println(sumfdigits)
}
英文:

I'm solving Project Euler problem 16, I've ended up with a code that can logically solve it, but is unable to process as I believe its overflowing or something? I tried int64 in place of int but it just prints 0,0. If i change the power to anything below 30 it works, but above 30 it does not work, Can anyone point out my mistake? I believe its not able to calculate 2^1000.

// PE_16 project main.go
package main

import (
	&quot;fmt&quot;
)

func power(x, y int) int {
	var pow int
	var final int
	final = 1
	for pow = 1; pow &lt;= y; pow++ {
		final = final * x
	}
	return final
}

func main() {
	var stp int
	var sumfdigits int
	var u, t, h, th, tth, l int
	stp = power(2,1000)
	fmt.Println(stp)
	u = stp / 1 % 10
	t = stp / 10 % 10
	h = stp / 100 % 10
	th = stp / 1000 % 10
	tth = stp / 10000 % 10
	l = stp / 100000 % 10
	sumfdigits = u + t + h + th + tth + l
	fmt.Println(sumfdigits)
}

1: http://projecteuler.net/problem=16 "Project Euler: Problem 16"

答案1

得分: 8

你对这个问题的方法需要精确的整数运算,最多可以达到1000位大小。但是你正在使用32位或64位的intmath/big.Int可以处理这样的任务。我故意没有提供使用big.Int的现成解决方案,因为我假设你的目标是通过自己的努力学习,这也是Project Euler的目的。

英文:

Your approach to this problem requires exact integer math up to 1000 bits in size. But you're using int which is 32 or 64 bits. math/big.Int can handle such task. I intentionally do not provide a ready made solution using big.Int as I assume your goal is to learn by doing it by yourself, which I believe is the intent of Project Euler.

答案2

得分: 1

正如@jnml所指出的,int不够大;如果你想在Go中计算2^1000,big.Int是一个很好的选择。请注意,math/big提供了Exp()方法,使用起来比将你的power函数转换为big.Int更容易。

大约一年前,我解决了一些Project Euler的问题,使用Go语言来熟悉这门语言。我不喜欢那些需要使用big.Int的问题,在Go中使用它们并不容易。对于这个问题,我在Ruby中用一行代码“作弊”解决了:

已删除,因为我记得即使是用另一种语言,展示一个可行的解决方案也被认为是不好的形式。

无论如何,我的Ruby示例展示了我在使用Go的big.Int时学到的另一件事情:有时候将它们转换为字符串并使用该字符串进行操作比直接使用big.Int本身更容易。这个问题对我来说就是这种情况之一。

将我的Ruby算法转换为Go,我只在一行中使用big.Int,然后使用字符串很容易,只需几行代码就能得到答案。

英文:

As noted by @jnml, ints aren't large enough; if you wish to calculate 2^1000 in Go, big.Ints are a good choice here. Note that math/big provides the Exp() method which will be easier to use than converting your power function to big.Ints.

I worked through some Project Euler problems about a year ago, doing them in Go to get to know the language. I didn't like the ones that required big.Ints, which aren't so easy to work with in Go. For this one, I "cheated" and did it in one line of Ruby:

Removed because I remembered it was considered bad form to show a working solution, even in a different language.

Anyway, my Ruby example shows another thing I learned with Go's big.Ints: sometimes it's easier to convert them to a string and work with that string than to work with the big.Int itself. This problem strikes me as one of those cases.

Converting my Ruby algorithm to Go, I only work with big.Ints on one line, then it's easy to work with the string and get the answer in just a few lines of code.

答案3

得分: 1

你不需要使用math/big。以下是一个学生数学的方法来将一个十进制数加倍,作为提示!

xs按最低有效位的顺序保存十进制数字。将指向这些数字的指针(pxs)作为参数传递,因为切片可能需要变大。

func double(pxs *[]int) {
	xs := *pxs
	carry := 0
	for i, x := range xs {
		n := x*2 + carry
		if n >= 10 {
			carry = 1
			n -= 10
		} else {
			carry = 0
		}
		xs[i] = n
	}
	if carry != 0 {
		*pxs = append(xs, carry)
	}
}
英文:

You don't need to use math/big. Below is a school boy maths way of doubling a decimal number as a hint!

xs holds the decimal digits in least significant first order. Pass in a pointer to the digits (pxs) as the slice might need to get bigger.

func double(pxs *[]int) {
	xs := *pxs
	carry := 0
	for i, x := range xs {
		n := x*2 + carry
		if n &gt;= 10 {
			carry = 1
			n -= 10
		} else {
			carry = 0
		}
		xs[i] = n
	}
	if carry != 0 {
		*pxs = append(xs, carry)
	}
}

huangapple
  • 本文由 发表于 2013年4月23日 16:50:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/16164944.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定