diff --git a/cmd/partitions.go b/cmd/partitions.go new file mode 100644 index 0000000..70a9d7b --- /dev/null +++ b/cmd/partitions.go @@ -0,0 +1,103 @@ +/* +Copyright © 2025 filifa + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . +*/ +package cmd + +import ( + "fmt" + "math/big" + + "github.com/spf13/cobra" +) + +var partitionsN string +var partitionsK string + +// TODO: use dynamic programming +func p(n, k *big.Int) *big.Int { + if n.Cmp(big.NewInt(0)) == -1 { + return big.NewInt(0) + } else if n.Cmp(big.NewInt(0)) == 0 { + return big.NewInt(1) + } else if k.Cmp(big.NewInt(0)) == 0 { + return big.NewInt(0) + } + + newN := new(big.Int).Sub(n, k) + x := p(newN, k) + + newK := new(big.Int).Sub(k, big.NewInt(1)) + y := p(n, newK) + + z := new(big.Int).Add(x, y) + return z +} + +func partitions(cmd *cobra.Command, args []string) { + n, ok := new(big.Int).SetString(partitionsN, 10) + if !ok { + cobra.CheckErr("invalid input " + partitionsN) + } + + var k *big.Int + if partitionsK == "" { + k = new(big.Int).Set(n) + } else { + var ok bool + k, ok = new(big.Int).SetString(partitionsK, 10) + if !ok { + cobra.CheckErr("invalid input " + partitionsK) + } + } + + if n.Cmp(big.NewInt(0)) == -1 { + cobra.CheckErr("n must be nonnegative") + } + + if k.Cmp(big.NewInt(0)) == -1 { + cobra.CheckErr("k must be nonnegative") + } + + z := p(n, k) + fmt.Println(z) +} + +// partitionsCmd represents the partitions command +var partitionsCmd = &cobra.Command{ + Use: "partitions", + Short: "Compute the number of partitions of an integer", + Long: `Compute the number of partitions of an integer.`, + Run: partitions, +} + +func init() { + rootCmd.AddCommand(partitionsCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // partitionsCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + // partitionsCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + + partitionsCmd.Flags().StringVarP(&partitionsN, "number", "n", "", "number to compute partitions of") + partitionsCmd.MarkFlagRequired("number") + + partitionsCmd.Flags().StringVarP(&partitionsK, "parts", "k", "", "maximum number of parts") +}