如何计算数组中循环排列的数量(可变换位)

huangapple go评论73阅读模式
英文:

How to calculate amount of cyclic permuations in an array (variable shift)

问题

关于另一个问题 ,我想要打印(并计算)数组的循环排列。我的输入将是数组、步长和起始值。

我的数组不一定只包含数字。

示例:给定数组 X, 1, 2, 3, Y(5个元素)和步长为3,我会有

X, 1, 2     // 第一行
3, Y, X
1, 2, 3
Y, X, 1
2, 3, Y     // 最后一行,因为在此之后它将重复。

在这种情况下,计数为 "5"。在许多情况下,计数与元素数量相同,但并非总是如此。具有8个元素和步长为4时,结果为2。使用8个元素和步长为6时,结果为4。

数组也可以包含相同的值,例如,前导/后导和重复的数字。

示例:LEADIN, LEADIN, LEADIN, LEADIN, 1, 1, 2, 2, 3, 3, 4, 4, LEADOUT, LEADOUT(4个前导,数字1到4重复2次,2个后导。总元素数=14。

目的是形成一个无限的子集序列,每个子集长度为1。子集中不能有空格。必须使用所有元素,数字必须保持不变。

具有前导的简单示例:LI, LI, 1, 2, 3, LO, LO,步长为2将是:

LI LI | 1 2 | 3 LO | LO LI | LI 1 | 2 3 | LO LO(7次重复)。

我可能会使用Python来完成这项任务。从循环数组中获取数据不是问题,但我需要找出需要执行多少次“移位”。

使用这个简单的函数,我可以“计算”数量,但我认为有一个公式可以做到这一点?

def getiterations(elements, stride):
    # 假设这里的元素>步长
    lc = 0
    lineno = 0
    finished = False
    while not finished:
        lc = lc+stride      # 模拟获取N个数字
        lineno= lineno+1
        if (lc % elements) == 0:
           finished = True
    return lineno
英文:

Referring to another question, I would like to print (and count amount of) cyclic permuations of an array. My input to such function would be the array, stride and start value.

My array does not necessarily contain numbers only.

Example: given the array X, 1, 2, 3, Y (5 elements) and a stride of 3, I would have

X, 1, 2     // first line
3, Y, X
1, 2, 3
Y, X, 1
2, 3, Y     // last line since it would be repeating hereafter.

The count would be "5" in this case. In many cases, the count is identical to amount of elements, but not always. With 8 elements and stride=4, it's 2. Using 8 elements and 6, it is 4.

The array may also contain identical values, such as leadin / leadout and duplicate numbers.

Example: LEADIN, LEADIN, LEADIN, LEADIN, 1, 1, 2, 2, 3, 3, 4, 4, LEADOUT, LEADOUT (for 4 leadin, numbers 1..4 duplicated *2 and 2 leadout. Total element count = 14.

The purpose is to form an endless sequence of subsets, each 1 stride long. There must not be any empty spaces in a subset. All elements must be used, and number must stay the same.

With leadin, trivial example: LI, LI, 1, 2, 3, LO, LO in a stride of 2 will be:

LI LI | 1 2 | 3 LO | LO LI | LI 1 | 2 3 | LO LO (7 repeats).

I would probably be using Python for the job. Getting data from a cyclic array is no problem - but I need to find out how many "shifts" I need to do.

Using this simple function, I can "count" the amount, but I would think there is a formula to do this ?

def getiterations(elements, stride):
    # assuming here that elements > stride
    lc = 0
    lineno = 0
    finished = False
    while not finished:
        lc = lc+stride      # simulate getting N numbers
        lineno= lineno+1
        if (lc %elements)==0:
           finished = True
    return lineno

答案1

得分: 1

你只需计算最小公倍数,然后除以步长来获取循环排列的数量。

import math

num_cycles = math.lcm(elements, stride) / stride
英文:

You just want to calculate the lowest common multiple and then divide by stride length to get the number of cyclic permutations.

import math

num_cycles = math.lcm(elements,stride)/stride

答案2

得分: 0

以下是完整的程序,如果对任何人有用的话。

感谢@michael-cao提供的解决方案。

"""
    该程序用于创建一个固定长度列表的方形数组,在顺序循环模式下,直到方形数组从头到尾填满。

    示例:在一个包含3列的列表中使用[*, * 1,2,3,4, X, X, X]
    2个前导元素,3个后导元素,4个值 = 8个元素。

      |------------|  步幅 = 3(每行的数量)
      |----- 第一个元素
        *;   *;0001;1
        0002;0003;   X;2
           X;   X;   *;3
           *;0001;0002;4
        0003;   X;   X;5
           X;   *;   *;6
        0001;0002;0003;7
           X;   X;   X;8
                    |---- 最后一个元素

      目的是在纸上打印每一行,将这些纸按顺序放置。
      在最后一行之后,第一行再次被打印。因此,行必须填满。

    要找到行数,使用以下公式:

              最小公倍数(元素数量,步幅)
               ------------------------
                        步幅

             例如:   lcm(8,3) = 24         24 /3  = 8行

    为了输出列表,使用itertools模块
          * 循环
          * islice


"""
import math
from itertools import cycle, islice

# ----------------------------------------------------
# -- 配置
#
leadin = '*'              # 前导字符串
leadincount =  2          # 前导数量
leadout = 'X'             # 后导字符串
leadoutcount = 3          # 后导数量
startvalue = 1            # 序列中的第一个数字
endvalue = 3              # 序列中的最后一个数字
startindex  = 0           # 列表的零基索引..

# ---- 输出选项
stride=3                  # 列的数量
numberformat='04d'        # 数字系列的格式
textformat  = '>4s'       # 字符串的格式(前导/后导)
listseparator = ';'       # 输出列表的分隔符...
outputIndex= True         # 在数据旁边打印索引号
#
# ----------------------------------------------------

dataelements = [leadin]*leadincount + list(range(startvalue, endvalue+1)) + [leadout]*leadoutcount


repeats = int(math.lcm(len(dataelements), stride)/stride)

"""
   根据需要格式化元素,文本或数字
"""
def outgroup(d):
    a = []
    for i in d:
        l = str(i)
        if l.isnumeric():
            a.append(f"{i:{numberformat}}")
        else:
            a.append(f"{l:{textformat}}")
    return a
    

for index, *group in zip(
             range(repeats), 
             *[islice(cycle(dataelements), startindex, None)] * stride
             ):
    dataline = listseparator.join(outgroup(group))
    if outputIndex:
        print(f"{dataline}{listseparator}{index+1}")
    else:
        print(f"{dataline}{listseparator}")
英文:

Here is the complete program if it is useful to anyone.

Solution with thanks to @michael-cao.

"""
    Program to create a square array of a fixed-length list, in a sequential cyclic pattern until
    square is filled from first to last.

    Example using [*, * 1,2,3,4, X, X, X]  in a 3-column list
    2 leadin, 3 leadout, 4 values = 8 elements.

      |------------|  stride = 3  (amount per row)
      |----- first element
        *;   *;0001;1
        0002;0003;   X;2
           X;   X;   *;3
           *;0001;0002;4
        0003;   X;   X;5
           X;   *;   *;6
        0001;0002;0003;7
           X;   X;   X;8
                    |---- last element

      The purpose is to print each row on a paper, put these papers in sequence.
      After last row, the first row is printed again. For this reason, the row must be filled.

    To find amount of lines the following formula is used:

              least common multiple (elementcount, stride)
               ---------------------------------------
                        stride

             example:   lcm(8,3) = 24         24 /3  = 8 rows

    to output the list, the itertools module is used
          * cycle
          * islice


"""
import math
from itertools import cycle, islice

# ----------------------------------------------------
# -- configuration
#
leadin = '*'              # which string for leadin
leadincount =  2          # amount of lead in
leadout = 'X'             # which string for leadout
leadoutcount = 3          # amount of leadout
startvalue = 1            # first number in sequence
endvalue = 3              # last number in sequence
startindex  = 0           # zero-based start index for the list..

# ---- options for output
stride=3                  # amount of columns
numberformat='04d'        # formatting number series
textformat  = '>4s'       # formatting string (lead in/out)
listseparator = ';'       # what separates output list...
outputIndex= True         # print index number next to data
#
# ----------------------------------------------------

dataelements = [leadin]*leadincount + list(range(startvalue, endvalue+1)) + [leadout]*leadoutcount


repeats = int(math.lcm(len(dataelements), stride)/stride)

"""
   format the elements according to needs, text or number
"""
def outgroup(d):
    a = []
    for i in d:
        l = str(i)
        if l.isnumeric():
            a.append(f"{i:{numberformat}}")
        else:
            a.append(f"{l:{textformat}}")
    return a
    

for index, *group in zip(
             range(repeats), 
             *[islice(cycle(dataelements), startindex, None)] * stride
             ):
    dataline = listseparator.join(outgroup(group))
    if outputIndex:
        print(f"{dataline}{listseparator}{index+1}")
    else:
        print(f"{dataline}{listseparator}")

huangapple
  • 本文由 发表于 2023年3月3日 23:33:49
  • 转载请务必保留本文链接:https://go.coder-hub.com/75629048.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定