ASCII Doodling: Laser in a Box

31

Czasami, gdy rysuję, rysuję prostokąt, zaczynam od przekątnej z jednego z rogów, a następnie po prostu wykreślam linię, „odbijając” ją, gdy uderzę w bok prostokąta. Kontynuuję to, dopóki nie trafię w kolejny narożnik prostokąta (i mam nadzieję, że proporcje mojego prostokąta nie były irracjonalne;)). To jest jak wytyczenie ścieżki lasera świecącego do pudełka. Wytworzysz to dzięki sztuce ASCII.

Jako przykład rozważmy pole szerokości 5i wysokości 3. Zawsze zaczniemy od lewego górnego rogu. Te #znaki graniczne z pudełka. Pamiętaj, że szerokość i wysokość odnoszą się do wymiarów wewnętrznych.

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

Wyzwanie

Biorąc pod uwagę (dodatnią) szerokość i wysokość pudełka, powinieneś uzyskać końcowy wynik śledzenia lasera. Możesz napisać program lub funkcję, przyjmując dane wejściowe za pośrednictwem STDIN (lub najbliższej alternatywy), argument wiersza poleceń, argument funkcji i wypisz wynik za pomocą STDOUT (lub najbliższej alternatywy) lub za pomocą zwracanych wartości lub argumentów funkcji.

Do wprowadzenia możesz użyć dowolnego wygodnego formatu listy, łańcucha lub liczby. Wynik musi być pojedynczym ciągiem znaków (chyba że wydrukujesz go do STDOUT, co oczywiście możesz zrobić stopniowo). Oznacza to również, że możesz wziąć najpierw wysokość, a szerokość drugą - po prostu określ dokładny format wejściowy w swojej odpowiedzi.

W żadnym wierszu wyniku nie może być ani początkowych ani końcowych białych znaków. Opcjonalnie możesz wypisać jeden końcowy znak nowej linii.

Musisz wykorzystać przestrzeń, /, \a #i rozmnażać przypadków testowych dokładnie tak, jak pokazano na rysunku.

Przypadki testowe

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

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

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

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

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

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

22 6
########################
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
# /\  /\  /\  /\  /\  /#
#/  \/  \/  \/  \/  \/ #
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
########################
Martin Ender
źródło
1
Być może miłym pytaniem uzupełniającym, gdy już skończy się ten kurs, jest wykonanie tego wyzwania z dowolnie ukształtowanymi polami i punktami początkowymi.
Sanchises
@sanchises Właściwie to rozważyłem (i nadal mogę to opublikować), ale zdecydowałem się pójść z prostokątem w nadziei, że ktoś może wymyślić wyraźną formułę. Zastanawiałem się również nad wieloma punktami początkowymi, które Xbyłyby konieczne do przejazdów. Może następnym razem. ;)
Martin Ender
2
Ważne: i.imgur.com/6tXrIfw.webm
orlp
Byłoby to idealne do punktu animacji. „Animuj 1 serię (jeden ukośnik) 1 cykl / nieskończony)”
Martijn

Odpowiedzi:

20

Pyth, 43 41 39 bajtów

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

Wypróbuj online: Pyth Compiler / Executor . Wprowadź liczby w następującej kolejności: wysokość pierwszej linii, szerokość drugiej linii.

Dzięki isaacg, który pomógł zaoszczędzić dwa bajty.

Wyjaśnienie:

Moje rozwiązanie nie śledzi lasera, używa prostego wzoru zawierającego gcd. Jeśli m, nsą wymiary pudełka, niech d = gcd(m, n). Rozmiar wzoru jest dokładnie 2*d x 2*d.

Np. Powtarzający się wzór dla 7 5

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

jest

\/
/\

( gcd(7, 5) = 1rozmiar wzoru to 2 x 2)

I powtarzający się wzór dla 22 6

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

jest

\  /
 \/ 
 /\
/  \

( gcd(22, 6) = 2rozmiar wzoru to 4 x 4)

Moje rozwiązanie wykonuje następujące czynności dla każdej linii: po prostu generuje jedną linię wzoru, powtarza ją kilka razy i wycina na końcu, aby pasowała do pudełka.

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
źródło
Ponieważ Xwsporniki „przypisania” do strun, można zmienić m\ , aby *di usunąć s.
isaacg,
@isaacg Dobra rozmowa. Myślałem o użyciu *\ zamiast m\ krótko, ale odrzuć go, ponieważ ma ten sam rozmiar. Nie myślałem o zmiennej di niepotrzebnych s.
Jakube,
11

C, 256 bajtów

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

Prawdopodobnie mogę dostać to pod 200, a dodam wyjaśnienia później, ale może mieć dokument ze względu na kilka godzin powinienem robić zamiast tego.

BrainSteel
źródło
27
Fałszywe punkty internetowe są warte więcej niż wykształcenie, jestem tego pewien.
Adam Davis,
230 bajtów
pułap cat
5

J, 85 bajtów

Let g = gcd(w,h). Funkcja wypełnia elementy aw/g by h/g osnowy z g by gpłytek, o /„S \” S w ich ukośne i anty-przekątnej. Powstała tablica 4D jest zapadnięta w 2D (wewnątrz pudełka), a następnie otoczona przez #'s. (Liczby 0 1 2 3są używane zamiast, [space] / \ #a liczby są zamieniane na znaki na końcu.)

Bezpośrednie obliczenie współrzędnych wewnętrznych oparte na położeniu może być może nieco krótszym rozwiązaniem.

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

Stosowanie:

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

Wypróbuj online tutaj.

randomra
źródło
0

Kalkulator Desmos - nie konkuruje, aby pomóc w dalszej wiedzy

Wypróbuj online!

Wejścia:

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

Produkty pośrednie:

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

Formula, w skrócie:

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

Wyjścia:

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

Jak to działa:

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

Program nie spełnia ostatecznego kryterium - generowania grafiki ASCII pola i linii, więc przesyłam jako niekonkurencyjne informacje, aby pomóc innym w ukończeniu wyzwania. Zauważ, że aby Desmos działał, gdy c = 0 lub c = b, wprowadzono mały współczynnik przesunięcia 0,01, ponieważ Desmos wydaje się mieć granice Mod (A, B) z (0, B) zamiast [0, B )

znak
źródło