Triangle Seidel

14

Le Triangle Seidel est une construction mathématique similaire au Triangle de Pascal, et est connu pour sa connexion aux nombres de Bernoulli.

Les premières lignes sont les suivantes:

      1
      1  1
   2  2  1
   2  4  5  5
16 16 14 10 5
16 32 46 56 61 61

Chaque ligne est générée comme suit:

Si le numéro de ligne est pair (indexé 1):

  • Faire tomber le premier élément de la ligne précédente

  • Chaque élément suivant est la somme de l'élément précédent et de l'élément au-dessus

  • Dupliquer le dernier élément

Si le numéro de ligne est impair:

  • Faire tomber le dernier élément de la ligne précédente

  • En reculant , chaque élément est la somme de l'élément précédent et de l'élément au-dessus

  • Dupliquez ce qui est maintenant le premier élément.

Fondamentalement, nous construisons le triangle en zigzag:

    1
    v
    1 > 1
        v
2 < 2 < 1
v
2 > 4 > 5 > 5

Pour plus d'informations, consultez la page Wikipedia sur les numéros de Bernoulli.

Le défi:

Étant donné n, soit en tant qu'argument de fonction, soit à partir de STDIN, imprimez ou renvoyez la ntroisième ligne du triangle Seidel ou les premières nlignes. Vous pouvez utiliser l'indexation 0 ou 1.

Vous n'avez pas besoin de gérer les entrées négatives ou non entières (ni 0, si elles sont indexées sur 1). Vous n'avez pas besoin de gérer des sorties supérieures à2147483647 = 2^31 - 1

Comme il s'agit de code-golf, faites-le en aussi peu d'octets que possible.

Exemples:

Dans ces exemples, la valeur de retour est la ne ligne, indexée sur 0.

Input   ->  Output

0           1
1           1 1
2           2 2 1
6           272 272 256 224 178 122 61
13          22368256 44736512 66750976 88057856 108311296 127181312 144361456 159575936 172585936 183194912 191252686 196658216 199360981 199360981
Bolce Bussiere
la source
"Vous n'avez pas à gérer des sorties plus grandes que le type int par défaut de votre langue", cela est trivial pour les langues avec seulement des entiers de 1 bit
ASCII uniquement
Les lignes peuvent-elles être sorties toujours triées de petite à grande?
Angs
@ ASCII-only Changé pour correspondre au maximum de C ++
Bolce Bussiere
@Angs Non, les rangées doivent être commandées comme indiqué
Bolce Bussiere
@ ASCII uniquement C'est une lacune par défaut (bien que l'OMI soit un peu mal formulé car cela dépend de ce que les gens considéreraient "raisonnable")
user202729

Réponses:

7

Brain-Flak , 66 octets

<>(())<>{({}[()]<(()[{}]<<>{(({}<>{}))<>}>)>)}{}{{}<>{({}<>)<>}}<>

Essayez-le en ligne!

La ligne est indexée sur 0.

# Push 1 (the contents of row 0) on other stack; use implicit zero as parity of current row
<>(())<>

# Do a number of times equal to input:
{({}[()]<

  # Subtract the row parity from 1
  (()[{}]<

    # For each entry in old row:
    <>{

      # Add to previous entry in new row and push twice
      (({}<>{}))<>

    }

  >)

>)}{}

# If row parity is odd:
{{}

  # Reverse stack for output
  <>{({}<>)<>}

# Switch stacks for output
}<>
Nitrodon
la source
4

JavaScript (SpiderMonkey) , 67 octets

Ce code abuse de la sort()méthode et ne fonctionne pas sur tous les moteurs.

Les lignes sont indexées 0.

f=(n,a=[1],r)=>n--?f(n,[...a.map(n=>k+=n,k=0),k].sort(_=>n|r),!r):a

Essayez-le en ligne!

Comment?

Nous inversons conditionnellement un tableau en utilisant la sort()méthode avec une fonction de rappel qui ignore ses paramètres et retourne 0 ou un entier positif. N'essayez pas ca a la maison! Cela ne fonctionne de manière fiable que sur SpiderMonkey.

let A = [1,2,3,4,5] and B = [1,2,3,4,5,6,7,8,9,10,11]

             | SpiderMonkey (Firefox)  | V8 (Chrome)             | Chakra (Edge)
-------------+-------------------------+-------------------------+------------------------
A.sort(_=>0) | 1,2,3,4,5               | 1,2,3,4,5               | 1,2,3,4,5
A.sort(_=>1) | 5,4,3,2,1               | 5,4,3,2,1               | 1,2,3,4,5
B.sort(_=>0) | 1,2,3,4,5,6,7,8,9,10,11 | 6,1,3,4,5,2,7,8,9,10,11 | 1,2,3,4,5,6,7,8,9,10,11
B.sort(_=>1) | 11,10,9,8,7,6,5,4,3,2,1 | 6,11,1,10,9,8,7,2,5,4,3 | 1,2,3,4,5,6,7,8,9,10,11

Notez que V8 utilise probablement différents algorithmes de tri en fonction de la longueur du tableau (moins ou plus de 10 éléments).

Commenté

f = (                     // f = recursive function taking:
  n,                      //   n   = row counter
  a = [1],                //   a[] = current row, initialized to [1]
  r                       //   r   = 'reverse' flag, initially undefined
) =>                      //
  n-- ?                   // decrement n; if it was not equal to zero:
    f(                    //   do a recursive call with:
      n,                  //     - the updated value of n
      [ ...a.map(n =>     //     - a new array:
          k += n, k = 0   //       - made of the cumulative sum of a[]
        ), k              //         with the last value appended twice
      ].sort(_ => n | r), //       - reversed if n is not equal to 0 or r is set
      !r                  //     - the updated flag r
    )                     //   end of recursive call
  :                       // else:
    a                     //   stop recursion and return a[]
Arnauld
la source
Quelle fonctionnalité spécifique au singe-araignée utilise-t-elle?
Downgoat
@Downgoat Il profite de l'implémentation spécifique de sort()dans ce moteur. J'ai ajouté une explication.
Arnauld
3

Haskell , 89 87 82 octets

(cycle[r,id]!!)<*>s
r=reverse
s 0=[1]
s n=let a=zipWith(+)(0:a)$(r.s$n-1)++[0]in a

sImprime simplement les lignes dans l'ordre zig-zag, la fonction anonyme sur la première ligne inverse la moitié des lignes.

Merci à @nimi d'avoir économisé 5 octets!

Essayez-le en ligne!

Angs
la source
2

Python 3 , 98 91 octets

from itertools import*
f=lambda n:n and[*accumulate(f(n-1)[::n&1or-1]+[0])][::n&1or-1]or[1]

Essayez-le en ligne!

Le passage à une numérotation des lignes basée sur 0 a permis d'économiser 7 octets.

RootTwo
la source
2

Julia 0,6 , 85 octets

r(l,n=cumsum(l))=[n...,n[end]]
w=reverse
f(n)=n<2?[1]:n%2<1?r(f(n-1)):w(r(w(f(n-1))))

Essayez-le en ligne!

Il s'agit d'une solution récursive dans Julia. Notez qu'il a une indexation basée sur 1. D'où les tests.

Version non golfée, pour comprendre la logique:

function new_row(last_row)
    new_row = cumsum(last_row)
    push!(new_row, new_row[end])
    return new_row
end


function triangle(n)
    if n == 1
        return [1]
    elseif mod(n,2) == 0
        return new_row(triangle(n-1))
    else
        return reverse(new_row(reverse(triangle(n-1))))
    end
end

En bonus, voici une version non récursive, mais elle est plus longue:

w=reverse;c=cumsum
r(l,i)=i%2<1?c([l...,0]):w(c(w([0,l...])))
f(n,l=[1])=(for i=2:n l=r(l,i)end;l)
niczky12
la source
1

Python 2 , 103 97 octets

f=lambda n,r=[1],k=2:n and f(n-1,[sum(r[-2::-1][:i],r[-1])for i in range(k)],k+1)or r[::-(-1)**k]

Essayez-le en ligne!

Version non récursive (plus facile à lire):

Python 2 , 106 octets

def f(n,r=[1],j=1):
 while n:
	a=r[-2::-1];r=r[-1:];n-=1;j=-j
	for x in a+[0]:r+=[r[-1]+x]
 return r[::-j]

Essayez-le en ligne!

Certes, mieux est possible!

Chas Brown
la source
1

Python 3 , 91 octets

from numpy import *
s=lambda n:n and cumsum(s(n-1)[::n%2*2-1]+[0]).tolist()[::n%2*2-1]or[1]

Essayez-le en ligne!

Guoyang Qin
la source
Vous pouvez supprimer l'espace entre importet*
12Me21