Générer la tresse de Pascal

32

Voici la tresse de Pascal:

 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

J'ai totalement inventé ça. Autant que je sache, Blaise Pascal n'avait pas de tresse, et s'il l'a fait, c'était probablement en cheveux plutôt qu'en chiffres.

Il est défini comme ceci:

  1. La première colonne a un seul 1au milieu.
  2. La deuxième colonne a un 1en haut et en bas.
  3. Maintenant, nous alternons entre mettre un nombre au milieu ou deux copies d'un nombre en haut et en bas.
  4. Si le nombre va en haut ou en bas, ce sera la somme des deux nombres adjacents (par exemple 56 = 15 + 41). Si vous inclinez un peu la tête, c'est comme une étape dans le triangle de Pascal.
  5. Si le nombre va au milieu, ce sera la somme des trois nombres adjacents (par exemple 41 = 15 + 11 + 15).

Votre tâche sera d'imprimer (une partie de) cette tresse.

Contribution

Vous devez écrire un programme ou une fonction, qui reçoit un seul entier n, donnant l'index de la dernière colonne à sortir.

Vous pouvez choisir si la première colonne (en n'imprimant qu'une seule 1sur la ligne médiane) correspond à n = 0ou n = 1. Cela doit être un choix cohérent parmi toutes les entrées possibles.

Sortie

Sortez la tresse de Pascal jusqu'à la ne colonne. L'espace doit correspondre exactement à la disposition d'exemple ci-dessus, sauf que vous pouvez remplir la ou les lignes plus courtes avec la longueur de la ou des lignes plus longues avec des espaces et vous pouvez éventuellement générer un seul saut de ligne de fin.

En d'autres termes, chaque colonne doit être exactement aussi large que le nombre (ou une paire de nombres égaux) dans cette colonne, les nombres dans les colonnes successives ne doivent pas se chevaucher et il ne doit pas y avoir d'espaces entre les colonnes.

Vous pouvez soit imprimer le résultat dans STDOUT (ou l'alternative la plus proche), ou si vous écrivez une fonction, vous pouvez renvoyer soit une chaîne avec le même contenu soit une liste de trois chaînes (une pour chaque ligne).

Plus de détails

Vous pouvez supposer que nce ne sera pas inférieur à l'index de la première colonne (donc pas inférieur 0ou 1dépendant de votre indexation). Vous pouvez également supposer que le dernier nombre de la tresse est inférieur à 256 ou le plus grand nombre représentable par le type entier natif de votre langue, selon le plus élevé des deux . Donc, si votre type d'entier natif ne peut stocker que des octets, vous pouvez supposer que le plus grand nest 9ou 10(selon que vous utilisez 0 ou 1 n) et s'il peut stocker des entiers 32 bits signés, nsera au plus 33ou 34.

Les règles de standard s'appliquent. Le code le plus court gagne.

OEIS

Voici quelques liens pertinents de l'OEIS. Bien sûr, ceux-ci contiennent des spoilers pour différentes façons de générer les nombres dans la tresse:

Cas de test

Ces cas de test utilisent l'indexation 1 base. Chaque cas de test est de quatre lignes, la première étant l'entrée et les trois autres étant la sortie.

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
Martin Ender
la source
Le format me semble un peu caméléon.
Leaky Nun
3
@LeakyNun J'ai essayé ce défi alors qu'il était dans le bac à sable, et j'ai dépensé environ la moitié autant d'octets pour calculer la tresse que pour l'imprimer. Cela me semble un excellent équilibre pour un défi ascii-art .
FryAmTheEggman
4
@LeakyNun J'espérais que la génération de séquences et l'art ASCII sont des éléments importants du défi, car la plupart des langues seront probablement meilleures dans l'un de ces deux, alors j'ai pensé qu'il serait intéressant de les mélanger. Et il introduit un composant supplémentaire où il n'est pas évident s'il est préférable de générer séparément haut / bas et milieu ou de générer le tout, puis de séparer les bissections.
Martin Ender
La tresse numérique de Pascal ?
Luis Mendo
Personne n'a encore écrit de solution en Pascal. Cela me rend triste.
dynamitereed

Réponses:

5

Gelée , 31 30 29 octets

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

Ceci est un lien monadique; il accepte un index de colonne basé sur 0 comme argument et renvoie une liste de chaînes.

Essayez-le en ligne!

Comment ça marche

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.
Dennis
la source
12

Pyth , 44 octets

La génération du nombre a pris 20 octets et le formatage a pris 24 octets.

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

Essayez-le en ligne!

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
Fuite, nonne
la source
7
C'est le plus grand programme Pyth que j'aie jamais vu.
imallett
7

Python 2, 120 octets

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

Essayez-le sur Ideone.

Lynn
la source
7

MATL , 38 octets

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

Essayez-le en ligne!

Le calcul d'un tableau avec les nombres (uniques) prend les 17 premiers octets. Le formatage prend les 21 octets restants.

Explication

Partie 1: générer les nombres

Cela génère un tableau contenant les numéros des première et seconde rangées dans l'ordre croissant: [1; 1; 3; 4; 11; 15; ...]. Il commence par 1, 1. Chaque nouveau numéro est obtenu itérativement à partir des deux précédents. Parmi ceux-ci, le second est multiplié par 1ou en 2fonction de l'indice d'itération, puis additionné au premier pour produire le nouveau nombre.

Le nombre d'itérations est égal à l'entrée n. Cela signifie que des n+2nombres sont générés. Une fois généré, le tableau doit être coupé afin que seules les premières nentrées soient conservées.

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

Partie 2: formater la sortie

Pour chaque nombre dans le tableau obtenu, cela génère deux chaînes: une représentation sous forme de chaîne du nombre et une chaîne de même longueur composée du caractère 0 répété (le caractère 0 est affiché comme un espace dans MATL). Pour des itérations égales, ces deux chaînes sont permutées.

Les deux chaînes sont ensuite concaténées verticalement. Les ntableaux de caractères 2D sont donc produits comme suit (en utilisant ·pour représenter le caractère 0):

·
1

1
·

· 
3

4
·

·· 
11

15
··

Ces tableaux sont ensuite concaténés horizontalement pour produire

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

Enfin, ce tableau de caractères 2D est divisé en ses deux lignes, et le premier est dupliqué sur le haut de la pile. Les trois chaînes sont affichées dans l'ordre, chacune sur une ligne différente, produisant la sortie souhaitée

!       % 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
Luis Mendo
la source
6

Haskell, 101 octets

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

Définit une fonction f :: Int → [String].

  • Michael Klein m'a rappelé que je n'avais pas besoin d'appeler unlinesle résultat, économisant 7 octets. Merci!

  • J'ai enregistré un octet en le remplaçant " 9"!!mod i 2par cycle" 9"!!i.

  • Trois octets supplémentaires en écrivant deux listes corecursives au lieu d'utiliser drop.

  • Ma copine a souligné que je pouvais économiser deux octets de plus en commençant mes réponses à la 0place de 1.

Lynn
la source
3

C, 183 177 176 octets

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

Explication

C ne gagnera jamais de prix pour la brièveté contre une langue de niveau supérieur, mais l'exercice est intéressant et constitue une bonne pratique.

La macro F réduit six octets au détriment de la lisibilité. Les variables sont déclarées globalement pour éviter plusieurs déclarations. J'avais besoin d'un tampon de caractères pour sprintf, mais comme K&R est lâche avec la vérification de type, sprintf et printf peuvent interpréter t [9] comme un pointeur vers un tampon de 36 octets. Cela enregistre une déclaration distincte.

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

Jolie fonction d'impression, où r est le numéro de ligne. Sprintf formate le nombre et calcule la largeur de la colonne. Pour économiser de l'espace, nous l'appelons simplement trois fois, un pour chaque ligne de sortie; l'expression ri & 1 filtre ce qui est imprimé.

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

Fonction point d'entrée, l'argument est le nombre de colonnes. Calcule le tableau a des valeurs de colonne a [], puis appelle la fonction d'impression p une fois pour chaque ligne de sortie.

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

Exemple d'appel (non inclus dans la réponse et le nombre d'octets):

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

Mis à jour

Intégration de la suggestion de sprintf en ligne du tomsmeding. Cela a réduit le nombre de 183 à 177 caractères. Cela permet également de supprimer les accolades autour du bloc printf (sprintf ()) car ce n'est qu'une seule instruction maintenant, mais cela n'a enregistré qu'un seul caractère car il a encore besoin d'un espace comme délimiteur. Donc, jusqu'à 176.

maharvey67
la source
Vous ne pouvez pas aligner la définition de l' wendroit où il est utilisé? Vous semblez ne l'utiliser qu'une seule fois.
tomsmeding
Vous ne pouvez pas utiliser itoaau lieu de sprintf?
Giacomo Garabello
J'ai considéré itoa, mais il n'existe pas sur mon système, et j'utilise la valeur de retour de sprintf pour définir la largeur du champ.
maharvey67
2

PowerShell v2 +, 133 octets

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 octets pour calculer les valeurs, 70 octets pour formuler l'ASCII

Prend l'entrée $ncomme colonne indexée zéro. Définit le début de notre tableau de séquences $a=1,1. On boucle ensuite $navec1..$n|%{...} pour construire le tableau. À chaque itération, nous concaténons la somme de (il y a deux éléments) + (l'élément précédent) * (que nous soyons impairs ou pairs). Cela générera $a=1,1,3,4,11...jusqu'à $n+2.

Donc, nous devons couper $apour ne prendre que les premiers 0..$néléments et les diriger vers une autre boucle |%{...}. À chaque itération, nous définissons helper $zcomme un nombre d'espaces plus l'élément actuel sous forme de chaîne. Ensuite, nous divisons si cela est concaténé sur $x(les rangées du haut et du bas) ou $y(la rangée du milieu) par un simple pair if/ impair /else . Ensuite, nous calculons le nombre d'espaces pour $len prenant le nombre actuel, en le stratifiant et en prenant son .Length.

Enfin, nous avons mis $x, $yet$x à nouveau sur le pipeline, et la sortie est implicite. Étant donné que le .ToString()séparateur par défaut d'un tableau lors de l'impression sur STDOUT est une nouvelle ligne, nous l'obtenons gratuitement.

Exemple

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
AdmBorkBork
la source
0

PHP 265 octets

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

Non-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 octets

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])
Sammitch
la source
0

Rubis, 120 octets

Renvoie une chaîne multiligne.

Essayez-le en ligne!

->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]*$/}
Valeur d'encre
la source
0

Matlab, 223 caractères, 226 octets

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

Non golfé et commenté:

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
sintax
la source
0

PHP, 135 124 123 120 120 octets

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

en profitant des typecasts implicites et des variables variables,
un tiers du code (37 octets) va dans les espaces, 64 octets au total utilisés pour la sortie

panne

$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";
Titus
la source
0

Lot, 250 octets

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

Étant donné que les première et troisième lignes sont identiques, il nous suffit de créer deux chaînes. Ici dreprésente la chaîne qui se termine par la dernière entrée et sreprésente la chaîne qui se termine par des espaces; les quatre dernières lignes garantissent qu'elles sont imprimées dans l'ordre approprié. iest juste le compteur de boucles (c'est un peu moins cher que le compte à rebours %1). jest la bascule entre doubler le nombre précédent avant de l'ajouter au nombre actuel pour obtenir le nombre suivant. met ncontenir ces numéros. l, en plus d'être utilisé comme un temporaire pour calculer le nombre suivant, obtient également ses chiffres remplacés par des espaces à remplir s; set dsont échangés à chaque fois via la variable intermédiaire t.

Neil
la source