Écrivez un effet domino


25

En utilisant le moins de caractères Unicode, écrivez une fonction qui accepte trois paramètres:

  • Nombre total de dominos
  • ne domino affecté
  • Direction de renversement du domino affecté ( 0ou Lpour gauche 1ou Rpour droite)

Une fois qu'un domino est renversé, il doit également renverser les dominos restants dans la même direction.

Vous devez sortir les dominos en |représentant un domino debout \et en /représentant un domino renversé respectivement à gauche et à droite.

Exemples

10, 5, 1devrait revenir ||||//////
6, 3, 0devrait revenir\\\|||


Le troisième paramètre doit-il être une chaîne ou un bool / int fera-t-il 0: gauche, 1: droite?
user80551

Votre exemple suggère que s'il y a 10 dominos et 5 sont renversés à droite, nous devrions afficher six des dix dominos renversés.
algorithmshark

1
@algorithmshark Je pense que nous devrions montrer le résultat si le cinquième domino est frappé à droite.
user80551

@ rybo111 Pouvez-vous autoriser le troisième paramètre à être un entier car cela peut raccourcir les opérations de comparaison. Simplement if(third_parameter)au lieu deif(third_paramter=='l')
user80551

Pouvons-nous choisir l'ordre des paramètres?
Justin

Réponses:


14

Rubis, 38 (46) caractères

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

Cette fonction prend la direction sous forme d'entier ( 1pour droite, 0pour gauche). Une fonction qui prend une chaîne a 8 caractères de plus:

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

Exemples d'utilisation:

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

pourquoi y a-t-il seulement 5 dominos frappés à gauche dans le deuxième exemple?
Clyde Lobo

1
@ClydeLobo Parce que vous commencez à la position 5 et renversez le domino vers la gauche, qui à son tour renverse les 4 dominos à sa gauche, pour un total de 5. Dans le premier exemple, à partir de la position 5, renversez 6 dominos: celui à la position 5 plus le 5 à sa droite.
Ventero

8

Haskell, 70

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

en supposant qu'il y a un type Direction , qui a des constructeurs R et L .


8

J - 32 26 car

J ne peut pas gérer plus de deux arguments sans utiliser une liste, et il ne peut pas gérer des listes non homogènes sans boxe. Donc, avoir l'entrée comme une liste de trois entiers est idéal. L'ordre des paramètres est l'inverse de celui standard: 0 pour la gauche ou 1 pour la droite, puis la position, puis le nombre total de dominos. La raison en est que J finira par les parcourir de droite à gauche.

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

Voici ce qui se passe. F`G/appliqué à une liste x,y,zsera évalué x F (y G z). y G zconstruit les deux façons possibles dont les dominos auraient pu basculer, puis Futilisex pour sélectionner lequel des deux utiliser.

Vous trouverez ci-dessous un va-et-vient avec le J REPL qui explique comment la fonction est construite ensemble: des lignes en retrait sont entrées dans le REPL, et les réponses sont alignées avec la marge de gauche. Rappelons que J évalue strictement de droite à gauche sauf s'il y a des 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
\\\|||||||

Au détriment de quelques caractères, nous pouvons faire de la commande la commande standard: il suffit d'ajouter @|.à la fin de la fonction:

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

L'adaptation de cela pour fonctionner avec un argument de chaîne pour la direction serait cependant beaucoup plus coûteuse.


Je sais que cela fait un moment que vous n'avez pas écrit cette réponse, mais la façon dont elle est structurée est très cool. J'aime vraiment la façon dont vous avez utilisé les gérondifs et /aussi la façon dont vous créez deux sorties et sélectionnez celle souhaitée. Je suppose que j'ai l'impression que cela n'a pas la reconnaissance qu'il mérite.
cole

Ce que @cole a dit, j'étais impressionné.
FrownyFrog

7

PowerShell, 66

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

Probablement la même idée que tout le monde avait.

  • Prend 0 ou 1 comme paramètre de direction (pour la gauche et la droite, respectivement)

6

Golfscript (44 53 )

Mon tout premier programme Golfscript. Cela m'a pris beaucoup plus de temps que prévu et peut probablement être fait de manière plus intelligente et plus concise (je suis sûr que quelqu'un le prouvera :)):

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

Un exemple d'entrée est 10 5 0.

Non 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
Preuve faite ;-) même si je ne suis pas encore satisfait de ma solution.
Howard

1
Quelques conseils: vous pouvez choisir dd'être 0/ 1au lieu de 'l'/ 'r'ce qui vous donne un code plus court. Sinon, si vous stockez d'l'=dans une variable oyu peut l'utiliser à la place de la deuxième comparaison avec d. Dans le terme, x i jvous pouvez enregistrer les deux espaces blancs si vous utilisez un nom de variable non alphanumérique à la place de i.
Howard

@Howard Merci pour les conseils! J'ai choisi 'l'/ 'r'car à l'époque je ne voyais pas encore que nous étions libres d'utiliser des entiers. L'astuce non alphanumérique est lisse, merci! Peut-être que je mettrai à jour la réponse plus tard.
Ingo Bürk

4

GolfScript, 28 23 caractères

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

Arguments en haut de la pile, essayez en ligne :

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

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

Incroyable. J'adore apprendre de toutes ces solutions de golfscript :)
Ingo Bürk

4

Python - 45 52

Cela nécessite 1pour la droite et 0pour la gauche.

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

Voici une version qui prend ret lcorrectement, à 58 :

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

Quelques exemples d'utilisation ...

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

merci à @nderscore!

Le 3ème param est un booléen (0: gauche / 1: droite)

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
cette entrée pourrait être une carte de référence pour ECMAScript 6: D
bebe

@bebe haha, et ce n'est même pas sa forme définitive. ES6 peut être très sale.
2014

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

1
génial! J'ai aussi trouvé ce truc fou mais c'est plus long (67): d = (a, b, c, d = a-b + 1) => "\\ |" [c] .repeat (c? B-1: d ) + "| /" [c] .repeat (c? d: b-1)
xem

Je ne pense pas que la répétition de l'alias vaut la peine. [r='repeat'][r]15 caractères. .repeat.repeat14 caractères
edc65

3

Python2 / 3 - 54

Cette dernière règle ajoutée était plutôt sympa (le 0/1 au lieu de 'l' / 'r'). Rendu le mien plus petit que la solution python existante. 0 est à gauche, 1 est à droite

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 octets

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

Essayez-le en ligne!

Prend des entrées comme (%) n k bpour les ndominos, k'th domino renversé, direction b.

Recherche le personnage à chaque position callant de 1àn en utilisant une expression arithmétique pour calculer l'indice de caractère 0, 1 ou 2.

Cas de test pris à partir d' ici .


Haskell , 44 octets

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

Essayez-le en ligne!

Une stratégie intéressante qui s'est avérée un peu plus longue. Génère la chaîne "\\|/"<*[1..n]avec ndes copies consécutives de chaque symbole, puis prend une tranche de ncaractères contigus avec une position de départ déterminée arithmétiquement.


2

Python 2.7, 68 65 61 59 58 caractères

Utiliser d=1pour gauche et d=0pour droite

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

Remarque: Merci à @TheRare pour l'avoir encore joué.


1
Pourquoi ne pas d and'\\'...or'/'...?
seequ

Vous pourriez aussi faire('\\'...,'/'...)[d]
seequ

@TheRare J'aurais besoin de deux de ces listes.
user80551

Je ne pense pas. 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.Pourriez-vous donner un cas de test à prouver?
user80551

2

Javascript, 46 caractères

On dirait que tricher pour faire 0 = l et 1 = r mais c'est le cas. Rétréci avec un peu de récursivité.

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

edit: manqué un personnage évident


2

JavaScript (ES6) 61 63

Edit C'était buggy - honte à moi.

Pas si différent de @xem, mais je l'ai trouvé moi-même et c'est plus court. Le paramètre d est 0/1 pour gauche / droite

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

Tester dans la console Firefox

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

Sortie

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

1
Devrait-il en être ainsi --p?
nderscore

@nderscore oui, les paramètres sont incorrects, idiot.
edc65

2

Perl, 67 65 personnages

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

Attribuez les trois premiers paramètres (total, position, direction sous forme d'entier [0 gauche, 1 droite]). Les extras vont dans l'éther. Soustrayez 1 de la position si nous nous dirigeons vers la droite afin que le domino en position X soit également inversé.


1
remplacer $p--if$dpar $p-=$dpour perdre deux personnages :)
perl goth chinois


2

R , 75 68 61 57 octets

Une fonction anonyme. Je posterai une explication plus complète s'il y a un intérêt.

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

Essayez-le en ligne!


2

Haskell , 51 octets

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

a= nombre de dominos, b= indice 1 de celui touché, c= direction (à 0gauche et à 1droite).

Essayez-le en ligne!


Définition d' un opérateur infixe travaille également pour plus de deux entrées: (a#b)c= ....
Laikoni

1

PHP - 64

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

Une boucle simple, et faisant écho au personnage.

Génère un Notice: Undefined variable: i, voici une autre version silencieux l'erreur (65 caractères):

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

Et une version sans erreur (69 caractères):

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

Autres fonctions en PHP:

sprintf/ printfrembourrage

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

remplissage via str_pad/ str_repeatfonctions

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

en utilisant les fonctions printfetstr_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 caractères

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

Le code principal est sur la deuxième ligne, la première ligne est juste pour obtenir les paramètres de l'entrée standard (sinon vous devez mettre les paramètres dans le code).

Essayez-le sur http://cjam.aditsu.net/

Exemples:

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

8 5 0
\\\\\|||

Explication:

:Xstocke le dernier paramètre (direction 0/1) dans la variable X
-soustrait X de la position de renversement, obtenir la longueur de la première séquence de caractères (appelons-le L)
_fait une copie de L
"\|"X=obtient le caractère à utiliser en premier: \pour X = 0 et |pour X = 1
*répète que le caractère L
oimprime la chaîne, la supprimant de la pile
-soustrait L du nombre de dominos, obtenant la longueur de la deuxième séquence de caractères (appelons-le R),
"|/"X=obtient le caractère utiliser ensuite: |pour X = 0 et /pour X = 1
*répète ce caractère R fois


1

Lisp commun

Cela ne gagnera pas dans un golf de code, mais cela met en évidence la directive de format de justification 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))))

L'arithmétique n'est pas mauvaise: nc'est le nombre total de dominos; pest la position du premier domino renversé; dest soit 0ou 1, représentant gauche et droite (comme autorisé dans les commentaires), et est utilisé comme index dans x; xest une chaîne de \, |et /. La chaîne de format utilise deux directives de justification (imbriquées), chacune autorisant un caractère de remplissage. Ainsi:

(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 caractères

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

Tout simplement parce que j'aime PHP.

EDIT: Le code suivant fait de même.

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

Vous avez une version plus détaillée?
Martijn

1
@Martijn, j'ai modifié mon article pour en inclure un.
TribalChief

Maintenant je peux voir ce que ça fait. Rien d'extraordinaire, mais +1 :)
Martijn

Merci! La ou les solutions de @NPlay semblent sophistiquées!
TribalChief

quelques conseils de golf: 1) parenthèses inutiles à ($i+1>$p). 2) La réécriture de votre expression ternaire $d?($i+1<$p?'|':'/'):$i+1>$p?'|':'\\'permet d' économiser 3 autres octets. Ou supprimez ==0et inversez simplement les directions. 3) Avec $i++<$avous pouvez supprimer $i++de la condition de publication et utiliser $iau lieu de $i+1(-6 octets). 4) $i=0n'est pas nécessaire; mais vous devrez supprimer les notifications (option --n) si vous la supprimez (-4 octets).
Titus


1

05AB1E , 19 octets

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

J'ai toujours l'impression que c'est un peu long, mais ça marche .. Et mieux que la solution initiale de 23 octets que j'avais avec la construction if-else, que j'ai rapidement abandonnée ..

L'ordre d'entrée est le même que dans le défi: longueur totale, index, 1/ 0pour gauche / droite respectivement.

Essayez-le en ligne ou vérifiez les deux cas de test .

Explication:

α                     # 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
Vous n'avez pas vraiment besoin de return 0partir explicitement main.
zennehoy

Il ne compile pas pour moi car cin et cout ne sont pas dans l'espace de noms global - quel compilateur utilisez-vous? En outre, C(n)>>k>>pserait-il court-circuité C(n)C(k)C(p)? Et si la définition de P () pouvait stringifier l'argument, cela ne sauverait-il pas les caractères pour toutes les guillemets? Et lorsque vous comparez p à 'l' et 'r': 0 et 1 seraient plus courts - spécifiquement> 0 au lieu de == 'r' et <1 au lieu de == 'l' (en supposant que vous êtes d'accord en utilisant des nombres au lieu de r / l - sinon <'r' est toujours plus court que == 'l' et> 'l' est toujours plus court que == 'r')
Jerry Jeremiah

@JerryJeremiah pour cin et cout doit "utiliser l'espace de noms std".
bacchusbeale

Je sais mais comme il n'est utilisé que deux fois, il est plus court pour qualifier les fonctions. Aucune des deux ne fonctionne sur mon compilateur sans inclure.
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;}

Exemples de résultats:

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

0

Javascript, 81 85 caractères

fonction e (a, b, c) {l = 'répéter'; d = '|' [l] (- a-b ++); retourner c> 'q'? d + "/" [l] (b): "\\" [l] (b) + d}

C'était la première fois que j'essayais du codegolf, c'était amusant merci :)


Peut aussi bien modifier la fonction pour être une fonction ES6, car la répétition de chaîne est ES6 (ne fonctionne pas dans Chrome).
Matt

0

JavaScript - 85 caractères

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

1 = gauche, 0 = droite

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

0

Clojure, 81 caractères

(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,"/")
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.