Уведомления

Группа в Telegram: @pythonsu

#1 Ноя. 11, 2017 01:12:57

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9727
Репутация: +  843  -
Профиль   Отправить e-mail  

Подскажите, можно ли улучшить решение задачи?

  
>>> def get_number_digit(number, count):
...     assert count > 0
...     return number // 10 ** (count - 1) % 10
... 
>>> def get_number_digits(number):
...     if number == 0:
...         yield 0
...         return
...     while number > 0:
...         yield number % 10
...         number //= 10
... 
>>> def f():
...     return (i for i in range(10000, 99999 + 1)
...             if i % 2 == 0
...             and get_number_digit(i, 3) % 2 != 0
...             and sum(get_number_digits(i)) % 4 == 0)
... 
>>> list(f())[:10]
[10102, 10106, 10120, 10124, 10128, 10142, 10146, 10160, 10164, 10168]
>>>



Отредактировано py.user.next (Ноя. 11, 2017 01:18:52)

Офлайн

#2 Ноя. 11, 2017 16:48:23

Franek
От: Беларусь
Зарегистрирован: 2016-05-09
Сообщения: 66
Репутация: +  0  -
Профиль   Отправить e-mail  

Подскажите, можно ли улучшить решение задачи?

py.user.next
спасибо. (yield 0 во второй функции не обязателен наверное).
Оказывается, можно еще так решить:

 lst = []
for i in range(10000, 99999):
    if i % 2 == 0:
        lst.append(i)
def digits_recursive(n, digits=[]):
    return digits_recursive(n // 10, [n % 10] + digits) if n else sum(digits) % 4 == 0 and digits[2] % 2 != 0
print(list(filter(digits_recursive, lst)))

Отредактировано Franek (Ноя. 11, 2017 18:27:30)

Офлайн

#3 Ноя. 12, 2017 02:40:16

py.user.next
От:
Зарегистрирован: 2010-04-29
Сообщения: 9727
Репутация: +  843  -
Профиль   Отправить e-mail  

Подскажите, можно ли улучшить решение задачи?

Franek
спасибо. (yield 0 во второй функции не обязателен наверное).
Не, эта функция является общей функцией. Это значит, что она написана так, чтобы решать тысячи разных задач.

Допустим, надо тебе список чисел превратить в список списков цифр этих чисел
  
>>> def get_number_digits(number):
...     if number == 0:
...         yield 0
...         return
...     while number > 0:
...         yield number % 10
...         number //= 10
... 
>>> lst = [1, 2, 3, 0, 123984, 987239, 0, 897234]
>>> out = list(map(list, map(get_number_digits, lst)))
>>> out
[[1], [2], [3], [0], [4, 8, 9, 3, 2, 1], [9, 3, 2, 7, 8, 9], [0], [4, 3, 2, 7, 9, 8]]
>>>
Как видишь, никаких пятизначных чисел тут нет и близко, это совсем другая задача, а функцию можно использовать сразу, не внося в неё никаких изменений.
Почему это важно? Потому что обычно таких функций написано сотни и каждую переделывать под решение новой задачи или вообще писать заново всю функцию для каждой новой задачи очень затратно по времени. Поэтому функции надо писать так, чтобы они были применимы к как можно большему числу задач, которые могут появиться. Тогда написание целой программы может занять не месяц, а один день. Ну и, соответственно, ты за месяц сможешь сделать тридцать программ, а не одну.
Если ты их продаёшь, разницу ты ощутишь сразу, а если ты действительно делаешь что-то сложное, где просто необходимо много программ делать, то ты реально имеешь потенциал выпустить хорошую и насыщенную программу собственного производства. Проблема того, что многие программисты не выпускают своих программ, относится не к тому, что они не знают, как их сделать, а к тому, что у них нет времени делать все элементы для этих программ. В результате они либо выпускают мелочёвки какие-то, которые не стоят внимания, либо просто идут куда-то там работать в чужие проекты и там так и пропадают, потому что их код присваивают эти проекты, даже копирайты их не увидишь, потому что их код принадлежит компании.



Отредактировано py.user.next (Ноя. 12, 2017 02:46:15)

Офлайн

#4 Ноя. 13, 2017 15:37:53

Vladimirv
Зарегистрирован: 2013-03-22
Сообщения: 108
Репутация: +  7  -
Профиль   Отправить e-mail  

Подскажите, можно ли улучшить решение задачи?

Franek с какой целью решил улучшать код? Какой параметр интересует?
Улучшать можно:
1 читаемость кода
2 скорость выполнения
3 минимизация числа строк
4 минимизация потребления памяти
5 универсальность
Возможно есть еще варианты.
Вариант 1-2 тебя не интересует, т.к. реализация на простых форах, ифах и быстрее и наглядней. Варианты 4-5 тебе показали.
Остался только 3 пункт:

 # на строках
li=[x for x in range(10000,100000,2) if int(str(x)[2])%2 and not sum(map(int,list(str(x))))%4 ]
# на цифрах
li=[x for x in range(10000,100000,2) if (x//100)%2 and not sum([(x//10**i)%10 for i in range(5)])%4 ]
Кстати, если нужен генератор, то меняешь li на g и квадратные скобки на круглые, варианты использования:
 g=(x for x in range(10000,100000,2) if (x//100)%2 and not sum([(x//10**i)%10 for i in range(5)])%4 )
# 1
print(next(g))
print(next(g))
# 2
for i, item in enumerate(g):
	if i>=10:
		break
	print(i)
# 3
print(list(g))

Офлайн

#5 Ноя. 17, 2017 21:14:36

Vladimirv
Зарегистрирован: 2013-03-22
Сообщения: 108
Репутация: +  7  -
Профиль   Отправить e-mail  

Подскажите, можно ли улучшить решение задачи?

Посмотрел три предложеных решения задачи, с перестановкой местами цифр наибольшей и наименьшей. Два из этих решений не рабочие, а именно вариант от Franek и Rodegast. Достаточно подставить другое число, например: 8812.
Мой вариант:

 s='8812'
l=list(s)
l.pop(s.index(min(s)))
l.insert(s.index(min(s)),max(s))
l.pop(s.index(max(s)))
l.insert(s.index(max(s)),min(s))
print(''.join(l))
Но лучше, думаю, использовать вариант от FishHook или поправить код Rodegast:
 s='8812'
l = list(s)
imin=l.index(min(l))
imax=l.index(max(l))
l[imin], l[imax] = l[imax], l[imin]
print("".join(l))
# или так
l = list(s)
l[s.index(min(s))], l[s.index(max(s))] = l[s.index(max(s))], l[s.index(min(s))]
print("".join(l))

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version