golang算法之鬼谷子问徒

鬼谷子问徒是一道经典的算法题,题目如下:

孙膑,庞涓都是鬼谷子的徒弟。一天鬼谷子出了这道题目:

他从2到99中选出两个不同的整数,把积告诉孙,把和告诉庞;

庞说:我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数是什么。

孙说:我本来的确不知道,但是听你这么一说,我现在能够确定这两个数字了。

庞说:既然你这么说,我现在也知道这两个数字是什么了。

请问这两个数字是什么?为什么?

看似几句话,其实对应了几种条件,转换为如下逻辑:

1 A != B

2 A+B  !=  素数+ 素数

3  A*B != 素数*素数

4 A*B 按二元分解后有且仅有一组元素的和 不等于任意质数加质数的和

5 A+B有且仅有A B组合按二元分解后,满足条件4

代码如下:

package main

import (
	"fmt"
	"sort"
)

//1 A != B
//2 A+B  !=  素数+ 素数
//3  A*B != 素数*素数
//4 A*B 按二元分解后有且仅有一组元素的和 不等于任意质数加质数的和
//5 A+B有且仅有A B组合按二元分解后,满足条件4

func main(){
	var as []int  // 素数
	for i:=2;i<100;i++{
		if isPrime(i){
			as = append(as,i)
		}
	}
	var bs []int
	for _,value1:=range as{
		for _,value2:=range as{
			if value2 <value1{
				continue
			}
			bs = append(bs,value1+value2)
		}
	}
	cs := RemoveRepeatedElement(bs)    //素数和

	var ds []int
	for _,value1:=range as{
		for _,value2:=range as{
			if value2 <value1{
				continue
			}
			ds = append(ds,value1*value2)
		}
	}
	es:=RemoveRepeatedElement(ds) //素数积
	for x:=2;x<100;x++{
		for y:=2;y<100;y++{
			if x >y{
				continue
			}
			if y>53{
				continue
			}
			// A != B
			if x == y {
				continue
			}
			// A+B  !=  素数+ 素数
			if isInInt(x+y,cs){
				continue
			}
			//A*B != 素数*素数
			if isInInt(x*y,es){
				continue
			}
			//A*B 按二元分解后有且仅有一组元素的和 不等于任意质数加质数的和
			if !checkfenjie(x,y,x*y,cs){
				continue
			}
			//A+B有且仅有A B组合按二元分解后,满足条件4
			if !checkdouble(x,y,x+y,cs){
				continue
			}
			fmt.Println(x,y)
			break
		}
	}

	fmt.Println("over")

}

func isInInt(a int,as []int)bool{
	for _,value:=range as{
		if a == value{
			return true
		}
	}
	return false
}

func isPrime(value int) bool {
	if value <= 3 {
		return value >= 2
	}
	if value%2 == 0 || value%3 == 0 {
		return false
	}
	for i := 5; i*i <= value; i += 6 {
		if value%i == 0 || value%(i+2) == 0 {
			return false
		}
	}
	return true
}

func RemoveRepeatedElement(arr []int) (newArr []int) {
	newArr = make([]int, 0)
	sort.Ints(arr)
	for i := 0; i < len(arr); i++ {
		repeat := false
		for j := i + 1; j < len(arr); j++ {
			if arr[i] == arr[j] {
				repeat = true
				break
			}
		}
		if !repeat {
			newArr = append(newArr, arr[i])
		}
	}
	return
}

func checkfenjie(a,b,x int,cs []int)bool{
	for i:=2;i<x;i++{

		if i*i >=x{
			break
		}
		if x%i==0{
			if x/i!=1{
				if i!=a || x/i!=b{
					if !isInInt(i+x/i,cs){
						return false
					}
				}
			}
		}
	}
	return true
}

func checkdouble(a,b,x int,cs[]int)bool{
	for i:=2;i<x;i++{
		if i+i >=x{
			break
		}
		if i == a{
			continue
		}
		if checkfenjie(i,x-i,i*(x-i),cs){
			return false
		}
	}
	return true
}

更多golang信息交流,欢迎入群:805574759

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值