Yavaş yavaş yakınsak zikzak


23

Girdi olarak tek bir pozitif tek tam sayı göz önüne alındığında, yakınsak bir zikzakı bir dizge listesi, karakter listesi listesi veya yeni satırla ayrılmış bir dizge olarak şu biçimde döndürün:

#
 #
  #
   #
    #
   #
  #
 #
  #
   #
  #

Sen yerini alabilecek #herhangi tutarlı boşluk olmayan karakteri ile. Her satırdaki sondaki boşluk boşluğuna izin verilir ve sondaki yeni satırın izin verilir

Zig-zag sütunda başlar 1ve her satır için bir sütuna, sütuna ulaşana kadar n( ngirdi nerede ) hareket eder. Sonra zikzak orta sütunda ( ) bitinceye kadar iki sınır birbirine yaklaşarak sola 2, sonra sağa n-1, sonra sola hareket eder .3(n+1)/2

Test Kılıfları

Yukarıdaki örnek, test durumudur 5.

Bireysel test durumları şunlardır:

3
#
 #
  #
 #

7
#
 #
  #
   #
    #
     #
      #
     #
    #
   #
  #
 #
  #
   #
    #
     #
    #
   #
  #
   #
    #
   #

1

#

Önde gelen (ancak tutarlı, yani şekil bozmayan) boşluklara izin verilir mi?
Outgolfer Erik,

@EriktheOutgolfer Bunun için hayır diyeceğim.
HyperNeutrino,

Yanıtlar:


15

C (gcc) , 89 bayt

f(n,a,b){puts("0");for(a=n;--a>n/2;)for(b=n-2*a;b<=2*a-n;)printf(" %*d\n",a-abs(b++),0);}

Çevrimiçi deneyin!

Boşluk sayısının sırasını şu şekilde analiz ederek çalışır (n = 7 için):

          0
1 2 3 4 5 6 5 4 3 2 1
    2 3 4 5 4 3 2
        3 4 3

Ve n = 3 için:

  0
1 2 1

Ortadaki sayının ( akoddaki) [n-1, n / 2) arasında olduğunu görebiliriz. Daha sonra, ilk sayı ile orta sayı arasındaki fark şudur:

a  n  b  2a-n
-------------
6  7  5  5
5  7  3  3
4  7  1  1
2  3  1  1

Öyleyse, b[- (2a-n), 2a-n] 'den geçiyorsak , a-abs(b)bize istenen diziyi verecektir. Temel olarak kodun yaptığı budur.





3

Haskell , 72 bayt

g[]=[]
g a=a++g(reverse$init a)
r="#":map(' ':)r
("#":).g.tail.(`take`r)

Çevrimiçi deneyin!

Sonsuz bir listeyi r, #köşenin sol üst köşesinden başlayarak çapraz olarak belirledik.

Daha sonra gişin en iyisini yapan bir fonksiyon tanımlarız . gbir listeyi alır ve art arda tersine çevirir ve liste boş kalana kadar ilk öğesini kaldırır, ardından her eylemin sonucunu birleştirir.

Buradaki ana fonksiyonumuz noktasız bir fonksiyondur. Bu işlev nsonsuz listeden elemanlar alarak başlar r, sonra ilk elemanın kesilmesiyle uygulanır g. Son olarak, başa bir #geri eklemek zorundayız , bunun nedeni, sorunun özelliklerini biraz garip yapmaktır, ilk köşegenin neden her zaman olması gerekenden daha uzun olduğunu bilmiyorum ama öyleyse, aa ekle #.


@nimi yaptığım sona erdi ("#":).g.init.(take r)ama teşekkür!
Buğday Sihirbazı,



2

05AB1E , 6 bayt

LN71SΛ

Çevrimiçi deneyin!

     Λ     use the canvas function with

L          a range list [1 .. input] as lengths for each path 

 N         a "0" as character to be printed 
           (N is the index variable used by loops. If there was no loop yet, its
           default value is 0. By using N, I avoid an extra space between 0 and 71)

  71S      and the directions 7 and 1 (NW and NE), that alternate automatically until
           the range list is finished.

Hayır, önce bunu denedim, ancak silme işlemini yaptığım zaman aralık listesinin bir sonraki öğesiyle devam etmeden önce her iki yönü de çizer S. Böylece çıktı iki kat daha uzun olacaktır. Henüz + ve × hakkında bir şey bilmiyordum. Onları rakamlarla birleştirirken çok ilginç kalıplar yaparlar
Dorian

Ah, gerçekten haklısın. Benim hatam. Bunun olmadan çalıştığını gördüm S, ancak çıktıya yeterince dikkat etmedim ..>.> Ve +ve ×temelde [0,4,4,0,2,6,6,2]ve [1,5,5,1,3,7,7,3]. Ve 8başladığınız orijine sıfırlanacaktır. İşte biraz daha fazla bilgi.
Kevin Cruijssen



1

JavaScript, 127 bayt

Hedefine ( g) ulaşmak için hesaplar . Bu hedefe ulaşıldığında, bir sonraki hedefe geri dönün. Ayrıca her eşit olmayan sayıya Math.round()ekleyerek kullanmaktan kaçınmak için bir numara kullanır 0.5.

f=n=>{c=0;for(i=0;i<n;i++){m=i/2;g=i%2==0?n-m:m+1.5;while(c!=g){c>g?c--:c++;console.log(' '.repeat(c-1)+'#'+' '.repeat(n-c))}}}

f=n=>{c=0;for(i=0;i<n;i++){m=i/2;g=i%2==0?n-m:m+1.5;while(c!=g){c>g?c--:c++;console.log(' '.repeat(c-1)+'#'+' '.repeat(n-c))}}}

f(5);


1

Haskell, 74 bayt

f[x]=[x]
f s=s++tail(f$reverse$tail s)
g n=f[(' '<$[2..x])++"#"|x<-[1..n]]

Çevrimiçi deneyin!

Nasıl çalışır:

    [(' '<$[2..x])++"#"|x<-[1..n]]     -- build the first diagonal, e.g. for n=3:
                                         -- ["#", " #", "  #"]
  f                                      -- call f, which is

f s = s ++                               -- the input list, followed by
           tail                          -- all but the first element of
                f                        -- a recursive call with
                  reverse                -- the reverse of
                          tail s         -- all but the first element of the input 
                                         -- list
f[x]=[x]                                 -- base case: stop if the input list a
                                         -- singleton list

Her özyinelemeli çağrı bir fsonraki köşegen ekler.



1

Kabuğu , 19 bayt

mo`:'#R' ∫`Ṙ¢e1_1tṫ

Çevrimiçi deneyin!

açıklama

Bu biraz tıknaz hissediyor.

mo`:'#R' ∫`Ṙ¢e1_1tṫ  Input is n (e.g. 5)
                  ṫ  Range from input to 1: [5,4,3,2,1]
                 t   Drop first element: [4,3,2,1]
             e1_1    The list [1,-1]
            ¢        repeated infinitely: [1,-1,1,-1,..
          `Ṙ         Clone with respect to the list above: [1,1,1,1,-1,-1,-1,1,1,-1]
         ∫           Cumulative sum: [0,1,2,3,4,3,2,1,2,3,2]
mo                   For each element k (e.g. 3) do this:
      R'             Repeat space k times: "   "
  `:'#               Append '#': "   #"
                     Print implicitly separated by linefeeds.


1

Retina , 71 bayt

.+
$* 
^
:>
 $
:
;{*T`:<>`_#
( ) >(:)|( )<
$1<$2$3
(:)( )<|>( )
$2$1$3>

Çevrimiçi deneyin! Açıklama: İlk üç aşama girişi :> :, :s arasındaki karakter sayısının girdi numarası olduğu forma dönüştürür . Son iki aşama daha sonra s arasında >(veya <sola doğru hareket ederken) zıplar :. Dördüncü aşama, sekmenin gerekli kısımlarını her seferinde basarak sekmeyi çevreler. ;Döngü sonra basılı olan dize durur.


1

05AB1E , 16 bayt

Î<L¤F¦})˜Ôð×X«»

Çevrimiçi deneyin!

açıklama

Î<L               # push 0 and range [1 ... input-1]
   ¤              # get the last element of the list
    F             # that many times do
     Â            # bifurcate
      ¦           # remove the head
       })˜        # end loop and wrap in flattened list
          Ô       # remove consecutive duplicates
           ð×     # repeat space a number of times corresponding to each number in the list
             X«   # append 1 to each
               »  # join on newline

1

K (Kona), 27 bayt

`0:{|x$"#"}'1,,/{1_|x}\-2-!

Bir vektörün başını boşalıncaya kadar arka arkaya ters çevirip bırakarak, alttaki sayısal diziyi üretir.


3
PPCG.SE'ye Hoşgeldiniz! Sırf bildiğiniz gibi, kodunuzu TIO (çevrimiçi deneyin) adlı çevrimiçi bir tercümana koyabilir ve insanların kodunuzu deneyebilmesi için buna bağlayabilirsiniz. tio.run/#k-kona , buraya göndermeniz için size biçimlendirilmiş bir PPCG postası bile sağlayacaktır.
Notts90

0

PHP, 65 bayt

<?while(--$n||$n=$d=--$argn)echo str_pad("X
",2+$x-=$d&1?:-1);?>X

Boru olarak çalıştırın -nFveya çevrimiçi olarak test edin .

açıklama:

İlk tekrar: $nolduğu NULL, bu yüzden --$nhiç bir etkisi ve değerlendirir sahiptir NULL
-> grubu $nve $dönceden indirildiği bağımsız değişken
1. artış $xiçin bile $dtek için, eksiltme $d
2. baskı X, bir satır ve$x boşluk

daha fazla yineleme: azalma $n; vurduğunda 0, önceden azaltılmış argümana sıfırla $n(ve $d)

final: bir tane daha yazdırın X.



0

Python 2, 159 145 141 136 bayt

print"".join([" "*p+"#\n"for p in(lambda l:[sum(l[:i])for i in range(len(l))])(sum([i*[1-i%2*2]for i in range(input())[::-1]],[])+[1])])

Bu soruna çoktan Python sürümleri çoktan geldi ama yine de bir tek astarımı göndereceğimi düşündüm. (Ancak noktalı virgül olmadan!)

Düzenleme: 14 bayt aşağı, çift liste anlama yerine toplamı kullanarak

Düzenleme: Sadece python 2'de raw_input yerine girdi kullanabilirsiniz. Her zaman sadece ikincisini kullandım.


0

Mathematica, 142 102 bayt (bağımsız)

Bu çözelti bir matematik tadı vardır:

UnitVector[#,1-Sum[(-1)^Floor[#+1/2-Sqrt[9/4+#*#-#-2x]],{x,k}]]~Table~{k,0,#(#-1)/2}/.{0->" ",1->"X"}&

Bu temelde hangi segmentte olduğumuzu (üçgen sayı fonksiyonunu ters çevirerek) ve sonra -1 değerini ekleyerek sola veya sağa hareket ettirdiğimizi hesaplar.

Bunu, Wolfram Code Sandbox'taki gibi bir kodu yapıştırarak UnitVector[#,1-Sum[(-1)^Floor[#+1/2-Sqrt[9/4+#*#-#-2x]],{x,k}]]~Table~{k,0,#(#-1)/2}/.{0->" ",1->"X"}&@6//MatrixFormve Shift + Enter veya Numpad Enter tuşlarına basarak veya Gear -> "Hücreyi Değerlendir" seçeneğini tıklatarak test edebilirsiniz .


Bu, Erik'in Python 2 çözümünün orijinal yanlış bağlantı noktasıyla aynı uzunluktadır (Bu bağlantı noktası daha yüksek bir girdi için çıktı verir):

(Print[X];l=Range@#;Do[Do[Print[StringRepeat[" ",l[[j]]]<>"X"],{j,Length@l}];l=l[[-2;;1;;-1]],{i,#}])&

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.