Fatoriais de fatoração

16

Hoje, na minha aula de estatística, descobri que alguns fatoriais podem ser simplificados quando multiplicados! Por exemplo:5! * 3! = 5! *3*2 = 5! *6 = 6!

Seu emprego:

Dada uma string contendo apenas números arábicos e pontos de exclamação, simplifique meu fatorial até a menor string possível, na menor quantidade de bytes para o seu idioma, codifique o estilo de golfe.

Entrada

Uma sequência contendo apenas números arábicos e pontos de exclamação. Os fatoriais para a entrada não serão maiores que 200 !. Os fatoriais não terão mais de um fator por número. A entrada pode ser tomada como uma lista de números inteiros.

Resultado

Uma cadeia possivelmente encurtada, que tem o valor equivalente na entrada. A ordem não é importante. A notação fatorial é uma obrigação, mas você não precisa usar mais de um símbolo fatorial por número.

Casos de teste

In: 3!2!2!  
Out: 4! 

In 2!3!2!0! 
Out: 4! 

In: 7!2!2!7!2!2!2!2! 
Out: 8!8! 

In: 23!3!2!2! 
Out: 24!  
Also: 4!!

In: 23!3!2!2!2! 
Out: 24!2!

In: 127!2!2!2!2!2!2!2! 
Out: 128!

In: 32!56!29!128!  
Out: 29!32!56!128!

Boa sorte

tuskiomi
fonte
Como o produto vazio é 1, é a saída para, digamos, 1!1!apenas uma string vazia?
Jonathan Allan
@JonathanAllan 1! 1! Reduz para 1! Ou 0!
tuskiomi
O que então se reduz à cadeia vazia: /
Jonathan Allan
@JonathanAllan eu vou dizer um não é igual a como string vazia
tuskiomi

Respostas:

5

Geléia ,  17  18 bytes

!P
ÇṗLÇ⁼¥ÐfÇḢḟ1ȯ0F

Um link monádico obtendo e retornando uma lista dos números (fica na opção de um fatorial por número)

Experimente online!

Quão?

Uma versão para golfe (embora escrita de forma independente) da solução de Pietu1998.

!P - Link 1, product of factorials: list
!  - factorial (vectorises)
 P - product

ÇṗLÇ⁼¥ÐfÇḢḟ1ȯ0F - Main link: list                       e.g. [3,2,2]
Ç               - call the last link (1) as a monad           24
  L             - length                                      3
 ṗ              - Cartesian power      [[1,1,1],[1,1,2],...,[1,1,24],...,[24,24,24]]
        Ç       - call the last link (1) as a monad           24
      Ðf        - filter keep if:
     ¥          -   last two links as a dyad:
   Ç            -     call the last link (1) as a monad     [1,2,...,24!,...,24!^3]
    ⁼           -     equal?
         Ḣ      - head
          ḟ1    - filter out any ones
            ȯ0  - or with zero (for the empty list case)
              F - flatten (to cater for the fact that zero is not yet a list)
Jonathan Allan
fonte
1
Parece claro o suficiente para mim - não somos obrigados a usá-lo, mas podemos fazê-lo se quisermos.
Jonathan Allan
1
@tuskiomi O rodapé está apenas formatando a saída da lista para maior clareza ... como um programa completo (e não como uma função), o código imprimirá o formato de uma lista da Jelly (nada para vazio e nenhum anexo [] para listas de comprimento 1) .
Jonathan Allan
1
@tuskiomi O TIO tem limites ;-) mas acho que funciona teoricamente.
Erik the Outgolfer
1
@tuskiomi, o poder cartesiano resultaria em uma lista de 23! ^ 4 listas. Ele ficará sem tempo (limite de 60s no TIO), se não houver memória.
Jonathan Allan
1
! N ^ M onde N é o produto e M é o número de termos (e no espaço também !!)
Jonathan Allan
3

Geléia , 19 bytes

,!P€E
SṗLçÐfµḢḟ1ȯ1F

Experimente online!

Rapido e sujo. Muito lento, até o 23!2!3!2!caso de teste é exagerado. E / S como listas de números inteiros.

Explicação

,!P€E    Helper link. Arguments: attempt, original
,        Make the array [attempt, original].
         Example: [[1,1,1,4], [2,3,2,0]]
 !       Take the factorial of each item.
         Example: [[1,1,1,24], [2,6,2,1]]
  P€     Take the product of each sublist.
         Example: [24, 24]
    E    Check if the values are equal.

SṗLçÐfµḢḟ1ȯ1F   Main link. Arguments: original
S               Find the sum S of the integers in the input.
  L             Find the number N of integers in the input.
 ṗ              Generate all lists containing N integers from 1 to S.
   çÐf          Take the lists whose factorial-product is the same as the original.
       Ḣ        Take the first match. This is the one with the most ones.
        ḟ1      Remove any ones.
          ȯ1    If there were only ones, return a one instead.
            F   Turn into a list if needed.
PurkkaKoodari
fonte
Podemos usar listas como E / S
Jonathan Allan
@JonathanAllan Oh, que não foi, aparentemente, editado na OP
PurkkaKoodari
Os meus 17 parecem ainda mais lentos ...
Jonathan Allan
Ah, é muito parecido - tio.run/##y0rNyan8/…
Jonathan Allan
@ JonathanAllan Vá em frente e poste, parece diferente para mim, embora o algoritmo seja essencialmente o mesmo.
PurkkaKoodari
2

Limpo , 397 ... 317 bytes

import StdEnv,StdLib
c=length
f c m=sortBy c o flatten o map m
%n=f(>)@[2..n]
@1=[]
@n#f=[i\\i<-[2..n]|n/i*i==n&&and[i/j*j<i\\j<-[2..i-1]]]
=f++ @(n/prod f)
?l=group(f(>)%l)
$l=hd(f(\a b=c a<c b)(~(?l))[0..sum l])
~[]_=[[]]
~i n=[[m:k]\\m<-take n[hd(i!!0++[0])..],k<- ~[drop(c a)b\\a<-group(%m)&b<-i|b>a]n|i== ?[m:k]]

Experimente online!

Isso leva a [Int], determina os fatores primos do resultado e reduz sobre os fatores para encontrar a menor representação, usando o maior fator em qualquer estágio como um valor de linha de base para o próximo fator fatorial. Ele não conclui alguns casos de teste no TIO, mas é bastante rápido e pode executá-los em menos de 3 minutos em um laptop de médio porte.

* para um O((prod(N)!)^sum(N))algoritmo de complexidade

Furioso
fonte
Testcase: 6, 2, 2
tsh
@tsh Corrigido agora. Não foi classificado pelo menor tamanho, mas pelo maior primeiro membro com base em uma suposição equivocada.
Οurous
1

> <> , 66 bytes

1}:?\~l1=?v{!
-:?!\:{*}1
v?( 4:{/}1<o"!"n-1
{:,} :{/?%}:+1
\:1-?n;

Experimente online!

Não é eficiente, não encontra a menor string e o intérprete não lida muito bem com números extremamente grandes. Mas pelo menos eu tentei? Recebe a entrada como uma lista de números através do-v bandeira.

Primeiro, calcula o valor da entrada fatorializando cada número e multiplicando-os juntos. Em seguida, encontra o maior fatorial que divide de maneira limpa o total e o produz. Repita até obter um prime (que sai) ou um 1 e sair do programa. Por isso, às vezes não encontra a representação mais curta do número, por exemplo, o caso de teste 7!2!2!7!2!2!2!2!retorna em 10!224vez de 8!8!porque acha que o total é divisível por 10! primeiro.

Brincadeira
fonte
1

Ruby , 240 237 233 bytes

Isso é incrivelmente ineficiente

Aceita uma matriz de entradas como entrada

Retorna uma string e escolhe a opção mais curta entre, digamos '720!', '6!!'e'3!!!'

->i{f=->n{n>0?n*f[n-1]:1}
s=->a{eval a.map{|i|f[i]}*?*}
r=->e,a=[2]{e==s[a]?a:s[a]<=e&&(r[e,a[0..-2]+[a[-1]+1]]||r[e,a+[2]])}
j=->v{v.join(?!)+?!}
u=r[s[i]]
while j[g=u.map{|i|i&&r[i]?[r[i],p]:i}.flatten].size<j[u].size;u=g;end
j[u]}

Experimente online!

Asone Tuhid
fonte