Створіть числа Фрідмана


9

Фрідман число це число , яке може бути виражено шляхом застосування основних математичних операцій (^, /, *, +, -) для всіх його цифр. Операції не повинні застосовуватися до кожної окремої цифри, але всі цифри повинні бути задіяні. Тобто 121 = 11 ^ 2 -> всі цифри задіяні, але 1 і 1 були з'єднані між собою, щоб зробити 11.

Використання дужок дозволено, але тривіальний розчин x= (x)не є правильним рішенням. Також не діє, x= +x.

Приклади

  • 25 = 5 ^ 2
  • 121 = 11 ^ 2
  • 343 = (3 + 4) ^ 3
  • 2048 = (8 ^ 4) / 2 + 0

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

Введення -

n m    | n, m integers, n>=0, m>n

Вихід -

count    | number of Friedman numbers in the given range
fn1 exp1 | Friedman number, expression
fn2 exp2
fn3 exp3
.
.
.

Найкоротший код, розміщений до неділі, 29 липня, 00:00.


2
Чи можете ви додати приклад чисел Фрідмана і пояснити, як це /працює? Наприклад, що таке 1/3?
JPvdMerwe

Число виражається шляхом застосування операцій до всіх його цифр. тобто 25 = 5 ^ 2, 126 = 6 * 21, 343 = (3 + 4) ^ 3 і так далі
elssar

Ви допускаєте одинарний мінус? наприклад -5?
JPvdMerwe

@JPvdMerwe перевірити специфікацію вводу, вам цього не потрібно буде робити, але якщо ви хочете, вибийте себе. Хоча одинарний плюс заборонений. тобто +5 не є правильним рішенням
elssar

1
Ви не відповіли на запитання JPvdMerwe про поділ. Повинен бути точним? Чи можуть проміжні результати бути невід’ємними?
Пітер Тейлор

Відповіді:


3

Рубі, 456 438 408 390 370 349 344 334 [фіксовано]

g={}
f=->a,b{a.permutation(b).to_a.uniq.flatten.each_slice b}
F,T=$*
([F.to_i,10].max..T.to_i).map{|c|f[a="#{c}".split(''),v=a.size].map{|m|f[[?+,?-,?*,?/,'','**'],v-1].map{|w|(d=(s=m.zip(w)*'').size)==v&&next
0.upto(d){|y|y.upto(d+1){|u|begin(r=eval t="#{s}".insert(y,?().insert(u,?)))==c&&g[r]=t
rescue Exception
end}}}}}
p g.size,g

Вихід:

% ruby ./friedman-numbers.rb 1 300
9
{25=>"(5)**2", 121=>"(11)**2", 125=>"5**(2+1)", 126=>"(6)*21", 127=>"(2)**7-1", 128=>"2**(8-1)", 153=>"(3)*51", 216=>"6**(1+2)", 289=>"(9+8)**2"}

Крім того, він працює відносно швидко для більшої кількості:

% time ruby friedman-numbers.rb 3863 3864   
1
{3864=>"(6**4-8)*3"}
ruby friedman-numbers.rb 3863 3864  14.05s user 0.17s system 99% cpu 14.224 total

1
Я запустив його з входом 5 40і отримав результат: [11, "11**1", 21, "21**1", 31, "31**1", 41, "41**1"]. Ніяких ознак входу 25немає, і я думаю, що правильне рішення (наприклад, для 21) - 2*1ні,21**1
Крістіан Лупаску

@ w0lf Дякую! Я думаю, що я це виправив.
дефлот

Так, зараз це чудово працює.
Крістіан Лупаску

@ w0lf додав багато символів, щоб форматувати вихід, як потрібно
defhlt

ви можете отримати 2 символи, замінивши '+-*/'.chars.to_a+['','**']на["+","-","*","/","","**"]
Крістіан Лупаску

4

Пітон 2,7 - 380 378 372 371 367 363 357 354 352 348 336 символів

Просто простий грубий пошук.

from itertools import*
s=lambda x:[x]['1'>x>'0':]+['(%s%s%s)'%f for i in range(1,len(x))for f in product(s(x[:i]),'*/-+^',s(x[i:]))]
def E(e):
 try:return eval(e.replace("^","**"))
 except:0
A={i:e for i in range(input(),input()+1)for x in permutations(`i`)for e in s("".join(x))[x>='1':]if E(e)==i}
print len(A)
for v in A:print v,A[v]

Приклад виконання:

1
300
9
128 (2^(8-1))
289 ((9+8)^2)
216 (6^(1+2))
121 (11^2)
153 (3*51)
25 (5^2)
125 (5^(2+1))
126 (6*21)
127 ((2^7)-1)

Пояснення:

s(x) це функція, яка приймає рядок, що містить послідовність цифр і повертає всі вирази, використовуючи ці цифри в тому порядку.

[x]['1'>x>'0':] оцінює до списку, що містить x, якщо x дорівнює "0" або послідовності цифр, що не починається з "0"; в іншому випадку він оцінюється в порожній список. В основному це стосується випадку, коли я з'єдную всі цифри разом.

['(%s%s%s)'%f for i in range(1,len(x))for f in product(s(x[:i]),'*/-+^',s(x[i:]))] в основному розділяє x на дві частини (обидві мають ненульову довжину), викликає s () на кожній частині та з'єднує всі результати разом з деяким оператором між ними, використовуючи product ().

E(e) в основному є безпечним eval. Він повертає значення e, якщо e дійсне, і None в іншому випадку.

A={i:e for i in range(input(),input()+1)for x in permutations(`i`)for e in s("".join(x))[x>='1':]if E(e)==i}

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

Альтернативна версія - 397 символів

Ось мій код, якщо вам потрібно використовувати дроби:

from fractions import*
from itertools import*
s=lambda x:["Fraction(%s)"%x]['1'>x>'0':]+['(%s%s%s)'%f for i in range(1,len(x))for f in product(s(x[:i]),'*/-+^',s(x[i:]))]
def E(e):
 try:return eval(e.replace("^","**"))
 except:0
A={i:e for i in range(input(),input()+1)for x in permutations(`i`)for e in s("".join(x))[x>='1':]if E(e)==i}
print len(A)
for v in A:print v,A[v].replace("Fraction","")

Я не думаю, що if len(x)<2це колись буде правдою s. Крім того , можна замінити formatз , "a[Fraction(%s)%s%s]='(%s%s%s)'"%(x[:i],o,v,x[:i],o,A)щоб зберегти 4 символів.
beary605

@ beary605: Це правда іноді, коли i = len (x) -1, то наступний дзвінок отримає один символ. Щодо другого пункту, дякую! :)
JPvdMerwe

так ... except:0розумно .. дуже розумно. Я пам’ятаю
Ev_genus

Будь ласка, включіть кілька ілюстративних результатів.
DavidC

1
Ні, все ще працює. Мені потрібно перенести свій ПК зараз, але я дам йому працювати кілька днів і побачити, чи закінчується він.
JPvdMerwe

3

Python3 (436) (434) (443)

Це було важко. Я можу шкодувати деяких персонажів, якщо зробити вихід більш рідним.

from itertools import*
r={};k=product;m=map
q=lambda n,h=1:["("+i+c+j+")"for(i,j),c in k(chain(*[k(*m(q,f))for f in sum(([(x[:q],x[q:])for q in range(1,len(x))]for x in m("".join,permutations(n))),[])]),list("+-*/^")+[""]*h)]if 1<len(n)else[n]*h
a,b=m(int,m(input,"nm"))
for i,j in chain(*[k(q(str(n),0),[n])for n in range(a,b+1)]):
    try:exec("if eval(%r)==j:r[j]=i"%i.replace("^","**"))
    except:0
print(len(r))
for j,i in r.items():print(i,j)

Вихідні дані

n100
m200
6
(2^(8-1)) 128
(3*(51)) 153
((11)^2) 121
(5^(1+2)) 125
(6*(21)) 126
((2^7)-1) 127

1
Тож у вас є багато розумних хитрощів; однак, я повинен зазначити, що ви неправильно обробляєте від 1 до 9, і ваш внесок не включений. Ви можете видалити 2 символів , хоча, видаливши пробіл після "("+i+c+j+")"і замін len(n)>1по 1<len(n)закінченню якого ви можете видалити пробіл після цього виразу.
JPvdMerwe

Справедливий. Виправлено всі, +7 символів
Ev_genus

Останній рядок можна замінити for j in r:print(r[j],j)на збереження 7 символів.
JPvdMerwe

1

Математика 456 416 402 404 400 396 символів

<< Combinatorica`; l = Length; p = Permutations; f = Flatten; c = Cases;
u[d_, o_, s_] := 
 Fold[#2[[1]] @@ If[s == 1, {#1, #2[[-1]]}, {#2[[-1]], #1}] &, 
 d[[1]], Thread@{o, Rest@d}];
q[t_, r_] := {u[t, #, r], u[HoldForm /@ t, #, r]} & /@ 
p[{Plus, Subtract, Times, Divide, Power}, {l@t - 1}];
v[m_, n_] := (t = Table[Union@
  c[f[{#~q~1, #~q~0} & /@ 
     f[p /@ c[
        FromDigits /@ # & /@ 
         f[SetPartitions /@ p@IntegerDigits@j, 1], x_ /; l@x > 1],
       1], 2], {j, _}], {j, m, n}]~f~1; {l@t}~Join~t)

Приклад :

v[1,300]//TableForm

Вихід :

вихід Фрідмена

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