Golang语法的25个练习题:11至15题

2023-02-22
3分钟阅读时长

题目11:剪刀石头布

游戏开始,初始状态下用户和电脑都有100分,赢一局+10分,输一局-10分。当用户为0分时,游戏结束,提示游戏结束,比赛输了,当用户为200分时,游戏结束,提示游戏结束,赢得比赛、每轮比赛都输出当前的分数

1代表剪刀 2代表石头 3代表布

package main

import (
	"fmt"
	"math/rand"
	"os"
	"strconv"
	"strings"
	"time"
)

var (
	gameInfo = map[int]string{
		1: "剪刀",
		2: "石头",
		3: "布",
	}
	score = 100
)

func main() {
	fmt.Println(strings.Repeat("=", 60))
	fmt.Println(strings.Repeat(" ", 20), "剪刀石头布游戏")
	fmt.Println("1代表剪刀 2代表石头 3代表布")
	for {
		rd := rand.New(rand.NewSource(time.Now().UnixNano()))
		robotsChoice := rd.Intn(3)
		if robotsChoice == 0 {
			robotsChoice++
		}
		userChoice, err := input("请出拳")
		if err != nil {
			fmt.Println(err)
			continue
		}
		if _, ok := gameInfo[userChoice]; !ok {
			fmt.Println("1代表剪刀 2代表石头 3代表布,你输入了", userChoice)
			continue
		}
		fmt.Println(strings.Repeat("*", 60))
		fmt.Printf("电脑出: %s\n", gameInfo[robotsChoice])
		fmt.Printf("你出: %s\n", gameInfo[userChoice])
		fmt.Println(strings.Repeat("*", 60))
		if userChoice == 1 && robotsChoice == 3 ||
			userChoice == 2 && robotsChoice == 1 ||
			userChoice == 3 && robotsChoice == 2 {
			score += 10
			fmt.Printf("你赢得本轮游戏,当前分数为%d\n", score)
		} else if userChoice == robotsChoice {
			fmt.Printf("本轮游戏平局,当前分数为%d\n", score)
		} else {
			score -= 10
			fmt.Printf("你输了本轮游戏,当前分数%d\n", score)
		}

		if score >= 200 {
			fmt.Println("游戏结束,你赢得比赛")
			break
		} else if score <= 0 {
			fmt.Println("游戏结束,你输了")
			break
		}
	}
}

func input(text string) (int, error) {
	fmt.Print(text)
	data := make([]byte, 1024)
	n, err := os.Stdin.Read(data)
	if err != nil {
		return 0, err
	}
	return strconv.Atoi(string(data[:n-1]))
}

题目12:快乐数

在给定的数字下,该数字所有数位(digits)的平方和,得到的新数再次求所有数位的平方和,如此重复进行,最终结果必定为1

比如数字:19

  • 1 1 = 1 9 9 = 81 = 1 + 81 = 82
  • 8 8 = 64 2 2 = 4 = 64 + 4 = 68
  • 6 6 = 36 8 8 = 64 = 36 + 64 = 100
  • 1 + 0 + 0 = 1
package main

import (
	"fmt"
	"os"
	"strconv"
)

func main() {
	n, err := input("请输入数字:")
	if err != nil {
		fmt.Println(err)
		return
	}
	mp := map[int]bool{}
	for n = sumSquare(n); !mp[n]; n = sumSquare(n) {
		mp[n] = true
	}
	if n == 1 {
		fmt.Println("是快乐数")
	} else {
		fmt.Println("不是是快乐数")
	}
}

func sumSquare(n int) int {
	sum := 0
	for n > 0 {
		mod := n % 10
		sum += mod * mod
		n = n / 10
	}
	return sum
}

func input(text string) (int, error) {
	fmt.Print(text)
	data := make([]byte, 1024)
	n, err := os.Stdin.Read(data)
	if err != nil {
		return 0, err
	}
	return strconv.Atoi(string(data[:n-1]))
}

题目13:猜年龄(一)

  1. 小明带两个妹妹参加元宵灯会。别人问她们多大了,她们调皮地说:“我们俩的年龄之积是年龄之和的6倍“。
  2. 小明又补充说:“她们可不是双胞胎,年龄差肯定也不超过8岁啊。“
  3. 请你写出:小明的较小的妹妹的年龄。
package main

import (
	"fmt"
)

func main() {
	for i := 1; i <= 100; i++ {
		for j := 1; j < i; j++ {
			if i*j == 6*(i+j) && i-j < 8 {
				fmt.Println(i, j)
			}
		}
	}
	// output:
	// 15 10
}

题目14:猜年龄(二)

美国数学家维纳(N.Wiener)智力早熟,11岁就上了大学。

他曾在1935~1936年应邀来中国清华大学讲学。

一次,他参加某个重要会议,年轻的脸孔引人注目。于是有人询问他的年龄,

他回答说:“我年龄的立方是个4位数。我年龄的4次方是个6位数。

这10个数字正好包含了从0到9这10个数字,每个都恰好出现1次。“

请你推算一下,他当时到底有多年轻

package main

import (
	"fmt"
	"math"
	"strconv"
)

func main() {
	for i := 10; i <= 30; i++ {
		i3, i4 := int(math.Pow(float64(i), 3)), int(math.Pow(float64(i), 4))
		if len(strconv.Itoa(i3)) == 4 && len(strconv.Itoa(i4)) == 6 {
			mp := map[int]struct{}{}
			for k := i3; k > 0; k /= 10 {
				mp[k%10] = struct{}{}
			}
			for k := i4; k > 0; k /= 10 {
				mp[k%10] = struct{}{}
			}
			if len(mp) == 10 {
				fmt.Println(i)
				fmt.Println(strconv.Itoa(i3) + strconv.Itoa(i4))
			}
		}
	}
	// output:
	// 18
	// 5832104976
}

题目15:split算法实现

  • split是python字符串内置的一个非常有用的方法它可以将一个字符串通过分隔符切成我们想要的列表比如现在我们有个字符串
  • life-is-short-you-need-python
  • 每一个单词之间使用横杆进行分割,当我们去调用字符串split的方法之后传入我们的分隔符横杆 - 那我们就会得到一个列表列表里面每个元素其实就是通过分隔符切出来的子字符串
  • 那这个算法该怎么样去实现呢?python内置的split方法是通过C语言实现的,我们今天去写一个函数,去实现和split相同的功能
  • 我们先来讲下算法该怎么样去实现这个算法需要我们对字符串进行迭代,我们先去定义一个初始化的指针,因为我们切片的时候需要从哪一个开始的位置进行切,所以我们先要初始化一个指针
  • 我们可以定义一个指针变量,默认值为0,紧接着我们开始对字符串进行迭代,当碰到第一个分隔符的时候,我们是不是会获取到当前分隔符的索引,那这个时候,我们就把初始的指针开始到分隔符结束对字符串进行切片
  • 因为我们字符串是遵守左闭右开的,你的结束索引写的是分隔符的索引,所以只会切到life,我们并把它添加到列表里面,紧接着添加完之后呢,我们需要把初始化的指针修改一下位置,修改到哪个地方呢?修改到我们第一次碰到的分隔符的下一个位置
  • 也就是i,紧接着继续进行迭代,迭代之后发现第二个分隔符,是不是还有一个分隔符的索引,这个时候我们继续向字符串进行切片,切片的开始位置是你的i这个位置的指针,结束的位置是第二个 - 的指针,那遵循左闭右开,所以我们is这个单词,也可以添加进列表
  • 就这样一直到最后呢,当我们去迭代到最后一个字符n的时候,发现后面是没有横杆分隔符了,这个时候我们需要进行处理一下,需要进行去判断一下,如果我们迭代到的字符是最后一个字符,那么我们进行切片的时候,就应该从哪个地方切呢?
  • 从p开始 ,如果切到n,我们只能取到pytho,少切一个n,所以到n + 1的位置,好,知道这个流程我们就用代码去实现这个算法
package main

import (
	"fmt"
)

func main() {
	fmt.Println(splits("life-is-short-you-need-python", "-", 0))
	fmt.Println(splits("life-is-short-you-need-python", "-", 2))
	// output:
	// [life is short you need python]
	// [life is short-you-need-python]
}

func splits(str string, sep string, num int) []string {
	splitWords := []string{}
	lastIndex := 0
	count := 0
	for index, char := range str {
		if count == num && num > 0 {
			splitWords = append(splitWords, str[lastIndex:])
			break
		}
		if string(char) == sep {
			splitWords = append(splitWords, str[lastIndex:index])
			lastIndex = index + 1
			count++
		} else if index+1 == len(str) {
			splitWords = append(splitWords, str[lastIndex:])
		}
	}
	return splitWords
}

python原文:https://www.52pojie.cn/thread-1689186-1-1.html

关注公众号获得更多精彩文章

公众号:程序员大兵