Argyle ASCII Art

27

Schreiben Sie ein Programm (oder eine Funktion), das / die eine positive Ganzzahl aufnimmt.

Wenn die Eingabe lautet 1, drucken (oder zurückgeben) Sie zwei nebeneinander liegende Diamanten mit einer Seitenlänge von jeweils 1 Schrägstrich:

/\/\
\/\/

NSehen Sie sich für jeden Eingang, der größer als 1 ist, den Ausgang für N-1jedes Paar benachbarter Diamanten an und fügen Sie einen neuen Diamanten dazwischen ein, dessen Seitenlänge die Summe der Seitenlängen der beiden Nachbarn ist. Drucken Sie dieses neue Rautenmuster aus (oder senden Sie es zurück).

Wenn 2also eingegeben wird, schauen wir auf die Ausgabe 1und können sehen, dass es zwei benachbarte Diamanten gibt, beide mit der Seitenlänge 1. Also fügen wir eine Seitenlänge von 2 (1 + 1) Diamanten dazwischen ein:

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

Als Eingabe betrachten 3wir die Ausgabe nach 2und addieren zwei Diamanten mit der Seitenlänge 3 (1 + 2 und 2 + 1) zwischen die beiden Paare benachbarter Diamanten:

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

Wenn Sie das Muster fortsetzen, 4lautet die Ausgabe für :

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

Und so weiter.

Ihre Ausgaben können Leerzeichen in beliebigen Zeilen enthalten, jedoch nur bis zu einer nachgestellten Zeile (und keine führenden Zeilen).

Der kürzeste Code in Bytes gewinnt.

Calvins Hobbys
quelle
1
Relevante OEIS: oeis.org/A002487 .
Orlp

Antworten:

8

Pyth, 50 49 Bytes

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

Demonstration

Erläuterung:

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
quelle
1
Was sind die Chancen? Ich habe auch genau habe u.iGsM.:G2tQjT9in meiner (Teil-) Lösung. Ich habe deine Antwort nie angeschaut ...
orlp
2
@orlp Es gibt oft nur einen besten Weg, um etwas zu tun.
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))))))

Beispiel

(funcall *fun* 4)

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

Ungolfed

(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))
Core-Dump
quelle
3

CJam, 59 58 57 Bytes

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

Vielen Dank an @ MartinBüttner für das Golfen ab 1 Byte.

Probieren Sie es online im CJam-Interpreter aus .

Idee

Für Eingabe 3 erzeugen wir zum Beispiel

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

durch Drehen der Saite  \und Ersetzen einiger Backslashes durch Slashes.

Dann zippen wir das resultierende Array (transponieren Sie Zeilen und Spalten), um die untere Hälfte der gewünschten Ausgabe zu erhalten.

Die obere Hälfte entspricht Byte für Byte der unteren Hälfte in umgekehrter Reihenfolge.

Code

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
quelle
1

Rev 1: Ruby 170

Neue Methode, die das Erzeugen des großen Diamanten und das Reduzieren vermeidet.

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

Die Größen der Diamanten werden gemäß der Wiederholungsrelation von https://oeis.org/A002487 berechnet. Daher erstellen wir das Array, adas alle Elemente für alle Zeilen von 1 bis enthält n. Wir interessieren uns nur für die letzten 1<<n-1Elemente (Ruby ermöglicht es uns, sie mit negativen Indizes aus dem Array abzurufen, wobei -1 das letzte Element im Array ist) sowie ein Inital 1von Position 0.

Zeile für Zeile und Diamant für Diamant zeichnen wir die Zeichenreihe für den größten Diamanten und schneiden dann die mittleren Spalten aus, um die Zeile für den gewünschten Diamanten zu erhalten. Rev 1 ist kürzer, aber ich mochte diese Methode.

Modulare Arithmetik wird zum Umbrechen verwendet, sodass derselbe Ausdruck alle /direkt und ebenso ein Ausdruck alle \direkt hinzufügt .

Ungolfed im Testprogramm

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
quelle