From e422c83803e8734b9d8fc5781c237382b649865f Mon Sep 17 00:00:00 2001 From: filifa Date: Mon, 15 Sep 2025 19:47:17 -0400 Subject: [PATCH] add mobius command --- cmd/mobius.go | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 cmd/mobius.go diff --git a/cmd/mobius.go b/cmd/mobius.go new file mode 100644 index 0000000..c961a8c --- /dev/null +++ b/cmd/mobius.go @@ -0,0 +1,97 @@ +/* +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" + + "github.com/spf13/cobra" +) + +var mobiusN uint + +func mobiusSieve(n uint) chan int { + sieve := make([]int, n) + for i := 0; i < int(n); i++ { + sieve[i] = i + } + + ch := make(chan int) + go func() { + for i := 0; i < int(n); i++ { + if i == 0 || i == 1 || sieve[i] != i { + ch <- sieve[i] + continue + } + + ch <- -1 + + for j := 2 * i; j < int(n); j += i { + if j%(i*i) == 0 { + sieve[j] = 0 + } + + sieve[j] /= -i + } + } + + close(ch) + }() + + return ch +} + +func mobius(cmd *cobra.Command, args []string) { + ch := mobiusSieve(mobiusN) + for i := 0; ; i++ { + v, ok := <-ch + if !ok { + break + } + + if i == 0 { + continue + } + + fmt.Println(v) + } +} + +// mobiusCmd represents the mobius command +var mobiusCmd = &cobra.Command{ + Use: "mobius", + Short: "Compute the Möbius function for all numbers less than n", + Long: `Compute the Möbius function for all numbers less than n.`, + Run: mobius, +} + +func init() { + sieveCmd.AddCommand(mobiusCmd) + + // Here you will define your flags and configuration settings. + + // Cobra supports Persistent Flags which will work for this command + // and all subcommands, e.g.: + // mobiusCmd.PersistentFlags().String("foo", "", "A help for foo") + + // Cobra supports local flags which will only run when this command + // is called directly, e.g.: + // mobiusCmd.Flags().BoolP("toggle", "t", false, "Help message for toggle") + + mobiusCmd.Flags().UintVarP(&mobiusN, "limit", "n", 0, "upper limit") + mobiusCmd.MarkFlagRequired("limit") +}