Rhombus de Pascal

20

O Rhombus de Pascal (que na verdade é um triângulo) é obtido adicionando o padrão:

  *
 ***
  x

ao invés de

* *
 x

Isso significa que cada célula é a soma das três células na linha diretamente acima dela e uma célula na linha 2 acima dela. Assim como o triângulo de Pascal, a linha zeroth tem uma única 1que gera o triângulo.

Aqui estão as primeiras linhas do Rhombus de Pascal

      1
    1 1 1
  1 2 4 2 1
1 3 8 9 8 3 1

Tarefa

Dado um número de linha (a partir do topo) e um número de coluna (a partir do primeiro item diferente de zero nessa linha) gera o valor nessa célula específica. Ambas as entradas podem ser indexadas 1 ou 0 (você pode misturar e combinar, se desejar).

Este é um portanto, você deve tentar tornar o tamanho do arquivo do seu código-fonte o menor possível.

OEIS A059317

Assistente de Trigo
fonte
4
Como no triângulo de Pascal, a paridade do losango cria padrões agradáveis ​​e fractais .
Martin Ender
você deve tentar tornar o tamanho do arquivo do seu código-fonte o menor possível, e se eu colocar meu código como argumento da linha de comando? : P
Erik the Outgolfer
Pesquisei atalhos no Google e aparentemente arxiv.org/abs/1504.04404 diz que calcular o resultado diretamente é inutilizável para o código de golfe.
JollyJoker

Respostas:

12

Haskell , 59 55 bytes

Losango de Pascal? Mais como o Rhombus de Haskell! Estou certo?

4 bytes salvos graças a Ørjan Johansen

Eu pensei em tentar meu próprio problema e praticar meu Haskell. Espero que isso inspire mais pessoas a responder a isso.

1!1=1
n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1]

Experimente online!

Explicação

Está um pouco desatualizado com as últimas novidades em golfe

Em vez de calcular

  *
 ***
  x

Calculamos

*
***
  x

Isso inclina todo o nosso triângulo para se tornar

1
1 1 1
1 2 4 2 1
1 3 8 9 8 3 1

Isso alinha todas as nossas linhas, facilitando a indexação do enésimo item de qualquer coluna. Em seguida, definimos nossos casos base.

A linha zeroth é toda zeros, então

0!_=0

Há um único 1na posição, 1,1então definimos que

1!1=1

E definimos o resto da primeira linha como zeros também

1!_=0

Em seguida, definimos o caso geral recursivamente usando o padrão descrito acima:

n!k=(n-2)!(k-2)+(sum$map((n-1)!)[k-2..k])
Assistente de Trigo
fonte
Bata-me para isso! Isso também é muito mais limpo que o meu.
Julian Lobo
@ JulianWolf Desculpe por isso, quando publiquei isso, parecia que ninguém além de Jorg estava fazendo o problema. Eu ainda gostaria de ver sua solução.
Wheat Wizard
1
Você pode salvar quatro bytes com n!k=sum[(n-2)!(k-2)+sum(map((n-1)!)[k-2..k])|n>1].
Ørjan Johansen
10

Pascal , 122 bytes

Bem, é o losango de Pascal .

37 bytes salvos graças a @manatwork

function f(n,k:integer):integer;begin f:=1-Ord((k<0)or(k>n*2));if n>0then f:=f(n-1,k-2)+f(n-1,k-1)+f(n-1,k)+f(n-2,k-2)end;

Experimente online!

Uriel
fonte
Parênteses em torno de toda a ifcondição são inúteis. (No 1º ifvocê salva 2 caracteres, no 2º ifcaractere, não deixando espaço entre a thenpalavra-chave e o dígito anterior.) Ah, e a variável r é completamente desnecessária.
Manatwork
Animal estranho que Pascal em Ideone. Nunca vi aspas delimitadas por aspas duplas em nenhuma variante de Pascal antes. Mais uma coisa que você pode remover: o ;antes do function's end.
Manatwork
@manatwork sim, agora que você mencionou, todos os outros editores on-line reclamou sobre isso
Uriel
@ manatwork Não sei se entendi. wouldnt que apenas prolongar o código com o >= <=? Eu ainda preciso preservar oif n=0
Uriel
Desculpe @ Uriel, eu não tenho mais essa versão. Atualmente estou emfunction f(n,k:integer):integer;begin f:=1-Ord((k<0)or(k>n*2));if n>0then f:=f(n-1,k-2)+f(n-1,k-1)+f(n-1,k)+f(n-2,k-2)end;
manatwork
7

PHP , 86 bytes

forma recursiva apenas a linha de função e coluna 0 indexadas

function f($r,$c){return$r|$c?$r<0?0:f($r-=1,$c)+f($r,$c-1)+f($r,$c-=2)+f($r-1,$c):1;}

Experimente online!

PHP , 114 bytes

maneira recursiva linha e coluna completas do programa 0-indexadas

<?=f(...$_GET);function f($r,$c){return$r|$c?$r<0|$c<0|$c>2*$r?0:f($r-=1,$c)+f($r,$c-1)+f($r,$c-=2)+f($r-1,$c):1;}

Experimente online!

PHP , 129 bytes

linha e coluna 0-indexadas

for(;$r<=$argv[1];$l=$t[+$r++])for($c=~0;$c++<$r*2;)$t[+$r][$c]=$r|$c?$t[$r-2][$c-2]+$l[$c]+$l[$c-1]+$l[$c-2]:1;echo$l[$argv[2]];

Experimente online!

Jörg Hülsermann
fonte
e uma para realmente melhorar o :)
Uriel
4

Geléia , 22 20 19 bytes

3ḶṚp@Ḣḣ4
Ḟ_ЀÇ߀ȯ¬S

Toma um par de índices com base em 0 como argumento da linha de comandos.

Experimente online!

Dennis
fonte
3

MATL , 22 20 19 bytes

Ti:"2Y6Y+FT_Y)]!i_)

Ambas as entradas são baseadas em 0.

Experimente online!

Explicação

Deixe rec denote as duas entradas, especificando linha e coluna com base em 0, respectivamente.

Cada nova linha no losango de Pascal pode ser construída a partir da matriz que contém as duas linhas anteriores, convolvendo com o kernel [1 1 1; 0 1 0]e mantendo as duas últimas linhas do resultado trocadas. Isso é feito rvezes, a partir da matriz 1.

É mais curto usar o kernel [0 1 0; 1 1 1; 0 1 0], que é um literal predefinido. Isso produz uma linha extra, que será descartada.

Considere, por exemplo r = 3, as 3iterações.

  1. Começando de

    1
    

    convolução com [0 1 0; 1 1 1; 0 1 0]

    0 1 0
    1 1 1
    0 1 0
    

    Manter as duas últimas linhas (a matriz inteira, neste caso) e trocá-las fornece

    0 1 0
    1 1 1
    
  2. Convolução do acima com [0 1 0; 1 1 1; 0 1 0]

    0 0 1 0 0
    0 1 1 1 0
    1 2 4 2 1
    0 1 1 1 0
    

    A matriz formada pelas duas últimas linhas trocadas é

    0 1 1 1 0
    1 2 4 2 1
    

    Contém a nova linha na parte inferior e a anterior estendida com zeros.

  3. A participação novamente produz

    0 0 1 1 1 0 0
    0 1 2 3 2 1 0
    1 3 8 9 8 3 1
    0 1 2 4 2 1 0
    

    Tomando as duas últimas linhas trocadas,

    0 1 2 4 2 1 0
    1 3 8 9 8 3 1
    

Após as riterações, a saída é contida na última linha da matriz final. Por exemplo, para c = 2(com base em 0) o resultado seria 8. Em vez de indexar a última linha e a coluna desejada, um truque pode ser usado para explorar a simetria de cada linha: a matriz final é transposta

0 1
1 3
2 8
4 9
2 8
1 3
0 1

e seu -c-ésimo elemento é obtido. Isso usa indexação linear, ou seja, a matriz é indexada por um único índice na ordem principal da coluna . Como a indexação é modular , a 0-entry é o canto inferior direito (valor 1) e a -2-a entrada é duas etapas acima (valor 8).

T       % Push true
i       % Input row number
:"      % Do the following that many times
  2Y6   %   Push predefined literal [0 1 0; 1 1 1; 0 1 0]
  Y+    %   2D convolution, increasing size
  FT_   %   Push [0 -1]
  Y)    %   Matrix with rows 0 (last) and -1 (second-last), in that order
]       % End
!       % Transpose
i       % Input: colun number
_       % Negate
)       % Entry with that index. Implicitly display
Luis Mendo
fonte
3

Pari / GP , 60 bytes

i->j->polcoeff(Vec(1/(1-x*(1+y+y^2+x*y^2))+O(x^i++))[i],j,y)

Experimente online!

alefalpha
fonte
2

Haskell , 74 bytes

0#0=1
n#m|m<=2*n&&m>=0=sum[(n-a)#(m-b)|(a,b)<-zip[2,1,1,1]$2:[0..2]]
n#m=0

Experimente online!

Ligue com n # m, onde nestá a linha e ma coluna.

Julian Wolf
fonte
m<=2*n&&m>=0pode ser justo n>0.
Ørjan Johansen
2

Mathematica, 56 bytes

If[#<1,Boole[##==0],Sum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]]&

Função pura, recebendo dois argumentos inteiros (linha primeiro, coluna segundo) e retornando um número inteiro. Também funciona para argumentos inteiros negativos, retornando 0. Uma estrutura recursiva bastante direta: If[#<1,Boole[##==0],...]define o comportamento de caso base para a 0a linha (e acima), enquanto Sum[#0[#-i,#2-j],{i,2},{j,2i-2,2}]implementa a definição recursiva.

Greg Martin
fonte
1

JavaScript (ES6), 68 bytes

f=(y,x)=>x<0|x>y+y?0:x>0&x<y+y?f(--y,x)+f(y,--x)+f(y,--x)+f(--y,x):1
Neil
fonte
1

Mathematica, 53 bytes

D[1/(1-x(1+y+y^2(1+x))),{x,#},{y,#2}]/#!/#2!/.x|y->0&

Usando a função geradora.

alefalpha
fonte
0

Python 3 , 82 84 bytes

Esta é uma implementação recursiva com linhas e colunas indexadas a 1. (Tecnicamente precisa de um f=na frente, alguém me avise se devo alterá-lo para 84 bytes. Ainda novo e sem 100% de certeza das regras.)

Isso usa a fórmula recursiva encontrada na página OEIS , mas com a ktecla deslocada para a esquerda para alinhar corretamente. Coincidentemente, sum(f(n-1,k-i)for i in(0,1,2))é do mesmo tamanho que f(n-1,k)+f(n-1,k-1)+f(n-1,k-2). Toda a função é o and ortruque do Python , onde a primeira condição verifica se k está dentro do triângulo e não no limite; nesse caso, a fórmula recursiva é usada. Se is is não, a parte após a oré retornada, que verifica se kestá dentro (1, 2*n-1), ou seja, na fronteira, retornando Truee False. k+1in(2,2*n)é um byte menor que k in(1,2*n-1). Envolvê-lo entre parênteses e colocar um +na frente se converte em número inteiro, o que é necessário.

f=lambda n,k:2*n-1>k>1and sum(f(n-1,k-i)for i in(0,1,2))+f(n-2,k-2)or+(k+1in(2,2*n))

Experimente online!

C McAvoy
fonte
Funções recursivas precisam do f=.
Assistente de trigo
Embora eu pessoalmente não concorde com isso de acordo com este meta consenso um tanto enterrado, você pode produzir em Truevez de, 1porque se comporta como o 1python. Isso permite que você remova o +(...)no final. Entendo que se você não quiser fazer isso, porque fará com que a saída pareça um pouco estranha, é uma opção.
Assistente de trigo
@ WheatWizard Uau, isso é muito interessante. Obrigado pela dica.
C McAvoy
0

Java (OpenJDK 8) , 87 bytes

int f(int r,int c){return c<0|2*r<c?0:0<c&c<2*r?f(--r,c)+f(r,--c)+f(r,--c)+f(--r,c):1;}

Experimente online!

No começo, fiquei feliz com meu método iterativo de 160 bytes ... Hmmm ... vamos esquecer, ok?

Olivier Grégoire
fonte
0

Python 3 , 75 bytes

Este é um lambda recursivo que utiliza coluna e linha como números inteiros indexados a 0.

p=lambda r,c:(r<0 or((c==0)|p(r-1,c-2)+p(r-1,c)+p(r-1,c-1)+p(r-2,c-2))+1)-1

Aqui está uma versão (ligeiramente) mais legível com uma função de impressão:

p = lambda r,c:(r<0 or ((c==0) | p(r-1,c-2)+p(r-1,c)+p(r-1,c-1)+p(r-2,c-2))+1)-1

def pp(r):
    ml = len(str(p(r,r)))+1
    for i in range(0, r):
            a=" "*ml*(r-i)
            for j in range(0,i*2 + 1):
                    a+=str(p(i,j))+(" "*(ml-len(str(p(i,j)))))
            print(a)
Eric Canam
fonte