141 Востаннє редагувалося leofun01 (23.09.2018 17:10:22)

Re: Потрібна допомога

/KIT\ написав:
koala написав:

код, швидше за все, можна скоротити в рази, але мені ліньки

Challenge accepted (437 bytes)
pm=lambda x,y,z:x*(y+1)*(z+1)+(x+1)*y*(z+1)+(x+1)*(y+1)*z
def sm(n):s=int(n**.5);s+=1if(s+1)**2==n else 0;sq=2*s*(s+1)+(s+1)**2;return sq if s**2==n else(sq+5+3*(n-s**2-1)if n-s**2<=s else sq+5+3*(s-1)+5+3*(n-s**2-s-1))
def cube_matches(n):s=int(n**(1/3));s+=1if(s+1)**3==n else 0;return pm(s,s,s)if s**3==n else(pm(s,s,s)+sm(n-s**3)if n<=s*s*(s+1)else(pm(s,s,s+1)+sm(n-(s+1)*s**2)if n<=s*(s+1)*(s+1)else pm(s,s+1,s+1)+sm(n-s*(s+1)**2)))

koala не це мав на увазі.
Робити таке на Python ...
Це прояв JavaScript'изму головного мозку. (ну ладно, трохи перегнув, сподіваюсь не образив вас).

142

Re: Потрібна допомога

leofun01 написав:

Це прояв JavaScript'изму головного мозку.

а ось це ображає...

Подякували: leofun011

143

Re: Потрібна допомога

Пане /KIT\, ну не тупо ж мініфікувати (до речі, ви дволітерні ідентифікатори використовуєте, коли ще не вичерпалися однолітерні). Принаймні, не до основних оптимізацій.
Наприклад, зараз я бачу, що parallelogram_matches завжди має хоча б пару однакових параметрів (а використовує вона їх симетрично). Отже, можна зробити

def parallelogram_matches(x,z):
    return x*(x+1)*(z+1)+(x+1)*x*(z+1)+(x+1)*(x+1)*z

а це далі скорочується до

def parallelogram_matches(x,z):
    return 2*x*(x+1)*(z+1)+(x+1)*(x+1)*z

можна ще спробувати

def parallelogram_matches(x,z):
    return (x+1)*(2*x*(z+1)+(x+1)*z)

А якщо дужки в зовнішних розкрити, то матимемо

def parallelogram_matches(x,z):
    return (x+1)*(3*x*z+2*x+z)

поки що виходить з 85 символів 63 проти ваших 57 - але ж це ще без жодної мініфікації, та й ще з десяток символів далі по коду вилетить, бо тепер замість parallelogram_matches(s+1,s+1,s) пишемо parallelogram_matches(s+1,s).
До речі, я якогось біса тут parallelogram замість parallelepiped написав. А насправді ж треба писати box, і тоді

def box_matches(x,z):
    return (x+1)*(3*x*z+2*x+z)

53 символи без мініфікації - проти ваших 57.
Ще можна подумати, як ефективно отримувати найбільше число, 2-ий чи 3-ій степіть котрого не перевищує задане. Оскільки 1/3 трохи менше за третину, int(125**(1/3)) дає 4; через це мені довелося дописати оте

    side = int(n**(1/3))
    if (side+1)**3==n:
        side+=1

Але, гадаю, це можна вирішити якось простіше (і коротше); скажімо,

side = int((n+.5)**(1/3))

і т.д.

Подякували: Eff1c1

144

Re: Потрібна допомога

286
b=lambda x,z:(x+1)*(3*x*z+2*x+z)
r=lambda x,p:int((x+.5)**(1/p))
def m(n):s=r(n,2);p=n-s**2;return 3*s**2+4*s+1+(3*p+(4-2*(p<=s))if p else 0)
def c(n):s=r(n,3);x,y=(s+1,s)if n<=s*(s+1)*(s+1)else(s,s+1);return b(s,s)+(0if s**3==n else m(n-s**3))if n<=s*s*(s+1) else b(y,x)+m(n-x*y**2)

викликати функцію c.

Подякували: /KIT\, Eff1c2

145

Re: Потрібна допомога

Я зрозумів, що зарано взявся за цю задачку... Вона занадто складна.
Але все-одно - дуже дякую) Повернусь до неї пізніше...

146

Re: Потрібна допомога

А поки що - https://www.e-olymp.com/uk/problems/20
Розв'язав цю задачку з двома while, але вибило, що 70% відповідей правильні, а решта 30% - не вкладаються в ліміт часу...
Переробив другу while на for...

inp = int(input())
inp1 = inp
outp = 0
m = 0
n = 1
while n > 0:
    m = 0
    n = 0
    t = len(str(inp))
    for i in range(t):
        m = m + (inp % 10)
        inp = inp // 10
    n = inp1 - m
    outp = outp + 1
    inp1 = n
    inp = inp1
print(outp)

Але результат такий самий...
Як можна ще спростити прогу? Чи прийдеться писати її на c++?

147

Re: Потрібна допомога

А ви гадаєте, str створюється без циклу та ділення?
Ну і так, схоже, на Python задача не розв'язується - 2*10^9 дає не менше 2*10^7 операцій, а ділення обчислюється не дуже швидко. Навіть divmod не рятує. Можна, звісно, погратися у віднімання від масиву, але навряд чи там вийде краще, а той факт, що всі числа, крім першого n, діляться на 9, не дуже допомагає.

Подякували: Eff1c1

148

Re: Потрібна допомога

Ок, спробую переробити на c++

149

Re: Потрібна допомога

ну от наприклад - варіант скорочення:
Ви якось ту суму цифр рахуєте складно
якщо вже робити це через  літерал числа, то так простіше:

>>> number = 123456
>>> print(sum(map(int, list(str(number)))))
21
>>> 

поміряємо швидкість:

from time import time
number = ''.join([str(i) for i in range(10**3)])
number = int(number)
print(number)
number_copy = number

Ваш код:

t_start = time()
m = 0
t = len(str(number))
for i in range(t):
    m = m + (number % 10)
    number = number // 10
print(m)
print(time() - t_start)

13500
0.015638351440429688

короткий варіант:

t_start = time()
print(sum(map(int, list(str(number_copy)))))
print(time() - t_start)

13500
0.0008478164672851562

Подякували: Eff1c1

150

Re: Потрібна допомога

inp = int(input())
inp1 = inp
outp = 0
m = 0
n = 1
while n > 0:
    n = 0
    m = sum(map(int, list(str(inp))))
    n = inp - m
    outp = outp + 1
    inp = n
print(outp)

Результат той самий...

151

Re: Потрібна допомога

ну,тут ще можна трохи оптимізувати, вернуся до компа  - наишу.але, нефакт що поможе
типу
x, y = y, x+1

Подякували: Eff1c1

152

Re: Потрібна допомога

Навряд чи допоможе, бо час виконання 3 секунди, а максимум 2...
І від тої оптимізації час виконання фактично не змінився (змінився на 1 мілісекунду)...

153

Re: Потрібна допомога

Eff1c написав:

Навряд чи допоможе, бо час виконання 3 секунди, а максимум 2...
І від тої оптимізації час виконання фактично не змінився (змінився на 1 мілісекунду)...

ну, принаймі хоч код спроститься:

inp, outp = int(input()), 0
while inp > 0:
    inp -= sum(map(int, list(str(inp))))
    outp += 1    
print(outp)
Подякували: Eff1c, ReAl2

154

Re: Потрібна допомога

Я в усі ці ваші map ще не вмію, але оце працює ± не повільніше

n = int(input())
outp = 0
while n > 0:
    m = 0
    s = str(n)
    for ch in s:
        # m = m + int(ch)
        m = m + ord(ch) - ord('0')
    n = n - m
    outp = outp + 1
print(outp)
Подякували: ping1

155

Re: Потрібна допомога

Та там просто неможливо цю задачку зробити на python і щоб вона вклалася в 2 секунди. Як не крути...

156

Re: Потрібна допомога

Хто розуміє в c++ - http://replace.org.ua/post/119683/#p119683

157 Востаннє редагувалося ping (25.09.2018 22:21:03)

Re: Потрібна допомога

без мапів та конвертації в стрінги:

def get_sum(number):
    summ = 0
    while number:
        number, r = divmod(number,10)
        summ += r
    return summ

inp, outp = int(input()), 0
while inp > 0:
    inp -= get_sum(inp)
    outp += 1    
    
print(outp)

але  while - повільна штука, тому це не поможе

158

Re: Потрібна допомога

ну ще так, щоб без while або if

inp, outp = int(input()), 0
try:
    for i in iter(int, 1):
        inp -= sum(map(int, list(str(inp))))
        outp += 1    
        1 / (inp + abs(inp))  
except Exception:
    pass

print(outp)

159

Re: Потрібна допомога

Виключні ситуації повільніші за if.

160 Востаннє редагувалося koala (26.09.2018 07:07:49)

Re: Потрібна допомога

Гм. Заміряв.

код
from timeit import timeit
print('abs:',timeit("a=5;abs(a)",number=10000000))
print('if:',timeit("a=5;a if a>0 else -a",number=10000000))
def while_if():
    n = 0
    while True:
        n+=1
        if n==100:
            break
def for_try():
    try:
        for i in iter(int,1):
            n+=1
            1/(n-100)
    except:
        pass

print('while:',timeit("import __main__;__main__.while_if()",number=100000))
print('for:',timeit("import __main__;__main__.for_try()",number=100000))
abs: 0.773834206276664
if: 0.5225441876465348
while: 0.9680562693382568
for: 0.18680880409061373

abs повільніший за if; але for значно швидший за while, навіть із діленням. Чому?