Pola Bergantian

16

Dalam sebuah pertanyaan stackoverflow sekarang dihapus, seseorang diposting berikut:

Menulis sebuah program atau fungsi untuk mencetak pola alternating di *dan #berdasarkan bilangan bulat tertentu n. Beberapa contoh:

Input: n=1
Output:

*

Input n=5
Output:

*####
###**
***##
###**
*####

Input: n=8
Output:

*#######
######**
***#####
####****
****####
#####***
**######
#######*

Sejak itu tampak seperti cukup keren kode-golf tantangan, ini dia.

Bagaimana pola-pola ini dibangun?

Baris pertama dimulai dengan satu *, diikuti oleh n-1jumlah tertinggal #.
Baris kedua kemudian berisi dua *, dengan n-2jumlah pemimpin #.
Baris ketiga dimulai dengan tiga *, diikuti oleh n-3jumlah tertinggal #.
dll.

Setelah kami sampai di tengah ( n/2), kita menghitung kembali lagi dengan jumlah *yang dapat dilihat pada contoh di atas.

CATATAN bahwa untuk nomor masukan aneh pasangan yang terbalik garis (jadi pertama dan terakhir; kedua dan di sebelah terakhir; dll) yang persis sama. Dalam n=5contoh, baris pertama dan terakhir adalah *####; baris kedua dan berikutnya adalah ###**.
Untuk nomor masukan bahkan namun pasangan yang terbalik dari garis terbalik. Dalam n=8contoh, baris pertama dan terakhir adalah *#######dan #######*; baris kedua dan berikutnya adalah ######**dan **######; dll.

Aturan tantangan:

  • Anda dapat menggunakan dua yang berbeda dicetak karakter bukan *dan #. Anda bisa menggunakan Adan B; 3dan 7; <dan >; dll Silahkan negara dalam jawaban Anda apa yang telah Anda gunakan.
  • Anda dapat mengasumsikan nakan menjadi bilangan bulat positif ( >= 1)
  • Anda diperbolehkan untuk output daftar / array string untuk setiap baris atau matriks 2D karakter, bukannya mencetak mereka untuk STDOUT.

Aturan umum:

  • Ini adalah , jadi jawaban tersingkat dalam byte menang.
    Jangan biarkan bahasa kode-golf mencegah Anda memposting jawaban dengan bahasa non-codegolf. Cobalah untuk memberikan jawaban sesingkat mungkin untuk bahasa pemrograman 'apa saja'.
  • Aturan standar berlaku untuk jawaban Anda, jadi Anda diperbolehkan menggunakan STDIN / STDOUT, fungsi / metode dengan parameter yang tepat dan tipe pengembalian, program lengkap. Panggilanmu.
  • Celah default tidak diperbolehkan.
  • Jika memungkinkan, tambahkan link dengan tes untuk kode Anda.
  • Juga, menambahkan penjelasan untuk jawaban Anda sangat dianjurkan.

Test case (pertama n=1melalui n=10)

*

*#
#*

*##
#**
*##

*###
##**
**##
###*

*####
###**
***##
###**
*####

*#####
####**
***###
###***
**####
#####*

*######
#####**
***####
###****
***####
#####**
*######

*#######
######**
***#####
####****
****####
#####***
**######
#######*

*########
#######**
***######
#####****
*****####
#####****
***######
#######**
*########

*#########
########**
***#######
######****
*****#####
#####*****
****######
#######***
**########
#########*
Kevin Cruijssen
sumber
" Anda dapat menggunakan dua karakter yang berbeda bukan * dan #. " - Apakah mereka harus dicetak? Dapat kita gunakan NUL dan SOH (kode ASCII 0 dan 1)?
ngn
@ngn Maaf, karakter yang dapat dicetak saja. Akan memperjelas dalam deskripsi tantangan.
Kevin Cruijssen

Jawaban:

14

Jelly , 9 byte

>þµoṚUÐeY

Cobalah online!

Penjelasan

>þ           Create a table of (x>y) over [1…n]×[1…n]:
               [0 1 1 1 1]
               [0 0 1 1 1]
               [0 0 0 1 1]
               [0 0 0 0 1]
               [0 0 0 0 0]
  µ          Take this array, and...
   oṚ        OR it with its reverse:
               [0 1 1 1 1]
               [0 0 1 1 1]
               [0 0 0 1 1]
               [0 0 1 1 1]
               [0 1 1 1 1]
    UÐe      Apply U (reverse) to even-indexed rows.
       Y     Join by newlines.
Lynn
sumber
17

Python 2 , 62 bytes

lambda n:["%*s"%(i%2*2*n-n,"x"*min(i+1,n-i))for i in range(n)]

Cobalah online!

Penggunaan xdan ruang.

Baris dihitung seperti ini:

"%-5s" % "x"      == "x    "
"%5s"  % "xx"     == "   xx"
"%-5s" % "xxx"    == "xxx  "
"%5s"  % "xx"     == "   xx"
"%-5s" % "x"      == "x    "

Menggunakan %*sspecifier untuk memilih antara ndan -n.

Lynn
sumber
6

MATL, 34 31 18 byte

:t!>tPY|!"@X@oQ&P!

Cobalah di MATL Online

Menggunakan 0 untuk * dan 1 untuk #. Berdasarkan jawaban Lynn's Jelly .


Jawabannya lebih tua, 31 bytes:

2/tk:wXk:Ph"X@ot~XHh@Gy-hHQ&PY"

Cobalah di MATL Online

Gunakan 1 untuk * dan 0 untuk #.

         % implicit input, say 5
2/       % divide input number by 2 [2.5]
tk       % make a copy and floor that [2.5, 2]
:        % create range 1 to the floored value [2.5, [1, 2]]
wXk      % bring out the division result and this time ceil it
         %  [[1, 2], 3]
:        % create range 1 to that [[1, 2], [1, 2, 3]]
Ph       % flip the last array and concatenate horizontally 
         %  [[1, 2, 3, 2, 1]]
"        % loop through the array
  X@o    % Is the current loop index odd? 1 for odd, 0 for even
  t~     % duplicate and logical negate that
  XH     % copy that value to clipboard H
  h      % and concatenate the values ([1 0] on odd iterations, [0 1] on even) 
  @      % push current value from array (say 2, then stack is [[0 1], 2)
  G      % push input again
  y-     % subtract current array value from input [[0 1], 2, 3]
  h      % concatenate those two [[0 1], [2, 3]]
  H      % get the stored value from clipboard H (1 for even iterations, 0 for odd) 
  Q      % increment that
  &P     % flip the array in that dimension: in even iterations, this flips
         %   across columns and hence inverts the two values. [[0 1], [3, 2]]
         %   in odd iterations, it's a no-op
  Y"     % run-length decoding - repeat the element from first array the number of times
         %  specified in the second array
         % implicit loop end, implicit output
sundar - mengembalikan Monica
sumber
6

APL (Dyalog Classic) , 18 byte

a[↑⊢∘⌽\(⊂>⊢⌊⌽)⍳⎕]

Cobalah online!

output ABbukan*#

input yang dievaluasi n

⍳⎕ vektor 0 1 ... n-1

⊢⌊⌽min ( ) antara mereka ( ) dan sebaliknya mereka ( ) - lihat kereta

⊂>⊢⌊⌽di mana vektor secara keseluruhan ( ) kurang dari masing-masing ⊢⌊⌽- kembalikan vektor vektor boolean (0/1)

⊢∘⌽\ membalikkan setiap vektor lainnya

campur menjadi sebuah matriks

⎕aalfabet bahasa Inggris huruf besar, 'AB...Z'

⎕a[ ]ganti 0 1dengan'A' 'B'

ngn
sumber
Karena penasaran. Berapa banyak byte hanya untuk menghasilkan matriks 0s dan 1s tanpa spasi? Saya berasumsi ⎕a[...}mengonversinya menjadi Adan Btanpa spasi lebih pendek daripada mempertahankannya sebagai 0dan 1tanpa spasi mengingat Anda pernah menggunakannya, tetapi hanya ingin tahu apakah ada banyak perbedaan dalam byte jika Anda menyimpannya sebagai 0dan 1.
Kevin Cruijssen
1
@KevinCruijssen Sejauh yang saya bisa golf, itu akan menjadi sama panjang - baik ⎕d[... ]atau ⊃¨⍕¨... Dalam ekspresi yang terakhir ⍕¨adalah "memformat masing-masing" - ternyata setiap nomor menjadi char bersarang vektor , jadi kita perlu "pertama masing-masing "( ⊃¨) untuk mendapatkan skalar char saja (dan karenanya tidak ada spasi saat mencetak).
ngn
5

Arang , 21 bytes

≔⮌…⁰NθEθ⭆蛧⟦μλ⟧κ⌊⟦κι

Cobalah online! Penggunaan 0dan 1. Tautan adalah untuk versi versi kode dan termasuk §*#yang menerjemahkan output ke *dan #dalam pertanyaan. Penjelasan:

    N                   Input number
  …⁰                    Range from 0
 ⮌                      Reversed
≔    θ                  Assign to `q`
      Eθ                Map over reversed range
        ⭆θ              Map over reversed range and join
           §⟦μλ⟧κ       Alternate between range and reversed range column
                 ⌊⟦κι   Minimum of range and reversed range row
          ›             Greater
                        Implicitly print each row on its own line
Neil
sumber
5

Jelly ,  12  15 byte

+3 memperbaiki n=1bug tepi-kasus :(

R«Ṛ$‘r⁸ṬUÐe0YE?

Program lengkap yang menerima integer yang mencetak output seperti yang didefinisikan dalam OP menggunakan 0dan 1untuk *dan #masing - masing.

Cobalah online!

Bagaimana?

R«Ṛ$‘r⁸ṬUÐe0YE? - Main Link: integer, n
R               - range -> [1,2,3,4,...,n]
   $            - last two links as a monad:
  Ṛ             -   reverse -> [n,...,4,3,2,1]
 «              -   minimum (vectorises) -> [1,2,3,4,...,4,3,2,1]
    ‘           - increment (vectorises) -> [2,3,4,5,...,5,4,3,2]
      ⁸         - chain's left argument, n
     r          - inclusive range (vectorises) -> [[2,3,...,n],[3,4,...n],[4,5,...n],[5,...n],...,[5,...n],[4,5,...n],[3,4,...n],[2,3,...,n]]
       Ṭ        - untruth (vectorises) -> [[0,1,1,...,1],[0,0,1,1,...,1],[0,0,0,1,...,1],[0,0,0,0,1,...,1],...,[0,0,0,0,1,...,1],[0,0,0,1,...,1],[0,0,1,1,...,1],[0,1,1,...,1]]
         Ðe     - apply to entries with even indices:
        U       -   upend              -> [[0,1,1,...,1],[1,1,...,1],[0,0,0,1,...,1],[1,...,1,0,0,0,0],...]
              ? - if...
             E  - ...condition: all equal? (only true when n=1, where we have [1,1])
           0    - ...then: zero
            Y   - ...else: join with newline characters
                - implicit print
Jonathan Allan
sumber
Sepertinya ini adalah persis algoritma saya, tetapi implementasi yang berbeda yang menghasilkan 0 bukannya 1 dan sebaliknya.
Erik the Outgolfer
Ya secara efektif hal yang sama ... dan saya belum memperbarui posting saya untuk menunjukkan perbaikan yang saya buat.
Jonathan Allan
4

Jelly , 15 byte

r1«RR;ṬṖɗ€‘UÐeY

Cobalah online!

program penuh.

*= 1
#=0

Erik the Outgolfer
sumber
4

Java 10, 145 byte

n->{var r=new char[n][n];for(int j=0,k;j<n;++j)for(k=0;k<n;)r[j][k]=k++<(j<n/2?j%2<1?j+1:n+~j:j%2>0?j:n-j)?j%2<1?'*':'#':j%2>0?'*':'#';return r;}

Semua ternary membuatnya agak berantakan, tetapi berfungsi dengan baik. Saya mencoba merata loop bersarang, dan berbagai hal lain, tetapi mereka hanya meningkatkan jumlah byte. Cobalah online di sini .

Tidak Terkumpul:

n -> { // lambda taking an integer as output and returning a char[][]
    var r = new char[n][n]; // the output array; we make use of Java 10's var here (replace with char[][] for another 4 bytes to make this work in Java 8)
    for(int j = 0, k; j < n; ++j) // iterate over the lines
        for(k = 0; k < n; )       // iterate over the j'th line
            r[j][k] = // set the current character
                      k++ < // determine if we're in the first or second portion of the line:
                            (j < n/2 ? // for the first half of the output:
                                 j%2 < 1  // on even lines ...
                                 ? j + 1  // ... print the first symbol j+1 times ...
                                 : n + ~j // ... on odd lines, print it n-j-1 times.
                             : j%2 > 0 ?  // for the second half of the output, on odd lines ...
                                 j :      // ... print the first symbol j times ...
                                 n - j)   // ... on even lines, print it n-j times.
                      ? j%2 < 1 ? '*' : '#'  // for the first part of the line, use '*' on even lines, '#' otherwise
                      : j%2 > 0 ? '*' : '#'; // for the second part of the line, use '*' on odd lines, '#' otherwise
    return r; // return the completed array
}

Java 8 11, 179 127 byte

n->{String r="",a,b;for(int j=0;j<n;b="#".repeat(j<n/2?n+~j:j),r+=(j++%2<1?a+b:b+a)+"\n")a="*".repeat(j<n/2?j+1:n-j);return r;}

Cobalah secara online di sini (TIO tidak memiliki Java 11 belum, jadi ini menggunakan metode kustom yang menghasilkan jumlah byte sama denganString#repeat() ).

Terimakasih untuk Kevin Cruijssen karena bermain golf 52 byte!

Tidak Terkumpul:

n -> { // lambda taking an int argument and returning a String
    String r = "", // the output String
           a,      // temporary String containing the '*'s
           b;      // temporary String containing the '#'s
    for(int j = 0; j < n; // loop over the lines
        b = "#".repeat( // repeat the '#' character ...
            j < n/2 ? n + ~j // ... n-j-1 times in the first half of the output ...
            : j), // ... j times in the second half
        r += (j++ % 2 < 1 ? a + b : b + a) + "\n") // assemble the j'th line and append it to the output: on even lines, the '*'s go first; on odd lines, the '#'s go first
        a = "*".repeat( // repeat the '*' character ...
              j < n/2 ? j + 1 // ... j+1 times in the first half of the output ...
              : n - j); // n-j times in the second half
    return r; // return the completed output
}
Ketidakseimbangan
sumber
3
Jika Anda mengubah ke Java 11, Anda dapat membuatnya menjadi 127 byte dengan menggunakan "*".repeat(...)dan "#".repeat(...)(serta mengembalikan String alih-alih mencetak langsung dan bermain golf n-j-1ke n+~j):n->{String r="",a,b;for(int j=0;j<n;b="#".repeat(j<n/2?n+~j:j),r+=(j++%2<1?a+b:b+a)+"\n")a="*".repeat(j<n/2?j+1:n-j);return r;}
Kevin Cruijssen
Terima kasih, itu penghematan besar dalam byte. Saya telah berhasil membuat versi 145-byte untuk Java 10 menggunakan nested loop - tidak bisa menunggu rilis Java 11, repeat()metode itu sangat bagus untuk bermain golf.
OOBalance
4

Lua ,  148  133 Bytes

function(n)t,a,b={},".","#"for i=1,n do r=i<n/2+1 and i or-~n-i s=a:rep(r)..b:rep(n-r)t[i]=i%2<1 and s:reverse()or s end return t end

Cobalah online!

-15 byte terima kasih kepada @KevinCruijssen dan @JoKing.

function(n)
   t = {}; a = "."; b = "#"          -- initialize variables, output is in table
                                     -- strings are needed in variables for
                                     --   the str:rep and str:reverse syntax

   for i = 1, n do                          -- build the rows of the table
      r = i<=(n+1)/2 and i or n-i+1         -- logic used to count up then down
      str = a:rep(r)..b:rep(n-r)            -- append correct number of '.'s, fill
                                            --   in the rest with '#'s
      t[i]=i%2==0 and str:reverse() or str  -- logic used to control reversing
   end
   return t                                 -- return table
end
Dataran Tinggi Azure
sumber
2
Saya tidak tahu Lua terlalu baik, tetapi tampaknya Anda dapat menyimpan lima byte: (n+1)/2untuk -~n/2; or n-i+1untuk or-~n-i; i%2==0untuk i%2<1; dan reverse() oruntuk reverse()or. Juga, versi TIO dan byte-count Anda keduanya mengandung semi-colon tambahan yang sepertinya tidak diperlukan. Jawaban pertama yang bagus. +1 dari saya. Dan selamat datang di PPCG! :)
Kevin Cruijssen
2
Anda benar-benar tidak perlu setiap dari semi-titik dua. 133 byte termasuk saran Kevin.
Jo King
@KevinCruijssen Terima kasih! Bisakah saya bertanya apa yang -~ndilakukan dalam saran Anda? Ini pasti berhasil, tetapi saya tidak mengerti mengapa.
Azure Heights
1
@AzureHeights Tentu. ~adalah operator negasi bitwise unary. Yang penting untuk codegolfing adalah, ~imemiliki nilai yang sama -i-1. Karena itu kita dapat menggunakan -~isebagai ganti i+1dan ~-ibukan i-1. Ini berguna dalam dua kasus, yang bisa saya manfaatkan dalam jawaban Anda: menyingkirkan tanda kurung, karena -dan ~memiliki operator yang lebih diutamakan daripada operasi matematika lainnya, (n+1)/2karena itu bisa jadi -~n/2. Dan bagian berguna lainnya adalah untuk menghilangkan ruang dalam beberapa kasus, seperti yang saya lakukan dengan or-~n-i.
Kevin Cruijssen
1
Berikut adalah dua tips yang relevan jika Anda ingin membaca lebih banyak tentangnya: Gunakan unary ~untuk x+1danx-1 dan Gunakan unary ~untuk a-b-1dana+b+1 . Semua kiat umum, serta kiat khusus bahasa ( Tip untuk bermain golf di Lua dalam kasus ini), mungkin menarik untuk dibaca. :)
Kevin Cruijssen
3

Kotlin , 86 byte

{n:Int->for(i in 0..n)println("%${i%2*2*n-n}s".format("x".repeat(Math.min(i+1,n-i))))}

Cobalah online!

Penggunaan xdan ruang sebagai simbol output. Berasal dari Lynn Answer

YGolybev
sumber
3

Perl 5 + -pa -MPOSIX -M5.010, 58 byte

say+sort{$|--}1x abs,2x("@F"-abs)for(1..ceil$_/=2),-$_..-1

Cobalah online!

Dom Hastings
sumber
3

C (gcc) , 104 99 byte

h,j,k;f(i){char s[h=i++];for(j=0;k=++j>i/2?i-j:j,j<i;memset(memset(s,42,h)+j%2*k,35,h-k),puts(s));}

Cobalah online!

ErikF
sumber
3

C (gcc) , 118 108 byte

Yang ini tidak akan menang, tapi ini pendekatan yang berbeda (atau setidaknya, saya pikir begitu!) Daripada melakukan manipulasi string, saya menggunakan fakta bahwa 10x-1 lebih [1 ..n]={9,99,999,...}, yang kemudian dapat dikalikan untuk mendapatkan pola yang sesuai; printf()kemudian melakukan zero-padding untuk pembenaran benar.

Sayangnya, inthanya memiliki jangkauan yang cukup untuk melakukan hingga 9 digit (pada platform 32-bit), jadi Anda perlu beralih ke longpola yang lebih besar; bahasa yang secara alami melakukan aritmatika MP mungkin dapat menggunakan ini untuk sesuatu.

Terima kasih kepada ceilingcat untuk sarannya.

h,j,k;p(h){h=h?10*p(--h):1;}f(i){for(j=0,h=i++;k=++j>i/2?i-j:j,j<i;printf("%0*d\n",h,~-p(k)*p(j%2*(h-k))));}

Cobalah online!


Bukti konsep bahwa ini bekerja dengan aritmatika MP:

C # (Mono C # compiler) , 187 165 byte

(143 byte + 22 byte untuk using System.Numerics;header)

q=>{var r="";for(int j=0,h=q+1,k;j<q;r+=((BigInteger.Pow(10,k)-1)*BigInteger.Pow(10,j%2*(q-k))).ToString("D"+q)+"\n")k=++j>h/2?h-j:j;return r;}

Cobalah online!

ErikF
sumber
1
Bukti konsep dengan angka di luar rentang bilangan bulat asli maksimum (menggunakan C # dan BigIntegers): Cobalah online!
ErikF
3

Vim, 99 penekanan tombol

Itu selalu menarik untuk mencoba melakukan vim dengan argumen input. Ini sangat tidak alami, jadi itu tidak akan menjadi sangat pendek. Mungkin ada pendekatan bagus lainnya untuk ini.

Input diasumsikan dengan sendirinya dalam buffer. Register diasumsikan kosong. Editor diasumsikan cukup tinggi untuk menampung hasil tanpa menggulir (ini secara teknis dapat dihindari dengan mengorbankan beberapa penekanan tombol).

"nD@ni<cr><esc>MmaGddM
<c-v>'aI*<esc>qwgvjokoI*<esc>@wq@w<esc>
:set ve=all<cr>@nlh<c-v>@nkr#
:%s/ /#/g<cr>o<esc>
2Gqqdt#$p2j0@qq@q

Penjelasan

 | Buffer state (odd and even case):
 | 5                    6

"nD              read input into register n
@ni<cr><esc>     add n newlines
MmaGddM<c-v>'a   visual block select center row(s)
I*<esc>          prepend a column of *
qw               record macro w
  gvjoko         expand selection up and down
  I*<esc>
  @w             recurse
q
@w<esc>          run macro w and exit visual block select

 | Buffer state:
 | *                    *
 | **                   **
 | ***                  ***
 | **                   ***
 | *                    **
 |                      *

:set ve=all<cr>  move anywhere!
@nlh<c-v>@nkr#   add last column of #s

 | Buffer state:
 | *   #                *    #
 | **  #                **   #
 | *** #                ***  #
 | **  #                ***  #
 | *   #                **   #
 |                      *    #

:%s/ /#/g<cr>      replace spaces with #

 | Buffer state:
 | *####                *#####
 | **###                **####
 | ***##                ***###
 | **###                ***###
 | *####                **####
 |                      *#####

o<esc>2G           prep and jump to line 2
qqdt#$p2j0@qq@q    (effectively) flip every other onward

 | Buffer state:
 | *####                *#####
 | ###**                ####**
 | ***##                ***###
 | ###**                ###***
 | *####                **####
 |                      #####*

Dan di base64, dengan karakter yang sebenarnya (masukkan input inputdan penekanan tombol keysdan jalankan menggunakan vim -u NONE -s keys input)

Im5EQG5pDRtNbWFHZGRNFidhSSobcXdndmpva29JKhtAd3FAdxs6c2V0IHZlPWFsbA1AbmxoFkBua3IjOiVzLyAvIy9nDW8bMkdxcWR0IyRwMmowQHFxQHE=
algmyr
sumber
2

R , 75 byte

function(n)outer(1:n,1:n,function(x,y,a=x<y|x>n-y+1)+ifelse(x%%2,a,rev(a)))

Cobalah online!

  • Terinspirasi oleh jawaban @Lynn
  • fungsi mendapatkan nsebagai parameter dan mengembalikan sebuah matriks di 0/1mana 0sesuai dengan '*'dan 1sesuai dengan'#'
menggali semua
sumber
2

K (ngn / k) , 22 byte

{"*#"i|:/'i>/:i&|i:!x}

Cobalah online!

{ } berfungsi dengan argumen x

!xdaftar (0;1;...;x-1)

i: menetapkan ke i

i&|iminima ( &) dari idan kebalikannya ( |)

i>/:bandingkan dengan lebih dari ( >) iterhadap setiap elemen dari daftar di sebelah kanan (/: ) - kembalikan matriks boolean (daftar daftar)

i|:/'untuk setiap ( ') j dalam i, mundur ( |:- kita perlu :memaksa |unary) elemen yang sesuai j kali ( n f/ xberlaku f nkali pada x). Secara efektif, balikkan setiap baris lainnya.

"*#" gunakan elemen matriks sebagai indeks dalam string "*#"

ngn
sumber