• Как отправить смайлики за минимальное количество операций?

    adugin
    @adugin Куратор тега Python
    Код на Python для расчёта "в лоб" (перебором) и выявления закономерностей:
    # -*- coding: utf-8 -*-
    
    import matplotlib.pyplot as plt
    from itertools import product
    
    def process(existing, required):
        for opcount in xrange(existing+required):
            for combo in product('dcv', repeat=opcount):
                buffer = 0
                smiles = existing
                data_y = [existing]
                for char in combo:
                    if char == 'd':
                        smiles -= 1
                    elif char == 'v':
                        smiles += buffer
                    else:
                        buffer = smiles
                    data_y.append(smiles)
                if smiles == required:
                    data_x = xrange(opcount+1)
                    plt.plot(data_x, data_y, linewidth=1)
                    print required, data_y
                    return ''.join(combo)
        return '-'
    
    for required in xrange(2, 101):
        plt.clf()
        plt.grid(True)
        plt.title('Target: %s' % required)
        plt.autoscale(enable=True, axis='both', tight=False)
        for existing in xrange(1, (required//2)+1):
            result = process(existing, required)
        plt.savefig('{:02d}.png'.format(required), dpi=96, bbox_inches='tight')

    Задача распадается на 2:
    1) Если M >= N div 2, то нужно удалить всё до половины, скопипастить, и по необходимости удалить 1 смайл.
    2) Если п.1 не выполняется, то нужно рассчитать делители N (если N простое - то взять следующие несколько чисел больше N) и спуститься к ближайшему наибольшему делителю N, который меньше M. Удалять смайлы, чтобы попадать в наблюдаемые на картинках горизонтальные уровни, соответствующие делителям.

    В общем случае решение не единственное - например, соседние группы D и V можно смешивать в любых последовательностях: DDVVV = VVVDD = VDVDV = ...

    N=12. Для M=5 видим DCVV (фиолетовая линия). Уровни (делители) - 6, 4, 3, 2, 1:
    042d326f2b1a45d2916c5ce012fca2f6.png
    N=28:
    c832673197de486aa072d81b56de27c4.png
    N=29:
    4e0ee3d81d9b47e38127cf8211c2c48f.png
    N=30:
    2629d000169449c1896414c348b61874.png
    N=71:
    5037b1d5028b4330aed51516ec81887f.png
    N=72:
    89fd833e066f423993665d4c54e8f6cc.png
    PDF со всеми картинками: dugin.org/dropbox/toster_188303.pdf (11 Mb)

    P.S. https://ru.wikipedia.org/wiki/Задача_о_ранце
    Ответ написан
    Комментировать
  • Как произвести проверку входных данных Python?

    adugin
    @adugin Куратор тега Python
    Специально написал посложнее (в жизни так не надо), в учебных целях.
    Если разберётесь, как и почему оно работает - научитесь очень многому.
    # -*- coding: utf-8 -*-
    
    from itertools import starmap, imap
    from math import sqrt
    
    options = {str(index):option for (index, option) in enumerate('Cathetus|Hypotenuse'.split('|'), 1)}
    
    if __name__ == '__main__':
        while True:
            try:
                menu = '\n'.join(
                    starmap('-'.join(chr(0x20)*2).join(['{}']*2).format, options.items())
                )
                choice = raw_input('\nCalculate:\n%s\n\nYour choice: ' % menu)
                side = options[choice]
                sign = -1 if int(choice) == 1 else 1
                print
                query = lambda index: raw_input('Enter side #%s: = ' % index)
                sides = sorted(float(x) for x in imap(query, options))
                assert 0 < sides[0] <= sides[1], '\nERROR: Length must be a positive number!'
                result = sqrt(pow(sides[-1], 2) + sign*(min(sides)**2))
            except KeyError:
                print '\nERROR: No such option!'
            except ValueError:
                print '\nERROR: Length must be a number!'
            except AssertionError, error_text:
                print error_text
            else:
                print '\nResult: {:.2f}'.format(result)
                exit(0)
    Ответ написан
  • Как внутри list, который состоит из элементов string удалить все символы не являющимися цифрами?

    adugin
    @adugin Куратор тега Python
    Решил поизвращаться с функциональным подходом :)
    >>> a
    ["['9', '8', '7', '4']", "['9', '8', '7', '5']", "['9', '8', '7', '6']"]
    
    >>> map(int, map(''.join, map(eval, a)))
    [9874, 9875, 9876]
    
    >>> reduce(lambda item, func: map(func, item), (eval, ''.join, int), a)
    [9874, 9875, 9876]
    
    >>> eval(','.join(a).translate(None,",' ").replace('][',','))
    [9874, 9875, 9876]
    
    >>> from itertools import starmap
    >>> map(int, starmap(('{}'*4).format, map(eval, a)))
    [9874, 9875, 9876]
    
    >>> import re
    >>> eval(re.sub("', '|['\[\]]", '', ','.join(a)))
    (9874, 9875, 9876)
    
    >>> map(lambda x: int(re.sub('[^\d]', '', x)), a)
    [9874, 9875, 9876]
    
    >>> repl = partial(re.sub, '[^\d]', '')
    >>> map(lambda x: int(repl(x)), a)
    [9874, 9875, 9876]
    
    >>> reduce(lambda item, func: map(func, item), (repl, int), a)
    [9874, 9875, 9876]
    
    >>> reduce(lambda *args: map(*args[::-1]), (repl, int), a)
    [9874, 9875, 9876]
    
    >>> reduce(lambda *args: map(*args[::-1]), (eval, ''.join, int), a)
    [9874, 9875, 9876]
    
    >>> func = lambda item: int(''.join(char for char in item if char in digits))
    >>> map(func, a)
    [9874, 9875, 9876]
    
    >>> from textwrap import wrap
    >>> map(int, wrap(re.sub('[^\d]', '', str(a)), 4))
    [9874, 9875, 9876]
    
    >>> d = set(digits)
    >>> fltr = partial(filter, d.issuperset)
    >>> map(int, map(fltr, a))
    [9874, 9875, 9876]
    
    >>> map(int, re.findall('\d{4}', re.sub('[^\d]', '', str(a))))
    [9874, 9875, 9876]
    Ответ написан
    Комментировать
  • Python создание и заполнение двумерного массива

    adugin
    @adugin Куратор тега Python
    >>> dx = 2
    >>> dy = 3
    >>> matrix = [[0 for x in xrange(dx)] for y in xrange(dy)]
    >>> matrix
    [[0, 0], [0, 0], [0, 0]]
    >>> matrix[0][0] = 1
    >>> matrix
    [[1, 0], [0, 0], [0, 0]]
    Ответ написан
    Комментировать
  • Как найти повторяющееся слово в строке?

    adugin
    @adugin Куратор тега Python
    def find_word(line):
        for step in xrange(1, len(line)):
            for start in xrange(step):
                if len(set(line[(start or None)::step])) != 1:
                    break
            else:
                return line[:step]
        return line
    
    print find_word('HELLOHELLOHELLOHEL')
    print find_word('HHHELLOHHHELLOHHHELLOHHH')
    print find_word('_HHELLOHHELLOHHELLOHHELLOHHELLOHHE')

    Результат:
    HELLO
    HHHELLO
    _HHELLOHHELLOHHELLOHHELLOHHELLOHHE
    Ответ написан
    Комментировать
  • Python отловить none?

    adugin
    @adugin Куратор тега Python
    Руки надо отрывать за такой говнокод на питоне...
    Вот как надо:
    data = '[{0}000,{1},{2}],'.format(str(r[i])[:-2], e[i], c[i])
    f.write(data)

    Что за шаманство с r[i], какого типа эта переменная? Тоже через .format() прогнать.
    И что-то мне подсказывает, что здесь хорошо пойдёт json.dumps()

    И ответ на сам вопрос:
    >>> x = None
    >>> x or 0
    0


    from itertools import izip
    ...
    
    data = izip(r, e, c)
    for trio in data:
        if all(trio):
            entry = '[{:.0f}000,{},{}],'.format(*trio)
            f.write(entry)


    from itertools import izip, ifilter
    ...
    
    for triplet in ifilter(all, izip(r, e, c)):
        entry = '[{:.0f}000,{},{}],'.format(*triplet)
        f.write(entry)
    Ответ написан
    2 комментария
  • Как найти похожие слова в списке?

    adugin
    @adugin Куратор тега Python
    # -*- coding: utf-8 -*-
    
    from difflib import SequenceMatcher
    from itertools import combinations, imap
    
    def ratio(pair):
        return (SequenceMatcher(None, *pair).ratio(), pair[0])
    
    def findword(wordlist):
        pairs = combinations(wordlist, 2)
        found = max(imap(ratio, pairs))[1] 
        return found
    
    print findword(['голубец', 'конь', 'голубцы', 'лист'])
    print findword(['стол', 'день', 'свет', 'клинок', 'светильник'])
    print findword(['восток', 'дань', 'исток', 'жир', 'голубь', 'да'])

    Результат:
    голубец
    свет
    восток
    Ответ написан
    3 комментария
  • Как создать tree+defaultdict произвольного уровня вложенности?

    adugin
    @adugin Автор вопроса, куратор тега Python
    Родил такое решение:
    def tree(levels=0, func=None):
    	if levels > 0 and func:
    		return defaultdict(reduce(lambda f, i: lambda: defaultdict(f), xrange(levels-1), func))
    	else:
    		return defaultdict(tree)


    Проверяем:
    >>> d = tree()
    >>> d[1][2][3][4][5] = 6
    >>> d = tree(3, float)
    >>> d
    defaultdict(<function <lambda> at 0x0280E3F0>, {})
    >>> d[1][2][3]
    0.0
    >>> d[7][8][9] += 10
    >>> d[7][8][9]
    10.0


    P.S. https://gist.github.com/hrldcpr/2012250

    P.P.S. Ещё вариант:
    def tree(func=lambda: tree(), depth=0):
    	return defaultdict(reduce(lambda f, i: lambda: defaultdict(f), xrange(depth-1), func))
    Ответ написан
    Комментировать
  • Балансировка нагрузки: как разбить набор чисел на две части с примерно равными суммами?

    adugin
    @adugin Автор вопроса
    В итоге я сделал полный перебор с исключением заведомо неоптимальных решений. Судя по википедии, это "Метод ветвей и границ". По моим наблюдениям, в зависимости от исходных данных, обсчёт набора из 25 чисел может занять от всего ~20 и вплоть до 3.5М циклов. На Python 2.7:

    # -*- coding: utf-8 -*-
    
    from random import randint
    from itertools import combinations
    
    #data = [53, 50, 74, 4, 11, 68, 65, 50, 25, 84, 65, 63, 14, 54, 49, 17, 65, 48, 74, 66]
    data = [randint(1,100) for i in xrange(25)]
    #data = [990,1,2,3,1000]
    
    data.sort(reverse=True)
    limit = float(sum(data))/2
    # Pre-calculate min and max possible number of elements in a group
    bounds = [0, 0]
    for i in (0,1):
        maxsum = 0
        for n, item in enumerate(data[::(1,-1)[i]], 1):
            cursum = maxsum + item
            if cursum <= limit:
                maxsum = cursum
            else:
                bounds[i] = n - int(n > 1)
                break
    nmin, nmax = bounds
    # Main calculations
    maxsum, cycles = 0, 0
    for n in xrange(nmin, nmax+1):
        # The following check could be efficient with integer numbers, not float
        if maxsum == limit:
            # One of exact solutions has been found
            break
        else:
            # Iterate through all possible combinations:
            # combinations('ABCD', 2) --> AB AC AD BC BD CD
            for vector in combinations(data, n):
                cycles += 1
                cursum = sum(vector)
                if maxsum < cursum <= limit:
                    maxsum = cursum
                    solution = vector
                    # The following check could be efficient with integer numbers, not float
                    if maxsum == limit:
                        # One of exact solutions has been found
                        break
                elif cursum <= maxsum:
                    # No reason to continue because data is sorted in descending order 
                    # and all of the following sums in this loop will be even smaller
                    break
    # Print result
    print 'data =', data
    print 'nmin =', nmin
    print 'nmax =', nmax
    print 'solution =', solution
    print 'cycles =', cycles
    print 'limit =', limit
    print 'sum =', maxsum
    Ответ написан
    Комментировать
  • Как записать результаты re python в словарь?

    adugin
    @adugin Куратор тега Python
    P.S. Вообще, у Вас две проблемы:

    1) Только первая строка содержит " - ", две другие содержат " -". Регулярку следует проапгрейдить до:

    p = re.compile(ur"^(?P<name>.+?)[ ]*-[ ]*(?P<value>\d+?)$", flags=re.M|re.U)


    2) Вместо "жадных" регулярок вида .* использовать ungreedy-версии .*? или .+?
    Ответ написан
    Комментировать
  • Как записать результаты re python в словарь?

    adugin
    @adugin Куратор тега Python
    # -*- coding: utf-8 -*-
    import re
    
    text = u"""Вася - 10
    Ваня - 20
    Петя - 30"""
    
    d = dict(re.findall(u"^(.+?) - (\d+?)$", text, flags=re.M|re.U))
    
    print d

    Если нужен именно список словарей - то, например, так:
    p = re.compile(u"^(?P<name>.+?) - (?P<value>\d+?)$", flags=re.M|re.U)
    d = [match.groupdict() for match in p.finditer(text)]
    Ответ написан
    Комментировать
  • Автоматическая генерация android-ресурсов в Gimp?

    adugin
    @adugin
    Не очень понял задачу. Если просто ресайз - попробуйде бесплатный BD Sizer, Irfan View.
    Ответ написан
    Комментировать
  • Где найти изображения грузовиков в высоком качестве?

    adugin
    @adugin
    В гугле: google.com
    Ответ написан
    Комментировать
  • Какие есть сервисы одиночной SMS-рассылки?

    adugin
    @adugin
    smsc.ru
    Ответ написан
    Комментировать
  • Где посмотреть лог соединения с FTP сервером?

    adugin
    @adugin
    Перехватить трафик на сетевом интерфейсе с помощью tcpdump/tethereal/wireshark

    tethereal -i eth01 -f 'tcp port 21'
    tcpdump -i eth01 -f 'tcp port 21'
    Ответ написан
    Комментировать
  • Как создать сеть 3g и 4g?

    adugin
    @adugin
    Хренасе у Вас вопросы.
    Ответ написан
    Комментировать
  • Python как он есть

    adugin
    @adugin Куратор тега Python
    a = [
    	[1, 2 ,3 ,4],
    	[3, 4, 5, 6],
    	[5, 3, 2, 2]
    ]
    
    b = {
    	1: ['ab', 'ba'],
    	2: ['bc', 'cd']
    }
    
    for r, row in enumerate(a):
    	a[r] = map(lambda x: [x]+b[x] if x in b else x, row)
    
    print a
    Ответ написан
    Комментировать
  • Тормоза google chrome?

    adugin
    @adugin
    1) То, что Chrome установлен на SSD, ничего не значит. Где лежит его кэш? Я у себя перенаправил кэш на ramdisk, изменив ярлык для запуска Chrome на следующую строку:
    "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disk-cache-dir=Z:\TEMP

    2) Pagefile в системе имеется?

    3) На Win 7 дефрагментация дисков по умолчанию настроена автоматически, но в какое именно время? Если ночью, и при этом компьютер выключен - то диски давно не дефрагментировались. Проверьте статус.
    Ответ написан
  • Как добиться одинаковой обработки юникода Python-скрипта в консоли и в Spyder (IDE)?

    adugin
    @adugin Куратор тега Python
    Все конструкции вида
    print text
    заменить на
    print text.encode('utf-8')
    (Предполагаю, что все строки у Вас юникодные)
    Ответ написан
  • Как исправить ошибку из-за четвертого if подряд?

    adugin
    @adugin Куратор тега Python
    Почему бы вместо
    if a == int(i)*int(j):
    		     return True
    		 return False

    Не написать
    return a == int(i)*int(j)
    ?

    Кроме того, у вас переменные i и j являются int по способу создания, так что постоянно писать int(i) и int(j) не обязательно.
    Ответ написан
    Комментировать