模拟旋转板


14

介绍

您正在玩一个匹配的游戏,在该游戏中,硬币由于重力而插入顶部,然后跌至底部(位于顶部硬币上)。

所以这

O <- inserting this coin

OO O
OOOOO

会变成这个

O
OO O
OOOOO

现在想象有人顺时针旋转电路板。将发生以下情况:

1.旋转单板

OOO
OO
O
OO
O

2.硬币由于重力而掉落

O
O
OO
OO
OOO

你的任务

您的任务是通过编写程序或函数来模拟电路板的旋转。为了简单起见,我们只处理一种硬币(不是太刺激的配对游戏,是……)。您可以假定仅在旋转完成后才应用重力。电路板顺时针旋转。

输入值

输入将是一个字符串,其中包含3种类型的字符:

  • O(大写o)或0(零)-一枚硬币(您决定解决方案支持的硬币)
  • (空格)-空字段
  • \ n(新行)-行尾

输入代表板的状态。您可以假设输入格式正确,并且包含板的有效状态(没有硬币漂浮)。输入可以是功能参数,也可以从标准输入或文件中读取。

输出量

输出是旋转后板的新状态。输出包含与输入相同的3种字符。输出可以从函数中返回,也可以写入标准输出或文件中。

样品

输入1:

O
OO O
OOOOO

输出1:

O
O
OO
OO
OOO

输入2:

O O
O O

输出2:

OO
OO

您可以使用任何语言以及所选语言的标准库。以字节为单位的最短程序获胜。


较短的行是否用尾随空格填充?
Ventero 2014年

如果需要,那么可以。
大卫·弗兰克

电路板尺寸有什么要求?我可以选择一个合理的最大大小,还是应用程序/功能需要适用于所有可能的大小?
Fors 2014年

2
如果旋转后施加重力,Input2如何变为Output2?我本来以为会把顶部的硬币掉下来而不是水平放下?
马特

2
@Matt请注意,Input2和Output2中都没有空行(SE在行之间显示边距)。
David Frank

Answers:


16

GolfScript,14个12个字符

' '-n%zip$n*

输入必须在STD​​IN上给出,硬币的字符可以是任何非空白字符。试试这里。感谢Peter指出减少两个字符。


哦,我不会为使用transposeRuby来处理不同长度的数组所
付出的代价

时代@Ventero大多数我用这个版本哈克:([nil]*a.map(&:size).max).zip(*a)。虽然不好打高尔夫球。
霍华德

您可以节省2个字符:由于最长的行总是在底部结束,因此可以替换-1%$
彼得·泰勒

@PeterTaylor你是对的-我们可以保存到字符。谢谢。
2014年

1
@PeterTaylor好吧,我的确包含了一个字符的别名" "
aidtsu退出,因为SE无效

6

Javascript(E6)103

首先尝试,仅矩阵运算。输入字符串中的每一行都需要填充。
相当罗.。

R=t=>(x=t.split('\n').reverse().map(x=>[...x].sort()),x.map((c,i)=>x.map(r=>r[i]).join('')).join('\n'))

伪代码

  1. 字符串->行数组
  2. 上/下反向阵列
  3. 每行-> char数组
  4. 对每一行进行排序(硬币“掉到右边”)
  5. 转置
  6. 行中的每个字符数组->字符串
  7. 连接数组->单个字符串

哇,排序很聪明(+1)!介意我偷了吗?
seequ 2014年

我以前从未看过语法[...x]。这叫什么?
ComFreek


2
@ edc65您用括号破坏了自己的链接。这是正确的链接
Chris Cirefice

6

Ruby 2.0,59个字符

puts$<.map(&:chars).reverse.transpose.sort[1,50].map &:join

通过stdin输入,假设所有行的长度相同。这可能比必要的时间长得多。但是至少它是可读的...


我认为您可以$<.map改用。
霍华德

@霍华德这是我永远忘记的一件事。谢谢!
Ventero 2014年

1
[1,50]在这里做什么?
并非查尔斯

1
@Charles跳过第一行,该行包含来自输​​入的所有换行符。David在评论中提到50x50是最大可能的大小,因此除了选择第一行(1..-1)之外,我没有选择其他所有内容,而是选择了第二行()开始的50行1,50
Ventero 2014年

@Ventero知道了。凉。谢谢!
并不是说

3

J- 49 31 24字节

我认为其中可能会有不必要的轮换,但否则效果很好。该函数接受指定的输入,硬币为O。输入中不需要尾随空格。

新版本,受edc65的Javascript答案启发:

f=:[:|."1@|:[:/:~"1,;._2

说明:

f=:[:|."1@|:[:/:~"1,;._2
                   ,;._2 Split the string at every fret, which is the last character in the string (newline).
              /:~"1      Sort every row separately.
     |."1@|:             Rotate the array clockwise.

旧版本:

f=:[:|:((#~=&' '),=&'O'#])"1@|:@(|."1@|:)@(,;._2)

说明:

f=:[:|:((#~=&' '),=&'O'#])"1@|:@(|."1@|:)@(,;._2)
                                          (,;._2) Split the string at every fret, which is the last character in the string (newline).
                                (|."1@|:)@        Rotate the array clockwise.
                             |:@                  Reverse the axes (columns become rows and vice-versa).
       ((#~=&' '),=&'O'#])"1                      Function that applies the "gravity"
                          "1                       Apply to every row separately:
                  =&'O'#]                           Get the O's in the row.
       (#~=&' ')                                    Get the spaces in the row.
                ,                                   Join them, spaces come first.
  [:|:                                            Reverse axes again.

示例(请注意,多行字符串0 : 0以方括号开头和结尾):

   f 0 : 0
O
OO O
OOOOO
) NB. output starts now
O  
O  
OO 
OO 
OOO
   f 0 : 0
O O
O O
) NB. Output starts now.

OO
OO

如果可以的话,请在旋转前进行排序
edc65 2014年

@ edc65你是个聪明人。
seequ 2014年

2

Haskell — 86

只是学习,所以我相信这可以改善。

import Data.List
c=putStr.unlines.filter(/="").sort.map(filter(/=' ')).transpose.lines

样本输入:

let a = "O    \nOO O \nOOOOO"
let b = " O O \n O O "
c a
c b

样本输出:

O
O
OO
OO
OOO

OO
OO

2

Python 2(69)(79)

for c in sorted(zip(*raw_input().split("\\n"))):print''.join(c[::-1])

接受用空格填充的输入,以便所有行的长度相等。所述split创建的各行的arrat。的zip有效转置阵列。然后,sorted按字典顺序对元组进行排序,导致所有硬币掉到底部。最后,我们打印每一行,然后将其转回字符串,尽管我们必须先将其反转。这样做print'O'*c.count('O')是等效的,并且使用相同数量的字符。

示例运行:

>> O    \nOO O \nOOOOO
O
O
OO
OO
OOO

1

C,167119字节

这个较短的版本(不幸的是?)也比原始版本清晰得多。

m;j;b[99];r;main(){while(j=getchar()+1)j-11?m+=j-33&&++b[r]>m:++r;for(j=r;m+1;putchar(j--?m<b[j]?79:32:(j=r,m--,10)));}

0

球拍:130

(let l((a'()))(let((b(sort(string->list(read-line))char<?)))(if
(null? b)(apply map(λ x(map display x)(newline))a)(l(cons b a)))))

它要求您用空格填充,以使线条相等。


0

C# - 209个 174字节

是的,我认为我必须在某些时候尝试Code Code高尔夫。创建了一个功能(r),它可以旋转电路板并进行打印。我猜我在打印我的char数组时有点作弊,但是如果您不知道为什么不应该生气:)

感谢ProgramFOX的提示:)

void r(string s){int x=s.IndexOf('\n'),j,i=-1,k,z=x+1;var y=new char[x*x+x];for(;++i<x;y[z*(i+1)-1]='\n')for(k=j=x;j>0;)if(s[i*z+--j]=='0')y[k--*z-i-2]='0';Console.Write(y);}

作弊

new char[x*x+x]'\0'和不填充数组' '


1
删除换行符和之间的空格char[]y将把您的字符数减少到192个字符。另外,static在此处发布答案时,并不一定需要提供关键字。删除它会将您的字符数减少到185个字符。
ProgramFOX 2014年

我也能够删除自从较早尝试以来就被遗忘的“ ref”。
WozzeC 2014年
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.