ASCII Doodling: Bir Kutuda Lazer


31

Bazen karalamalar yaparken bir dikdörtgen çizerim, köşelerden birinden köşegen bir köşeyle başlarım ve sonra dikdörtgenin bir tarafına çarptığımda "yansıtarak" bir çizgi çizerim. Dikdörtgenin başka bir köşesine gelinceye kadar devam ediyorum (ve dikdörtgemin en boy oranının irrasyonel olmadığını umuyorum;). Bu, bir lazer parlamasına bir kutuya giden yolu bulmak gibi. Bunun sonucunu ASCII sanatıyla üreteceksin.

Örnek olarak, genişlik 5ve yükseklik bir kutu düşünün 3. Her zaman sol üst köşeden başlayacağız. #İşaretleri kutusunun sınırı. Genişlik ve yüksekliğin iç boyutlara atıfta bulunduğuna dikkat edin.

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

Meydan okuma

Kutunun (pozitif) genişliği ve yüksekliği göz önüne alındığında, lazerin izlenmesinin nihai sonucunu vermelisiniz. STDIN (veya en yakın alternatif), komut satırı argümanı, işlev argümanı ile giriş alarak bir program veya işlev yazabilir, sonucu STDOUT (veya en yakın alternatif) veya işlev dönüş değerleri veya argümanları aracılığıyla çıktı alabilirsiniz.

Giriş için herhangi bir uygun liste, dize veya sayı biçimini kullanabilirsiniz. Çıktı tek bir dize olmalıdır (yavaş yavaş yapabileceğiniz STDOUT'a yazdırmazsanız). Bu, ayrıca önce yüksekliği ve ikinci genişliği alabileceğiniz anlamına gelir - cevabınıza tam giriş biçimini belirtmeniz yeterlidir.

Çıktının herhangi bir satırında öncü veya iz bırakmayan boşluk olmamalıdır. İsteğe bağlı olarak tek bir izleyen yeni satır gönderebilirsiniz.

Sen alanı kullanabilir, gerekir /, \ve #ve tam olarak gösterilen test durumları yeniden.

Test Kılıfları

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

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

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

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

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

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

22 6
########################
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
# /\  /\  /\  /\  /\  /#
#/  \/  \/  \/  \/  \/ #
#\  /\  /\  /\  /\  /\ #
# \/  \/  \/  \/  \/  \#
########################

1
Belki de güzel bir takip sorusu, bu bir kez onun yolunu izlemiştir, bu zorluğu keyfi şekillendirilmiş kutular ve başlangıç ​​noktalarıyla yapmaktır.
Sanchises,

@sanchises Bunu gerçekten düşünmüştüm (ve hala gönderebilirdim), ancak birisinin açık bir formülle gelebileceğini umarak dikdörtgeni kullanmaya karar verdim. Ayrıca Xgeçişler için gerekli olacak şekilde birden fazla başlangıç ​​noktası düşünüyordum . Belki gelecek sefere. ;)
Martin Ender


Bu bir animasyon noktası için mükemmel olurdu. "1 patlamayı canlandır (bir eğik çizgi) 1 devir / sonsuz)"
Martijn

Yanıtlar:


20

Pyth, 43 41 39 bayt

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

Çevrimiçi deneyin: Pyth Derleyici / Yürütücü . Numaraları aşağıdaki sırayla girin: yükseklik birinci satır, genişlik ikinci satır.

İki bayt kurtarmaya yardımcı olan isaacg sayesinde.

Açıklama:

Benim çözümüm lazeri izlemiyor, gcd içeren basit bir kalıp kullanıyor. Eğer m, nkutunun boyutları, let d = gcd(m, n). Desenin boyutu tam olarak 2*d x 2*d.

Örneğin, yinelenen model 7 5

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

olduğu

\/
/\

( gcd(7, 5) = 1, desenin boyutu 2 x 2)

Ve yinelenen desen 22 6

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

olduğu

\  /
 \/ 
 /\
/  \

( gcd(22, 6) = 2, desenin boyutu 4 x 4)

Çözümüm, her bir satır için aşağıdakileri yapar: basitçe, desenin bir satırını oluşturur, birkaç kez tekrarlar ve sonunda kutuya sığması için keser.

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

Yana Xdestekleri dizelere "atama", değiştirebileceğiniz m\ için *dve kaldırmak s.
isaacg

@ isaacg İyi arama. Kısaca kullanmak *\ yerine düşündüm m\ , ama aynı boyutta olduğu için onu atın. Değişken dve gereksiz olduğunu düşünmedim s.
Jakube

11

C, 256 bayt

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

Muhtemelen bunu 200'ün altında bulabilirim ve daha sonra bir açıklama ekleyeceğim, ancak birkaç saat içinde yapmam gereken bir kağıt olabilir .


27
Sahte internet noktaları bir eğitim derecesinden daha değerli, bundan eminim.
Adam Davis


5

J, 85 bayt

Let g = gcd(w,h). Fonksiyon elemanlarını doldurur w/g by h/gile matris g by gsahip olan, fayans /'in ve \' kendi çapraz ve anti-diyagonal olarak s. Elde edilen 4D dizisi 2D olana (kutunun içi) sürülür ve sonra #s ile çevrilir . (Bunun 0 1 2 3yerine sayılar kullanılır [space] / \ #ve sayılar sonunda karakter olarak değiştirilir.)

İç koordinatın doğrudan pozisyon temelli bir şekilde hesaplanması belki biraz daha kısa bir çözüm sağlayabilir.

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

Kullanımı:

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

Burada çevrimiçi deneyin.


0

Desmos Calculator - Daha Fazla Bilgi Yardımcı Olmak İçin Rekabet Etmeyen

Çevrimiçi deneyin!

girişler:

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

Ara maddeler:

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

Kısaltılmış formül:

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

Çıktılar:

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

Nasıl çalışır:

(|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 son kriteri karşılamıyor - ASCII kutu ve çizgiler sanatı üretiyor, bu yüzden diğerlerinin zoru tamamlamalarına yardımcı olmak için bilgi için rekabetçi olmayan bir teklif veriyorum. Desmos'un c = 0 veya c = b olduğunda çalışmasını sağlamak için, Desmos'un [0, B) yerine (0, B) Mod (A, B) sınırları gözüktüğü için, 0.01 değerinde küçük bir ofset faktörü getirildiğini unutmayın. )

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.