Tabla divisoria principal

28

Introducción

Algo con lo que he jugado en matemáticas recreativas ha sido la construcción de una tabla de divisores para comparar / contrastar visualmente los divisores primos de un conjunto de números. El conjunto de números de entrada se encuentra en la parte superior como etiquetas de columna, los divisores primos están a la izquierda como etiquetas de fila y una marca indica dónde se alinean los dos.

Por ejemplo, para la entrada 6, 9, 14, 22se construiría una tabla similar a la siguiente:

    6  9 14 22
 2  *     *  *
 3  *  *
 7        *
11           *

Esto se debe a que 6tiene divisores primos de 2y 3, 9tiene divisores primos de 3, y así sucesivamente.

Construcción

  • La tabla está construida de tal manera que los números de entrada forman etiquetas de columna que están separadas por espacios y en orden ascendente (puede suponer que están ordenadas previamente), y los divisores primos se enumeran a la izquierda en orden ascendente uno por línea que forma la fila etiquetas.
  • Tenga en cuenta que los espacios iniciales en los divisores primos y los números de entrada pueden ser necesarios si los números tienen longitudes diferentes, de modo que todas las columnas tengan el mismo ancho y se alineen adecuadamente.
  • Cada divisor está representado por un solo *(u otro carácter ASCII adecuado de su elección, siempre que se utilice el mismo carácter para todas las ocurrencias).
  • Se ignoran múltiples divisores (por ejemplo, 3 x 3 = 9pero solo hay uno *para esa intersección).
  • El *se puede colocar en cualquier lugar horizontalmente en la columna, siempre que no sea ambiguo (tengo todos mis ejemplos con el *alineado a la derecha).

Entrada

  • Una lista de enteros positivos en cualquier formato conveniente , cada uno >1.
  • Puede suponer que la entrada está ordenada previamente.
  • Se garantiza que la entrada solo tiene valores únicos.

Salida

La representación de arte ASCII resultante de la tabla de divisores primos.

Reglas

  • Las nuevas líneas o espacios en blanco iniciales o finales son opcionales, siempre que los caracteres se alineen correctamente.
  • Si es más corto tener una línea divisoria que separe los encabezados de columna / fila de los datos tabulares, también está permitido.
  • Un programa completo o una función son aceptables. Si es una función, puede devolver el resultado en lugar de imprimirlo.
  • Si es posible, incluya un enlace a un entorno de prueba en línea para que las personas puedan probar su código.
  • Las lagunas estándar están prohibidas.
  • Este es el por lo que se aplican todas las reglas habituales de golf, y gana el código más corto (en bytes).

Ejemplos

6,9,14,22

    6  9 14 22
 2  *     *  *
 3  *  *
 7        *
11           *


2,3,5,7

  2 3 5 7
2 *
3   *
5     *
7       *

2,4,8,16,32

   2  4  8 16 32
2  *  *  *  *  *

75,99,151,153

     75  99 151 153
  3   *   *       *
  5   *
 11       *
 17               *
151           *
AdmBorkBork
fuente
1
¿Podemos tener líneas divisorias después de la fila superior y la columna izquierda?
ngenisis
@ngenisis Claro, lo permitiré. La formulación exacta de la tabla es bastante abierta, ya que ese no es el objetivo exacto de este desafío.
AdmBorkBork

Respuestas:

5

Mathematica, 101 90 bytes

¡Gracias a ngenisis por guardar 11 bytes!

TableForm[Outer[If[#∣#2,Y,""]&,f=#&@@@FactorInteger[1##],g={##}],TableHeadings->‌{f,g}]&

El carácter de aproximadamente un tercio del camino es U + 2223 (3 bytes). Función sin nombre de un número variable de argumentos, cada uno de los cuales es un número entero distinto de cero, que devuelve un TableFormobjeto (salida formateada) así:

Salida de TableForm

f=#&@@@FactorInteger[1##]define fcomo el conjunto de todos los números primos que dividen cualquiera de las entradas (de manera equivalente, dividiendo su producto 1##), mientras que ges la lista que consta de las entradas. Outer[If[#∣#2,Y,""]&,f,g]crea una tabla de Ysy cadenas vacías correspondientes a la divisibilidad (utilizamos el token indefinido en Ylugar de una cadena "Y"o "*"para guardar dos bytes). Luego, usamos TableForm[...,TableHeadings->‌{f,g}]para formatear la matriz resultante con encabezados de fila y columna apropiados.

Presentación previa:

Grid[p=Prepend;Thread[q[Outer[If[#∣#2,Y,""]&,f=#&@@@FactorInteger[1##],g={##}]~p~g,f~p~""]]/.q->p]&
Greg Martin
fuente
Puedes dejar de lado el primero "".
Martin Ender
2
TableForm[Outer[If[#∣#2,Y,""]&,f=#&@@@FactorInteger[1##],g={##}],TableHeadings->{f,g}]&si se permiten divisores
ngenisis
Y el segundo también si lo cambias a p[f,].
Martin Ender
Se permiten líneas de cuadrícula para separar los encabezados.
AdmBorkBork
1
TableFormes genial, ¡espero que se quede en mi caja de herramientas!
Greg Martin
3

Jalea , 18 bytes

PÆfQ0;ðḍ€+W}⁸;"o⁶G

Utiliza en 1lugar de *, según lo permitido por las reglas.

Pruébalo en línea!

Cómo funciona

PÆfQ0;ðḍ€+W}⁸;"o⁶G  Main link. Argument: A (array of integers greater than 1)

P                   Take the product of the integers in A.
 Æf                 Compute all prime factors (with multiplicity) of the product.
   Q                Unique; deduplicate the prime factors.
    0;              Prepend a 0. Let's call the result P.
      ð             Begin a new, dyadic chain. Left argument: P. Right argument: A
       ḍ€           Divisible each; for each p in P, test all integers in A for
                    divisibility by P. Yields one row of the shape of A for each p.
                    Note that the first element of P is 0, so the first row of the
                    resulting matrix contains only zeroes.
          W}        Wrap right; yield [A].
         +          Add the results to both sides. Because of how Jelly's auto-
                    vectorization works, this adds the first row of [A] (just A) to
                    the first row of the divisibility matrix (all zeroes) and
                    leaves the other rows untouched.
            ⁸;"     Prepend the elements of P to the corresponding rows of the
                    previous result.
               o⁶   OR space; replace all zeroes with spaces.
                 G  Grid; format the matrix as requested in the challenge spec.
Dennis
fuente
2

Jalea , 25 23 bytes

PÆfQ©ḍþµị⁾* ³;"Z⁶;®¤;"G

Pruébalo en línea!

¿Cómo?

Puede ser más corto de usar ÆEy filtrar filas vacías.

PÆfQ©ḍþµị⁾* ³;"Z⁶;®¤;"G - Main link: list of numbers, L
       µ                - monadic chain separation
P                       - product of L - multiply them all together
 Æf                     - prime factors (with repetitions, in ascending order)
   Q                    - unique items, maintaining order
                              - note that the product was performed to keep order
    ©                   - place in the register for later use, and yield
      þ                   - form the outer product of that and L using the dyad:
     ḍ                  -     isDivisor - 1 if divides, 0 if not
        ị⁾* <space      - index into "* " (1s to "*", 0s to " ")
            ³           - program's first input, L
             ;"         - zip with concatenation (column headers to the left)
               Z        - transpose (get it around the right way)
                   ¤    - nilad followed by link(s) as a nilad
                ⁶;®     - space (⁶) concatenated with (;) the register value (®)
                    ;"  - zip with concatenation (row labels to the left)
                      G - format the result as a grid (join items with spaces and
                                               rows with line feeds so they align)
                        - implicit print
Jonathan Allan
fuente
2

JavaScript (ES6), 264 260 ... 179 173 bytes

a=>[for(c of s=' '.repeat(w=a.slice(-1),i=0))if(!+(r=[i++?i:s,...i<2?a:a.map(x=>x%i&&c)].map(y=>(s+y).slice(-(w+1).length),a=a.map(d=x=>i<2|x%i?x:d(x/i))).join``))r].join`
`

Creo que este enfoque ahora ha superado permanentemente el recursivo (actualmente 178 bytes):

f=(a,i=0,w=a.slice(-1))=>i++-w?(+(r=[i<2?'':i,...i<2?a:a.map(x=>x%i&&' ')].map(y=>(' '.repeat(w)+y).slice(-(w+1).length)).join``)?'':r+`
`)+f(a.map(d=x=>i<2|x%i?x:d(x/i)),i,w):''

Usos 0en lugar de *, que está permitido por el desafío.

Fragmento de prueba

ETHproducciones
fuente
Si no me equivoco, se puede utilizar el |operador de la sentencia if, ya que está comparando 2 booleanos ...
Lucas
@Luke Hola, tienes razón. No sabe cómo me perdí
ETHproductions
¿No es más corto mover el i<2cheque dentro de la .mapfunción?
Lucas
@Luke Si te refieres a cambiar ...i<2?a:a.map(x=>x%i&&c)a ...a.map(x=>i<2?x:x%i&&c), eso no es más corto. Si te refieres a moverlo al otro .map , tal vez ...
ETHproductions
2

Python 2 - 197 bytes

Cambió a Python 2 para facilitar el manejo de entradas y permitir `` la conversión de cadenas. Usos gmpy2para generar el próximo primo. El formato de salida aún se basa en el envío anterior de Python 3 (ver más abajo), es decir, llenar una lista gcon símbolos y formatearla.

import gmpy2
i=input()
n=len(i)+1
p=1;g=[' ']+i
while p<i[-1]:
 p=gmpy2.next_prime(p)
 t=['*'[m%p:]for m in i]
 if'*' in t:g+=[p]+t
print((('{:>%d}'%(len(`i[-1]`)+1)*n+'\n')*(len(g)/n)).format(*g))

Pruébalo en línea!

Explicación

Para aquellos que no quieren decodificarlo ellos mismos.

import gmpy2                    # arithmetic library
i=input()
n=len(i)+1                      # saves bytes by not needing ()
                                # afterwards
p=1                             # starting number
g=[' ']+i                       # initialsing header row
while p<i[-1]:                  # looping until last character
  p=gmpy2.next_prime(p)         # get the next prime
  t=['*'[m%p:] for m in i]      # verify whether p is a 
                                # divisor of each number
  if'*'in t:g+=[p]+t            # if any divisor found, append
                                # p + divisors to g.
print(
    (('{:>%d}'%(len(`i[-1]`)+1) # compute right formatting element
                                # for length of last character + 1
        *n+'\n'                 # repeat for each input + once
                                # for the prime and add newline
     )*(len(g)/n)               # repeat row format until g
                                # can be inserted
    ).format(*g)                # format using g
)


Anterior

Python 3 - 251 bytes

Estoy bastante seguro de que alguien puede hacerlo mejor. Basado en esta respuesta para generar los primos < k.

i=list(map(int,input().split(',')))
l=len(str(i[-1]))+1
n=len(i)+1
g=[0]+i+sum([l for l in [[k]+[j%k==0for j in i]for k in range(2,i[-1])if all(k%f for f in range(2,k))]if 1in l],[])
print((('{:>%d}'%l*n+'\n')*(len(g)//n)).format(*g).replace('0',' '))

Seguirá una versión no explicada y una explicación.

PidgeyUsedGust
fuente
44
Bienvenido a PPCG!
AdmBorkBork
1
En lugar de i=list(map(int,input().split(',')))hacerlo i=input(), podría hacerlo y tomar la entrada en el formulario [1, 2, 3, 4].
nedla2004
Gracias, no lo sabía. Pero voy a volver a trabajar más tarde de todos modos :).
PidgeyUsedGust
Puede guardar 2 bytes p=gmpy2.next_prime(p);t=['*'[m%p:]for m in i]y eliminar el espacio en if"*" in.
Trelzevir
1

Mathematica, 165 bytes

Más bien detallado, tal vez alguien pueda hacer algo con él:

(j=Join;a=#[[All,1]]&/@FactorInteger@#;b=Sort@DeleteDuplicates@Flatten@a;Grid[j[{j[{""},#]},Transpose@j[{b},Table[If[MemberQ[a[[t]],#],"*",""]&/@b,{t,Length@a}]]]])&
martín
fuente
1

Bash utilidades + GNU, 134 133 132 125 123 bytes

q=printf\ ;u=$q%9s
$u
$q%9d $@
echo
for p in $($u\\n `factor $@`|bc|sort -un)
{
$q%9d $p
for x;{ ((x%p))&&$u||$u X;}
echo
}

Pruébalo en línea!

Mitchell Spector
fuente
1

Python 2 , 181 179 bytes

-2 bytes gracias a FlipTack

n=input()
p=[]
t="%%%ss "%len(`n[-1]`)*-~len(n)
print t%(('',)+n)
i=2
while n[-1]/i:
 if all(i%j for j in p):
	p+=[i];s=['*'[m%i:]for m in n]
	if'*'in s:print t%tuple([i]+s)
 i+=1

La entrada debe ser una tupla.
Pruébalo en línea!

Barra
fuente
¿ all(i%j for j in p)Funciona en lugar de usar map?
FlipTack
@FlipTack sí, fue mejor, pero cambié algo y olvidé la actualización
Rod
1

Lote, 451 bytes

@echo off
set/am=0,w=2,p=1
for %%n in (%*)do set/a"n=m-%%n,m+=(n>>31)*n
for /l %%i in (0,1,9)do set/am/=10,w+=!!m
set s=
for %%n in ("" %*)do set t=%%~n&call:t
set v=%*
:g
if not %s: =%==%p% echo%s%
if %m%==1 exit/b
set/at=p+=1,m=0
set s=
call:t
set v=&for %%n in (%v%)do set n=%%n&set t=&call:c
goto g
:c
set/ar=n%%p
if %r%==0 set/an/=p&set t=*&goto c
set/a"m|=n
set v=%v% %n%
:t
set t=           %t%
call set s=%%s%%%%t:~-%w%%%

Explicación: Comienza calculando el ancho del campo a wtravés del máximo de los valores de entrada m. Genera la primera línea de salida rellenando una cadena vacía y los números de entrada al ancho wusando la subrutina t. Luego recorre los enteros comenzando en 2, generando la línea de salida rellenando el entero y luego llamando a la subrutina cpara rellenar una cadena vacía o un asterisco según corresponda para cada valor, sin embargo, la línea generada se omite si no contiene asteriscos. A medida que se genera la salida, cada valor se divide por el entero hasta que quede un resto, por lo que el ciclo termina cuando ningún valor es mayor que 1.

Tenga en cuenta que el set v=es ejecutado después de la %v%se sustituye en el forbucle en la misma línea.

Neil
fuente
1

Python 2 , 157 148 146 145 143 bytes

def p(*t):print'%%%ds '%len(`x[-1]`)*len(t)%t
def f(x):k=m=1;p(' ',*x);exec"r=[n%k and' 'for n in x]\nif 0in m%k*r:p(k,*r)\nm*=k*k;k+=1;"*x[-1]

Utiliza en 0lugar de *, según lo permitido por las reglas.

Pruébalo en línea!

Fondo

Para identificar números primos, usamos un corolario del teorema de Wilson :

corolario del teorema de Wilson

Cómo funciona

La primera línea define una función auxiliar.

def p(*t):print'%%%ds '%len(`x[-1]`)*len(t)%t

p toma un número variable de argumentos que almacena en la tupla t .

El '%%%ds '%len(`x[-1]`)utiliza una cadena de formato para construir una cadena de formato; %%es un signo de porcentaje literal, %des un marcador de posición para el entero que len(`x[-1]`)devuelve, es decir, el número de dígitos del último elemento en x (la entrada, aún no está definido), y es literal.

Si, por ejemplo, el último elemento de x tiene tres dígitos, esto produce %3s , que se *len(t)repite una vez para cada elemento de x . Finalmente, %taplica esa cadena de formato a la tupla t , construyendo una cadena de elementos de t , separados por espacios y todos justificados a la derecha en cierta longitud.

La segunda línea define el envío real: una función f que toma una lista x como entrada. Después de reemplazar la execdeclaración, que ejecuta la cadena que precede a x[-1]veces, con un forbucle, obtenemos el siguiente código.

def f(x):
    k=m=1;p(' ',*x)
    for _ in range(x[-1]):
        r=[n%k and' 'for n in x]
        if 0in m%k*r:p(k,*r)
        m*=k*k;k+=1

En primer lugar, f inicializa k y m a 1 . Tenga en cuenta que (k - 1)! = 0! = 1 = m .

Luego, p(' ',*x)imprime un espacio y los enteros en x , utilizando la función p .

Ahora, ingresamos al bucle para imprimir la salida restante.

Primero, r=[n%k and' 'for n in x]construye la lista de los restos de cada número entero n en x dividido por k . Los residuos positivos, es decir, los residuos que no corresponden a múltiplos de k , son verdaderos y se reemplazan con un espacio por and' '.

A continuación, construimos m%k*r. ¡Ya que m = (k - 1)! , por el corolario del teorema de Wilson, esto será simplemente r si k es primo, pero una lista vacía si no. Si hay al menos un 0 en el resultado, es decir, si k es primo y al menos un entero en x es divisible por k , 0in m%k*rdevolverá Verdadero y p(k,*r)se llamará, imprimiendo k y los indicadores de divisibilidad: 0si es divisible, un espacio si no .

Finalmente, multiplicamos m por e incrementamos k , entonces la calidad m = (k - 1). continúa aguantando.

Dennis
fuente
1

MATL , 31 bytes

pYfu!Gy\~h0GhwvVZ{'(?<!\d)0'0YX

Esto utiliza en 1lugar de *, según lo permitido por el desafío.

Pruébalo en línea! O verificar todos los casos de prueba .

Explicación ( obsoleta )

p           % Implictly input array of numbers. Push product of array
Yf          % Prime factors as a row vector
u           % Keep only unique values
!           % Transpose into column vector
G           % Push input again
y           % Duplicate column vector of unique prime factors onto top
\           % Modulo, element-wise with broadcast
~           % Negate
h           % Concatenate horizontally
0           % Push 0
G           % Push input again
h           % Concatenate horizontally
w           % Swap
v           % Concatenate vertically
V           % Char array representation
Z{          % Convert to cell array of strings. Each row gives a string
'(?<!\d)0'  % Push this string: match '0' not preceded by a digit
0           % Push this string: '0' will be replaced by char 0
YX          % Regexp replace
            % Implicit inoput. Char 0 is displayed as space
Luis Mendo
fuente
0

Raqueta 176 bytes

(let((p printf))(display"   ")(for((x nl))(p" ~a " x))(displayln"")(for((i '(2 3 7 11)))
(p"~a  " i)(for((j nl))(if(member i(prime-divisors j))(p" * ")(p"   ")))(displayln"")))

Sin golf:

(define (f nl)
  (let ((p printf))

    (display "   ")
    (for ((x nl))
      (p " ~a " x))
    (displayln "")

    (for ((i '(2 3 7 11)))
      (p "~a  " i)
      (for ((j nl))
        (if (member i (prime-divisors j))
            (p " * ")
            (p "   ")))
      (displayln ""))))

Pruebas:

(f '(6 9 14 22))

Salida:

    6  9  14  22 
2   *     *  * 
3   *  *       
7         *    
11            * 
rnso
fuente