# Write a domino effect

Using the fewest Unicode characters, write a function that accepts three parameters:

• Total number of dominoes
• nth affected domino
• Topple direction of the affected domino (0 or L for left, 1 or R for right)

Once a domino is toppled, it must also topple the remaining dominoes in the same direction.

You should output the dominoes with | representing a standing domino and \ and / representing a domino toppled to the left and right respectively.

## Examples

10, 5, 1 should return ||||//////
6, 3, 0 should return \\\|||

• Should the third parameter be a string or will a bool/int do like 0:left , 1:right? Jul 9, 2014 at 18:11
• Your example suggests that if there are 10 dominoes, and 5 are knocked right, we should display six of the ten dominoes knocked over. Jul 9, 2014 at 18:21
• @algorithmshark I think we should show the result if the fifth domino is knocked right. Jul 9, 2014 at 18:22
• @rybo111 Can you allow the third parameter to be an int as that can make comparison operations shorter. Simply if(third_parameter) instead of if(third_paramter=='l') Jul 9, 2014 at 18:42
• Can we choose the order of the parameters? Jul 9, 2014 at 18:52

## Ruby, 38 (46) characters

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


This function takes the direction as an integer (1 for right, 0 for left). A function that takes a string is 8 characters longer:

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


Usage examples:

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

• why are there only 5 dominoes knocked left in the second example? Jul 10, 2014 at 16:06
• @ClydeLobo Because you start at position 5 and knock the domino to the left, which in turn knocks over the 4 dominoes to its left, for a total of 5. In the first example, starting at position 5 knocks over 6 dominoes: The one at position 5 plus the 5 to its right. Jul 10, 2014 at 16:10

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


assuming there is a type Direction, which has constructors R and L.

# J - 32 26 char

J can't handle more than two arguments without using a list, and it can't handle non-homogenous lists without boxing. So having the input as a list of three integers is ideal. The parameter order is the reverse of the standard one: 0 for left or 1 for right, then position, then total number of dominoes. The reason for this is because J will end up going through them right-to-left.

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


Here's what's going on. FG/ applied to a list x,y,z will evaluate x F (y G z). y G z constructs both possible ways the dominoes could have toppled, and then F uses x to select which of the two to use.

Below is a back-and-forth with the J REPL that explains how the function is built together: indented lines are input to the REPL, and responses are flush with the left margin. Recall that J evaluates strictly right to left unless there are parens:

   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
\\\|||||||


At the expense of a few characters, we can make the order the standard order: just append @|. to the end of the function:

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


Adapting this to work with a string argument for direction would be much more costly, however.

• I know it's been a while since you wrote this answer, but the way it is structured is very cool. I really like how you made use of gerunds and / and also the way you build two outputs and select the desired one. I guess I feel like this lacks the recognition it deserves.
– cole
Jan 4, 2018 at 3:04
• What @cole said, I was awed. Jan 4, 2018 at 7:13

## PowerShell, 66

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


Probably the same idea every one else had.

• Takes either 0 or 1 as the direction parameter (for left and right, respectively)

## Golfscript (44 53)

My first ever Golfscript program. Took me way longer than it should have and can probably be done in a smarter, more concise way (I'm sure someone will prove that :) ):

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


A sample input is 10 5 0.

Ungolfed:

: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

• Proof done ;-) although I am not happy with my solution yet. Jul 10, 2014 at 6:06
• Some tips: you may choose d to be 0/1 instead of 'l'/'r' which gives you some shorter code. Otherwise, if you store d'l'= in a variable oyu may use it instead of the second comparison with d. In the term x i j you can save both whitespaces if you use a non-alphanumeric variable name instead of i. Jul 10, 2014 at 6:12
• @Howard Thanks for the tips! I chose 'l'/'r' because at the time I didn't see yet that we are free to use integers. The non-alphanumeric trick is slick, thanks! Maybe I'll update the answer later. Jul 10, 2014 at 6:14

### GolfScript, 28 23 characters

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


Arguments on top of stack, try online:

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

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

• Amazing. Love to learn from all these golfscript solutions :) Jul 10, 2014 at 6:15

# Python - 45 52

This requires 1 for right and 0 for left.

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


Here's a version that takes r and l correctly, at 58:

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


Some usage examples...

>>> 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))
\\\|||||||


## JS (ES6) - 79747265 62

thanks to @nderscore!

The 3rd param is a boolean (0: left / 1: right)

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); // => "\\\\\\\\||"

• this entry could be a reference card for ECMAScript 6 :D
– bebe
Jul 9, 2014 at 19:00
• @bebe haha, and it's not even its final form. ES6 can be very dirty.
– xem
Jul 9, 2014 at 19:08
• 65: d=(a,b,c)=>"\\"[r="repeat"](!c&&a-b+1)+"|"[r](--b)+"/"[r](c&&a-b) Jul 10, 2014 at 3:47
• great! I also found this crazy thing but it's longer (67): d=(a,b,c,d=a-b+1)=>"\\|"[c].repeat(c?b-1:d)+"|/"[c].repeat(c?d:b-1)
– xem
Jul 10, 2014 at 7:04
• I don't think repeat aliasing is worth. [r='repeat'][r] 15 chars. .repeat.repeat 14 chars Jul 10, 2014 at 15:33

Python2/3 - 54

That last added on rule was quite nice (the 0/1 instead of 'l'/'r'). Made mine actually smaller than the existing python solution. 0 is left, 1 is right

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)) # => \\\\\|||||


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


Try it online!

Takes input like (%) n k b for n dominos, k'th domino toppled, direction b.

Finds the character at each position c ranging from 1 to n by using an arithmetic expression to compute the character index 0, 1, or 2.

Test cases taken from here.

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


Try it online!

An interesting strategy that turned out a bit longer. Generates the string "\\|/"<*[1..n] with n consecutive copies of each symbol, then takes a slice of n contiguous characters with start position determined arithmetically.

## Python 2.7, 68 65 61 59 58 chars

Use d=1 for left and d=0 for right

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


Note: Thanks to @TheRare for further golfing it.

• Why not d and'\\'...or'/'...? Jul 9, 2014 at 19:21
• You could also do ('\\'...,'/'...)[d] Jul 10, 2014 at 7:59
• @TheRare I would need two of those lists. Jul 10, 2014 at 8:55
• I don't think so. f=lambda a,p,d:('|'*(p-1)+'/'*(a-p+1),'\\'*p+'|'*(a-p))[d] Jul 10, 2014 at 9:11
• @TheRare Also, I don't think your code works when falling left. Could you give a test case to prove? Jul 10, 2014 at 9:16

Javascript, 46 characters

Seems like cheating to do 0=l and 1=r but there is is. Shrunk it with a little recursion.

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


edit: missed an obvious character

# JavaScript (ES6) 61 63

Edit It was buggy - shame on me.

Not so different from @xem, but found it myself and it's shorter. Parameter d is 0/1 for left/right

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


Test In Firefox console

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


Output

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

• Should it be --p? Jul 10, 2014 at 16:48
• @nderscore yes it should, got parameters wrong, silly me. Jul 11, 2014 at 9:36

## Perl, 67 65 Characters

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


Assign the first three params (total, position, direction as an integer [0 left, 1 right]). Extras go into the ether. Subtract 1 from the position if we're headed right so the domino in position X is flipped, too.

• replace $p--if$d with $p-=$d to lose two characters :) Aug 4, 2014 at 14:35

4 bytes saved thanks to this tip

f 0 b _=[]
f a b c=last("|/":["\\|"|b>c])!!c:f(a-1)(b-1)c


Try it online!

(0!b)_=[]
(a!b)c|b==c=a!b$c+1|1>0="\\|/"!!c:((a-1)!(b-1))c  Try it online! Not a very complex answer but it beats both of the existing Haskell answers. # R, 756861 57 bytes An anonymous function. I'll post a fuller explanation if there is interest. function(t,n,d)cat(c("\\","|","/")[(1:t>n-d)+1+d],sep="")  Try it online! # Haskell, 51 bytes f a b c=("\\|"!!c<$[1..b-c])++("|/"!!c<$[b-c..a-1])  a = number of dominoes, b = 1-based index of the touched one, c = direction (0 is left and 1 is right). Try it online! • Defining an infix operator also works for more than two inputs: (a#b)c= .... Oct 13, 2018 at 8:28 # PHP - 64 function f($a,$b,$c){for($w='\|/';++$i<=$a;)echo$w[$c+($i>$b)];}  A simple loop, and echo-ing the character. Generates a Notice: Undefined variable: i, here's another version silenting the error (65 characters) : function f($a,$b,$c){for($w='\|/';@++$i<=$a;)echo$w[$c+($i>$b)];}  And a version withtout any error (69 characters) : function f($a,$b,$c){for($w='\|/',$i=0;++$i<=$a;)echo$w[$c+($i>$b)];}


Other functions in PHP :

sprintf / printf padding

function f($a,$b,$c){printf("%'{${0*${0}=$c?'|':'\\'}}{$a}s",sprintf("%'{${0*${0}=$c?'/':'|'}}{${0*${0}=$a-$b+$c}}s",''));}  padding via str_pad / str_repeat functions 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?'/':'|');}


using both printf and str_repeat functions

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));}  # Scala 75 characters def f(l:Int,p:Int,t:Char)=if(t=='l')"\\"*p++"|"*(l-p) else "|"*(l-p):+"/"*p  # CJam - 20 q~ :X-_"\|"X=*o-"|/"X=*  The main code is on the second line, the first line is just for getting the parameters from the standard input (otherwise you need to put the parameters in the code). Try it at http://cjam.aditsu.net/ Examples: 12 4 1 |||///////// 8 5 0 \\\\\|||  Explanation: :X stores the last parameter (0/1 direction) in variable X - subtracts X from the knock-over position, obtaining the length of the first sequence of characters (let's call it L) _ makes a copy of L "\|"X= gets the character to use first: \ for X=0 and | for X=1 * repeats that character L times o prints out the string, removing it from the stack - subtracts L from the number of dominoes, obtaining the length of the second sequence of characters (let's call it R) "|/"X= gets the character to use next: | for X=0 and / for X=1 * repeats that character R times ## Common Lisp This won't win in a code golf, but it highlights Common Lisp's justification format directive: (lambda (n p d &aux (x "\\|/")) (format t "~v,,,v<~v,,,v<~>~>" n (aref x d) (+ d (- n p)) (aref x (1+ d))))  The arithmetic isn't bad: n is the total number of dominoes; p is the position of the first toppled domino; d is either 0 or 1, representing left and right (as allowed in the comments), and is used as an index into x; x is a string of \, |, and /. The format string uses two (nested) justification directives, each of which allows for a padding character. Thus: (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))) \||||||||| \\|||||||| \\\||||||| \\\\|||||| \\\\\||||| \\\\\\|||| \\\\\\\||| \\\\\\\\|| \\\\\\\\\| \\\\\\\\\\ ////////// |///////// ||//////// |||/////// ||||////// |||||///// ||||||//// |||||||/// ||||||||// |||||||||/  PHP, 89 Characters function o($a,$p,$d){for($i=0;$i<$a;$i++)echo$d==0?($i+1>$p)?'|':'\\':($i+1<$p?'|':'/');}  Just because I love PHP. EDIT: The following code does the same. 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 '/'; } } } }  • Got a more detailed version? Jul 10, 2014 at 14:59 • @Martijn , I edited my post to include one. Jul 11, 2014 at 3:17 • Now I can see what it does. Nothing too fancy, but +1 :) Jul 11, 2014 at 7:04 • Thanks! @NPlay 's solution(s) look fancy though! Jul 11, 2014 at 7:08 • a couple of golfing tips: 1) Unnecessary parentheses at ($i+1>$p). 2) Rewriting your ternary expression to $d?($i+1<$p?'|':'/'):$i+1>$p?'|':'\\' saves another 3 bytes. Or just remove ==0 and invert directions. 3) With $i++<$a you can remove $i++ from the post condition and use $i instead of $i+1 (-6 bytes). 4) $i=0 is not necessary; but you´d have to suppress notices (option --n) if you remove it (-4 bytes). Oct 12, 2018 at 15:57

# J, 23 21 19 bytes

'|/\'{~{:-(>i.)~-/


Try it online!

Input is a list of integers in the standard order.

# 05AB1E, 19 bytes

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


I still have the feeling it's a bit long, but it works.. And better than the initial 23 bytes solution I had with if-else construction, which I quickly dropped..

Input order is the same as in the challenge: total length, index, 1/0 for left/right respectively.

Explanation:

α                     # 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 "|||" → "///|||"


# Vyxal, 23 bytes

[-‹\|*₴+\/*,|-\\*₴+\|*,


Try it Online!

## 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;}

• You don't actually need to explicitly return 0 from main. Jul 10, 2014 at 16:27
• It doesn't compile for me because cin and cout are not in the global namespace - what compiler are you using? Also, C(n)>>k>>p would be shorted than C(n)C(k)C(p) wouldn't it? And if the define for P() could stringify the argument wouldn't that save characters for all the quotes? And when you compare p to 'l' and 'r': 0 and 1 would be shorter - specifically >0 instead of =='r' and <1 instead of =='l' (assuming you are ok using numbers instead of r/l - if not <'r' is still shorter than =='l' and >'l' is still shorter than =='r') Aug 4, 2014 at 0:48
• @JerryJeremiah for cin and cout need "using namespace std". Aug 6, 2014 at 1:37
• I know but since it is only used twice it is shorter to qualify the functions. Neither way works on my compiler without the include. Aug 6, 2014 at 9:21

# 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;}


Example results:

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


# Javascript, 81 85 characters

function e(a,b,c){l='repeat';d='|'[l](--a-b++);return c>'q'?d+"/"[l](b):"\\"[l](b)+d}


First time trying codegolf, was fun thanks :)

• Might as well modify the function to be an ES6 function, as string repeat is ES6 (doesn;t work in Chrome).
– Matt
Jul 11, 2014 at 2:03

# JavaScript - 85 chars

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


1 = Left, 0 = Right

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


Clojure, 81 chars

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