// 第 12 周 – 实践课练习的参考答案
// 运行：go run ./w12/exercises
package main

import (
	"fmt"
	"strconv"
)

func digitSum(n int) int {
	if n < 10 {
		return n
	}
	return n%10 + digitSum(n/10)
}

func toBinary(n int) string {
	if n < 2 {
		return strconv.Itoa(n)
	}
	return toBinary(n/2) + strconv.Itoa(n%2)
}

func maxOf(a []int) int {
	if len(a) == 1 {
		return a[0]
	}
	return max(a[0], maxOf(a[1:]))
}

func count(a []int, x int) int {
	if len(a) == 0 {
		return 0
	}
	c := 0
	if a[0] == x {
		c = 1
	}
	return c + count(a[1:], x)
}

type Node struct {
	Value int
	Next  *Node
}

func printBackward(p *Node) {
	if p == nil {
		return
	}
	printBackward(p.Next)
	fmt.Print(p.Value, " ")
}

func length(p *Node) int {
	if p == nil {
		return 0
	}
	return 1 + length(p.Next)
}

func binom(n, k int) int {
	if k == 0 || k == n {
		return 1
	}
	return binom(n-1, k-1) + binom(n-1, k)
}

func main() {
	fmt.Println("E1. digitSum(2026) =", digitSum(2026))
	fmt.Println("E2. toBinary(50) =", toBinary(50))
	fmt.Println("E3. max([3 9 2 7]) =", maxOf([]int{3, 9, 2, 7}))
	fmt.Println("E4. count([1 2 1 1 3], 1) =", count([]int{1, 2, 1, 1, 3}, 1))
	list := &Node{1, &Node{2, &Node{3, &Node{4, nil}}}}
	fmt.Print("E5. printBackward([1 2 3 4]): ")
	printBackward(list)
	fmt.Println()
	fmt.Println("E6. length =", length(list))
	fmt.Println("E7. binom(5, 2) =", binom(5, 2), ", binom(10, 5) =", binom(10, 5))
}
