广场拼图的解决方案 [英] square puzzle solution

查看:194
本文介绍了广场拼图的解决方案的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

问:给定一个整数N,打印从1号直到n 2 是这样的:

N = 4

结果是:

  01 02 03 04
12 13 14 05
11 16 15 06
10 09 08 07
 

你如何(从下面的链接提供的解决方案分开)解决呢?

<一个href="http://www.programmersheaven.com/mb/CandCPP/81986/81986/problem-in-making-ap-c++-program/?S=B20000" rel="nofollow">http://www.programmersheaven.com/mb/CandCPP/81986/81986/problem-in-making-ap-c++-program/?S=B20000

我期待在另一个方向。到目前为止,我想弄清楚,如果我能得到位置的顺序列表我填写

下面就是林寻找到:是不是在基体中行走

有没有办法获得fdisp,以解决问题的方式,?

矩阵= [[1,2,3,4],[5,6,7,8],[9,10,11,12],[13,14, 15,16]]
N = LEN(矩阵)

#最终处理写道手:如何得到它的任意N?
fdisp = [(0,0),(0,1),(0,2),(0,3),(1,3),(2,3),(3,3),(3,2) ,
(3,1),(3,0),(2,0),(1,0),(1,1),(1,2),(2,2),(2,1)]

为VAL,在历数我(fdisp):
矩阵[I [0] [I [1] = VAL +1

高清show_matrix(矩阵,N):
对于I,L在历数(矩阵):
对于j的范围(n)的:
打印%D \ T%矩阵[I] [J]。
		打印

show_matrix(矩阵,N)
 

解决方案

下面是一个不同的方法。它依赖于察觉你做的循环动作:右,下,左,上,右,......此外,移动的次数云:3吧,3下,3左,2个,2个右,1倒,1人。因此,事不宜迟,我将code这件事在Python。

首先,我会用一些itertools有的numpy的:

 从itertools进口环链,循环,IMAP,izip,重复
从numpy的导入阵列
 

之间的方向循环:右,下,左,上,右,...

 方向=周期(阵列(五)V IN((0,1),(1,0),(0,-1),( -  1,0)) )
 

(我使用numpy的的阵列在这里,所以我可以轻松地添加方向在一起。元组不添加很好。)

接着,对次余移动递减计数从正 - 1比1,重复各号数的两倍,并且第一号码三次:

 倒计时=链((N-1),* IMAP(重复,范围(N-1,0,-1),重复(2)))
 

所以,现在我的方向顺序可以通过配对数倒计时重复每个连续的方向创建:

  dirseq =链(* IMAP(重复,方向,倒计时))
 

要得到我的索引顺序,我可以总结这个序列,但(据我所知)Python不提供这样的方法,让我们快速地抛出1在一起:

 高清sumseq(序列,启动= 0):
  V =启动
  产量v
  对于s的序列:
    V + = S
    产量v
 

现在生成原始阵列,我可以做到以下几点:

  A =阵列(((0,)* N,)* N)#N乘n阵列零的
对于I,V在枚举(sumseq(dirseq,阵列((0,0)))):
  一个[V [0],V [1]] = i + 1的
打印一
 

其中,对于n = 4,给出了:

  [1 2 3 4]
 [12 13 14 5]
 [11 16 15 6]
 [10 9 8 7]
 

和,对于n = 5,给出了:

  [1 2 3 4 5]
 [16 17 18 19 6]
 [15 24 25 20 7]
 [14 23 22 21 8]
 [13 12 11 10 9]
 

此方法可以推广到矩形网格;在我离开这个作为一个练习留给读者;)

Question: given an integer number n, print the numbers from 1 up to n2 like this:

n = 4

result is:

01 02 03 04
12 13 14 05
11 16 15 06
10 09 08 07

How do you solve it (apart from the solution provided in the link below)?

http://www.programmersheaven.com/mb/CandCPP/81986/81986/problem-in-making-ap-c++-program/?S=B20000

I'm looking in another direction. So far, I'm trying to figure out if I could obtain the ordered list of positions I have to fill in.

Here's what Im looking into: is there a way to obtain the "fdisp" so as to solve the problem that way, instead of "walk" in the matrix?

matrix = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]
n = len(matrix)

# final disposition wrote by hand: how to get it for arbitrary n?
fdisp = [(0,0), (0,1), (0,2), (0,3), (1,3), (2,3), (3,3), (3,2),
		 (3,1), (3,0), (2,0), (1,0), (1,1), (1,2), (2,2), (2,1)]

for val,i in enumerate(fdisp):
	matrix[i[0]][i[1]] = val + 1

def show_matrix(matrix, n):
	for i,l in enumerate(matrix):
		for j in range(n):
			print "%d\t" % matrix[i][j],
		print

show_matrix(matrix, n)

解决方案

Here's a different approach. It relies on spotting that the movements you make cycle between: right, down, left, up, right, .... Further, the number of times you move goes: 3 right, 3 down, 3 left, 2 up, 2 right, 1 down, 1 left. So without further ado, I will code this up in Python.

First, I will use some itertools and some numpy:

from itertools import chain, cycle, imap, izip, repeat
from numpy import array

The directions cycle between: right, down, left, up, right, ...:

directions = cycle(array(v) for v in ((0,1),(1,0),(0,-1),(-1,0)))

(I'm using numpy's arrays here so I can easily add directions together. Tuples don't add nicely.)

Next, the number of times I move counts down from n-1 to 1, repeating each number twice, and the first number three times:

countdown = chain((n-1,), *imap(repeat, range(n-1,0,-1), repeat(2)))

So now my sequence of directions can be created by repeating each successive direction by the paired number in countdown:

dirseq = chain(*imap(repeat, directions, countdown))

To get my sequence of indices, I can just sum this sequence, but (AFAIK) Python does not provide such a method, so let's quickly throw one together:

def sumseq(seq, start=0):
  v = start
  yield v
  for s in seq:
    v += s
    yield v

Now to generate the original array, I can do the following:

a = array(((0,)*n,)*n) # n-by-n array of zeroes
for i, v in enumerate(sumseq(dirseq, array((0,0)))):
  a[v[0], v[1]] = i+1
print a

Which, for n = 4, gives:

[[ 1  2  3  4]
 [12 13 14  5]
 [11 16 15  6]
 [10  9  8  7]]

and, for n = 5, gives:

[[ 1  2  3  4  5]
 [16 17 18 19  6]
 [15 24 25 20  7]
 [14 23 22 21  8]
 [13 12 11 10  9]]

This approach can be generalised to rectangular grids; I leave this as an exercise for the reader ;)

这篇关于广场拼图的解决方案的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆