Skip to content

Instantly share code, notes, and snippets.

@ydm
Last active August 29, 2015 14:05
Show Gist options
  • Save ydm/e9793035c6b387709988 to your computer and use it in GitHub Desktop.
Save ydm/e9793035c6b387709988 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python2
# -*- coding: utf-8 -*-
from __future__ import print_function
from itertools import count
from math import sqrt
seqsum = lambda step, end: (step + end - (end % step)) * (end // step) // 2
def pe001():
# Твоето решение създава два списъка, а след това и множество от
# уникални стойности (set). Защо? Задачата се решава от аматьори с
# цикъл (виж ОК), а най–доброто решение е с формула (виж GREAT).
# Излишно е да казвам, че цикълът се изпълнява с време О(Н), докато
# решението с формула е О(1).
ok = sum([x for x in range(1000) if x % 3 == 0 or x % 5 == 0])
great = seqsum(3, 999) + seqsum(5, 999) - seqsum(15, 999)
print('ok={}, great={}'.format(ok, great))
def pe002():
# Това го запомни – рекурсия използваш единствено и само когато
# влаганията са logN. В никакъв случай не трябва да използваш
# линейна рекурсия. Или поне не в Пайтън. Виж, в езици като Хаскел
# и (някои диалекти на) Лисп е напълно разумно, но в Пайтън –
# категорично не. Това решение използва ГЕНЕРАТОР. Виж в
# документацията.
def fib(end, pred):
a, b = 0, 1
while a < end:
if pred(a):
yield a
a, b = b, a + b
print(sum(fib(4000000, lambda x: x % 2 == 0)))
def pe003():
# Доста буквално си възприел идеята за ситото на Ератостен. Виж
# други имплементации, например тези на Доналд Кнут –
# http://www-cs-faculty.stanford.edu/~uno/programs.html .
pass
def pe004():
# Брутална сила.
pass
def pe005():
# Тази е добре решена, браво!
pass
def pe006():
# Както и за първата, използваш брутална сила, а може много по–лесно
# и ефективно да бъде, ако използваш формулата.
# https://github.com/ydm/some-stuff-i-need-shared-between-pcs/blob/master/pe/pe006.lisp
pass
def pe007():
# Ц!
pass
def pe008():
# От раз става ясно, че по–добро решение от О(Н) не можеш да дадеш,
# защото трябва да обходиш всички цифрит в дадения ред. Какво
# по–просто има от това? Да използваш стр.сплит('0') е абсурдно,
# защото, когато пишеш код, искаш той да не е зависим по никакъв
# начин от входните данни. В твоя случай обаче това е точно така.
# Какво ще стане, ако входните ти данни имат 0 на всяка десета
# позиция? Алгоритъмът ти ще се провали, а това е недопустимо.
pass
def pe009():
# топ() е функция, която открива горна граница за по–малкия от двата
# катета на правоъгълен триъгълник с даден сбор на страните а + б +
# ц. Оставям те сам да откриеш защо и как. Ако ти се занимава,
# разбира се. :)
s = 1000
top = lambda k: int((4*k - sqrt(8*k*k)) / 4 + 1)
fb = lambda a, s: (2*s*a - s*s) // (2*a - 2*s)
for a in range(1, top(s)):
b = fb(a, s)
c = s - a - b
if c*c == a*a + b*b:
print('a={}, b={}, c={}'.format(a, b, c))
break
def pe010():
# Още едно Ц!
pass
def main():
g = globals()
for i in count(1):
fn = 'pe{:03}'.format(i)
try:
f = g[fn]
except KeyError:
break
else:
print('{}: '.format(fn), end='')
f()
print()
if __name__ == '__main__':
main()
@ydm
Copy link
Author

ydm commented Aug 14, 2014

А така се решава задачата на С:

int
greater (int a, int b)
{
  const int res = a - b;
  const int mask = res >> 31;
  return (mask & b ) | (~mask & a);
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment