Seni Argyle ASCII

27

Tulis program (atau fungsi) yang menggunakan bilangan bulat positif.

Jika inputnya adalah 1, cetak (atau kembalikan) dua berlian yang berdekatan berdampingan, masing-masing dengan panjang sisi 1 garis miring:

/\/\
\/\/

Untuk setiap input yang Nlebih besar dari 1, lihat output untuk N-1dan untuk setiap pasangan berlian tetangga, masukkan berlian baru di antara mereka yang panjang sisi adalah jumlah dari panjang sisi kedua tetangga. Cetak (atau kembalikan) pola berlian baru ini.

Jadi ketika 2input, kita melihat output untuk 1dan dapat melihat bahwa ada dua berlian tetangga, keduanya dengan panjang sisi 1. Jadi kita memasukkan panjang sisi 2 (1 + 1) berlian di antaranya:

   /\
/\/  \/\
\/\  /\/
   \/

Untuk input, 3kita melihat output untuk 2dan menambahkan dua berlian dengan panjang sisi 3 (1 + 2 dan 2 + 1) di antara dua pasang berlian tetangga:

    /\        /\
   /  \  /\  /  \
/\/    \/  \/    \/\
\/\    /\  /\    /\/
   \  /  \/  \  /
    \/        \/

Melanjutkan polanya, output untuk 4adalah:

                    /\            /\
     /\            /  \          /  \            /\
    /  \    /\    /    \        /    \    /\    /  \
   /    \  /  \  /      \  /\  /      \  /  \  /    \
/\/      \/    \/        \/  \/        \/    \/      \/\
\/\      /\    /\        /\  /\        /\    /\      /\/
   \    /  \  /  \      /  \/  \      /  \  /  \    /
    \  /    \/    \    /        \    /    \/    \  /
     \/            \  /          \  /            \/
                    \/            \/

Dan seterusnya.

Output Anda mungkin memiliki spasi tambahan pada garis apa pun tetapi hanya hingga satu baris tambahan (dan tidak ada baris baru).

Kode terpendek dalam byte menang.

Hobi Calvin
sumber
1
OEIS yang relevan: oeis.org/A002487 .
orlp

Jawaban:

8

Pyth, 50 49 byte

L.rR"\/"_bjbyK.tsm+Jm+*\ k\\dyJu.iGsM.:G2tQjT9djK

Demonstrasi

Penjelasan:

L.rR"\/"_bjbyK.tsm+Jm+*\ k\\dyJu.iGsM.:G2tQjT9djK
                                                     Implicit:
                                                     Q = eval(input())
                                                     T = 10
                                                     d = ' '
                                                     b = '\n'
L                                                    def y(b): return
 .rR"\/"                                             Swap \ and / in
        _b                                           reversed input.
                                                     This effectively vertically
                                                     mirrors the input.
                               u                     Apply the function repeatedly
                                           jT9       Starting with [1, 1]
                                         tQ          and repeating Q - 1 times
                                .iG                  interlace G (input) with
                                     .:G2            All 2 element substrings of G
                                   sM                mapped to their sums.
                 m                                   map over these values
                                                     implicitly cast to ranges
                    m       d                        map over the range values
                                                     impicitly cast to ranges
                     +*\ k\\                         to k spaces followed by
                                                     a backslash.
                   J                                 Save to J, which is roughly:
                                                     \
                                                      \
                  +          yJ                      And add on y(J), giving
                                                     \
                                                      \
                                                      /
                                                     /
                s                                    Combine the half diamonds
                                                     into one list.
              .t                              d      Traspose, filling with ' '.
             K                                       Save to K, giving
                                                     something like:
                                                     \  /
                                                      \/
            y                                        Vertically mirror.
          jb                                         Join on newlines and print.
                                               jK    Join K on (implicitly)
                                                     newlines and print.
isaacg
sumber
1
Apa peluangnya? Saya juga persis memiliki u.iGsM.:G2tQjT9di saya (parsial) solusi. Saya tidak pernah melihat jawaban Anda ...
orlp
2
@orlp Seringkali hanya ada satu cara terbaik untuk melakukan sesuatu.
isaacg
5

Common Lisp, 425

(labels((a(n)(if(> n 1)(loop for(x y)on(a(1- n))by #'cdr collect x when y collect(+ x y))'(1 1))))(lambda(~ &aux(l(a ~))(h(apply'max l))(w(*(apply'+ l)2))(o(* 2 h))(m(make-array(list o w):initial-element #\ ))(x 0)(y h))(labels((k(^ v)(setf(aref m y x)^(aref m(- o y 1)x)v)(incf x))(d(i)(when(plusp i)(k #\\ #\/)(incf y)(d(1- i))(decf y)(k #\/ #\\))))(mapc #'d l))(dotimes(j o)(fresh-line)(dotimes(i w)(princ(aref m j i))))))

Contoh

(funcall *fun* 4)

                    /\            /\                    
     /\            /  \          /  \            /\     
    /  \    /\    /    \        /    \    /\    /  \    
   /    \  /  \  /      \  /\  /      \  /  \  /    \   
/\/      \/    \/        \/  \/        \/    \/      \/\
\/\      /\    /\        /\  /\        /\    /\      /\/
   \    /  \  /  \      /  \/  \      /  \  /  \    /   
    \  /    \/    \    /        \    /    \/    \  /    
     \/            \  /          \  /            \/     
                    \/            \/                    

Tidak disatukan

(labels
    ((sequence (n)
       (if (> n 1)
           (loop for(x y) on (sequence (1- n)) by #'cdr
                 collect x
                 when y
                   collect(+ x y))
           '(1 1))))
  (defun argyle (input &aux
                  (list (sequence input))
                  (half-height (apply'max list))
                  (width (* (apply '+ list) 2))
                  (height (* 2 half-height))
                  (board (make-array
                          (list height width)
                          :initial-element #\ ))
                  (x 0)
                  (y half-height))
    (labels ((engrave (^ v)
               (setf (aref board y              x) ^ ;; draw UP character
                     (aref board (- height y 1) x) v ;; draw DOWN character (mirrored)
                     )
               (incf x) ;; advance x
               )
             (draw (i)
               (when (plusp i)
                 (engrave #\\ #\/)  ;; write opening "<" shape of diamond
                 (incf y)
                 (draw (1- i))   ;; recursive draw
                 (decf y)
                 (engrave #\/ #\\)  ;; write closing ">" shape of diamond
                 )))
      ;; draw into board for each entry in the sequence
      (mapc #'draw list))

    ;; ACTUAL drawing
    (dotimes(j height)
      (fresh-line)
      (dotimes(i width)
        (princ (aref board j i))))
    board))
coredump
sumber
3

CJam, 59 58 57 byte

YXbri({{_2$+\}*]}*:,_:|,S*0'\tf{fm>_W%'\f/'/f*}:+zN*_W%N@

Terima kasih kepada @ MartinBüttner untuk bermain golf 1 byte.

Cobalah online di juru bahasa CJam .

Ide

Untuk input 3 , misalnya, kami hasilkan

\  
/  
\  
 \ 
  \
  /
 / 
/  
\  
 \ 
 / 
/  
\  
 \ 
  \
  /
 / 
/  
\  
/  

dengan memutar senarnya  \ dan mengganti beberapa garis miring terbalik dengan garis miring.

Kemudian, kita zip array yang dihasilkan (transpos baris dan kolom) untuk mendapatkan bagian bawah dari output yang diinginkan

Bagian atas adalah byte per byte sama dengan bagian bawah secara terbalik.

Kode

YXb     e# Push A := [1 1] and 2 in unary.
ri(     e# Read an integer fro STDIN and subtract 1.
{       e# Do the following that many times:
  {     e#   For each I in A but the first:
    _2$ e#     Push a copy of I and the preceding array element.
    +\  e#     Compute the sum of the copies and swap it with I.
  }*    e#
  ]     e#   Collect the entire stack in an array.
}*      e#
:,      e# Replace each I in A with [0 ... I-1].
_       e# Push a copy of A.
:|      e# Perform set union of all the ranges.
,S*     e# Get the length (highest I in A) and push a string of that many spaces.
0'\t    e# Replace the first space with a backslash.
f{      e# For each range in A, push the generated string; then:
  fm>   e#   Rotate the string by each amount in the array.
  _W%   e#   Push a reversed copy of the resulting array of strings.
  '\f/  e#   In each string, split at backslashes.
  '/f*  e#   Join each string, separating with slashes.
}       e#
:+      e# Concatenate the resulting arrays of strings.
zN*     e# Zip and join, separating by linefeeds.
_W%     e# Push a reversed copy of the string.
N@      e# Push a linefeed and rotate the original string on top of it.
Dennis
sumber
1

Rev 1: Ruby 170

Metode baru menghindari membuat berlian besar dan mengurangi.

->n{a=[1]
m=1<<n-1
(m-1).times{|i|a<<a[i]<<a[i]+a[i+1]}
(-b=a.max).upto(b-1){|j|0.upto(m){|i|d=' '*q=a[-i]*2
(j*2+1).abs<q&&(d[j%q]=?\\;d[-1-j%q]=?/)   
print d}
puts""}}

Rev 0: Ruby, 187

->n{a=[1]
m=1<<n-1
(m-1).times{|i|a<<a[i]<<a[i]+a[i+1]}
(2*b=a.max).times{|j|
0.upto(m){|i|d=' '*b*2;d[(b+j)%(b*2)]='\\';d[(b-1-j)%(b*2)]=?/
r=b-a[-i]
d.slice!(b-r,r*2)
print d}
puts ""}}

Ukuran berlian dihitung sesuai dengan hubungan perulangan dari https://oeis.org/A002487 Jadi kami membuat array yang aberisi semua elemen untuk semua baris dari 1 hingga n. Kami hanya tertarik pada 1<<n-1elemen terakhir (Ruby memungkinkan kami untuk mendapatkannya dari array menggunakan indeks negatif, -1 menjadi elemen terakhir dalam array), ditambah inital1 dari posisi 0.

Baris demi baris dan berlian demi berlian, kami menggambar deretan karakter untuk berlian terbesar, kemudian memotong kolom tengah untuk mendapatkan baris untuk berlian yang dibutuhkan. Rev 1 lebih pendek, tetapi saya menyukai metode ini.

Aritmatika modular digunakan untuk membungkus sehingga ekspresi yang sama menambahkan semua / secara langsung dan juga satu ekspresi menambahkan semua \secara langsung.

Tidak digabungkan dalam program uji

f=->n{
  a=[1]
  m=1<<n-1
  (m-1).times{|i|a<<a[i]<<a[i]+a[i+1]}                   #concatenate a[i] and a[i]+a[i+1] to the end of a
    (2*b=a.max).times{|j|                                #run through lines (twice the largest number in a
      0.upto(m){|i|                                      #run through an initial '1' plus the last m numbers in a
      d=' '*b*2;d[(b+j)%(b*2)]='\\';d[(b-1-j)%(b*2)]=?/  #d is the correct string for this line of the largest diamond
      r=b-a[-i]                                          #calculate number of characters to be deleted from middle of d
      d.slice!(b-r,r*2)                                  #and delete them
      print d                                            #print the result
    }
    puts ""                                              #at the end of the line, print a newline
  }
}

f.call(gets.to_i)
Level River St
sumber