写一个多米诺骨牌效果


25

使用最少的Unicode字符,编写一个接受三个参数的函数:

  • 多米诺骨牌总数
  • n受影响的多米诺骨牌
  • 受影响的多米诺骨牌的倾覆方向(0L向左1R向右)

一旦多米诺骨牌倒塌,它也必须沿相同方向推倒其余的多米诺骨牌。

你应该输出与多米诺骨牌|代表一个常设Domino和\/代表骨牌效应,向左,右分别。

例子

10, 5, 1应该返回||||//////
6, 3, 0应该返回\\\|||


第三个参数应该是字符串,还是bool / int像0:left,1:right一样?
user80551 2014年

您的示例表明,如果有10个多米诺骨牌,而5个被正确敲除,则应该显示10个多米诺骨牌中的6个
algorithmhark

1
@algorithmshark我认为如果第五个多米诺骨牌被正确敲打,我们应该显示结果。
user80551 2014年

@ rybo111是否可以将第三个参数设置为int,因为这会使比较操作更短。只是if(third_parameter)代替了if(third_paramter=='l')
user80551

我们可以选择参数的顺序吗?
贾斯汀

Answers:


14

Ruby,38(46)个字符

e=->n,k,r{k-=r;'\|'[r]*k+'|/'[r]*n-=k}

此函数将方向作为整数(1对于右,0对于左)。接受字符串的函数长8个字符:

d=->n,k,r{n-=k;r<?r??\\*k+?|*n :?|*~-k+?/*-~n}

用法示例:

puts e[10, 5, 1] # or d[10, 5, 'r']
||||//////
puts e[10, 5, 0] # or d[10, 5, 'l']
\\\\\|||||

为什么在第二个示例中只剩下5个多米诺骨牌?
Clyde Lobo 2014年

1
@ClydeLobo因为您从位置5开始,将多米诺骨牌敲向左侧,这反过来又敲打了其左侧的4个多米诺骨牌,总共5个。在第一个示例中,从位置5开始,敲打了6个多米诺骨牌:在位置5 及其右边的5
Ventero 2014年

8

哈斯克尔,70岁

f R i l=(i-1)#'|'++(l-i+1)#'/'
f L i l=i#'\\'++(l-i)#'|'
(#)=replicate

假设有一个类型方向,其具有构造ř大号


8

J- 32 26个字符

J在不使用列表的情况下不能处理两个以上的参数,并且在没有装箱的情况下也不能处理不均匀的列表。因此,将输入作为三个整数的列表是理想的。参数顺序与标准顺序相反:0表示左侧,1表示右侧,然后是位置,然后是多米诺骨牌总数。这样做的原因是因为J最终会从右到左遍历它们。

{`(('|/\'{~-@>:,:<:)1+i.)/

这是怎么回事。F`G/应用于列表x,y,z将进行评估x F (y G z)y G z构造了多米诺骨牌可能倒塌的两种可能方式,然后 F用于x选择要使用的两种方式。

下面是J REPL的来回说明,它说明了如何构建函数:缩进的行输入到REPL,并且响应与左边距齐平。回想一下,除非有括号,否则J的评估结果严格是从右到左:

   1 ] 3 (]) 10            NB. ] ignores the left argument and returns the right
10
   1 ] 3 (] 1+i.) 10       NB. hook: x (F G) y  is  x F (G y)
1 2 3 4 5 6 7 8 9 10
   1 ] 3 (>: 1+i.) 10      NB. "greater than or equal to" bitmask
1 1 1 0 0 0 0 0 0 0
   1 ] 3 (-@>: 1+i.) 10    NB. negate
_1 _1 _1 0 0 0 0 0 0 0
   1 ] 3 (<: 1+i.) 10      NB. "less than or equal to"
0 0 1 1 1 1 1 1 1 1
   1 ] 3 ((-@>:,:<:)1+i.) 10          NB. laminate together
_1 _1 _1 0 0 0 0 0 0 0
 0  0  1 1 1 1 1 1 1 1
   1 ] 3 (('|/\'{~-@>:,:<:)1+i.) 10   NB. turn into characters
\\\|||||||
||////////
   1 { 3 (('|/\'{~-@>:,:<:)1+i.) 10   NB. select left or right version
||////////
   {`(('|/\'{~-@>:,:<:)1+i.)/ 1 3 10  NB. refactor
||////////
   {`(('|/\'{~-@>:,:<:)1+i.)/ 0 3 10
\\\|||||||

可以牺牲一些字符,使该顺序成为标准顺序:只需追加@|.到函数的末尾:

   |. 10 3 1
1 3 10
   {`(('|/\'{~-@>:,:<:)1+i.)/@|. 10 3 1
||////////

但是,将其修改为与用于方向的字符串参数一起使用将花费更多。


我知道距您编写此答案已有一段时间了,但是它的结构方式非常酷。我非常喜欢您如何使用动名词,/以及构建两个输出并选择所需输出的方式。我想我觉得这缺乏应有的认可。
科尔

@科尔说的话,我很敬畏。
FrownyFrog

7

PowerShell,66岁

filter d($n,$k,$d){"$('\|'[$d])"*($k-$d)+"$('|/'[$d])"*($n-$k+$d)}

每个人可能都有相同的想法。

  • 将0或1作为方向参数(分别用于左和右)

6

Golfscript(44 53

我的第一个Golfscript程序。花费了我更长的时间,而且可能以一种更聪明,更简洁的方式来完成(我敢肯定有人会证明:)):

:d;:j;:^,{:x j<d&'\\'{x^j)->d!&'/''|'if}if}%

样本输入为10 5 0

取消高尔夫:

:d;:j;:^      # save input in variables and discard from stack, except total length ^
,             # create an array of numbers of length ^
{             # start block for map call
  :x          # save current element (= index) in variable
  j<          # check whether we are left of the first knocked over domino
  d           # check whether the direction is to the left
  &           # AND both results
  '\\'        # if true, push a backslash (escaped)
  {           # if false, start a new block
    x^j)->    # check whether we are on the right of the knocked over domino
    d!        # check whether the direction is to the right
    &         # AND both results
    '/'       # if true, push a slash
    '|'       # if false, push a non-knocked over domino
    if
  }
  if
}%            # close block and call map

1
证明已经完成;-)虽然我对自己的解决方案还不满意。
霍华德

1
一些提示:你可以选择d0/ 1不是'l'/ 'r'它给你一些更短的代码。否则,如果您将d'l'=变量存储在oyu中,则可以使用它代替与的第二次比较d。在该术语中x i j,如果您使用非字母数字变量名代替,则可以保存两个空格i
霍华德

@Howard感谢您的提示!我选择'l'/ 'r'是因为当时我还没有看到我们可以自由使用整数。非字母数字的技巧很不错,谢谢!也许我稍后再更新答案。
IngoBürk'14

4

GolfScript,28个 23个字符

'\\'@*2$'|/'*$-1%1>+@/=

关于堆栈的参数,请在线尝试:

> 10 5 1
||||//////

> 10 5 0
\\\\\|||||

惊人。爱从所有这些解决方案golfscript学习:)
英戈·伯克

4

蟒蛇-45 52

这需要1对右和0左。

x=lambda n,k,d:'\\|'[d]*(k-d)+"|/"[d]*(n-k+d)

如下是一个版本r,并l正确,在58

def x(n,k,d):d=d=='r';return'\\|'[d]*(k-d)+"|/"[d]*(n-k+d)

一些用法示例...

>>> print(x(10,3,0))
\\\|||||||
>>> print(x(10,3,1))
||////////
>>> print(x(10,5,1))
||||//////
>>> print(x(10,5,0))
\\\\\|||||
>>> print(x(10,3,0))
\\\|||||||

4

JS(ES6)-79 74 72 65 62

感谢@nderscore!

第三个参数是布尔值(0:左/ 1:右)

d=(a,b,c)=>"\\|"[a-=--b,c].repeat(c?b:a)+"|/"[c].repeat(c?a:b)

// Test
d(10,3,1); // => "||////////"
d(10,3,0); // => "\\\\\\\\||"

1
此条目可能是ECMAScript 6:D的参考卡
Bebe 2014年

@beha哈哈,它甚至不是最终形式。ES6可能很脏。
xem 2014年

1
65:d=(a,b,c)=>"\\"[r="repeat"](!c&&a-b+1)+"|"[r](--b)+"/"[r](c&&a-b)
nderscore 2014年

1
大!我也发现了这个疯狂的东西,但是它更长了(67):d =(a,b,c,d = a-b + 1)=>“ \\ |” [c] .repeat(c?b-1:d )+“ | /” [c] .repeat(c?d:b-1)
Xem 2014年

我认为重复的别名不值得。[r='repeat'][r]15个字符。.repeat.repeat14个字符
edc65

3

Python2 / 3-54

最后添加的规则非常好(0/1而不是“ l” /“ r”)。使我的实际上比现有的python解决方案小。左0,右1

def f(a,b,c):d,e='\|/'[c:2+c];h=b-c;return d*h+e*(a-h)

# Usage:
print(f(10,5,1)) # => ||||//////
print(f(10,5,0)) # => \\\\\|||||

3

Haskell,42个字节

(n%k)b=["\\|/"!!(b-div(k-b-c)n)|c<-[1..n]]

在线尝试!

接受像多米诺骨牌一样(%) n k b的输入nk第一个多米诺骨牌被推翻,方向b

通过使用算术表达式计算字符索引0、1或2,查找c1n的每个位置的字符。

测试用例从这里取得


Haskell,44个字节

(n%k)b=take n$drop(n+n*b+b-k)$"\\|/"<*[1..n]

在线尝试!

一个有趣的策略,结果变得更长一些。生成"\\|/"<*[1..n]具有n每个符号的连续副本的字符串,然后获取一片n连续字符,其起始位置通过算术方式确定。


2

Python 2.7、68 65 61 59 58个字符

使用d=1左和d=0

f=lambda a,p,d:['|'*(p-1)+'/'*(a-p+1),'\\'*p+'|'*(a-p)][d]

注意:感谢@TheRare进一步打高尔夫球。


1
为什么不d and'\\'...or'/'...呢?
seequ 2014年

您也可以这样做('\\'...,'/'...)[d]
Seequ 2014年

@TheRare我需要其中两个列表。
user80551 2014年

我不这么认为。f=lambda a,p,d:('|'*(p-1)+'/'*(a-p+1),'\\'*p+'|'*(a-p))[d]
seequ 2014年

@TheRare Also, I don't think your code works when falling left.您能否举一个测试案例来证明?
user80551 2014年

2

Javascript,46个字符

好像作弊是0 = l和1 = r,但是确实存在。递归将其缩小。

f=(a,p,d)=>a?'\\|/'[(p-d<1)+d]+f(a-1,p-1,d):''

编辑:错过了明显的角色


2

JavaScript(ES6)61 63

编辑这是越野车-对我感到羞耻。

与@xem没什么不同,但我自己发现了它,而且它更短。左/右参数d为0/1

F=(a,p,d,u='|'.repeat(--p),v='\\/'[d].repeat(a-p))=>d?u+v:v+u

在Firefox控制台中测试

for(i=1;i<11;i+=3) console.log('L'+i+' '+F(10,i,0) + ' R'+i+' '+ F(10,i,1))

输出量

L1 \\\\\\\\\\ R1 //////////
L4 \\\\\\\||| R4 |||///////
L7 \\\\|||||| R7 ||||||////
L10 \||||||||| R10 |||||||||/

1
应该是--p吗?
nderscore 2014年

@nderscore是的,参数错误,愚蠢的我。
edc65 2014年

2

Perl, 67 65个字符

sub l{($t,$p,$d)=@_;$p-=$d;($d?'|':'\\')x$p.($d?'/':'|')x($t-$p)}

分配前三个参数(总计,位置,方向为整数[左0,右1])。多余的东西会进入乙醚。如果我们向右行驶,则从该位置减去1,因此X位置的多米诺骨牌也会被翻转。


1
更换$p--if$d$p-=$d失去两个字符:)
中国perl的歌特


2

R75 68 61 57字节

匿名函数。如果有兴趣,我会发表更详尽的解释。

function(t,n,d)cat(c("\\","|","/")[(1:t>n-d)+1+d],sep="")

在线尝试!



1

PHP-64

function f($a,$b,$c){for($w='\|/';++$i<=$a;)echo$w[$c+($i>$b)];}

一个简单的循环,然后回显字符。

生成一个Notice: Undefined variable: i,这是使错误静音的另一个版本(65个字符):

function f($a,$b,$c){for($w='\|/';@++$i<=$a;)echo$w[$c+($i>$b)];}

一个没有任何错误的版本(69个字符):

function f($a,$b,$c){for($w='\|/',$i=0;++$i<=$a;)echo$w[$c+($i>$b)];}

PHP中的其他功能:

sprintf/ printf填充

function f($a,$b,$c){printf("%'{${0*${0}=$c?'|':'\\'}}{$a}s",sprintf("%'{${0*${0}=$c?'/':'|'}}{${0*${0}=$a-$b+$c}}s",''));}

通过str_pad/ str_repeat功能填充

function f($a,$b,$c){$f='str_repeat';echo$f($c?'|':'\\',$b-$c).$f($c?'/':'|',$a-$b+$c);}
function f($a,$b,$c){echo str_pad(str_repeat($c?'|':'\\',$b-$c),$a,$c?'/':'|');}

同时使用printfstr_repeat功能

function f($a,$b,$c){printf("%'{${0*${0}=$c?'|':'\\'}}{$a}s",str_repeat($c?'/':'|',$a-$b+$c));}
function f($a,$b,$c){$w='\|/';printf("%'$w[$c]{$a}s",str_repeat($w[$c+1],$a-$b+$c));}

1

Scala 75个字​​符

def f(l:Int,p:Int,t:Char)=if(t=='l')"\\"*p++"|"*(l-p) else "|"*(l-p):+"/"*p

1

果酱-20

q~
:X-_"\|"X=*o-"|/"X=*

主代码在第二行,第一行仅用于从标准输入中获取参数(否则,您需要将参数放入代码中)。

http://cjam.aditsu.net/上尝试

例子:

12 4 1
|||/////////

8 5 0
\\\\\|||

说明:

:X存储在变量中的最后一个参数(0/1方向)X
-减去X从脱圈位置,获得字符的第一个序列的长度(让我们称之为L)
_使得L的副本
"\|"X=获得的字符首先使用:\用于X = 0,|对于X = 1,
*重复该字符L次以
o打印出字符串,将其从堆栈中删除,从
-多米诺骨牌数中减去L,获得第二个字符序列的长度(我们称其为R)
"|/"X=得到字符使用next:|对于X = 0和/X = 1
*重复该字符R次


1

普通口齿不清

这不会在代码争夺中获胜,但会突出显示Common Lisp的对正格式指令:

(lambda (n p d &aux (x "\\|/"))
   (format t "~v,,,v<~v,,,v<~>~>" n (aref x d) (+ d (- n p)) (aref x (1+ d))))

算术还不错: n多米诺骨牌的总数;p是第一个倒塌的多米诺骨牌的位置;d01,代表左右(在注释中允许),并用作的索引xx是的字符串\|/。格式字符串使用两个(嵌套的)对齐指令,每个指令都允许使用填充字符。从而:

(dotimes (d 2)
  (dotimes (i 10)
    ((lambda (n p d &aux (x "\\|/"))
       (format t "~v,,,v<~v,,,v<~>~>" n (aref x d) (+ d (- n p)) (aref x (1+ d))))
     10 (1+ i) d)
    (terpri)))

\|||||||||
\\||||||||
\\\|||||||
\\\\||||||
\\\\\|||||
\\\\\\||||
\\\\\\\|||
\\\\\\\\||
\\\\\\\\\|
\\\\\\\\\\
//////////
|/////////
||////////
|||///////
||||//////
|||||/////
||||||////
|||||||///
||||||||//
|||||||||/

1

PHP,89个字符

function o($a,$p,$d){for($i=0;$i<$a;$i++)echo$d==0?($i+1>$p)?'|':'\\':($i+1<$p?'|':'/');}

只是因为我爱PHP。

编辑:以下代码执行相同的操作。

function dominoes ($number, $position, $direction) {
    for ($i=0; $i<$number; $i++){
        if ($direction==0) {
            if (($i+1) > $position) {
                echo '|';
            } else {
                echo '\\';
            }
        } else {
            if (($i+1) < $position) {
                echo '|';
            } else {
                echo '/';
            }
        }
    }
}

有更详细的版本?
Martijn 2014年

1
@Martijn,我编辑了我的帖子以包括其中一个。
TribalChief

现在,我可以看到它的作用。没什么特别的,但+1 :)
Martijn 2014年

谢谢!@NPlay的解决方案看起来不错!
TribalChief

一些打高尔夫球的技巧:1)不必要的括号($i+1>$p)。2)重写三元表达式以$d?($i+1<$p?'|':'/'):$i+1>$p?'|':'\\'节省另外3个字节。或者只是删除==0并反转方向。3)$i++<$a您可以$i++从发布条件中删除并使用$i代替$i+1(-6字节)。4)$i=0没有必要;但是--n如果您将其删除(-4字节),则必须禁止显示通知(选项)。
泰特斯


1

05AB1E,19 个字节

αα©„\|³è×¹®-„|/³è×J

我仍然觉得它有点长,但是它可以工作。并且比起我最初使用if-else构造的最初的23字节解决方案要好,我很快就放弃了。

输入顺序与挑战中的顺序相同:总长度,索引,1/ 0分别为左/右。

在线尝试验证两个测试用例

说明:

α                     # Take the absolute difference of the first two (implicit) inputs
                      #  i.e. 10 and 5 → 5
                      #  i.e. 6 and 3 → 3
 α                    # Then take the absolute difference with the third (implicit) input
                      #  i.e. 5 and 1 → 4
                      #  i.e. 3 and 0 → 3
  ©                   # Store this number in the register (without popping)
   \|                # Push "\|"
      ³è              # Use the third input to index into this string
                      #  i.e. 1 → "|"
                      #  i.e. 0 → "\"
        ×             # Repeat the character the value amount of times
                      #  i.e. 4 and "|" → "||||"
                      #  i.e. 3 and "\" → "\\\"
         ¹®-          # Then take the first input, and subtract the value from the register
                      #  i.e. 10 and 4 → 6
                      #  i.e. 6 and 3 → 3
            „|/       # Push "|/"
               ³è     # Index the third input also in it
                      #  i.e. 1 → "/"
                      #  i.e. 0 → "|"
                 ×    # Repeat the character the length-value amount of times
                      #  i.e. 6 and "/" → "//////"
                      #  i.e. 3 and "|" → "|||"
                  J   # Join the strings together (and output implicitly)
                      #  i.e. "||||" and "//////" → "||||//////"
                      #  i.e. "///" and "|||" → "///|||"

0

C ++ 181

#define C(x) cin>>x;
#define P(x) cout<<x;
int n,k,i;char p;
int main(){C(n)C(k)C(p)
for(;i<n;i++){if(p=='r'&&i>=k-1)P('/')else if(p=='l'&&i<=k-1)P('\\')else P('|')}
return 0;}

1
您实际上不需要显式地return 0来自main
zennehoy 2014年

它对我不编译,因为cin和cout不在全局命名空间中-您在使用什么编译器?另外,C(n)>>k>>p会比C(n)C(k)C(p)不是更短吗?而且,如果P()的定义可以使参数字符串化,那么是否不会为所有引号保存字符?当将p与'l'和'r'进行比较时:0和1会更短-特别是> 0而不是=='r'和<1而不是=='l'(假设您可以使用数字代替r / l-如果不是<'r'仍然短于=='l',而>'l'仍然短于=='r')
Jerry Jeremiah 2014年

cin和cout的@JerryJeremiah需要“使用命名空间std”。
bacchusbeale 2014年

我知道,但是由于只使用了两次,因此限定功能的时间要短一些。如果没有包含,这两种方法都无法在我的编译器上运行。
杰里·耶利米

0

PHP - 105,97,96

 function a($r,$l,$f){$a=str_repeat('|',$l-$f);$b=str_repeat($r?'/':'\\',$f);echo$r?$a.$b:$b.$a;}

结果示例:

a(true,10,4);  -> \\\\||||||
a(false,10,5); -> |||||/////
a(false,10,2); -> ||||||||//

0

Javascript,81 85个字符

函数e(a,b,c){l ='repeat'; d ='|'[l](-a-b ++);返回c>'q'?d +“ /” [l](b): “ \\” [l](b)+ d}

第一次尝试codegolf,很有趣,谢谢:)


最好将函数修改为ES6函数,因为字符串重复是ES6(在Chrome中不起作用)。
马特

0

JavaScript-85个字符

function d(a,b,c){for(r=c?"\\":"/",p="",b=a-b;a--;)p+=c?a<b?"|":r:a>b?"|":r;return p}

1 =左,0 =右

d(10,3,1)
\\\|||||||
d(10,3,0)
||////////
d(10,7,1)
\\\\\\\|||
d(10,7,0)
||||||////

0

Clojure,81个字符

(defn g[a,p,d](apply str(map #(nth "\\|/"(+(if(>= % (- p d)) 1 0) d))(range a))))

0

vb.net(〜75c)

Dim f=Function(l,p,d)(If(d="l",StrDup(p,"\"),"")& StrDup(l-p-If(d="l",1,0),"|")).PadRight(l,"/")
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.