Hasilkan Pascal's Braid


32

Ini adalah Pascal's Braid:

 1 4  15  56   209   780    2911    10864     40545      151316      564719
1 3 11  41  153   571   2131    7953     29681     110771      413403      1542841
 1 4  15  56   209   780    2911    10864     40545      151316      564719

Saya benar-benar mengarangnya. Sejauh ini yang saya tahu, Blaise Pascal tidak memiliki rambut kepang, mungkin itu terbuat dari rambut, bukan angka.

Itu didefinisikan seperti ini:

  1. Kolom pertama memiliki satu 1di tengah.
  2. Kolom kedua memiliki 1di bagian atas dan di bawah.
  3. Sekarang kita bergantian antara meletakkan nomor di tengah atau dua salinan angka di bagian atas dan bawah.
  4. Jika angka tersebut berada di bagian atas atau bawah, itu akan menjadi jumlah dari dua angka yang berdekatan (misalnya 56 = 15 + 41). Jika Anda sedikit memiringkan kepala, ini seperti langkah dalam segitiga Pascal.
  5. Jika angkanya di tengah, itu akan menjadi jumlah dari ketiga angka yang berdekatan (misalnya 41 = 15 + 11 + 15).

Tugas Anda adalah mencetak (sebagian) kepang ini.

Memasukkan

Anda harus menulis sebuah program atau fungsi, yang menerima integer tunggal n, memberikan indeks kolom terakhir yang akan dikeluarkan.

Anda dapat memilih apakah kolom pertama (hanya mencetak satu 1di garis tengah) sesuai dengan n = 0atau n = 1. Ini harus menjadi pilihan yang konsisten di semua input yang mungkin.

Keluaran

Keluarkan Pascal's Braid hingga nkolom ke - th. Spasi putih harus sama persis dengan tata letak contoh di atas, kecuali bahwa Anda dapat menyambungkan garis yang lebih pendek ke panjang garis yang lebih panjang dengan spasi dan Anda dapat secara opsional menampilkan satu baris feed baris tambahan.

Dengan kata lain, setiap kolom harus sama persis dengan jumlah (atau pasangan angka yang sama) di kolom itu, angka dalam kolom berturut-turut tidak boleh tumpang tindih dan tidak boleh ada spasi di antara kolom.

Anda dapat mencetak hasilnya ke STDOUT (atau alternatif terdekat), atau jika Anda menulis suatu fungsi, Anda dapat mengembalikan string dengan konten yang sama atau daftar tiga string (satu untuk setiap baris).

Keterangan lebih lanjut

Anda dapat berasumsi bahwa ntidak akan kurang dari indeks kolom pertama (jadi tidak kurang dari 0atau 1tergantung pada indeks Anda). Anda juga dapat mengasumsikan bahwa angka terakhir dalam jalinan kurang dari 256 atau angka terbesar yang dapat diwakili oleh tipe bilangan bulat asli bahasa Anda, mana yang lebih besar . Jadi jika tipe integer asli Anda hanya dapat menyimpan byte, Anda dapat mengasumsikan bahwa yang terbesar nadalah 9atau 10(tergantung pada apakah Anda menggunakan berbasis 0 atau 1 n) dan jika itu dapat menyimpan bilangan bulat 32-bit yang ditandatangani, nakan paling banyak 33atau 34.

Aturan standar berlaku. Kode terpendek menang.

OEIS

Berikut adalah beberapa tautan OEIS yang relevan. Tentu saja, ini berisi spoiler untuk berbagai cara untuk menghasilkan angka dalam jalinan:

Uji Kasus

Kasing uji ini menggunakan pengindeksan 1 basis. Setiap test case terdiri dari empat baris, dengan yang pertama menjadi input dan tiga sisanya menjadi output.

1

1

---
2
 1
1
 1
---
3
 1
1 3
 1
---
5
 1 4
1 3 11
 1 4
---
10
 1 4  15  56   209
1 3 11  41  153
 1 4  15  56   209
---
15
 1 4  15  56   209   780    2911
1 3 11  41  153   571   2131    7953
 1 4  15  56   209   780    2911
---
24
 1 4  15  56   209   780    2911    10864     40545      151316      564719       2107560
1 3 11  41  153   571   2131    7953     29681     110771      413403      1542841
 1 4  15  56   209   780    2911    10864     40545      151316      564719       2107560

Formatnya tampak seperti bunglon bagi saya.
Leaky Nun

3
@ LeakyNun Saya mencoba tantangan ini saat berada di kotak pasir, dan saya menghabiskan sekitar setengah byte untuk menghitung kepang saat mencetaknya. Ini sepertinya keseimbangan yang sangat baik bagi saya untuk tantangan ascii-art .
FryAmTheEggman

4
@LeakyNun Saya berharap bahwa generasi urutan dan seni ASCII adalah komponen penting dari tantangan, karena sebagian besar bahasa mungkin akan lebih baik di salah satu dari dua, jadi saya pikir akan menarik untuk mencampurnya. Dan itu memperkenalkan komponen tambahan di mana tidak jelas apakah lebih baik untuk menghasilkan atas / bawah dan tengah secara terpisah atau untuk menghasilkan seluruh hal dan kemudian memisahkan membagi dua.
Martin Ender


Belum ada yang menulis solusi dalam Pascal. Ini membuatku sedih.
dynamitereed

Jawaban:


5

Jelly , 31 30 29 byte

Q;S⁹o_
3ḶḂç@⁸СIµa"Ṿ€o⁶z⁶Zµ€Z

Ini adalah tautan monadik; itu menerima indeks kolom berbasis 0 sebagai argumen dan mengembalikan daftar string.

Cobalah online!

Bagaimana itu bekerja

Q;S⁹o_                  Helper link.
                        Arguments: [k, 0, k] and [0, m, 0] (any order)

Q                       Unique; deduplicate the left argument.
 ;                      Concatenate the result with the right argument.
  S                     Take the sum of the resulting array.
   ⁹o                   Logical OR with the right argument; replaces zeroes in the
                        right argument with the sum.
     _                  Subtract; take the difference with the right argument to
                        remove its values.
                        This maps [k, 0, k], [0, m, 0] to [0, k + m, 0] and
                        [0, m, 0], [k, 0, k] to [m + 2k, 0, m + 2k].


3ḶḂç@⁸СIµa"Ṿ€o⁶z⁶Zµ€Z  Monadic link. Argument: A (array of column indices)

3Ḷ                      Yield [0, 1, 2].
  Ḃ                     Bit; yield [0, 1, 0].
        I               Increments of n; yield [].
      С                Apply...
   ç@                       the helper link with swapped arguments...
     ⁸                      n times, updating the left argument with the return
                            value, and the right argument with the previous value
                            of the left one. Collect all intermediate values of
                            the left argument in an array.
         µ         µ€   Map the chain in between over the intermediate values.
            Ṿ€          Uneval each; turn all integers into strings.
          a"            Vectorized logical AND; replace non-zero integers with
                        their string representation.
              o⁶        Logical OR with space; replace zeroes with spaces.
                z⁶      Zip with fill value space; transpose the resulting 2D
                        array after inserting spaces to make it rectangular.
                  Z     Zip; transpose the result to restore the original shape.
                     Z  Zip; transpose the resulting 3D array.

12

Pyth , 44 byte

Pembuatan angka membutuhkan 20 byte, dan pemformatannya membutuhkan 24 byte.

jsMC+Led.e.<bkC,J<s.u+B+hNyeNeNQ,1 1Qm*;l`dJ

Cobalah online!

jsMC+Led.e.<bkC,J<s.u+B+hNyeNeNQ,1 1Qm*;l`dJ   input as Q
                   .u          Q,1 1           repeat Q times, starting with [1,1],
                                               collecting all intermediate results,
                                               current value as N:
                                               (this will generate
                                                more than enough terms)
                       +hNyeN                  temp <- N[0] + 2*N[-1]
                     +B      eN                temp <- [temp+N[-1], temp]

now, we would have generated [[1, 1], [3, 4], [11, 15], [41, 56], ...]

jsMC+Led.e.<bkC,J<s                 Qm*;l`dJ
                  s                            flatten
                 <                  Q          first Q items
                J                              store in J
                                     m    dJ   for each item in J:
                                         `     convert to string
                                        l      length
                                      *;       repeat " " that many times

jsMC+Led.e.<bkC,
              C,     transpose, yielding:
[[1, ' '], [1, ' '], [3, ' '], [4, ' '], [11, '  '], ...]
(each element with as many spaces as its length.)
        .e            for each sub-array (index as k, sub-array as b):
          .<bk            rotate b as many times as k

[[1, ' '], [' ', 1], [3, ' '], [' ', 4], [11, '  '], ...]

jsMC+Led
    +Led              add to each sub-array on the left, the end of each sub-array
   C                  transpose
 sM                   sum of each sub-array (reduced concatenation)
j                     join by new-lines

7
Itu adalah program Pyth terbesar yang pernah saya lihat.
Imallett

7

Python 2, 120 byte

a=1,1,3,4
n=input()
y=0
exec"y+=1;t='';x=0;%sprint t;"%(n*"a+=a[-2]*4-a[-4],;v=`a[x]`;t+=[v,len(v)*' '][x+y&1];x+=1;")*3

Cobalah di Ideone.


7

MATL , 38 byte

1ti:"yy@oQ*+]vG:)!"@Vt~oX@o?w]&v]&hZ}y

Cobalah online!

Menghitung array dengan angka (unik) membutuhkan 17 byte pertama. Memformat mengambil 21 byte yang tersisa.

Penjelasan

Bagian 1: menghasilkan angka

Ini menghasilkan sebuah array dengan nomor dari baris pertama dan kedua dalam urutan yang meningkat: [1; 1; 3; 4; 11; 15; ...]. Dimulai dengan 1, 1. Setiap nomor baru secara iteratif diperoleh dari dua sebelumnya. Dari mereka, yang kedua dikalikan dengan 1atau 2tergantung pada indeks iterasi, dan kemudian dijumlahkan ke yang pertama untuk menghasilkan nomor baru.

Jumlah iterasi sama dengan input n. Ini berarti bahwa n+2angka-angka dihasilkan. Setelah dihasilkan, array perlu dipangkas sehingga hanya nentri pertama yang disimpan.

1t      % Push 1 twice
i:      % Take input n. Generage array [1 2 ... n]
"       % For each
  yy    %   Duplicate the two most recent numbers
  @o    %   Parity of the iteration index (0 or 1)
  Q     %   Add 1: gives 1 for even iteration index, 2 for odd
  *+    %   Multiply this 1 or 2 by the most recent number in the sequence, and add
       %    to the second most recent. This produces a new number in the sequence
]       % End for each
v       % Concatenate all numbers in a vertical array
G:)     % Keep only the first n entries

Bagian 2: memformat output

Untuk setiap angka dalam array yang diperoleh, ini menghasilkan dua string: representasi string dari angka, dan string dengan panjang yang sama yang terdiri dari karakter 0 berulang (karakter 0 ditampilkan sebagai spasi dalam MATL). Bahkan untuk iterasi, dua string ini ditukar.

Kedua string ini kemudian digabungkan secara vertikal. Jadi narray char 2D dihasilkan sebagai berikut (menggunakan ·untuk mewakili karakter 0):

·
1

1
·

· 
3

4
·

·· 
11

15
··

Array ini kemudian digabungkan secara horizontal untuk menghasilkan

·1·4··15
1·3·11··

Akhirnya, array char 2D ini dibagi menjadi dua baris, dan yang pertama diduplikasi ke atas tumpukan. Tiga string ditampilkan secara berurutan, masing-masing pada garis yang berbeda, menghasilkan output yang diinginkan

!       % Transpose into a horizontal array [1 1 3 4 11 15 ...]
"       % For each
  @V    %   Push current number and convert to string
  t~o   %   Duplicate, negate, convert to double: string of the same length consisting 
        %   of character 0 repeated
  X@o   %   Parity of the iteration index (1 or 0)
  ?     %   If index is odd
    w   %     Swap
  ]     %   End if
  &v    %   Concatenate the two strings vertically. Gives a 2D char array representing
        %   a "numeric column" of the output (actually several columns of characters)
]       % End for
&h      % Concatenate all 2D char arrays horizontally. Gives a 2D char array with the
        % top two rows of the output
Z}      % Split this array into its two rows
y       % Push a copy of the first row. Implicitly display

6

Haskell, 101 byte

a=1:1:t
t=3:4:zipWith((-).(4*))t a
g(i,x)=min(cycle" 9"!!i)<$>show x
f n=[zip[y..y+n]a>>=g|y<-[0..2]]

Menentukan fungsi f :: Int → [String].

  • Michael Klein mengingatkan saya bahwa saya tidak perlu memanggil unlineshasilnya, menghemat 7 byte. Terima kasih!

  • Saya menyimpan byte dengan menggantinya " 9"!!mod i 2dengan cycle" 9"!!i.

  • Tiga byte lagi dengan menulis dua daftar korektif daripada menggunakan drop.

  • Pacar saya menunjukkan bahwa saya dapat menyimpan dua byte lagi dengan memulai jawaban saya di 0alih-alih 1.


3

C, 183 177 176 byte

#define F for(i=0;i<c;i++)
int i,c,a[35],t[9];p(r){F printf("%*s",sprintf(t,"%d",a[i]),r-i&1?t:" ");putchar(10);}b(n){c=n;F a[i]=i<2?1:a[i-2]+a[i-1]*(i&1?1:2);p(0);p(1);p(0);}

Penjelasan

C tidak akan pernah memenangkan hadiah untuk singkatnya terhadap bahasa tingkat yang lebih tinggi, tetapi latihan ini menarik dan praktik yang baik.

Makro F mencukur enam byte dengan biaya keterbacaan. Variabel dideklarasikan secara global untuk menghindari deklarasi berganda. Saya membutuhkan buffer karakter untuk sprintf, tetapi karena K&R longgar dengan pengecekan tipe, sprintf dan printf dapat menafsirkan t [9] sebagai pointer ke buffer 36-byte. Ini menyimpan deklarasi terpisah.

#define F for(i=0;i<c;i++)
int i,c,a[35],t[9];

Fungsi pencetakan cantik, di mana r adalah nomor baris. Sprintf memformat angka dan menghitung lebar kolom. Untuk menghemat ruang, kami hanya memanggil ini tiga kali, satu untuk setiap baris output; ekspresi ri & 1 menyaring apa yang akan dicetak.

p(r) {
    F
        printf("%*s", sprintf(t, "%d", a[i]), r-i&1 ? t
                                                    : " ");
    putchar(10);
}

Fungsi titik masuk, argumen adalah jumlah kolom. Menghitung array a dari nilai kolom a [], lalu memanggil fungsi pencetakan p satu kali untuk setiap baris output.

b(n) {
    c=n;
    F
        a[i] = i<2 ? 1
                   : a[i-2] + a[i-1]*(i&1 ? 1
                                          : 2);
    p(0);
    p(1);
    p(0);
}

Permintaan contoh (tidak termasuk dalam jumlah jawaban dan byte):

main(c,v) char**v;
{
    b(atoi(v[1]));
}

Diperbarui

Memasukkan saran sprintf sebaris dari tomsmeding. Itu mengurangi hitungan dari 183 menjadi 177 karakter. Ini juga memungkinkan menghapus kawat gigi di sekitar blok printf (sprintf ()) karena hanya satu pernyataan sekarang, tetapi itu hanya menyelamatkan satu karakter karena masih membutuhkan ruang sebagai pembatas. Jadi turun ke 176.


Tidak bisakah Anda sebariskan definisi di wmana ia digunakan? Anda sepertinya hanya menggunakannya sekali.
tomsmeding

Anda tidak bisa menggunakan itoabukan sprintf?
Giacomo Garabello

Saya menganggap itoa, tetapi tidak ada di sistem saya, dan saya menggunakan nilai balik sprintf untuk mengatur lebar bidang.
maharvey67

2

PowerShell v2 +, 133 byte

param($n)$a=1,1;1..$n|%{$a+=$a[$_-1]+$a[$_]*($_%2+1)};$a[0..$n]|%{$z=" "*$l+$_;if($i++%2){$x+=$z}else{$y+=$z}$l="$_".Length};$x;$y;$x

44 byte untuk menghitung nilai-nilai, 70 byte untuk merumuskan ASCII

Mengambil input $nsebagai kolom tanpa indeks. Mengatur awal susunan urutan kami $a=1,1. Kami kemudian beralih ke $ndengan 1..$n|%{...}untuk membangun array. Setiap iterasi, kami menggabungkan jumlah (dua elemen lalu) + (elemen sebelumnya) * (apakah kami ganjil atau genap indeks). Ini akan menghasilkan $a=1,1,3,4,11...hingga$n+2 .

Jadi, kita perlu mengiris $auntuk hanya mengambil 0..$nelemen pertama , dan menyalurkannya melalui loop lain |%{...}. Setiap iterasi yang kami tetapkan helper $zsama dengan sejumlah spasi plus elemen saat ini sebagai string. Kemudian, kami membagi-bagi apakah itu digabungkan ke $x(baris atas dan bawah) atau $y(baris tengah) dengan ganjil genap if/ else. Kemudian, kami menghitung jumlah spasi untuk $ldengan mengambil angka saat ini, mengelompokkannya, dan mengambilnya .Length.

Akhirnya, kami menempatkan $x,, $ydan $xsekali lagi pada pipeline, dan output tersirat. Karena .ToString()pemisah default untuk array saat mencetak ke STDOUT adalah baris baru, kami mendapatkannya secara gratis.

Contoh

PS C:\Tools\Scripts\golfing> .\pascal-braid.ps1 27
 1 4  15  56   209   780    2911    10864     40545      151316      564719       2107560       7865521        29354524
1 3 11  41  153   571   2131    7953     29681     110771      413403      1542841       5757961       21489003
 1 4  15  56   209   780    2911    10864     40545      151316      564719       2107560       7865521        29354524

0

PHP 265 byte

<?php $i=$argv[1];$i=$i?$i:1;$a=[[],[]];$s=['',''];$p='';for($j=0;$j<$i;$j++){$y=($j+1)%2;$x=floor($j/2);$v=$x?$y?2*$a[0][$x-1]+$a[1][$x-1]:$a[0][$x-1]+$a[1][$x]:1;$s[$y].=$p.$v;$a[$y][$x]=$v;$p=str_pad('',strlen($v),' ');}printf("%s\n%s\n%s\n",$s[0],$s[1],$s[0]);

Tidak golf:

$a = [[],[]];
$s = ['',''];

$p = '';

$i=$argv[1];
$i=$i?$i:1;
for($j=0; $j<$i; $j++) {
    $y = ($j+1) % 2;
    $x = floor($j/2);

    if( $x == 0 ) {
        $v = 1;
    } else {
        if( $y ) {
            $v = 2 * $a[0][$x-1] + $a[1][$x-1];
        } else {
            $v = $a[0][$x-1] + $a[1][$x];
        }
    }
    $s[$y] .= $p . $v;
    $a[$y][$x] = $v;
    $p = str_pad('', strlen($v), ' ');
}

printf("%s\n%s\n%s\n", $s[0], $s[1], $s[0]);

Python 278 byte

import sys,math;a=[[],[]];s=['',''];p='';i=int(sys.argv[1]);i=1 if i<1 else i;j=0
while j<i:y=(j+1)%2;x=int(math.floor(j/2));v=(2*a[0][x-1]+a[1][x-1] if y else a[0][x-1]+a[1][x]) if x else 1;s[y]+=p+str(v);a[y].append(v);p=' '*len(str(v));j+=1
print ("%s\n"*3)%(s[0],s[1],s[0])

0

Ruby, 120 byte

Mengembalikan string multiline.

Cobalah online!

->n{a=[1,1];(n-2).times{|i|a<<(2-i%2)*a[-1]+a[-2]}
z=->c{a.map{|e|c+=1;c%2>0?' '*e.to_s.size: e}*''}
[s=z[0],z[1],s]*$/}

0

Matlab, 223 karakter, 226 byte

function[]=p(n)
r=[1;1];e={(' 1 ')',('1 1')'}
for i=3:n;r(i)=sum((mod(i,2)+1)*r(i-1)+r(i-2));s=num2str(r(i));b=blanks(floor(log10(r(i)))+1);if mod(i,2);e{i}=[b;s;b];else e{i}=[s;b;s];end;end
reshape(sprintf('%s',e{:}),3,[])

Tidak dikumpulkan dan berkomentar:

function[]=p(n) 
r=[1;1];                                    % start with first two 
e={(' 1 ')',('1 1')'}                       % initialize string output as columns of blank, 1, blank and 1, blank, 1.
for i=3:n;                                  % for n=3 and up! 
    r(i)=sum((mod(i,2)+1)*r(i-1)+r(i-2));   % get the next number by 1 if even, 2 if odd times previous plus two steps back
    s=num2str(r(i));                        % define that number as a string
    b=blanks(floor(log10(r(i)))+1);         % get a number of space characters for that number of digits
    if mod(i,2);                            % for odds
        e{i}=[b;s;b];                       % spaces, number, spaces
    else                                    % for evens
        e{i}=[s;b;s];                       % number, spaces, number
    end;
end
reshape(sprintf('%s',e{:}),3,[])            % print the cell array of strings and reshape it so it's 3 lines high

0

PHP, 135 124 123 120 byte

<?while($i<$argv[1]){${s.$x=!$x}.=${v.$x}=$a=$i++<2?:$v1+$v+$x*$v;${s.!$x}.=str_repeat(' ',strlen($a));}echo"$s
$s1
$s";

mengambil keuntungan dari typecasts implisit dan variabel variabel
sepertiga dari kode (37 byte) masuk ke spasi, 64 byte sama sekali digunakan untuk output

kerusakan

$i=0; $x=false; $v=$v1=1; $s=$s1='';    // unnecessary variable initializations
for($i=0;$i<$argv[1];$i++)  // $i is column number -1
{
    $x=!$x; // $x = current row: true (1) for inner, false (empty string or 0) for outer
    // calculate value
    $a=
        $i<2?               // first or second column: value 1
        :$v1+(1+$x)*$v      // inner-val + (inner row: 1+1=2, outer row: 1+0=1)*outer-val
    ;
    ${s.$x}.=${v.$x}=$a;    // replace target value, append to current row
    ${s.!$x}.=str_repeat(' ',strlen($a));    // append spaces to other row
}
// output
echo "$s\n$s1\n$s";

0

Batch, 250 byte

@echo off
set s=
set d=
set/ai=n=0,j=m=1
:l
set/ai+=1,j^^=3,l=m+n*j,m=n,n=l
set t=%s%%l%
for /l %%j in (0,1,9)do call set l=%%l:%%j= %%
set s=%d%%l%
set d=%t%
if not %i%==%1 goto l
if %j%==1 echo %d%
echo %s%
echo %d%
if %j%==2 echo %s%

Karena baris pertama dan ketiga sama, kita hanya perlu membangun dua string. Di sini dmewakili string yang berakhir dengan entri terakhir dan smewakili string yang berakhir dengan spasi; empat baris terakhir memastikan bahwa mereka dicetak dalam urutan yang sesuai. ihanyalah penghitung putaran (sedikit lebih murah daripada menghitung mundur dari %1). jadalah beralih antara menggandakan nomor sebelumnya sebelum menambahkannya ke nomor saat ini untuk mendapatkan nomor berikutnya. mdan nberisi angka-angka itu. l, serta digunakan sebagai sementara untuk menghitung angka berikutnya, juga mendapatkan digitnya diganti dengan ruang untuk keluar s; sdan dditukar setiap kali melalui variabel perantara t.

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.