稀疏量角器


12

给定一些正整数n,设计一个带有最少标记数的量角器,使您能够测量所有角度的整数倍2π/n(每个角度一次测量)。

细节

作为输出,可以在的范围内输出的整数列表0n-1(或1n)表示每一个标记的位置。或者,也可以输出长度的串/列表n#在每个标记的位置和_(下划线)在有无。(或两种不同的字符,如果更方便的。)
实施例:对于n = 5您需要的3马克到能够测量所有角度2π/5, 4π/5, 6π/5, 8π/5, 2π通过设置(例如)在1马克0,在1马克2π/5和1马克6π/5。我们可以将其编码为列表[0,1,3]或字符串##_#_

例子

注意,输出不一定是唯一的。

n:  output:
 1  [0]
 2  [0,1]
 3  [0,1]
 4  [0,1,2]
 5  [0,1,2]
 6  [0,1,3]
 7  [0,1,3]
 8  [0,1,2,4]
 9  [0,1,3,4]
10  [0,1,3,6]
11  [0,1,3,8]
20  [0,1,2,3,6,10]

PS:这类似于稀疏标尺问题,但是我们考虑使用圆形(角形)刻度,而不是线性刻度(两端)。

PPS:此脚本应为每个脚本计算一组标记的一个示例n在线尝试!

PPPS:正如@ngn所指出的,此问题等效于找到阶的循环组的最小差分基n。最小订单在http://oeis.org/A283297中列出,一些理论界限在https://arxiv.org/pdf/1702.02631.pdf中找到



边界线欺骗,当n = q^2 + q + 1具有主要力量时具有精确的重叠q
彼得·泰勒

@PeterTaylor我不明白为什么你认为这是一个骗子。您能以什么方式详细说明“重叠”吗?尽管存在相似之处,但这是两个非常不同的问题。此外,这是代码问题,您链接的挑战甚至没有在评分中包括程序的大小。
骗子

它们不是两个截然不同的问题。阅读PPPS中的OEIS链接:提到的“歌手差异集”正是我的答案中实施的射影场方法生成的Golomb标尺。我认为计分方法是不同的。
彼得·泰勒

Answers:


4

果冻,13个字节

ŒPðṗ2I%QLðÐṀḢ

在线尝试!

怎么运行的

ŒPðṗ2I%QLðÐṀḢ  Main link. Argument: n (integer)

ŒP             Powerset; generate all subsequences of [1, ..., n].
  ð       ÐṀ   Begin a dyadic chain. Call it with all subsequences S as left
               argument and n as right one. Return the array of all sequences for
               which the chain returns the maximal result, i.e., [0, ..., n-1].
   ṗ2              Cartesian power 2; generate all pairs of elements of S.
     I             Increments; map each pair [x, y] to [y-x].
      %            Map each [y-x] to [(y-x)%n].
       Q           Unique; deduplicate the array of modular difference singletons.
        L          Take the length.
         ð     Begin a new, dyadic chain.
               Left argument: S' (filted subsequences). Right argument: n
            Ḣ  Take the first element of S'.
               Since S was sorted by length, so is S', so the first element of S'
               is the shortest subsequence that satisfies the condition.

4

MATL,20字节

:qGZ^!"G:q@&-G\m?@u.

对于TIO以外的输入,这会耗尽TIO上的内存8

在线尝试!

怎么运行的

这将生成[0 1 ... n-1]具有指数的笛卡尔乘方n,并使用一个循环来测试每个笛卡尔元组。该测试包括在计算元素如果元组所有成对差异,看是否这些差异模n包括所有号码01,... n-1

一旦找到满足条件的笛卡尔元组,就退出循环,并打印该元组中的唯一条目作为解决方案。

之所以可行,是因为在给定u > v的情况下,保证具有u个唯一条目的足够多的元组要比具有v个唯一条目的任何元组更早地进行测试。“足够的集合”意味着,如果该集合中的所有元组都不是解决方案,那么没有其他具有相同唯一条目数量的元组是解决方案。

例如,对于n = 3笛卡尔元组如下所示,其中每一行都是一个元组:

0 0 0
0 0 1
0 0 2
0 1 0
0 1 1
0 1 2
0 2 0
 ···
2 2 1
2 2 2
  • 第一个元组0 0 0是唯一具有1唯一值的相关元组。即使1 1 1并且2 2 2将在以后出现,0 0 0也是一种解决方法,当且仅当这些情况存在时。因此,由元组形成的单例集0 0 0对于u = 是足够的1
  • 第二和第三元组(即0 0 10 0 2)构成u = 的足够集2。也就是说,它们以2唯一的值覆盖了所有情况。0 1 0永远不会选择第四个元组作为解决方案,因为0 0 1将首先对其进行测试。同样,元组0 2 0将永远不会被选中,因为它的出现时间晚于0 0 2。像这样的元组2 2 1将永远不会被选作解决方案,因为的元组0 0 1是等效的(取模n,直到重复值),并且首先出现。
  • 等等。

注释代码:

:q         % Push [0 1 ... n-1], where n is the input (implicit)
GZ^        % Cartesian power with exponent n. Gives an (n^n) × n matrix
           % where each row is a Cartesian tuple
!          % Transpose. Now each Cartesian tuple is a column
!"         % For each column (that is, each Cartesian tuple)
  G:q      %   Push [0 1 ... n-1] (*)
  @        %   Push current column
  &-       %   Matrix of pairwise differences (**)
  G\       %   Modulo n, element-wise
  m        %   Ismember function: for each entry in (*), gives true iff
           %   it is present in (**)
  ?        %   If all entries are true
    @      %     Push current column
    u      %     Unique entries. This is the solution
    .      %     Break loop
           %   End (implicit)
           % End (implicit)
           % Display (implicit)

3

Stax26 21 字节

Åæ4&╕u◙╩►s∙Φ▬═(0~ d+Q

在线运行和调试!

现在,在线版本无法输入,20但此错误已得到修复,尚未部署到在线解释器 Deployed。请注意,运行此20案例需要花费一些时间。

说明

事实证明,由于计算成对差异的方式,我不必担心kand x-k在这里的等效性。节省5个字节。

使用解压后的版本进行解释。

rS{%o~{;i@c:2{E-x%mu%x<wm
r                            [0..`x`], where `x` is input
 S                           Powerset
  {%o~                       Sort by length
      {;i@             w     For each element in the powerset
          c:2                All pairs
             {    m          Map each pair `[p,q] to
              E-                 `q-p`
                x%               `(q-p)%x`
                   u%        Count of unique modulo differences
                     x<      Loop until the count of unique modulo differences is larger than the input(`n`)
                             Now we have found a valid set in the powerset
                        m    Output the members of the set,one element per line.

通过强制要求01都必须是答案的成员,我们可以使用[2..x]代替生成Powerset,[0..x]然后将01手动添加到Powerset中的每个元素。它效率更高,但需要1专门处理输入,并且占用更多字节。



0

Python 2,148个字节

from itertools import*
def f(n):
 r=range(n)
 for i in r:
  for p in combinations(r,i+1):
   if all(any((y+x)%n in p for y in p)for x in r):return p

在线尝试!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.