パスカルの三つ編みを生成


32

これはパスカルの三つ編みです。

 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

完全に作り上げました。ブレイズ・パスカルは、私が知る限り編組を持っていませんでした。もしそうなら、おそらく数字ではなく髪でできていたでしょう。

次のように定義されます。

  1. 最初の列1の中央にはシングルがあります。
  2. 2番目の列には1、上部と下部にあります。
  3. 次に、中央に数字を置くか、上下に数字のコピーを2つ置くかを交互に選択します。
  4. 数字が上または下にある場合、2つの隣接する数字の合計になります(例:)56 = 15 + 41。頭を少し傾けると、Pascalの三角形のステップのようになります。
  5. 数値が中央にある場合、3つの隣接する数値すべての合計になります(例:)41 = 15 + 11 + 15

あなたの仕事は、この三つ編み(の一部)を印刷することです。

入力

n出力する最後の列のインデックスを提供する単一の整数を受け取るプログラムまたは関数を作成する必要があります。

最初の列(1中央の行に1つだけ印刷する)がn = 0またはに対応するかどうかを選択できますn = 1。これは、可能なすべての入力にわたって一貫した選択である必要があります。

出力

パスカルの三つ編みをnth列まで出力します。空白は上記のレイアウト例と正確に一致する必要がありますが、短い行を長い行の長さまでスペースで埋め、オプションで末尾の改行を出力できる点が異なります。

言い換えると、すべての列はその列の数(または同じ数のペア)と同じ幅でなければならず、連続する列の数は重複してはならず、列間にスペースがあってはなりません。

結果をSTDOUT(または最も近い代替)に出力するか、関数を記述する場合、同じ内容の文字列または3つの文字列のリスト(各行に1つ)を返すことができます。

詳細

あなたはそれnが最初の列のインデックスより小さくないことを仮定するかもしれません(それで、あなたのインデックスより小さくない、0または1依存します)。また、組紐の最後の数が256未満、または言語のネイティブ整数型で表現可能な最大数のいずれか大きい方であると仮定することもできます。だからあなたのネイティブ整数型はバイトのみを保存することができれば、あなたは最大であることを前提とすることができnている910(ベース1あなたは0-かを使用するかに応じてn)、それは32ビット符号付き整数を格納することができた場合、nせいぜいでしょう3334

標準の規則が適用されます。最短のコードが優先されます。

OEIS

関連するOEISリンクをいくつか示します。もちろん、これらには三つ編みの数字を生成するさまざまな方法のためのネタバレが含まれています:

テストケース

これらのテストケースでは、1ベースのインデックス付けを使用します。各テストケースは4行で、最初の行は入力で、残りの3行は出力です。

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

このフォーマットは、私には少しカメレオンのようです。
リーキー修道女

3
@LeakyNunサンドボックスにいる間にこの挑戦を試みましたが、三つ編みを計算するのに約半分のバイトを費やしました。これは、私にとってアスキーアートの挑戦にとって素晴らしいバランスのようです。
FryAmTheEggman

4
@LeakyNunシーケンス生成とASCIIアートの両方がチャレンジの重要なコンポーネントであることを望んでいました。ほとんどの言語はおそらくこれら2つのうちの1つで優れているからです。そして、トップ/ボトムとミドルを別々に生成するのが良いのか、それとも全体を生成してから二等分するのが良いのかわからない追加のコンポーネントを導入します。
マーティンエンダー


Pascalで解決策を書いた人はまだいません。これは私を悲しくさせます。
dynamitereed

回答:


5

ゼリー31 30 29 バイト

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

これは単項リンクです。引数として0から始まる列インデックスを受け取り、文字列のリストを返します。

オンラインでお試しください!

使い方

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バイト

数の生成には20バイト、フォーマットには24バイトが必要でした。

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

オンラインでお試しください!

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
これは私が見た中で最大のPythプログラムです。
imallett


7

MATL、38バイト

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

オンラインでお試しください!

(一意の)数値を使用して配列を計算するには、最初の17バイトが必要です。フォーマットには残りの21バイトが必要です。

説明

パート1:数値を生成する

これにより、1行目と2行目の数字が昇順で配列されます[1; 1; 3; 4; 11; 15; ...]。それはで始まります11。それぞれの新しい番号は、前の2つから繰り返し取得されます。そのうち、2番目の要素は反復インデックスで乗算される12、反復インデックスに応じて1番目の要素に加算され、新しい数値が生成されます。

反復回数は入力に等しくなりますn。これは、n+2数値が生成されることを意味します。生成された配列は、最初のnエントリのみが保持されるようにトリミングする必要があります。

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

パート2:出力をフォーマットする

取得した配列の各数値に対して、2つの文字列を生成します。数値の文字列表現と、繰り返される文字0で構成される同じ長さの文字列です(文字0はMATLでスペースとして表示されます)。繰り返しの場合でも、これら2つの文字列は交換されます。

次に、2つの文字列は垂直方向に連結されます。したがって、n2D char配列は次のように生成されます(·文字0を表すために使用):

·
1

1
·

· 
3

4
·

·· 
11

15
··

これらの配列は、水平に連結されて生成されます

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

最後に、この2D char配列は2つの行に分割され、最初の行はスタックの最上部に複製されます。3つの文字列が順番に、それぞれ異なる行に表示され、目的の出力が生成されます

!       % 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バイト

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]]

関数を定義しますf :: Int → [String]

  • Michael Klein unlinesは、結果を呼び出す必要はないことを思い出させて、7バイトを節約しました。ありがとう!

  • に置き換え" 9"!!mod i 2て1バイトを保存しましたcycle" 9"!!i

  • を使用する代わりに2つのcorecursiveリストを記述することにより、さらに3バイトdrop

  • 私のガールフレンドは私の0代わりに私の答えを始めることでさらに2バイト節約できると指摘しました1


3

C、183の 177 176バイト

#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);}

説明

Cは、より高いレベルの言語に対する簡潔さで賞を獲得することは決してありませんが、この演習は興味深く、良い習慣です。

マクロFは、読みやすさを犠牲にして6バイトを削ります。複数の宣言を避けるために、変数はグローバルに宣言されます。私はsprintfに文字バッファーが必要でしたが、K&Rは型チェックがゆるいので、sprintfとprintfはt [9]を36バイトのバッファーへのポインターとして解釈できます。これにより、別の宣言が保存されます。

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

プリティ印刷機能。rは行番号です。Sprintfは数値をフォーマットし、列幅を計算します。スペースを節約するために、出力の各行に1つずつ、これを3回呼び出すだけです。式ri&1は、印刷されるものをフィルタリングします。

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

エントリポイント関数、引数は列数です。列値a []の配列aを計算し、出力の行ごとに印刷関数pを1回呼び出します。

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);
}

サンプル呼び出し(回答とバイトカウントには含まれません):

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

更新しました

tomsmedingからのインラインsprintfの提案を組み込みました。これにより、カウントが183文字から177文字に減少しました。これにより、printf(sprintf())ブロックの括弧を削除することもできます。これは、ステートメントが1つしかないためですが、区切り文字としてスペースが必要なため、1文字しか保存されません。176まで。


w使用場所の定義をインライン化できませんか?一度だけ使用するようです。
tomsmeding

itoasprintfの代わりに使用できませんか?
ジャコモガラベッロ16

itoaを検討しましたが、システムには存在しません。フィールド幅を設定するためにsprintfの戻り値を使用しています。
maharvey67

2

PowerShell v2 +、133バイト

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バイト、ASCIIを定式化するには70バイト

$nゼロインデックスの列として入力を受け取ります。シーケンス配列の開始を設定し$a=1,1ます。次に、$nwith 1..$n|%{...}にループして配列を作成します。繰り返しごとに、(2つの要素の前の)+(前の要素)*(奇数または偶数のインデックス)の合計で連結します。これにより、$a=1,1,3,4,11...最大が生成され$n+2ます。

その$aため、最初の0..$n要素のみを取得し、それらを別のループにパイプするためにスライスする必要があります|%{...}。各反復では、ヘルパー$zをスペースの数と文字列としての現在の要素に等しく設定します。次に、単純な奇数/ 偶数/ によって連結されるかどうかを分割します$x(上と下の行)または$y(中央の行)。次に、現在の数を取得し、それを文字列化し、そのを取得することにより、スペースの数を計算します。ifelse$l.Length

最後に、我々は入れて$x$yと、$x再びパイプライン上で、出力は暗黙的です。.ToString()STDOUTに出力するときの配列のデフォルトの区切り文字は改行なので、無料で取得できます。

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バイト

<?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]);

ゴルフをしていない:

$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バイト

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

Matlab、223文字、226バイト

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,[])

非ゴルフとコメント:

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バイト

<?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";

暗黙の型キャストと変数変数を利用して
、コードの3分の1(37バイト)がスペースに入り、64バイトがすべて出力に使用されます

壊す

$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

バッチ、250バイト

@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%

1行目と3行目は同じなので、2つの文字列を作成するだけです。ここdでは、最後のエントリsで終わる文字列を表し、スペースで終わる文字列を表します。最後の4行は、適切な順序で印刷されるようにします。iループカウンタです(からカウントダウンするよりも少し安いです%1)。j次の番号を取得するために現在の番号に追加する前に、前の番号を2倍にすることを切り替えます。mそしてn、これらの数字を含みます。l、次の数値を計算するための一時的なものとして使用されるだけでなく、その数字をスペースで置き換えて埋めますssそしてd、中間変数を介して毎回交換されますt

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.