Gere a trança de Pascal

32

Esta é a trança 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

Eu inventei isso totalmente. Blaise Pascal não tinha uma trança, até onde eu sei, e se ele tinha, provavelmente era feito de cabelo em vez de números.

É definido assim:

  1. A primeira coluna tem uma única 1no meio.
  2. A segunda coluna tem um 1 na parte superior e na parte inferior.
  3. Agora alternamos entre colocar um número no meio ou duas cópias de um número na parte superior e inferior.
  4. Se o número for na parte superior ou inferior, será a soma dos dois números adjacentes (por exemplo, 56 = 15 + 41 ). Se você inclina um pouco a cabeça, é como um passo no triângulo de Pascal.
  5. Se o número ficar no meio, será a soma dos três números adjacentes (por exemplo 41 = 15 + 11 + 15).

Sua tarefa será imprimir (parte de) esta trança.

Entrada

Você deve escrever um programa ou função que receba um único número inteiro n , fornecendo o índice da última coluna a ser impressa.

Você pode escolher se a primeira coluna (imprimindo apenas uma única 1na linha do meio) corresponde a n = 0ou n = 1. Essa deve ser uma escolha consistente em todas as entradas possíveis.

Saída

Saída Braid de Pascal até a nth coluna. O espaço em branco deve corresponder exatamente ao layout de exemplo acima, exceto que você pode preencher a (s) linha (s) mais curta (s) ao comprimento da (s) linha (s) mais longa (s) com espaços e, opcionalmente, pode gerar um único avanço de linha à direita.

Em outras palavras, cada coluna deve ser exatamente tão larga quanto o número (ou par de números iguais) nessa coluna, os números em colunas sucessivas não devem se sobrepor e não deve haver espaços entre as colunas.

Você pode imprimir o resultado em STDOUT (ou a alternativa mais próxima) ou, se escrever uma função, poderá retornar uma string com o mesmo conteúdo ou uma lista de três strings (uma para cada linha).

Detalhes adicionais

Você pode supor que nnão será menor que o índice da primeira coluna (portanto, não será menor que 0ou 1dependendo da sua indexação). Você também pode supor que o último número na trança seja menor que 256 ou o maior número representável pelo tipo inteiro nativo do seu idioma, o que for maior . Portanto, se o seu tipo inteiro nativo puder armazenar apenas bytes, você pode assumir que o maior né 9ou 10(dependendo de você usar com base em 0 ou 1 n) e se ele pode armazenar números inteiros de 32 bits assinados, nserá no máximo 33ou 34.

Aplicam-se as regras padrão de . O código mais curto vence.

OEIS

Aqui estão alguns links OEIS relevantes. Obviamente, eles contêm spoilers de diferentes maneiras de gerar os números na trança:

Casos de teste

Esses casos de teste usam indexação de 1 base. Cada caso de teste tem quatro linhas, sendo a primeira a entrada e as três restantes a saída.

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
fonte
O formato parece um pouco camaleão para mim.
Leaky Nun
3
@LeakyNun Tentei esse desafio enquanto estava na caixa de areia e gastei cerca de metade dos bytes no cálculo da trança e na impressão. Parece-me um excelente equilíbrio para um desafio de arte ascii .
FryAmTheEggman
4
@LeakyNun Eu esperava que tanto a geração de sequências quanto a arte ASCII fossem componentes importantes do desafio, porque a maioria dos idiomas provavelmente será melhor em um desses dois, então imaginei que seria interessante misturá-los. E introduz um componente adicional, onde não é óbvio se é melhor gerar a parte superior / inferior e média separadamente ou a coisa toda e depois separar as bissecções.
Martin Ender
Ninguém escreveu uma solução em Pascal ainda. Isso me deixa triste.
dynamitereed

Respostas:

5

Geléia , 31 30 29 bytes

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

Este é um link monádico; ele aceita um índice de coluna baseado em 0 como argumento e retorna uma lista de seqüências de caracteres.

Experimente online!

Como funciona

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
fonte
12

Pitão , 44 bytes

A geração do número levou 20 bytes e a formatação levou 24 bytes.

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

Experimente 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
Freira Furada
fonte
7
Esse é o maior programa Pyth que eu já vi.
imallett
7

Python 2, 120 bytes

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

Experimente em Ideone.

Lynn
fonte
7

MATL , 38 bytes

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

Experimente online!

Computar uma matriz com os números (únicos) leva os primeiros 17 bytes. A formatação leva os 21 bytes restantes.

Explicação

Parte 1: gerar os números

Isto gera uma matriz com os números das primeira e segunda linhas em ordem crescente: [1; 1; 3; 4; 11; 15; ...]. Ela começa com 1, 1. Cada novo número é obtido iterativamente dos dois anteriores. Desses, o segundo é multiplicado 1ou 2dependendo do índice de iteração e depois somado ao primeiro para produzir o novo número.

O número de iterações é igual à entrada n. Isso significa que os n+2números são gerados. Depois de gerada, a matriz precisa ser cortada para que apenas as primeiras nentradas sejam mantidas.

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

Parte 2: formate a saída

Para cada número na matriz obtida, isso gera duas seqüências de caracteres: representação do número e uma sequência do mesmo comprimento que consiste no caractere 0 repetido (o caractere 0 é exibido como um espaço no MATL). Mesmo para iterações, essas duas seqüências são trocadas.

As duas seqüências são concatenadas verticalmente. Portanto, nmatrizes de caracteres 2D são produzidas da seguinte maneira (usando ·para representar o caractere 0):

·
1

1
·

· 
3

4
·

·· 
11

15
··

Essas matrizes são concatenadas horizontalmente para produzir

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

Por fim, essa matriz de caracteres 2D é dividida em duas linhas e a primeira é duplicada no topo da pilha. As três strings são exibidas em ordem, cada uma em uma linha diferente, produzindo a saída desejada

!       % 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
fonte
6

Haskell, 101 bytes

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

Define uma função f :: Int → [String].

  • Michael Klein me lembrou que eu não precisava chamar unlineso resultado, economizando 7 bytes. Obrigado!

  • Salvei um byte substituindo " 9"!!mod i 2por cycle" 9"!!i.

  • Mais três bytes escrevendo duas listas corecursivas em vez de usar drop.

  • Minha namorada apontou que eu posso salvar mais dois bytes iniciando minhas respostas em 0vez de 1.

Lynn
fonte
3

C, 183 177 176 bytes

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

Explicação

C nunca vai ganhar nenhum prêmio por brevidade contra um idioma de nível superior, mas o exercício é interessante e é uma boa prática.

A macro F retira seis bytes ao custo da legibilidade. As variáveis ​​são declaradas globalmente para evitar várias declarações. Eu precisava de um buffer de caracteres para o sprintf, mas, como o K&R está livre da verificação de tipo, o sprintf e o printf podem interpretar t [9] como um ponteiro para um buffer de 36 bytes. Isso salva uma declaração separada.

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

Função de impressão bonita, em que r é o número da linha. Sprintf formata o número e calcula a largura da coluna. Para economizar espaço, chamamos isso três vezes, um para cada linha de saída; a expressão ri & 1 filtra o que é impresso.

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

Função do ponto de entrada, argumento é o número de colunas. Calcula a matriz a dos valores da coluna a [] e chama a função de impressão p uma vez para cada linha de saída.

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

Chamada de amostra (não incluída na resposta e na contagem de bytes):

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

Atualizada

Incorporou a sugestão de sprint em linha da tomsmeding. Isso reduziu a contagem de 183 para 177 caracteres. Isso também permite remover as chaves ao redor do bloco printf (sprintf ()), já que é apenas uma instrução agora, mas isso só salvou um caractere, porque ainda precisa de um espaço como delimitador. Então, para 176.

maharvey67
fonte
Você não pode incorporar a definição de wonde é usada? Você parece usá-lo apenas uma vez.
tomsmeding 21/07
Você não pode usar em itoavez do sprintf?
Giacomo Garabello
Eu considerei isso, mas ele não existe no meu sistema e estou usando o valor de retorno do sprintf para definir a largura do campo.
maharvey67
2

PowerShell v2 +, 133 bytes

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 bytes para calcular os valores, 70 bytes para formular o ASCII

Recebe a entrada $ncomo a coluna indexada a zero. Define o início da nossa matriz de sequências $a=1,1. Em seguida, fazemos loop até $ncom 1..$n|%{...}para construir a matriz. A cada iteração, concatenamos a soma de (dois elementos atrás) + (o elemento anterior) * (se somos ímpares ou pares). Isso gerará $a=1,1,3,4,11...até$n+2 .

Portanto, precisamos cortar $aapenas os primeiros 0..$nelementos e canalizá-los através de outro loop |%{...}. A cada iteração, definimos helper $zigual a um número de espaços mais o elemento atual como uma string. Então, estamos dividindo se isso é concatenado $x(nas linhas superior e inferior) ou $y(na linha do meio) por um simples ímpar-par if/ else. Em seguida, calculamos o número de espaços $lusando o número atual, especificando-o e obtendo o seu .Length.

Finalmente, nós colocamos $x, $ye $xnovamente no gasoduto, ea saída está implícita. Como o .ToString()separador padrão de uma matriz ao imprimir em STDOUT é uma nova linha, obtemos isso de graça.

Exemplo

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
fonte
0

PHP 265 bytes

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

Sem golfe:

$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 bytes

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
fonte
0

Ruby, 120 bytes

Retorna uma cadeia de linhas múltiplas.

Experimente 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]*$/}
Value Ink
fonte
0

Matlab, 223 caracteres, 226 bytes

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

Ungolfed e comentou:

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
fonte
0

PHP, 135 124 123 120 bytes

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

tirando proveito de previsões implícitas e variáveis ​​variáveis,
um terço do código (37 bytes) vai para os espaços, 64 bytes totalmente usados ​​para saída

demolir

$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
fonte
0

Lote, 250 bytes

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

Como a primeira e a terceira linhas são as mesmas, só precisamos criar duas strings. Aqui drepresenta a sequência que termina com a última entrada e srepresenta a sequência que termina com espaços; as últimas quatro linhas garantem que elas sejam impressas na ordem apropriada. ié apenas o contador de loops (é um pouco mais barato que a contagem regressiva %1). jé a alternância entre dobrar o número anterior antes de adicioná-lo ao número atual para obter o próximo número. me ncontém esses números. l, além de ser usado temporariamente para calcular o próximo número, também substitui seus dígitos por espaços para preencher s; se dsão trocados sempre pela variável intermediária t.

Neil
fonte