Argyle ASCII ст


27

Напишіть програму (або функцію), яка приймає додатне ціле число.

Якщо введення є 1, роздрукуйте (або поверніть) два алмази, розташовані поруч, кожен із довжиною сторони 1 косою рисою:

/\/\
\/\/

Для кожного входу Nбільше 1 подивіться на вихідN-1 та для кожної пари сусідніх алмазів, вставте між ними новий ромб, довжина сторони якого становить суму бічних довжин двох сусідів. Роздрукуйте (або поверніть) цей новий алмазний візерунок.

Отже, коли 2вводимо, ми дивимось на вихід 1та бачимо, що є два сусідніх діаманта, обидва з бічною довжиною 1. Отже, вставляємо між ними 2 (1 + 1) ромб між ними:

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

Для введення 3ми дивимось на вихід 2і додаємо два алмази довжиною сторони 3 (1 + 2 та 2 + 1) між двома парами сусідніх алмазів:

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

Продовжуючи шаблон, вихід для 4:

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

І так далі.

Ваші виходи можуть мати пробіли у будь-яких рядках, але лише до одного кінцевого нового рядка (і жодних нових рядків).

Виграє найкоротший код у байтах.


1
Відповідна OEIS: oeis.org/A002487 .
orlp

Відповіді:


8

Pyth, 50 49 байт

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

Демонстрація

Пояснення:

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.

1
Які шанси? Я також точно маю u.iGsM.:G2tQjT9своє (часткове) рішення. Я ніколи не дивився на вашу відповідь ...
orlp

2
@orlp Часто є лише один найкращий спосіб зробити щось.
isaacg

5

Загальний Лісп, 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))))))

Приклад

(funcall *fun* 4)

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

Безумовно

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

3

CJam, 59 58 57 байт

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

Дякуємо @ MartinBüttner за те, що виграли 1 байт.

Спробуйте його в Інтернеті в інтерпретаторі CJam .

Ідея

Наприклад, для введення 3 ми генеруємо

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

обертанням струни  \ та заміни деяких косих косої риски косою рисою.

Потім ми блискаємо отриманий масив (транспоніруємо рядки та стовпці), щоб отримати нижню половину потрібного виводу.

Верхня половина - байт на один байт, рівний нижній половині у зворотному напрямку.

Код

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.

1

Ред. 1: Рубін 170

Новий метод уникнення створення великого алмазу та скорочення.

->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""}}

Випуск 0: Рубін, 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 ""}}

Розміри алмазів розраховуються відповідно до відношення повторення з https://oeis.org/A002487 Таким чином, ми робимо масив, aщо містить усі елементи для всіх рядків від 1 до n. Нас цікавлять лише останні 1<<n-1елементи (Ruby дозволяє нам отримувати їх з масиву за допомогою негативних індексів, -1 - останній елемент масиву), а також inital1 з позиції 0.

Рядок за рядком і ромб за алмазом ми малюємо рядок символів для найбільшого ромба, потім вирізаємо середні стовпчики, щоб отримати рядок для потрібного алмазу. Випуск 1 коротший, але мені сподобався цей метод.

Модульна арифметика використовується для обгортання так, що той самий вираз додає все /безпосередньо, а також один вираз додає все\ безпосередньо.

Ungolfed в тестовій програмі

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)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.