Факторинг факторіалів


16

Сьогодні в моєму класі статистики я виявив, що деякі фактичні факти можуть бути спрощені при множенні разом! Наприклад:5! * 3! = 5! *3*2 = 5! *6 = 6!

Ваша робота:

Враховуючи рядок, що містить лише арабські цифри та знаки оклику, спростіть мою фабрику до її найкоротшого можливого рядка, щонайменше, кількість байтів для вашої мови, код стилю гольфу.

Вхідні дані

Рядок, що містить лише арабські цифри та знаки оклику. Фабрики для введення не будуть більшими за 200! Фактори не матимуть більше одного фактора на число. Введення може сприйматися як список цілих чисел.

Вихідні дані

Можливо скорочений рядок, який має еквівалентне значення на вході. Порядок - це неважливо. Факторні позначення є обов'язковими, але вам не потрібно використовувати більше одного факторіального символу на номер.

Тестові справи

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!

Удачі


Оскільки порожній продукт 1 - це вихід, скажімо, 1!1!просто порожній рядок?
Джонатан Аллан

@JonathanAllan 1! 1! Зменшується до 1! Або 0!
тускіоми

Тоді зводиться до порожнього рядка: /
Джонатан Аллан

@JonathanAllan Я хочу сказати, що 1 не дорівнює порожній рядку
tuskiomi

Відповіді:


5

Желе ,  17  18 байт

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

Монадічне посилання, яке приймає та повертає список номерів (приклеюється до одного параметра на кожен номер)

Спробуйте в Інтернеті!

Як?

Гольф (хоча і незалежно написана) версія рішення 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)

1
Мені здається досить зрозумілим - ми не вимагаємо цього використовувати, але можемо зробити це, якщо хочемо.
Джонатан Аллан

1
@tuskiomi Нижній колонтитул просто форматує вихідний список для ясності ... як повна програма (а не як функція) код надрукує формат списку Jelly (нічого для порожнього та без додавання [] для списків довжиною 1) .
Джонатан Аллан

1
@tuskiomi TIO має обмеження ;-) але я думаю, що це працює теоретично.
Ерік Аутгольфер

1
@tuskiomi Картезіанська влада призведе до списку з 23! ^ 4 списків. У нього закінчиться час (обмеження 60-х років на TIO), якщо не пам'ять.
Джонатан Аллан

1
N! ^ M, де N - добуток, а M - кількість термінів (і в просторі теж !!)
Джонатан Аллан

3

Желе , 19 байт

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

Спробуйте в Інтернеті!

Швидкий і брудний. Дуже повільно, навіть23!2!3!2! тестовий випадок - розтяжка. I / 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.

Ми можемо використовувати списки як I / O
Джонатан Аллан

@JonathanAllan О, це, очевидно, не було відредаговано в ОП
PurkkaKoodari

Мої 17 здаються ще повільнішими ...
Джонатан Аллан

О, це дуже схоже - tio.run/##y0rNyan8/…
Джонатан Аллан

@JonathanAllan Попередньо та опублікуй це, мені виглядає інакше, хоча алгоритм по суті той самий.
PurkkaKoodari

2

Чистота , 397 ... 317 байт

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

Спробуйте в Інтернеті!

Це приймає [Int], визначає основні фактори результату і зменшує над чинниками, щоб знайти найменше представлення, використовуючи найбільший коефіцієнт на будь-якій стадії як базове значення для наступного факторіального терміна. Деякі тестові випадки на TIO не завершаться, але це досить * швидкий, і може запустити їх за 3 хвилини на середньому діапазоні ноутбука.

* для O((prod(N)!)^sum(N))алгоритму складності


Тестовий набір: 6, 2, 2
тш

@tsh Виправлено зараз. Це було не сортування за найменшою довжиною, а за найбільшим першим членом на основі помилкового припущення.
Οurous

1

> <> , 66 байт

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

Спробуйте в Інтернеті!

Не ефективний, не знаходить найменшої струни, і перекладач не дуже добре справляється з надзвичайно великою кількістю. Але принаймні я спробував? Приймає введення як список чисел через-v прапор.

Спочатку він обчислює значення вхідних даних шляхом фабрикалізації кожного числа та множення їх разом. Потім він знаходить найбільшу фабрику, яка чітко ділиться на загальну і виводить її. Повторюйте, доки він не отримає простий (який він виводить) або 1 та не завершить програму. Через це він іноді не знаходить найкоротшого представлення числа, наприклад, тестовий випадок 7!2!2!7!2!2!2!2!повертається 10!224замість того, 8!8!що він знаходить, що загальна сума ділиться на 10! спочатку.


1

Ruby , 240 237 233 байт

Це неймовірно неефективно

Приймає масив ints як вхідний

Повертає рядок і вибирає найкоротший варіант між, скажімо '720!', '6!!'і'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]}

Спробуйте в Інтернеті!

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.