Escribe un efecto dominó


25

Usando la menor cantidad de caracteres Unicode, escriba una función que acepte tres parámetros:

  • Numero total de fichas de dominó
  • ndomino afectado
  • Derribar la dirección del dominó afectado ( 0o Lhacia la izquierda 1o Rhacia la derecha)

Una vez que se derriba un dominó, también debe derribar los dominós restantes en la misma dirección.

Debe generar las fichas de dominó |representando una ficha de dominó permanente \y /representando una ficha de dominó derribada a la izquierda y a la derecha, respectivamente.

Ejemplos

10, 5, 1debería regresar ||||//////
6, 3, 0debería regresar\\\|||


¿Debería el tercer parámetro ser una cadena o un bool / int hará 0: left, 1: right?
user80551

Su ejemplo sugiere que si hay 10 fichas de dominó y 5 se tiran a la derecha, deberíamos mostrar seis de las diez fichas de dominó.
algorithmshark

1
@algorithmshark Creo que deberíamos mostrar el resultado si el quinto dominó se golpea a la derecha.
user80551

@ rybo111 ¿Puede permitir que el tercer parámetro sea un int ya que puede acortar las operaciones de comparación? Simplemente en if(third_parameter)lugar deif(third_paramter=='l')
user80551

¿Podemos elegir el orden de los parámetros?
Justin

Respuestas:


14

Ruby, 38 (46) personajes

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

Esta función toma la dirección como un entero ( 1para la derecha, 0para la izquierda). Una función que toma una cadena es 8 caracteres más larga:

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

Ejemplos de uso:

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

¿Por qué solo quedan 5 fichas de dominó en el segundo ejemplo?
Clyde Lobo

1
@ClydeLobo Porque comienzas en la posición 5 y golpeas el dominó a la izquierda, que a su vez derriba los 4 dominós a su izquierda, para un total de 5. En el primer ejemplo, comenzando en la posición 5 derriba a 6 dominó: El en la posición 5 más el 5 a su derecha.
Ventero

8

Haskell, 70

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

suponiendo que es un tipo de dirección , que tiene constructores R y L .


8

J - 32 26 char

J no puede manejar más de dos argumentos sin usar una lista, y no puede manejar listas no homogéneas sin boxeo. Por lo tanto, tener la entrada como una lista de tres enteros es ideal. El orden de los parámetros es el reverso del estándar: 0 para la izquierda o 1 para la derecha, luego la posición, luego el número total de fichas de dominó. La razón de esto es porque J terminará yendo a través de ellos de derecha a izquierda.

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

Esto es lo que está pasando. F`G/aplicado a una lista x,y,zevaluará x F (y G z). y G zconstruye ambas formas posibles en que las fichas de dominó podrían haberse derrumbado, y luego Fusa xpara seleccionar cuál de las dos usar.

A continuación hay un intercambio de información con J REPL que explica cómo se construye la función: las líneas sangradas se ingresan en REPL y las respuestas se alinean con el margen izquierdo. Recuerde que J evalúa estrictamente de derecha a izquierda a menos que haya 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
\\\|||||||

A expensas de unos pocos caracteres, podemos hacer que la orden sea la orden estándar: solo agregue @|.al final de la función:

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

Sin embargo, adaptar esto para trabajar con un argumento de cadena para la dirección sería mucho más costoso.


Sé que ha pasado un tiempo desde que escribiste esta respuesta, pero la forma en que está estructurada es muy buena. Realmente me gusta cómo hizo uso de gerundios y /también la forma en que construye dos salidas y selecciona la deseada. Creo que siento que esto carece del reconocimiento que merece.
cole

Lo que @cole dijo, quedé impresionado.
FrownyFrog

7

PowerShell, 66

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

Probablemente la misma idea que todos los demás tenían.

  • Toma 0 o 1 como parámetro de dirección (para izquierda y derecha, respectivamente)

6

Golfscript (44 53 )

Mi primer programa Golfscript. Me llevó mucho más tiempo del que debería y probablemente se pueda hacer de una manera más inteligente y concisa (estoy seguro de que alguien probará eso :)):

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

Una entrada de muestra es 10 5 0.

Sin golf:

: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
Prueba realizada ;-) aunque todavía no estoy contento con mi solución.
Howard

1
Algunos consejos: puede elegir dser 0/ en 1lugar de 'l'/, lo 'r'que le da un código más corto. De lo contrario, si almacena d'l'=en una variable, oyu puede usarlo en lugar de la segunda comparación con d. En el término x i j, puede guardar ambos espacios en blanco si usa un nombre de variable no alfanumérico en lugar de i.
Howard

@Howard ¡Gracias por los consejos! Elegí 'l'/ 'r'porque en ese momento aún no veía que somos libres de usar números enteros. El truco no alfanumérico es ingenioso, ¡gracias! Tal vez actualice la respuesta más tarde.
Ingo Bürk

4

GolfScript, 28 23 caracteres

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

Argumentos en la cima de la pila, intente en línea :

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

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

Asombroso. Me encanta aprender de todas estas soluciones de golfscript :)
Ingo Bürk

4

Python - 45 52

Esto requiere 1para la derecha y 0para la izquierda.

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

Aquí hay una versión que toma ry lcorrectamente, en 58 :

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

Algunos ejemplos de uso ...

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

gracias a @nderscore!

El tercer parámetro es un booleano (0: izquierda / 1: derecha)

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
esta entrada podría ser una tarjeta de referencia para ECMAScript 6: D
bebe

@bebe jaja, y ni siquiera es su forma final. ES6 puede estar muy sucio.
xem

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

1
¡Excelente! También encontré esta cosa loca pero es más larga (67): d = (a, b, c, d = a-b + 1) => "\\ |" [c] .repeat (c? B-1: d ) + "| /" [c] .repeat (c? d: b-1)
xem

No creo que valga la pena repetir alias. [r='repeat'][r]15 caracteres .repeat.repeat14 caracteres
edc65

3

Python2 / 3 - 54

El último agregado en la regla fue bastante bueno (el 0/1 en lugar de 'l' / 'r'). Hizo la mía realmente más pequeña que la solución existente de python. 0 izquierda, 1 derecha

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 bytes

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

Pruébalo en línea!

Toma datos como (%) n k bpara ndominó, k'dominó derribado, dirección b.

Encuentra el carácter en cada posición c, desde 1a nutilizando una expresión aritmética para calcular el índice de caracteres 0, 1 o 2.

Casos de prueba tomados de aquí .


Haskell , 44 bytes

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

Pruébalo en línea!

Una estrategia interesante que resultó un poco más larga. Genera la cadena "\\|/"<*[1..n]con ncopias consecutivas de cada símbolo, luego toma una porción de ncaracteres contiguos con la posición de inicio determinada aritméticamente.


2

Python 2.7, 68 65 61 59 58 caracteres

Usar d=1para izquierda y d=0derecha

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

Nota: Gracias a @TheRare por seguir jugando al golf.


1
¿Por qué no d and'\\'...or'/'...?
seequ

También podría hacerlo('\\'...,'/'...)[d]
seequ

@TheRare Necesitaría dos de esas listas.
user80551

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

@TheRare Also, I don't think your code works when falling left.¿Podría dar un caso de prueba para probar?
user80551

2

Javascript, 46 caracteres

Parece que hacer trampa para hacer 0 = ly 1 = r pero la hay. Lo encogió con un poco de recursión.

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

editar: se perdió un personaje obvio


2

JavaScript (ES6) 61 63

Editar Fue buggy - lástima de mí.

No es tan diferente de @xem, pero lo encontré yo mismo y es más corto. El parámetro d es 0/1 para izquierda / derecha

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

Prueba en la consola de Firefox

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

Salida

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

1
Debe ser --p?
nderscore

@nderscore sí, debería, tengo parámetros incorrectos, tonto de mí.
edc65

2

Perl 67 65 caracteres

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

Asigne los primeros tres parámetros (total, posición, dirección como un entero [0 izquierda, 1 derecha]). Los extras van al éter. Resta 1 de la posición si nos dirigimos a la derecha para que el dominó en la posición X también se voltee.


1
reemplace $p--if$dcon $p-=$dpara perder dos caracteres :)
chino perl goth


2

R , 75 68 61 57 bytes

Una función anónima. Publicaré una explicación más completa si hay interés.

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

Pruébalo en línea!


2

Haskell , 51 bytes

f a b c=("\\|"!!c<$[1..b-c])++("|/"!!c<$[b-c..a-1])

a= número de fichas de dominó, b= índice basado en 1 del tocado, c= dirección ( 0izquierda y 1derecha).

Pruébalo en línea!


La definición de un operador infijo también trabaja desde hace más de dos entradas: (a#b)c= ....
Laikoni

1

PHP - 64

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

Un bucle simple, y haciendo eco del personaje.

Genera un Notice: Undefined variable: i, aquí hay otra versión que silencia el error (65 caracteres):

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

Y una versión sin ningún error (69 caracteres):

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

Otras funciones en PHP:

sprintf/ printfrelleno

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

relleno a través de str_pad/ str_repeatfunciones

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?'/':'|');}

usando ambos printfy str_repeatfunciones

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 caracteres

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

1

CJam - 20

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

El código principal está en la segunda línea, la primera línea es solo para obtener los parámetros de la entrada estándar (de lo contrario, debe poner los parámetros en el código).

Pruébalo en http://cjam.aditsu.net/

Ejemplos:

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

8 5 0
\\\\\|||

Explicación:

:Xalmacena el último parámetro (dirección 0/1) en la variable X
-resta X de la posición de arrastre, obteniendo la longitud de la primera secuencia de caracteres (llamémosla L)
_hace que una copia de L
"\|"X=obtenga el carácter para usar primero: \para X = 0 y |para X = 1
*repite que el carácter L veces
oimprime la cadena, quitándola de la pila
-resta L del número de fichas de dominó, obteniendo la longitud de la segunda secuencia de caracteres (llamémosla R)
"|/"X=hace que el carácter use siguiente: |para X = 0 y /para X = 1
*repite ese carácter R veces


1

Lisp común

Esto no ganará en un código de golf, pero destaca la directiva de formato de justificación de 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))))

La aritmética no es mala: nes el número total de fichas de dominó; pes la posición del primer dominó derribado; des 0o 1, representando a la izquierda y a la derecha (según lo permitido en los comentarios), y se usa como índice en x; xes una cadena de \, |y /. La cadena de formato utiliza dos directivas de justificación (anidadas), cada una de las cuales permite un carácter de relleno. Así:

(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 caracteres

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

Solo porque amo PHP.

EDITAR: El siguiente código hace lo mismo.

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 '/';
            }
        }
    }
}

¿Tienes una versión más detallada?
Martijn

1
@Martijn, edité mi publicación para incluir una.
TribalChief

Ahora puedo ver lo que hace. Nada demasiado elegante, pero +1 :)
Martijn

¡Gracias! ¡Sin embargo, las soluciones de @NPlay parecen elegantes!
TribalChief

Un par de consejos de golf: 1) Paréntesis innecesarios en ($i+1>$p). 2) Reescribiendo su expresión ternaria para $d?($i+1<$p?'|':'/'):$i+1>$p?'|':'\\'guardar otros 3 bytes. O simplemente elimine ==0e invierta las direcciones. 3) Con $i++<$apuede eliminar $i++de la condición de publicación y usar en $ilugar de $i+1(-6 bytes). 4) $i=0no es necesario; pero tendría que suprimir avisos (opción --n) si lo elimina (-4 bytes).
Titus


1

05AB1E , 19 bytes

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

Todavía tengo la sensación de que es un poco largo, pero funciona ... Y mejor que la solución inicial de 23 bytes que tuve con la construcción if-else, que rápidamente eliminé ...

El orden de entrada es el mismo que en el desafío: longitud total, índice, 1/ 0para izquierda / derecha, respectivamente.

Pruébelo en línea o verifique ambos casos de prueba .

Explicación:

α                     # 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
En realidad no necesita explícitamente return 0a main.
zennehoy

No se compila para mí porque cin y cout no están en el espacio de nombres global: ¿qué compilador está utilizando? Además, C(n)>>k>>psería corto de C(n)C(k)C(p)lo que no? Y si la definición de P () pudiera stringificar el argumento, ¿eso no guardaría caracteres para todas las comillas? Y cuando compara p con 'l' y 'r': 0 y 1 serían más cortos, específicamente> 0 en lugar de == 'r' y <1 en lugar de == 'l' (suponiendo que esté bien usando números en lugar de r / l - si no <'r' todavía es más corto que == 'l' y> 'l' aún es más corto que == 'r')
Jerry Jeremiah

@JerryJeremiah para cin y cout necesita "usar el espacio de nombres estándar".
bacchusbeale

Lo sé, pero dado que solo se usa dos veces, es más corto calificar las funciones. De ninguna manera funciona en mi compilador sin incluir.
Jerry Jeremiah

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

Resultados de ejemplo:

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

0

Javascript, 81 85 caracteres

función e (a, b, c) {l = 'repetir'; d = '|' [l] (- a-b ++); devolver c> 'q'? d + "/" [l] (b): "\\" [l] (b) + d}

La primera vez que probé codegolf, fue divertido gracias :)


También podría modificar la función para que sea una función ES6, ya que la repetición de cadena es ES6 (no funciona en Chrome).
Matt

0

JavaScript: 85 caracteres

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

1 = Izquierda, 0 = Derecha

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

0

Clojure, 81 caracteres

(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,"/")
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.