Tabela najlepszych dzielników

28

Wprowadzenie

Coś, z czym bawiłem się w matematyce rekreacyjnej, to konstrukcja tabeli dzielników do wizualnego porównywania / kontrastowania głównych dzielników zbioru liczb. Zestaw liczb wejściowych znajduje się u góry jako etykiety kolumn, główne dzielniki znajdują się po lewej stronie jako etykiety wierszy, a znak wskazuje, gdzie dwa wiersze w górę.

Na przykład w celu wprowadzenia zostanie 6, 9, 14, 22zbudowana tabela podobna do poniższej:

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

Jest tak, ponieważ 6ma główne dzielniki 2i 3, 9ma główne dzielniki 3i tak dalej.

Budowa

  • Tabela jest skonstruowana w taki sposób, że liczby wejściowe tworzą etykiety kolumn oddzielone spacjami i w porządku rosnącym (można założyć, że są wstępnie posortowane), a główne dzielniki są wymienione po lewej stronie w porządku rosnącym, po jednym w wierszu tworzącym wiersz etykiety.
  • Zauważ, że początkowe spacje na głównych dzielnikach i liczbach wejściowych mogą być wymagane, jeśli liczby mają różne długości, tak aby wszystkie kolumny miały tę samą szerokość i odpowiednio się wyrównały.
  • Każdy dzielnik jest reprezentowany przez jedną *(lub inną odpowiednią postać ASCII, którą wybierzesz, o ile ten sam znak jest używany we wszystkich wystąpieniach).
  • Wiele dzielników jest ignorowanych (np. 3 x 3 = 9Ale jest tylko jeden *dla tego skrzyżowania).
  • *Może być umieszczony w dowolnym miejscu w kolumnie poziomej, tak długo, jak jest to jednoznaczne (mam wszystkie moje przykłady Europejska *wyrównany do prawej).

Wkład

  • Lista liczb całkowitych dodatnich w dowolnym, wygodnym formacie , każdy >1.
  • Możesz założyć, że dane wejściowe są wstępnie posortowane.
  • Gwarantujemy, że dane wejściowe mają tylko unikalne wartości.

Wydajność

Wynikowa reprezentacja ASCII w formie tabeli pierwszego dzielnika.

Zasady

  • Wiodące lub końcowe znaki nowej linii lub białe znaki są opcjonalne, o ile same znaki są odpowiednio ustawione w linii.
  • Jeśli krótsza jest linia podziału oddzielająca nagłówki kolumn / wierszy od danych tabelarycznych, jest to również dozwolone.
  • Dopuszczalny jest pełny program lub funkcja. Jeśli funkcja, możesz zwrócić dane wyjściowe zamiast je drukować.
  • Jeśli to możliwe, dołącz link do internetowego środowiska testowego, aby ludzie mogli wypróbować Twój kod!
  • Standardowe luki są zabronione.
  • To jest więc obowiązują wszystkie zwykłe zasady gry w golfa, a wygrywa najkrótszy kod (w bajtach).

Przykłady

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
źródło
1
Czy możemy mieć linie podziału za górnym rzędem i lewą kolumną?
ngenisis
@ngisis Pewnie, pozwolę na to. Dokładne sformułowanie tabeli jest dość otwarte, ponieważ nie jest to dokładny cel tego wyzwania.
AdmBorkBork

Odpowiedzi:

5

Mathematica, 101 90 bajtów

Dzięki ngenisis za uratowanie 11 bajtów!

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

Znaków o jedną trzecią sposób przez to U + 2223 (3 bity). Nienazwana funkcja zmiennej liczby argumentów, z których każdy jest niezerową liczbą całkowitą, która zwraca TableFormobiekt (sformatowane wyjście) w następujący sposób:

Dane wyjściowe TableForm

f=#&@@@FactorInteger[1##]definiuje fsię jako zbiór wszystkich liczb pierwszych dzielących dowolne dane wejściowe (równoważnie, dzieląc ich iloczyn 1##), podczas gdy gjest to lista zawierająca dane wejściowe. Outer[If[#∣#2,Y,""]&,f,g]tworzy tabelę Ys i puste ciągi odpowiadające podzielności (używamy niezdefiniowanego tokena Yzamiast ciągu "Y"lub w "*"celu zapisania dwóch bajtów). Następnie używamy TableForm[...,TableHeadings->‌{f,g}]do formatowania wynikowej tablicy za pomocą odpowiednich nagłówków wierszy i kolumn.

Poprzednie zgłoszenie:

Grid[p=Prepend;Thread[q[Outer[If[#∣#2,Y,""]&,f=#&@@@FactorInteger[1##],g={##}]~p~g,f~p~""]]/.q->p]&
Greg Martin
źródło
Możesz pominąć pierwszy "".
Martin Ender,
2
TableForm[Outer[If[#∣#2,Y,""]&,f=#&@@@FactorInteger[1##],g={##}],TableHeadings->{f,g}]&jeśli dzielniki są dozwolone
ngenisis
I drugi również, jeśli zmienisz na p[f,].
Martin Ender
Dozwolone są linie siatki oddzielające nagłówki.
AdmBorkBork
1
TableFormjest spoko, mam nadzieję, że pozostanie w moim zestawie narzędzi!
Greg Martin
3

Galaretka , 18 bajtów

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

Używa 1zamiast *, zgodnie z regułami.

Wypróbuj online!

Jak to działa

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
źródło
2

Galaretka , 25 23 bajtów

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

Wypróbuj online!

W jaki sposób?

Może być krótszy w użyciu ÆEi odfiltrowaniu pustych wierszy.

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
źródło
2

JavaScript (ES6), 264 260 ... 179 173 bajtów

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

Myślę, że to podejście na stałe przekroczyło obecnie wartość rekurencyjną (obecnie 178 bajtów):

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):''

Wykorzystuje 0zamiast *, co jest dozwolone przez wyzwanie.

Testowy fragment kodu

ETHprodukcje
źródło
Jeśli się nie mylę, możesz użyć |operatora w instrukcji if, ponieważ porównujesz 2 booleany ...
Luke
@Luke Hej, masz rację. Nie jestem pewien, jak mi tego brakowało
ETHproductions
Czy nie jest krótsze przesunięcie i<2kontroli wewnątrz .mapfunkcji?
Łukasz
@Luke Jeśli masz na myśli zmianę ...i<2?a:a.map(x=>x%i&&c)na ...a.map(x=>i<2?x:x%i&&c), nie jest to krótsze. Jeśli masz na myśli przeniesienie go do drugiego .map , być może ...
ETHprodukcje
2

Python 2 - 197 bajtów

Przełączono na Python 2, aby ułatwić obsługę danych wejściowych i umożliwić konwersję napisów. Zastosowania gmpy2do generowania następnej liczby pierwszej. Format wyjściowy nadal oparty na poprzednim zgłoszeniu do Python 3 (patrz poniżej), mianowicie wypełnienie listy gsymbolami i sformatowanie jej.

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

Wypróbuj online!

Wyjaśnienie

Dla tych, którzy sami nie chcą dekodować.

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
)


Poprzedni

Python 3 - 251 bajtów

Jestem pewien, że ktoś może zrobić lepiej. Na podstawie tej odpowiedzi dotyczącej generowania liczb pierwszych < 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',' '))

Pojawi się wersja bez golfa i wyjaśnienie.

PidgeyUsedGust
źródło
4
Witamy w PPCG!
AdmBorkBork
1
Zamiast tego i=list(map(int,input().split(',')))możesz po prostu zrobić i=input()i pobrać dane z formularza [1, 2, 3, 4].
nedla2004
Dzięki, nie wiedziałem tego. Ale i tak przerobię to później :).
PidgeyUsedGust
Możesz zapisać 2 bajty p=gmpy2.next_prime(p);t=['*'[m%p:]for m in i]i usunąć miejsce w if"*" in.
Trelzevir,
1

Mathematica, 165 bajtów

Raczej gadatliwy - może ktoś może coś z tym zrobić:

(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}]]]])&
jaskółka oknówka
źródło
1

Narzędzia Bash + GNU, 134 133 132 125 123 bajtów

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
}

Wypróbuj online!

Mitchell Spector
źródło
1

Python 2 , 181 179 bajtów

-2 bajty dzięki 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

Dane wejściowe muszą być krotką.
Wypróbuj online!

Pręt
źródło
Czy all(i%j for j in p)działa zamiast używać map?
FlipTack,
@FlipTack tak, było lepiej, ale zmieniłem coś i zapomniałem o aktualizacji
Rod
1

Partia, 451 bajtów

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

Objaśnienie: Zaczyna się od obliczenia szerokości pola wna podstawie maksimum wartości wejściowych m. Generuje pierwszy wiersz wyniku, wypełniając pusty ciąg i liczby wejściowe do szerokości wza pomocą podprogramu t. Następnie zapętla liczby całkowite, zaczynając od 2, generując linię wyjściową, wypełniając liczbę całkowitą, a następnie wywołując proceduręc aby wstawić pusty ciąg lub gwiazdkę stosownie do każdej wartości, jednak wygenerowana linia jest pomijana, jeśli nie zawiera gwiazdek. Podczas generowania wyniku każda wartość jest dzielona przez liczbę całkowitą, aż pozostawi resztę, więc pętla kończy się, gdy żadna wartość nie jest większa niż 1.

Zauważ, że set v=zostanie wykonany po%v% jest podstawiona do forpętli na tej samej linii.

Neil
źródło
1

Python 2 , 157 148 146 145 143 bajtów

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]

Używa 0zamiast *, zgodnie z regułami.

Wypróbuj online!

tło

Aby zidentyfikować liczby pierwsze, używamy następstwa twierdzenia Wilsona :

następstwo twierdzenia Wilsona

Jak to działa

Pierwszy wiersz określa funkcję pomocnika.

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

p przyjmuje zmienną liczbę argumentów, które przechowuje w krotce t .

'%%%ds '%len(`x[-1]`)Wykorzystuje ciąg formatu skonstruować ciąg formatu; %%to dosłowny znak procentu, %djest symbolem zastępczym dla liczby całkowitej, która len(`x[-1]`)zwraca, tj. liczbę cyfr ostatniego elementu w x (dane wejściowe, jeszcze nie zdefiniowane), oraz jest dosłowny.

Jeśli np. Ostatni element x ma trzy cyfry, daje to wynik %3s , który *len(t)powtarza się raz dla każdego elementu x . Na koniec %tstosuje ten ciąg formatu do krotki t , konstruując ciąg elementów t , oddzielonych spacjami i wyrównanych do prawej do określonej długości.

Drugi wiersz definiuje faktyczne przesłanie: funkcję f, która przyjmuje listę x jako dane wejściowe. Po zastąpieniu execinstrukcji, która wykonuje poprzedzający ją ciąg x[-1], forpętlą, otrzymujemy następujący kod.

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

Najpierw f inicjuje k i m do 1 . Zauważ, że (k - 1)! = 0! = 1 = m .

Następnie p(' ',*x)wypisuje spację i liczby całkowite w x , używając funkcji p .

Teraz wchodzimy do pętli, aby wydrukować pozostałe dane wyjściowe.

Po pierwsze, r=[n%k and' 'for n in x]tworzy się listę resztek każda liczba całkowita n w x , podzielonej przez k . Reszty dodatnie, tj. Reszty , które nie odpowiadają wielokrotnościom k , są zgodne z prawdą i zostają zastąpione spacją and' '.

Następnie konstruujemy m%k*r. Ponieważ m = (k - 1)! na podstawie twierdzenia Wilsona będzie to po prostu r, jeśli k jest liczbą pierwszą, ale pusta lista, jeśli nie. Jeśli w wyniku jest co najmniej jedna 0 , tj. Jeśli k jest liczbą pierwszą, a co najmniej jedna liczba całkowita w x jest podzielna przez k , 0in m%k*rzwróci True i p(k,*r)zostanie wywołana, drukuje k i wskaźniki podzielności: 0jeśli podzielne, spacja, jeśli nie .

Na koniec mnożymy m przez i inkrementujemy k , więc jakość m = (k - 1)! nadal utrzymuje.

Dennis
źródło
1

MATL , 31 bajtów

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

To używa 1zamiast *, jak pozwala na to wyzwanie.

Wypróbuj online! Lub sprawdź wszystkie przypadki testowe .

Wyjaśnienie ( nieaktualne )

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
źródło
0

Rakieta 176 bajtów

(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"")))

Nie golfowany:

(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 ""))))

Testowanie:

(f '(6 9 14 22))

Wydajność:

    6  9  14  22 
2   *     *  * 
3   *  *       
7         *    
11            * 
rnso
źródło