绘制排列路径


20

想象以下图表为垂直纵横交错的管组。

1 2    1 2    1 2 3 4
\ /    \ /    \ / \ /
 X      |      |   |
/ \    / \    / \ / \
2 1    1 2   |   X   |
              \ / \ /
               X   X
              / \ / \
              3 1 4 2

在最左边的图中,1和和2滑下各自的斜线,在处交叉X,并从它们开始的相反侧出来。

中间图中的想法相同,但是|表示路径没有交叉,因此没有任何变化。

最右边的图显示了置换1 2 3 4为的更复杂的电子管布线3 1 4 2

目标

在此高尔夫挑战代码中,您的目标是在给定诸如的排列的情况下绘制这些“管状布线图” 3 1 4 2。以字节为单位的最短程序将获胜。

细节

  1. 输入来自stdin,是数字从1到n的任意排列,用空格分隔,其中n是一个正整数。您可以假设所有输入的格式正确。
  2. 路由图输出转到stdout。

    • 将数字1到n依次“ 滴加”到图的顶部,应导致输入排列在底部出现。(顶部和底部始终是斜线层。)
    • 该图不必最佳地小。只要是正确的,它就可以根据需要有多个级别。
    • 该图应仅包含字符\/ X|和换行符(无数字)。
    • |应该始终在最外面的路口使用X,因为使用没有意义。
    • 只要图中的所有行正确对齐,就可以使用一些前导或尾随空格。

例子

输入3 1 4 2可能产生(与上述相同)

 \ / \ /
  |   | 
 / \ / \
|   X   |
 \ / \ /
  X   X 
 / \ / \

输入1可能会产生

 \
  |
 /
|
 \
  |
 /

输入3 2 1可能会产生

 \ / \
  X   |
 / \ /
|   X
 \ / \
  X   |
 / \ /

输入2 1 3 4 6 5可能会产生

\ / \ / \ /
 X   |   X
/ \ / \ / \

4
好问题!我不敢相信您加入的只有两个星期了-您似乎无处不在。
xnor

@xnor:D谢谢你。但实际上我在这里花了太多时间...
卡尔文的爱好2014年

可以X直接连接到|方式/吗?要另一个X
xnor 2014年

1
@xnor号应该始终处于row of slashesrow of X's and |'srow of slashesrow of X's and |'s,...格式。
加尔文的爱好2014年

可以n大于10吗?
2011年

Answers:


4

Python 2中,218 219 220 222 224 227 243 247 252 259 261 264

l=map(int,raw_input().split())
f=n=len(l)
o=s=n*' \ /'
while f+n%2:
 f-=1;i=f+n&1;a=s[2*i:][:2*n]+'\n|   '[::2-i]
 while~i>-n:a+='|X'[l[i+1]<l[i]]+'   ';l[i:i+2]=sorted(l[i:i+2]);i+=2
 o=a+f%2*'|'+'\n'+o
print o[:-2*n]

我采用了一种略有不同的方法:我发现对输入进行排序所必需的交换,然后垂直反转该交换以获取将已排序列表转换为输入所必需的交换。作为此方法的额外好处,它可以采用任意数字列表,并提供排列路径以将输入的类别转换为输入。

例:

$ python sort_path.py <<< '3 1 4 5 9 2 6 8 7'
 \ / \ / \ / \ / \
  |   |   |   |   |
 / \ / \ / \ / \ /
|   |   |   |   |   
 \ / \ / \ / \ / \
  |   |   |   |   |
 / \ / \ / \ / \ /
|   |   |   |   |   
 \ / \ / \ / \ / \
  |   |   |   |   |
 / \ / \ / \ / \ /
|   X   |   |   X   
 \ / \ / \ / \ / \
  |   X   |   X   |
 / \ / \ / \ / \ /
|   |   X   X   |   
 \ / \ / \ / \ / \
  X   |   X   |   |
 / \ / \ / \ / \ /
|   |   |   |   X   
 \ / \ / \ / \ / \

改进之处:

264-> 261:将外循环从for切换为while。

261-> 259:f%2代替(c^m),因为在python中算术运算符的优先级高于按位运算符。

259-> 252:将内部循环从for切换为while。合并ic变量。

252-> 247:更改了构建,然后反向以仅以反向顺序进行构建。

247-> 243:手动添加了换行符,而不是使用join。

243-> 227:采用了grc的斜线生成方法(感谢grc!),并添加了s。

227-> 224:将斜线生成移到内部while循环之前,以%4使用扩展切片来删除a 并保存字符。

224-> 222:删除了m。

222-> 220:f%2+n%2->f+n&1

220-> 219:| 1<n-1|-> |~i>-n|(删除前导空格)

219-> 218:组合o和的初始化,并将s切片移到末尾。


9

Python,290

def g(o,u=1):
 s=['|']*o
 for i in range(o,n-1,2):v=r[i+1]in a[:a.index(r[i])]*u;s+=['|X'[v]];r[i:i+2]=r[i:i+2][::1-2*v]
 print'  '*(1-o)+'   '.join(s+['|']*(o^n%2))*u+'\n'*u+(' / \\'*n)[2*o:][:n*2]
a=map(int,raw_input().split())
n=len(a)
r=range(1,n+1)
o=1
g(1,0)
g(0)
while r!=a:g(o);o^=1

我选择了一种基本的方法,但是结果比我希望的要长一些。它成对考虑列表,并决定是否交换每对。对于每个相交的行重复此操作,直到列表与输入匹配。

例:

$ python path.py
5 3 8 1 4 9 2 7 6
 \ / \ / \ / \ / \
  |   |   |   X   |
 / \ / \ / \ / \ /
|   X   X   X   X
 \ / \ / \ / \ / \
  X   X   X   X   |
 / \ / \ / \ / \ /
|   X   X   |   X
 \ / \ / \ / \ / \
  X   X   X   |   |
 / \ / \ / \ / \ /
|   |   |   X   |
 \ / \ / \ / \ / \

2

HTML JavaScript, 553 419

感谢@izlin和@TomHart指出我的错误。

p=prompt();b=p.split(" "),l=b.length,d=l%2,o="",s=["","","\\/"],n="\n",a=[];for(i=0;i<l;i++){a[b[i]-1]=i+1;s[1]+=" "+s[2][i%2];s[0]+=" "+s[2][(i+1)%2];o+=" "+(i+1)}s[1]+=n,s[0]+=n;o+=n+s[1];f=1,g=2;do{var c="";for(var i=(f=f?0:1);i<l-1;i+=2)if(a[i]>a[i+1]){c+="  x ";g=2;t=a[i];a[i]=a[i+1];a[i+1]=t;}else c+="  | ";if(g==2){o+=(d?(f?"| "+c:c+"  |"):(f?"| "+c+"  |":c))+n;o+=(s[f]);}}while(--g);o+=" "+p;alert(o);

在这里测试:http//goo.gl/NRsXEj
在此处输入图片说明 在此处输入图片说明


您犯了一个小错误:就像上面的示例一样,第一行应该是排序后的数字,最后一行应该是您的输入。
伊兹林2014年

你是对的。谢谢。我查看了@grc的输出,并认为数字是起始位置。哎呀。
JeffSB 2014年

我可能正在看这个错误,但是在您发布的两张图片中,由于没有任何变化,最后一行不是多余的吗?
TMH 2014年

是的,你是对的。我知道这是我如何达成共识。但这不一定是必须的。我会考虑的。感谢您的评论。
JeffSB 2014年

@izlin-感谢您注意到这一点。我已修复此错误。
JeffSB 2014年

1

Javascript-395

378如果我不在输出上打印数字,但是看起来更好,并提高了可读性。
在这里测试。(无高尔夫球版)

高尔夫球版:

a=prompt(),n=a.split(" "),l=n.length,k=[],s="",i=1;for(j=0;j<l;j++){k[n[j]-1]=j+1;s+=" "+(j+1)}s+="\n";while(i++){for(j=0;j<l;j++)s+=i%2?j%2?" \\":" /":j%2?" /":" \\";for(z=0,y=0;z<l-1;z++)if(k[z]>k[z+1])y=1;if(y==0&&i!=2)break;s+="\n";for(m=i%2;m<l;m+=2){s+=i%2&&m==1?"|":"";if(k[m]>k[m+1]){[k[m],k[m+1]]=[k[m+1],k[m]];s+=i%2?"   X":"  X "}else{s+=i%2?"   |":"  | "}}s+="\n"}s+="\n "+a;alert(s)

说明

首先,我用索引号对输入进行归位,并用结果更改第一行。例如

3 1 4 2
v v v v substitude with
1 2 3 4

so the first line will become:
1 2 3 4
v v v v
2 4 1 3

sorting 1,2,3,4 to 3,1,4,2 is equivalent to 2,4,1,3 to 1,2,3,4

通过这种替换,我可以使用冒泡排序算法将2,4,1,3排序为1,2,3,4,并且该图将是我们正在寻找的最短的图。
如果您有任何想法如何使代码更小,请评论:)

input: 3 4 2 1 7 5 6
output:
 1 2 3 4 5 6 7
 \ / \ / \ / \
  X   |   |   | 
 / \ / \ / \ /
|   X   |   X
 \ / \ / \ / \
  X   X   X   | 
 / \ / \ / \ /
|   X   |   |
 \ / \ / \ / \
 3 4 2 1 7 5 6


(1)我看到您在三个地方使用了BR标签,因此可以通过将其放在变量中来节省一些时间。另外,由于输出到PRE,因此您可能会使用\ n。
JeffSB 2014年

(2)我一直在尝试不同的方法来处理高尔夫JavaScript,并且具有方便的输入和输出。我想我喜欢受您的提示和警报启发的最新方法...我在代码中使用了提示和警报,因此可以将其粘贴到控制台中,并且适用于任何人。但是我还制作了一个带有TEXTAREA和PRE的网页,以显示其工作原理。该网页将覆盖提示和警报以使用TEXTAREA和PRE-因此它是相同的代码,并且混乱程度较小-也许吗?
JeffSB 2014年

@JeffSB我<br>只在jsfiddle上使用了tag和textarea,因为它看起来好多了。警报没有等宽字体,因此输出看起来很糟糕。在我的高尔夫版本中,我使用Alert和\ n。您的网页是公开的吗?
伊兹林2014年

1

眼镜蛇- 334 344 356 360

class P
    def main
        a,o,n=CobraCore.commandLineArgs[1:],['/','\\'],0
        c,l=a.count,a.sorted
        while (n+=1)%2or l<>a
            p,d='',(~n%4+4)//3
            for i in n%2*(c+1-c%2),p,o=p+o[1]+' ',[o.pop]+o
            for i in 1+d:c-n%2*c:2
                z=if(l[:i]<>a[:i],1,0)
                l.swap(i-z,i)
                p+=' ['|X'[z]]  '
            print[['','| '][d]+[p,p+'|'][d^c%2],p][n%2][:c*2]

通过从左侧开始将每个元素移到适当位置来工作。因此,它通常会输出一个非常大的(尽管仍然正确的)路径图。

例子:

3 1 4 2

\ / \ / 
 X   X  
/ \ / \ 
|  X  |
\ / \ / 
 X   X  
/ \ / \ 
|  X  |
\ / \ / 
 X   X  
/ \ / \ 
|  X  |
\ / \ / 
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.