【问题标题】:Spiral Pattern: how do I find a number given coordinates?螺旋图案:如何找到给定坐标的数字?
【发布时间】:2019-11-29 04:31:27
【问题描述】:

给定一个螺旋模式,我的工作是编写一个函数,它采用某些坐标并返回这些坐标处的数字。 例如:

4 < 3 < 2
v       ^
5   0 > 1
v
6 > 7 > 8

如果输入是(1, -1),函数将返回8

我不是在寻找代码。我正在寻找关于螺旋模式如何工作的解释,因为我对编程相对较新(参加介绍性在线课程)并且我从未遇到过这样的事情。我也想了解所涉及的算法。

同样,我不想要任何代码,因为我希望自己解决这个问题。我只是要求一个解释。

更新:我想出了这段代码,它有效地确定了外部正方形的最小数量并迭代直到达到所需的坐标。

def spiral_index(x, y):
    small = max(x, y)*2 - 1
    min_number = small**2

    xpos = max(x, y)
    ypos = -max(x, y) + 1
    count = min_number

    while xpos != x:
          xpos -= 1
          count += 1
    while ypos != y:
          ypos += 1
          count += 1

    return count

但是,我的在线课程提交页面拒绝了代码,因为执行时间太长。所以我需要一种对初学者友好的更快的方法。

【问题讨论】:

  • 它总是应该从 3 点钟位置开始逆时针走吗?
  • 这个问题的答案有一些有趣的想法(忽略Haskell并专注于解释):stackoverflow.com/questions/57569623/…这些答案是关于在给定序列号的情况下找到坐标,而你的问题是相反的- 找到给定坐标的序列号,所以它不是重复的,但你可能会发现它很有用。
  • @Selcuk 是的,这就是问题的表述方式。
  • 根据您的输入,您向右移动 1 并向下移动 1 以达到 8。因此,您不会从 0 索引开始吗? 3点钟开始是什么意思?从 1 点开始?
  • @Ibragile 3 点逆时针指的是螺旋图案本身。它从 0 开始,1 在它的右边,数字按逆时针方向列出。

标签: python algorithm spiral


【解决方案1】:

这里尝试编写一些代码来了解我had in mind 的内容。我不确定它是否完全没有错误,但也许您可以发现并修复任何错误:)(我错过了 x 等于 y 的情况吗?)

(注意,在线评估器可能不喜欢函数体中的打印语句。)

"""
  c  c  c  T2 c  c
  b  a  a  a  a  c
  T4 4  3  2  a  c
  b  5  0  1  a  c
  b  6  7  8  a  T1
  b  T3 b  b  b  c
"""

def f(x, y):
  square_size = 1

  if x > 0:
    square_size = 2 * x
  elif x < 0:
    square_size = -2 * x + 1
  if y > 0:
    square_size = max(square_size, 2 * y)
  elif y < 0:
    square_size = max(square_size, -2 * y + 1)

  corner_length = square_size * 2 - 1
  offset = square_size // 2

  # Top-right corner (even square side)
  if square_size % 2 == 0:
    # Target is on the right
    if abs(x) > abs(y):
      num_ahead = corner_length - (offset + y)
    # Target is on the top
    else:
      num_ahead = offset + x - 1

  # Bottom-left corner (odd square side)
  else:
    # Target is on the left
    if abs(x) > abs(y):
      num_ahead = corner_length - (offset - y) - 1
    # Target is on the bottom
    else:
      num_ahead = offset - x

  print ""
  print "Target: (%s, %s)" % (x, y)
  print "Square size: %sx%s" % (square_size, square_size)
  print "Corner length: %s" % corner_length
  print "Num ahead: %s" % num_ahead

  return square_size * square_size - 1 - num_ahead

T1 = (3, -1)
T2 = (1, 3)
T3 = (-1, -2)
T4 = (-2, 1)

print f(*T1)
print f(*T2)
print f(*T3)
print f(*T4)

输出(见代码sn-p顶部的插图):

Target: (3, -1)
Square size: 6x6
Corner length: 11
Num ahead: 9
26

Target: (1, 3)
Square size: 6x6
Corner length: 11
Num ahead: 3
32

Target: (-1, -2)
Square size: 5x5
Corner length: 9
Num ahead: 3
21

Target: (-2, 1)
Square size: 5x5
Corner length: 9
Num ahead: 7
17

【讨论】:

  • 这很好用,除了 abs(x) = abs(y)x&lt;0 以及 square_size % 2 != 0 时。因此,我已将这行代码更改为:else: # Target is on the left if abs(x) &gt; abs(y): num_ahead = corner_length - (offset - y) - 1 至:else: # Target is on the left if abs(x) &gt;= abs(y) and x &lt; 0: num_ahead = corner_length - (offset - y) - 1
  • @EddieEC 啊,好的。这能解决吗?在线评委怎么玩?
  • 它被接受了。但由于某种原因,我似乎无法掌握偏移的概念。你能详细说明一下吗?
  • @EddieEC 偏移是因为 (0, 0) 在螺旋的中间。假设我们正在查看图表中的cs(顶部和右侧)和坐标(3, 0)。 y 将为零,但我们需要从总角长度中减去的数字包括那些低于目标的条目。那是偏移量计算,因为螺旋从中间延伸到所有末端。如果 (0,0) 在正方形的左下角,也许我们不需要它。
  • 非常感谢!这很有帮助!我现在已经很明白了!
【解决方案2】:

我会考虑这些事情开始:给定 x 和 y 坐标的更远,(1)我们正在看的正方形有多大? (其中有多少条目); (2) 我们是否处于数字上升或下降的列? (行和右/左相同); (3) 如果我们完成当前方块,将我们的目标放在方块的外边界上,有多少数字“领先”于目标?显然,如果我们知道广场上总共有多少人,并且知道前面有多少人,我们就可以计算出目标。

让我们将您的示例扩展为 (3, -1):

  c c c c c c
  b a a a a c
  b 4 3 2 a c
  b 5 0 1 a c
  b 6 7 8 a T
  b b b b b c

注意as 正在完成 4x4 方格; bs 5x5;和cs,我们的目标T所在的6x6。一个 6x6 的正方形有 36 个条目。我们认为T 前面有 9 个条目,因此 T = 35 - 9 = 26。

【讨论】:

  • 这对我认为的小数字很有用。如果我想搜索 (100, 100) 怎么办。这样做仍然是最好的方法吗?
  • @EddieEC 我的目的是提供一种直接计算结果的方法,在 O(1) 中,给定坐标。
  • @EddieEC (100, 100) 的边界是多大的正方形?在这个边界上,有多少数字会领先于它?我们应该可以直接计算出来。
  • @EddieEC 他们交替。第一个是1,2,3,然后是4,5,6,7,8,等等,只是增加奇数。右上角为偶数大小的正方形,然后左下角为奇数大小的正方形,重复。第 100 个将是 101x101 正方形的左下角(在我的头顶上)。您可以通过奇数公式计算“全角”的大小,您可能知道它们的格式为2x + 1
  • @EddieEC 然后考虑坐标在边界内的位置。从小例子开始,这样您就可以轻松地测试您的方法。
【解决方案3】:

考虑一个递归公式。

c c c c c
c b b b c
c b a b c
c b b b c
c c c c c

按照螺旋枚举去 1 a、8 b、16 c、24 d 等。如果我们认为 a 为 0 级(特殊情况),b 为 1 级,以此类推,那么每个正方形的大小2*level+1 里面有 8*level 字母。

从那里,有 4 种情况,坐标位于正方形的哪一侧(右、上、左、下)。确定坐标在哪个平方,简单的算术确定螺旋数。

【讨论】:

  • 这与我已经发布的答案有何不同? (即考虑目标所在的方格)
  • @גלעדברקן 相似的想法,不同的表述
  • @qwr 这是个好主意。我实际上是这么想的,但我的问题在于方向的逻辑。如果我想找到 (100,100) 处的数字,遍历所有数字是否是个好主意?
  • @qwr 我一直在确定它是哪个正方形的数字。那里有任何指针吗?
  • 考虑四种情况:它是在正方形的右侧、顶部、左侧还是底部。
猜你喜欢
  • 2021-08-13
  • 1970-01-01
  • 2014-10-03
  • 1970-01-01
  • 2019-12-25
  • 1970-01-01
  • 1970-01-01
  • 2021-05-18
  • 2010-12-28
相关资源
最近更新 更多