Generar trenza de Pascal


32

Esta es la trenza 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

Lo inventé totalmente. Blaise Pascal no tenía una trenza, por lo que puedo decir, y si la tenía, probablemente estaba hecha de cabello en lugar de números.

Se define así:

  1. La primera columna tiene un sencillo 1en el medio.
  2. La segunda columna tiene un 1en la parte superior y en la parte inferior.
  3. Ahora alternamos entre poner un número en el medio o dos copias de un número en la parte superior e inferior.
  4. Si el número va arriba o abajo, será la suma de los dos números adyacentes (p 56 = 15 + 41. Ej .). Si inclinas un poco la cabeza, esto es como un paso en el triángulo de Pascal.
  5. Si el número va en el medio, será la suma de los tres números adyacentes (por ejemplo 41 = 15 + 11 + 15).

Su tarea será imprimir (alguna parte de) esta trenza.

Entrada

Debe escribir un programa o función, que recibe un solo número entero n, dando el índice de la última columna que se generará.

Puede elegir si la primera columna (imprimiendo solo una 1en la línea central) corresponde a n = 0o n = 1. Esto tiene que ser una elección consistente en todas las entradas posibles.

Salida

Salida de trenza de Pascal hasta la ncolumna th. El espacio en blanco debe coincidir exactamente con el diseño de ejemplo anterior, excepto que puede rellenar las líneas más cortas a la longitud de las líneas más largas con espacios y, opcionalmente, puede generar un solo salto de línea final.

En otras palabras, cada columna debe ser exactamente tan ancha como el número (o par de números iguales) en esa columna, los números en columnas sucesivas no deben superponerse y no debe haber espacios entre columnas.

Puede imprimir el resultado en STDOUT (o la alternativa más cercana), o si escribe una función, puede devolver una cadena con el mismo contenido o una lista de tres cadenas (una para cada línea).

Más detalles

Puede suponer que nno será menor que el índice de la primera columna (por lo tanto, no será menor 0o 1dependerá de su indexación). También puede suponer que el último número en la trenza es menor que 256 o el número más grande representable por el tipo entero nativo de su idioma, el que sea mayor . Entonces, si su tipo de entero nativo solo puede almacenar bytes, puede suponer que el más grande nes 9o 10(dependiendo de si usa 0 o 1 n) y si puede almacenar enteros de 32 bits con signo, nserá como máximo 33o 34.

Aplican reglas estándar de . El código más corto gana.

OEIS

Aquí hay algunos enlaces OEIS relevantes. Por supuesto, estos contienen spoilers de diferentes formas de generar los números en la trenza:

Casos de prueba

Estos casos de prueba usan indexación de 1 base. Cada caso de prueba tiene cuatro líneas, siendo la primera la entrada y las tres restantes la salida.

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

El formato me parece un poco camaleónico.
Leaky Nun

3
@LeakyNun Intenté este desafío mientras estaba en la caja de arena, y gasté aproximadamente la mitad de bytes en calcular la trenza que imprimirla. Esto me parece un excelente equilibrio para un desafío ascii-art .
FryAmTheEggman

44
@LeakyNun Esperaba que tanto la generación de secuencia como el arte ASCII sean componentes importantes del desafío, porque la mayoría de los idiomas probablemente serán mejores en uno de esos dos, así que pensé que sería interesante mezclarlos. Y presenta un componente adicional donde no es obvio si es mejor generar arriba / abajo y el medio por separado o generar todo y luego separar las bisecciones.
Martin Ender


Nadie ha escrito una solución en Pascal todavía. Esto me pone triste.
dynamitereed

Respuestas:


5

Jalea , 31 30 29 bytes

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

Este es un enlace monádico; acepta un índice de columna basado en 0 como argumento y devuelve una lista de cadenas.

Pruébalo en línea!

Cómo 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.

12

Pyth , 44 bytes

La generación del número tomó 20 bytes y el formato tomó 24 bytes.

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

Pruébalo en línea!

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

77
Ese es el programa Pyth más grande que he visto.
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

Pruébalo en Ideone.


7

MATL , 38 bytes

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

Pruébalo en línea!

Calcular una matriz con los números (únicos) toma los primeros 17 bytes. El formateo toma los 21 bytes restantes.

Explicación

Parte 1: genera los números

Esto genera una matriz con los números de la primera y segunda filas en orden creciente: [1; 1; 3; 4; 11; 15; ...]. Se inicia con 1, 1. Cada nuevo número se obtiene iterativamente de los dos anteriores. De ellos, el segundo se multiplica por 1o 2según el índice de iteración, y luego se suma al primero para producir el nuevo número.

El número de iteraciones es igual a la entrada n. Esto significa que n+2se generan números. Una vez generada, la matriz necesita recortarse para que solo nse conserven las primeras entradas.

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: formatear la salida

Para cada número en la matriz obtenida, esto genera dos cadenas: representación de cadena del número y una cadena de la misma longitud que consiste en el carácter 0 repetido (el carácter 0 se muestra como un espacio en MATL). Para iteraciones pares, estas dos cadenas se intercambian.

Las dos cadenas se concatenan verticalmente. Entonces, las nmatrices de caracteres 2D se producen de la siguiente manera (usando ·para representar el carácter 0):

·
1

1
·

· 
3

4
·

·· 
11

15
··

Estas matrices se concatenan horizontalmente para producir

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

Finalmente, esta matriz de caracteres 2D se divide en sus dos filas, y la primera se duplica en la parte superior de la pila. Las tres cadenas se muestran en orden, cada una en una línea diferente, produciendo la salida deseada

!       % 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 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 una función f :: Int → [String].

  • Michael Klein me recordó que no necesitaba llamar unlinesal resultado, ahorrando 7 bytes. ¡Gracias!

  • Ahorré un byte reemplazándolo " 9"!!mod i 2con cycle" 9"!!i.

  • Tres bytes más escribiendo dos listas corecursive en lugar de usar drop.

  • Mi novia señaló que puedo guardar dos bytes más al comenzar mis respuestas en 0lugar de 1.


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

Explicación

C nunca va a ganar ningún premio por brevedad contra un lenguaje de nivel superior, pero el ejercicio es interesante y una buena práctica.

La macro F elimina seis bytes a costa de la legibilidad. Las variables se declaran globalmente para evitar múltiples declaraciones. Necesitaba un búfer de caracteres para sprintf, pero dado que K&R no funciona con la verificación de tipos, sprintf e printf pueden interpretar t [9] como un puntero a un búfer de 36 bytes. Esto guarda una declaración por separado.

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

Bonita función de impresión, donde r es el número de fila. Sprintf formatea el número y calcula el ancho de la columna. Para ahorrar espacio, lo llamamos tres veces, una para cada fila de salida; la expresión ri & 1 filtra lo que se imprime.

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

Función de punto de entrada, el argumento es el número de columnas. Calcula la matriz a de valores de columna a [], luego llama a la función de impresión p una vez para cada fila de salida.

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

Invocación de muestra (no incluida en el conteo de respuestas y bytes):

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

Actualizado

Se incorporó la sugerencia de sprintf en línea de tomsmeding. Eso redujo el recuento de 183 a 177 caracteres. Esto también permite eliminar los corchetes alrededor del bloque printf (sprintf ()) ya que ahora es solo una declaración, pero eso solo salvó un carácter porque todavía necesita un espacio como delimitador. Así que hasta 176.


¿No puedes incluir la definición de wdónde se usa? Parece que solo lo usas una vez.
tomsmeding

¿No puedes usar en itoalugar de sprintf?
Giacomo Garabello

Lo consideré isoa, pero no existe en mi sistema, y ​​estoy usando el valor de retorno de sprintf para establecer el ancho del 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 los valores, 70 bytes para formular el ASCII

Toma la entrada $ncomo la columna de índice cero. Establece el inicio de nuestra matriz de secuencia $a=1,1. Luego hacemos un bucle con $ncon 1..$n|%{...}para construir la matriz. Cada iteración, concatenamos en la suma de (hace dos elementos) + (el elemento anterior) * (ya sea que estemos impares o pares). Esto generará $a=1,1,3,4,11...hasta $n+2.

Entonces, necesitamos cortar $apara tomar solo los primeros 0..$nelementos y canalizarlos a través de otro bucle |%{...}. En cada iteración establecemos helper $zigual a un número de espacios más el elemento actual como una cadena. Luego, estamos dividiendo si eso se concatena en $x(las filas superior e inferior) o $y(la fila central) por un simple impar if/ par / else. Luego, calculamos el número de espacios para $ltomar el número actual, encadenarlo y tomar su .Length.

Por último, ponemos $x, $yy $xde nuevo en la tubería, y la salida es implícita. Dado que el .ToString()separador predeterminado para una matriz al imprimir en STDOUT es una nueva línea, lo obtenemos de forma gratuita.

Ejemplo

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

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

0

Ruby, 120 bytes

Devuelve una cadena multilínea.

Pruébalo en línea!

->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]*$/}

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 y comentó:

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

aprovechando los tipos de letra implícitos y las variables variables,
un tercio del código (37 bytes) va a los espacios, 64 bytes en total utilizados para la salida

Descompostura

$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

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 la primera y la tercera línea son iguales, solo tenemos que construir dos cadenas. Aquí drepresenta la cadena que termina con la última entrada y srepresenta la cadena que termina con espacios; Las últimas cuatro líneas aseguran que se impriman en el orden apropiado. ies solo el contador de bucles (es un poco más barato que contar desde atrás %1). jes la alternancia entre duplicar el número anterior antes de agregarlo al número actual para obtener el siguiente número. my ncontienen esos números. l, además de ser utilizado como temporal para calcular el siguiente número, también reemplaza sus dígitos con espacios para rellenar s; sy dse intercambian cada vez a través de la variable intermedia t.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.