ASCII-Doodling: Laser in einer Box

31

Manchmal zeichne ich beim Kritzeln ein Rechteck, beginne mit einer Diagonale an einer der Ecken und zeichne dann einfach eine Linie aus, indem ich sie "reflektiere", wenn ich auf eine Seite des Rechtecks ​​treffe. Ich mache so weiter, bis ich eine andere Ecke des Rechtecks ​​getroffen habe (und hoffe, dass das Seitenverhältnis meines Rechtecks ​​nicht irrational war;)). Das ist, als würde man den Weg eines Lasers in eine Kiste verfolgen. Das Ergebnis soll mit ASCII-Kunst erzeugt werden.

Betrachten Sie als Beispiel eine Box mit Breite 5und Höhe 3. Wir werden immer in der oberen linken Ecke beginnen. Das #markiert die Begrenzung der Box. Beachten Sie, dass sich Breite und Höhe auf die Innenmaße beziehen.

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

Die Herausforderung

Angesichts der (positiven) Breite und Höhe der Box sollten Sie das Endergebnis der Laserverfolgung erzielen. Sie können ein Programm oder eine Funktion schreiben, indem Sie die Eingabe über STDIN (oder die nächstgelegene Alternative), das Befehlszeilenargument oder das Funktionsargument vornehmen und das Ergebnis über STDOUT (oder die nächstgelegene Alternative) oder über Funktionsrückgabewerte oder -argumente ausgeben.

Sie können für die Eingabe ein beliebiges Listen-, Zeichenfolge- oder Zahlenformat verwenden. Die Ausgabe muss eine einzelne Zeichenfolge sein (es sei denn, Sie drucken sie nach STDOUT, was Sie natürlich schrittweise tun können). Dies bedeutet auch, dass Sie zuerst die Höhe und dann die Breite eingeben können. Geben Sie einfach das genaue Eingabeformat in Ihrer Antwort an.

In keiner Zeile der Ausgabe darf ein führender oder nachfolgender Leerraum vorhanden sein. Optional können Sie eine einzelne nachgestellte Newline ausgeben.

Sie müssen Raum nutzen, /, \und #und die Testfälle genau wie dargestellt reproduzieren.

Testfälle

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

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

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

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

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

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

22 6
########################
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
# /\  /\  /\  /\  /\  /#
#/  \/  \/  \/  \/  \/ #
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
########################
Martin Ender
quelle
1
Vielleicht ist es eine schöne Folgefrage, diese Herausforderung mit willkürlich geformten Kisten und Startpunkten zu meistern, wenn diese einmal ihren Lauf genommen hat.
Sanchises
@sanchises Ich hatte das tatsächlich in Betracht gezogen (und könnte es immer noch posten), aber ich entschied mich für das Rechteck in der Hoffnung, dass jemand eine explizite Formel finden könnte. Ich habe auch mehrere Startpunkte in Betracht gezogen, Xdie für Überfahrten notwendig wären. Vielleicht nächstes Mal. ;)
Martin Ender
2
Relevant: i.imgur.com/6tXrIfw.webm
orlp
Dies wäre perfekt für einen Animationspunkt. "Animieren Sie 1 Burst (einen Schrägstrich) 1 Zyklus / endlos)"
Martijn

Antworten:

20

Pyth, 43 41 39 Bytes

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

Probieren Sie es online aus: Pyth Compiler / Executor . Geben Sie die Zahlen in der folgenden Reihenfolge ein: Höhe erste Zeile, Breite zweite Zeile.

Danke an isaacg, der geholfen hat, zwei Bytes zu sparen.

Erläuterung:

Meine Lösung verfolgt den Laser nicht, sondern verwendet ein einfaches Muster, das den gcd enthält. Wenn m, ndie Maße der Box sind, lassen Sie d = gcd(m, n). Die Größe des Musters ist genau 2*d x 2*d.

ZB das Wiederholungsmuster für 7 5

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

ist

\/
/\

( gcd(7, 5) = 1, Größe des Musters ist 2 x 2)

Und das sich wiederholende Muster für 22 6

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

ist

\  /
 \/ 
 /\
/  \

( gcd(22, 6) = 2, Größe des Musters ist 4 x 4)

Meine Lösung macht für jede der Linien folgendes: Sie erzeugt einfach eine Linie des Musters, wiederholt es einige Male und schneidet es am Ende so, dass es in die Box passt.

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
quelle
Da XTräger „Zuordnen“ in Strings, können Sie ändern m\ zu *dund entfernen s.
Isaacg
@isaacg Guter Anruf. Ich dachte darüber nach, *\ anstatt m\ kurz zu verwenden, aber verwerfe es, weil es die gleiche Größe hat. Ich habe nicht an die Variable dund das Unnötige gedacht s.
Jakube
11

C 256 Bytes

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

Ich kann das wahrscheinlich unter 200 bekommen, und ich werde später eine Erklärung hinzufügen, aber vielleicht habe ich in ein paar Stunden eine Arbeit, die ich stattdessen machen sollte.

BrainSteel
quelle
27
Gefälschte Internetpunkte sind mehr wert als ein Bildungsabschluss, da bin ich mir sicher.
Adam Davis
230 Bytes
Ceilingcat
5

J, 85 Bytes

Lassen g = gcd(w,h). Die Funktion füllt die Elemente einer w/g by h/gMatrix mit g by gKacheln mit /und \in ihrer Diagonale und Antidiagonale. Das resultierende 4D-Array wird in ein 2D-Array (das Innere der Box) zerlegt und dann mit #'s umgeben. (Die Zahlen 0 1 2 3werden anstelle von verwendet [space] / \ #und die Zahlen werden am Ende in Zeichen geändert.)

Eine direkte positionsbasierte Berechnung der Innenkoordinate könnte möglicherweise zu einer etwas kürzeren Lösung führen.

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

Verwendung:

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

Probieren Sie es hier online aus.

randomra
quelle
0

Desmos Calculator - nicht konkurrierend, um weiterführendes Wissen zu verbessern

Probieren Sie es online!

Eingänge:

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

Zwischenprodukte:

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

Formel, abgekürzt:

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

Ausgänge:

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

Wie es funktioniert:

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

Das Programm erfüllt nicht das endgültige Kriterium - die Erzeugung von ASCII-Zeichen in Form von Rahmen und Linien. Daher werde ich Informationen als nicht wettbewerbsfähig einreichen, um anderen bei der Bewältigung der Herausforderung zu helfen. Damit Desmos funktioniert, wenn c = 0 oder c = b ist, wurde ein kleiner Versatzfaktor von 0,01 eingeführt, da Desmos anscheinend die Grenzen von Mod (A, B) von (0, B) anstelle von [0, B aufweist )

Kennzeichen
quelle