ASCII Doodling: Laser dans une boîte

31

Parfois, lorsque je gribouille, je dessine un rectangle, je commence par une diagonale dans l'un des coins, puis je trace une ligne en la "réfléchissant" chaque fois que je frappe un côté du rectangle. Je continue avec cela jusqu'à ce que j'atteigne un autre coin du rectangle (et j'espère que le rapport d'aspect de mon rectangle n'était pas irrationnel;)). C'est comme tracer le chemin d'un laser brillé dans une boîte. Vous devez produire le résultat de cela avec l'art ASCII.

À titre d'exemple, considérons une boîte de largeur 5et de hauteur 3. Nous commencerons toujours dans le coin supérieur gauche. Le #marque la limite de la boîte. Notez que la largeur et la hauteur se réfèrent aux dimensions intérieures.

#######    #######    #######    #######    #######    #######    #######
#\    #    #\    #    #\   \#    #\  /\#    #\  /\#    #\/ /\#    #\/\/\#
# \   #    # \  /#    # \  /#    # \/ /#    # \/ /#    #/\/ /#    #/\/\/#
#  \  #    #  \/ #    #  \/ #    # /\/ #    #\/\/ #    #\/\/ #    #\/\/\#
#######    #######    #######    #######    #######    #######    #######

Le défi

Étant donné la largeur et la hauteur (positives) de la boîte, vous devriez produire le résultat final du traçage du laser. Vous pouvez écrire un programme ou une fonction, en prenant des entrées via STDIN (ou l'alternative la plus proche), l'argument de ligne de commande, l'argument de la fonction et la sortie du résultat via STDOUT (ou l'alternative la plus proche), ou via des valeurs ou des arguments de retour de fonction.

Vous pouvez utiliser n'importe quel format de liste, chaîne ou nombre commode pour la saisie. La sortie doit être une seule chaîne (sauf si vous l'imprimez sur STDOUT, ce que vous pouvez bien sûr faire progressivement). Cela signifie également que vous pouvez prendre la hauteur en premier et la largeur en second - spécifiez simplement le format d'entrée exact dans votre réponse.

Il ne doit y avoir ni espace de début ni de fin sur aucune ligne de la sortie. Vous pouvez éventuellement générer une seule nouvelle ligne de fin.

Vous devez utiliser l' espace, /, \et #et reproduire les cas de test exactement comme indiqué.

Cas de test

2 2
####
#\ #
# \#
####

3 2
#####
#\/\#
#/\/#
#####

6 3
########
#\    /#
# \  / #
#  \/  #
########

7 1
#########
#\/\/\/\#
#########

1 3
###
#\#
#/#
#\#
###

7 5
#########
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#########

22 6
########################
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
# /\  /\  /\  /\  /\  /#
#/  \/  \/  \/  \/  \/ #
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
########################
Martin Ender
la source
1
Peut-être qu'une bonne question de suivi, une fois celle-ci terminée, est de relever ce défi avec des boîtes et des points de départ de forme arbitraire.
Sanchises
@sanchises J'avais réellement envisagé cela (et je pourrais toujours le publier), mais j'ai décidé de suivre le rectangle dans l'espoir que quelqu'un puisse trouver une formule explicite. J'envisageais également plusieurs points de départ tels que Xcela serait nécessaire pour les traversées. Peut-être la prochaine fois. ;)
Martin Ender
2
Pertinent: i.imgur.com/6tXrIfw.webm
orlp
Ce serait parfait pour un point d'animation. "Animer 1 rafale (une barre oblique) 1 cycle / sans fin)"
Martijn

Réponses:

20

Pyth, 43 41 39 octets

K*\#+2QKVvzp<*QXX*dyivzQN\\_hN\/Q\#\#)K

Essayez-le en ligne: Pyth Compiler / Executor . Saisissez les nombres dans l'ordre suivant: hauteur première ligne, largeur deuxième ligne.

Merci à isaacg, qui a aidé à économiser deux octets.

Explication:

Ma solution ne trace pas le laser, elle utilise un motif simple qui inclut le gcd. Si m, nsont les dimensions de la boîte, laissez d = gcd(m, n). La taille du motif est exactement 2*d x 2*d.

Par exemple, le motif répétitif pour 7 5

#########
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#/\/\/\/#
#\/\/\/\#
#########

est

\/
/\

( gcd(7, 5) = 1, la taille du motif est 2 x 2)

Et le motif répétitif pour 22 6

########################
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
# /\  /\  /\  /\  /\  /#
#/  \/  \/  \/  \/  \/ #
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
########################

est

\  /
 \/ 
 /\
/  \

( gcd(22, 6) = 2, la taille du motif est 4 x 4)

Ma solution fait la chose suivante pour chacune des lignes: elle génère simplement une ligne du motif, la répète plusieurs fois et la coupe à la fin pour qu'elle rentre dans la boîte.

K*\#+2QK   implicit: Q is the second input number (=width)
K          K = 
 *\#+2Q        "#" * (2 + Q)
       K   print K (first line)

Vvzp<*QXX*dyivzQN\\_hN\/Q\#\#)K  implicit: vz is the first input number (=height)
VQ                               for N in [0, 1, ..., vz-1]:
           ivzQ                             gcd(vz,Q)
          y                               2*gcd(vz,Q)
        *d                           string with 2*gcd(vz,Q) space chars
       X       N\\                   replace the Nth char with \
      X           _hN\/              replace the -(N+1)th char with /
    *Q                               repeat Q times
   <                   Q           only use the first Q chars
  p                     \#\#       print "#" + ... + "#"
                            )    end for
                             K   print K
Jakube
la source
Étant donné que les Xsupports « affectation » à des chaînes, vous pouvez changer m\ pour *det enlever s.
isaacg
@isaacg Bon appel. J'ai pensé à utiliser *\ au lieu de m\ peu de temps, mais jetez-le car il a la même taille. Je n'ai pas pensé à la variable det à l'inutile s.
Jakube
11

C, 256 octets

f(w,h){int i,j,x=1,y=1,v=1,u=1;char b[h+2][w+3];for(i=0;i<w+3;i++)for(j=0;j<h+2;j++)b[j][i]=!i||!j||i>w||j>h?i>w+1?0:35:32;while((x||y)&&(x<=w||y<=h))v=x&&w+1-x?v:(x-=v,-v),u=y&&h+1-y?u:(y-=u,-u),b[y][x]=v/u<0?47:92,x+=v,y+=u;for(i=0;i<h+2;i++)puts(b[i]);}

Je peux probablement obtenir moins de 200, et j'ajouterai une explication plus tard, mais je pourrais avoir un document dû dans quelques heures que je devrais faire à la place.

BrainSteel
la source
27
Les faux points Internet valent plus qu'un diplôme d'études, j'en suis sûr.
Adam Davis
230 octets
plafondcat
5

J, 85 octets

Soit g = gcd(w,h). La fonction remplit les éléments d'une w/g by h/gmatrice avec des g by gtuiles, ayant des /«et \» dans leurs diagonales et anti-diagonales. Le tableau 4D résultant est défilé en 2D (l'intérieur de la boîte) puis entouré de #. (Les nombres 0 1 2 3sont utilisés à la place de [space] / \ #et les nombres sont modifiés en caractères à la fin.)

Un calcul direct basé sur la position des coordonnées internes pourrait peut-être donner une solution un peu plus courte.

' \/#'echo@:{~3,.~3,.3,~3,,$[:,[:,"%.0 2 1 3|:((,:2*|.)@=@i.@+.){~[:(2&|@+/&:i.)/,%+.

Usage:

   6 (' \/#'echo@:{~3,.~3,.3,~3,,$[:,[:,"%.0 2 1 3|:((,:2*|.)@=@i.@+.){~[:(2&|@+/&:i.)/,%+.) 22
########################
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
# /\  /\  /\  /\  /\  /#
#/  \/  \/  \/  \/  \/ #
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
########################

Essayez-le en ligne ici.

randomra
la source
0

Desmos Calculator - Non en concurrence pour aider à approfondir les connaissances

Essayez-le en ligne!

Contributions:

h as height of box, with 0-indexing
w as width of box, with 0-indexing

Intermédiaires:

Let b = gcd(h,w),
Let c = |b-h%2b| Or |b-mod(h,2b)|

Formule, abrégée:

(|b-(x+y)%2b|-c)(|b-(x-y)%2b|-c)=0

Les sorties:

x as x position, 0-indexed, where the ball will land when released
y as y position, 0-indexed, where the ball will land when released

Comment ça marche:

(|b-(x+y)%2b|-c)*(|b-(x-y)%2b|-c)=0
                ^ OR operation - |b-(x+y)%2b|-c=0 or |b-(x-y)%2b|-c=0
|b-(x+/-y)%2b|-c = 0
|b-(x+/-y)%2b| = c
|b-(x+/-y)%2b| = c means (b-(x+/-y))%2b = + or -c 
b-(x+/-y)%2b = +/- c -> b +/- c = (x+/-y)%2b -> (x+/-y) = n*2*b + b +/- c 
Where n is integer.  This will force patterns to repeat every 2b steps in x and y.  
Initial pattern n=0: (x +/- y) = b +/- c -> y = +/- x + b +/- c
In the x positive and y positive plane only, these correspond to lines of positive and 
negative slope, set at intercept b, offset by c on either side.

Le programme ne répond pas au critère final - générer de l'art ASCII de la boîte et des lignes, donc je soumets comme non concurrentiel des informations pour aider les autres à relever le défi. Notez que pour que Desmos fonctionne lorsque c = 0 ou c = b, un petit facteur de décalage de 0,01 a été introduit, car Desmos semble avoir des limites de Mod (A, B) de (0, B) au lieu de [0, B )

marque
la source