Escreva um efeito dominó


25

Usando o menor número de caracteres Unicode, escreva uma função que aceite três parâmetros:

  • Número total de dominós
  • nth dominó afetado
  • Derrubar a direção do dominó afetado ( 0ou Lpara a esquerda 1ou Rpara a direita)

Depois que um dominó é derrubado, ele também deve derrubar os dominós restantes na mesma direção.

Você deve exibir os dominós |representando um dominó em pé \e /representando um dominó tombado para a esquerda e direita, respectivamente.

Exemplos

10, 5, 1deve retornar ||||//////
6, 3, 0deve retornar\\\|||


O terceiro parâmetro deve ser uma string ou um bool / int fará como 0: left, 1: right?
User80551

Seu exemplo sugere que, se houver 10 dominós e cinco forem acertados, devemos exibir seis dos dez dominós derrubados.
algorithmshark

1
@algorithmshark Acho que devemos mostrar o resultado se o quinto dominó for acertado.
User80551

@ rybo111 Você pode permitir que o terceiro parâmetro seja um int, pois isso pode reduzir as operações de comparação. Simplesmente em if(third_parameter)vez deif(third_paramter=='l')
user80551

Podemos escolher a ordem dos parâmetros?
9137 Justin

Respostas:


14

Ruby, 38 (46) caracteres

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

Esta função assume a direção como um número inteiro ( 1para a direita, 0para a esquerda). Uma função que usa uma string tem 8 caracteres a mais:

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

Exemplos de uso:

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

por que restam apenas cinco dominós no segundo exemplo?
Clyde Lobo

1
@ClydeLobo Como você começa na posição 5 e bate no dominó para a esquerda, que por sua vez bate nos 4 dominós à sua esquerda, num total de 5. No primeiro exemplo, começando na posição 5 bate em 6 dominós: O na posição 5 mais o 5 à sua direita.
Ventero

8

Haskell, 70

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

assumindo que há um tipo de direcção , o qual tem construtores R e L .


8

J - 32 26 car

J não pode lidar com mais de dois argumentos sem usar uma lista e não pode lidar com listas não homogêneas sem boxe. Portanto, ter a entrada como uma lista de três números inteiros é ideal. A ordem dos parâmetros é o inverso do padrão: 0 para a esquerda ou 1 para a direita e, em seguida, posição e número total de dominós. A razão para isso é que J acabará passando por eles da direita para a esquerda.

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

Aqui está o que está acontecendo. F`G/aplicado a uma lista x,y,zavaliará x F (y G z). y G zconstrói as duas maneiras possíveis que os dominós poderiam ter derrubado e, em seguida, Fusa xpara selecionar qual dos dois usar.

A seguir, é apresentado um J-REPL que explica como a função é construída em conjunto: linhas recuadas são inseridas no REPL e as respostas são alinhadas com a margem esquerda. Lembre-se de que J avalia estritamente da direita para a esquerda, a menos que haja parênteses:

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

À custa de alguns caracteres, podemos fazer da ordem a ordem padrão: basta acrescentar @|.ao final da função:

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

Adaptar isso para trabalhar com um argumento de string para direção seria muito mais caro, no entanto.


Eu sei que já faz um tempo desde que você escreveu esta resposta, mas a maneira como ela é estruturada é muito legal. Eu realmente gosto de como você utilizou os gerúndios e /também a maneira de criar duas saídas e selecionar a desejada. Acho que sinto que isso não tem o reconhecimento que merece.
cole

O que @cole disse, fiquei impressionado.
FrownyFrog

7

PowerShell, 66

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

Provavelmente a mesma ideia que todo mundo tinha.

  • Aceita 0 ou 1 como parâmetro de direção (para esquerda e direita, respectivamente)

6

Golfe (44 53 )

Meu primeiro programa de golfe. Demorei muito mais do que deveria e provavelmente pode ser feito de maneira mais inteligente e concisa (tenho certeza de que alguém provará isso :)):

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

Uma entrada de amostra é 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

1
Prova concluída ;-) embora ainda não esteja feliz com minha solução.
1011 Howard

1
Algumas dicas: você pode optar dpor ser 0/ em 1vez de 'l'/ o 'r'que fornece um código mais curto. Caso contrário, se você armazenar d'l'=em uma variável oyu, use-a em vez da segunda comparação com d. No termo, x i jvocê pode salvar os dois espaços em branco se usar um nome de variável não alfanumérico em vez de i.
1011 Howard

@ Howard Obrigado pelas dicas! Eu escolhi 'l'/ 'r'porque na época ainda não vi que somos livres para usar números inteiros. O truque não alfanumérico é liso, obrigado! Talvez eu atualize a resposta mais tarde.
Ingo Bürk

4

GolfScript, 28 23 caracteres

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

Argumentos no topo da pilha, tente online :

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

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

Surpreendente. Adoro aprender com todas essas soluções golfscript :)
Ingo Bürk

4

Python - 45 52

Isso requer 1para a direita e 0para a esquerda.

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

Aqui está uma versão que leva re lcorretamente, em 58 :

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

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

graças a @nderscore!

O terceiro parâmetro é um booleano (0: esquerda / 1: direita)

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 pode ser um cartão de referência para ECMAScript 6: D
bebe

@bebe haha, e nem é sua forma final. ES6 pode estar muito sujo.
xem

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

1
ótimo! Eu também achei essa coisa louca, mas é mais longa (67): d = (a, b, c, d = a-b + 1) => "\\ |" [c] .repeat (c? B-1: d ) + "| /" [c] .repeat (c? d: b-1)
xem

Eu não acho que vale a pena repetir o alias. [r='repeat'][r]15 caracteres. .repeat.repeat14 chars
edc65

3

Python2 / 3-54

Essa última regra adicionada foi bastante agradável (0/1 em vez de 'l' / 'r'). Tornou o meu realmente menor que a solução python existente. 0 é deixado, 1 é certo

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

Experimente online!

Toma entrada como (%) n k bnos ndominós, com ko dominó derrubado, na direção b.

Localiza o caractere em cada posição, cvariando de 1até nusando uma expressão aritmética para calcular o índice de caracteres 0, 1 ou 2.

Casos de teste retirados daqui .


Haskell , 44 bytes

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

Experimente online!

Uma estratégia interessante que acabou um pouco mais. Gera a sequência "\\|/"<*[1..n]com ncópias consecutivas de cada símbolo e pega uma fatia de ncaracteres contíguos com a posição inicial determinada aritmeticamente.


2

Python 2.7, 68 65 61 59 58 caracteres

Use d=1para esquerda e d=0direita

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

Nota: Agradecemos a @TheRare por jogar mais.


1
Por que não d and'\\'...or'/'...?
Veja

Você também pode fazer('\\'...,'/'...)[d]
Veja

@ TheRare eu precisaria de duas dessas listas.
user80551

Acho que não. f=lambda a,p,d:('|'*(p-1)+'/'*(a-p+1),'\\'*p+'|'*(a-p))[d]
see

@TheRare Also, I don't think your code works when falling left.Você poderia dar um caso de teste para provar?
user80551

2

Javascript, 46 caracteres

Parece trapaça fazer 0 = le 1 = r, mas existe. Encolheu-o com um pouco de recursão.

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

editar: perdeu um personagem óbvio


2

JavaScript (ES6) 61 63

Editar Foi um buggy - vergonha para mim.

Não é tão diferente do @xem, mas o achei por mim mesmo e é mais curto. O parâmetro d é 0/1 para esquerda / direita

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

Teste no console do Firefox

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

Saída

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

1
Deveria ser --p?
Ndscore

@ Underscore sim, deve, tem parâmetros errados, bobo eu.
11124 Edc65

2

Perl, 67 65 caracteres

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

Atribua os três primeiros parâmetros (total, posição, direção como um número inteiro [0 à esquerda, 1 à direita]). Os extras vão para o éter. Subtraia 1 da posição se estivermos indo para a direita, para que o dominó na posição X também seja invertido.


1
substituir $p--if$dcom $p-=$da perder dois personagens :)
perl chineses goth


2

R , 75 68 61 57 bytes

Uma função anônima. Vou postar uma explicação mais completa, se houver interesse.

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

Experimente online!


2

Haskell , 51 bytes

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

a= número de dominós, b= índice baseado em 1 do tocado, c= direção (à 0esquerda e à 1direita).

Experimente online!


Definindo um operador infixo também funciona para mais de duas entradas: (a#b)c= ....
Laikoni

1

PHP - 64

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

Um loop simples e ecoando o personagem.

Gera um Notice: Undefined variable: i, aqui está outra versão que silencia o erro (65 caracteres):

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

E uma versão sem erros (69 caracteres):

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

Outras funções no PHP:

sprintf/ printfpadding

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

preenchimento via str_pad/ str_repeatfunções

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 as funções printfestr_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 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=*

O código principal está na segunda linha, a primeira linha é apenas para obter os parâmetros da entrada padrão (caso contrário, você precisa colocar os parâmetros no código).

Experimente em http://cjam.aditsu.net/

Exemplos:

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

8 5 0
\\\\\|||

Explicação:

:Xarmazena o último parâmetro (0/1 direção) na variável X
-subtrai X do bate-over posição, obtendo o comprimento da primeira sequência de caracteres (vamos chamá-lo L)
_faz uma cópia de L
"\|"X=recebe o personagem para usar em primeiro lugar: \para X = 0 e |para X = 1
*repete esse caractere L vezes
oimprime a string, removendo-a da pilha
-subtrai L do número de dominós, obtendo o comprimento da segunda sequência de caracteres (vamos chamá-lo de R)
"|/"X=obtém o caractere use next: |para X = 0 e /para X = 1
*repete esse caractere R vezes


1

Lisp comum

Isso não ganha em um código de golfe, mas destaca a diretiva de formato de justificação do 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))))

A aritmética não é ruim: né o número total de dominós; pé a posição do primeiro dominó tombado; dé um 0ou ou 1representa esquerda e direita (conforme permitido nos comentários) e é usado como um índice para x; xé uma cadeia de \, |e /. A cadeia de formato usa duas diretivas de justificação (aninhadas), cada uma das quais permite um caractere de preenchimento. Portanto:

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

Só porque eu amo PHP.

EDIT: O código a seguir faz o mesmo.

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

Tem uma versão mais detalhada?
287 Martijn

1
@ Martijn, editei meu post para incluir um.
TribalChief

Agora eu posso ver o que faz. Nada muito extravagante, mas um :)
Martijn

Obrigado! As soluções da @NPlay parecem sofisticadas!
TribalChief

algumas dicas de golfe: 1) Parênteses desnecessários em ($i+1>$p). 2) Reescrevendo sua expressão ternária para $d?($i+1<$p?'|':'/'):$i+1>$p?'|':'\\'salvar outros 3 bytes. Ou apenas remova ==0e inverta as direções. 3) Com $i++<$avocê pode remover $i++da condição de postagem e usar em $ivez de $i+1(-6 bytes). 4) $i=0não é necessário; mas você teria que suprimir avisos (opção --n) se você removê-lo (-4 bytes).
Titus


1

05AB1E , 19 bytes

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

Ainda tenho a sensação de que é um pouco longo, mas funciona .. E melhor do que a solução inicial de 23 bytes que tive com a construção if-else, que eu larguei rapidamente ..

A ordem de entrada é a mesma do desafio: comprimento total, índice, 1/ 0para esquerda / direita, respectivamente.

Experimente online ou verifique os dois casos de teste .

Explicação:

α                     # 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
Você realmente não precisa explicitamente return 0de main.
Zennehoy

Não é compilável para mim porque cin e cout não estão no espaço de nomes global - que compilador você está usando? Além disso, C(n)>>k>>pseria curto-circuito do C(n)C(k)C(p)que não? E se a definição para P () pudesse especificar o argumento, isso não salvaria caracteres para todas as aspas? E quando você compara p com 'l' e 'r': 0 e 1 seriam menores - especificamente> 0 em vez de == 'r' e <1 em vez de == 'l' (assumindo que você está bem usando números em vez de r / l - se não <'r' ainda for menor que == 'l' e> 'l' ainda for menor que == 'r')
Jerry Jeremiah

@JerryJeremiah para cin e cout precisa "usar o namespace std".
precisa saber é o seguinte

Eu sei, mas como ele é usado apenas duas vezes, é mais curto para qualificar as funções. De nenhuma maneira funciona no meu compilador sem a inclusão.
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 exemplo:

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

0

Javascript, 81 85 caracteres

função e (a, b, c) {l = 'repita'; d = '|' [l] (- a-b ++); retorna c> 'q'? d + "/" [l] (b): "\\" [l] (b) + d}

Primeira vez tentando codegolf, foi divertido obrigado :)


Também é possível modificar a função para ser uma função ES6, pois a repetição de sequência é ES6 (não funciona no 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 = Esquerda, 0 = Direita

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,"/")
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.