2025-09-07 16:27:27 +00:00
/ *
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 < http : //www.gnu.org/licenses/>.
* /
package cmd
import (
"fmt"
"math/big"
2025-09-17 03:09:22 +00:00
"strconv"
2025-09-07 16:27:27 +00:00
"github.com/spf13/cobra"
)
var partitionsN string
var partitionsK string
2025-09-17 03:09:22 +00:00
// given a slice where vals[i] = p_{k-1}(i) for a given k, nextPartition updates the slice so vals[i] = p_k(i) using the property that p_k(n) = p_k(n-k) + p_{k-1}(n)
func nextPartition ( k int , vals [ ] * big . Int ) {
for i := 1 ; i < len ( vals ) ; i ++ {
if i - k >= 0 {
vals [ i ] . Add ( vals [ i ] , vals [ i - k ] )
}
}
}
func p ( n , k int ) * big . Int {
if n < 0 {
2025-09-07 16:27:27 +00:00
return big . NewInt ( 0 )
}
2025-09-17 03:09:22 +00:00
if k > n {
k = n
}
vals := make ( [ ] * big . Int , n + 1 )
for i := range vals {
vals [ i ] = big . NewInt ( 0 )
}
vals [ 0 ] = big . NewInt ( 1 )
2025-09-07 16:27:27 +00:00
2025-09-17 03:09:22 +00:00
for i := 1 ; i <= k ; i ++ {
nextPartition ( i , vals )
}
2025-09-07 16:27:27 +00:00
2025-09-17 03:09:22 +00:00
return vals [ n ]
2025-09-07 16:27:27 +00:00
}
func partitions ( cmd * cobra . Command , args [ ] string ) {
2025-09-17 03:09:22 +00:00
n , err := strconv . Atoi ( partitionsN )
if err != nil {
2025-09-07 16:27:27 +00:00
cobra . CheckErr ( "invalid input " + partitionsN )
}
2025-09-17 03:09:22 +00:00
var k int
2025-09-07 16:27:27 +00:00
if partitionsK == "" {
2025-09-17 03:09:22 +00:00
k = n
2025-09-07 16:27:27 +00:00
} else {
2025-09-17 03:09:22 +00:00
var err error
k , err = strconv . Atoi ( partitionsK )
if err != nil {
2025-09-07 16:27:27 +00:00
cobra . CheckErr ( "invalid input " + partitionsK )
}
}
2025-09-17 03:09:22 +00:00
if n < 0 {
2025-09-07 16:27:27 +00:00
cobra . CheckErr ( "n must be nonnegative" )
}
2025-09-17 03:09:22 +00:00
if k < 0 {
2025-09-07 16:27:27 +00:00
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" )
}