def power(a, n): assert n > 0 or (a != 0 or n != 0) if n == 0: return 1 else: a2 = power(a, n/2) if n & 1: return a*a2*a2 else: return a2*a2
int power(int a, int n) { assert(n > 0 || (a != 0 || n != 0)); if (n == 0) return 1; else { int a2 = power(a, n/2); if (n & 1) return a*a2*a2; else return a2*a2; } }
Let's use arbitrariness when writing programs and write them so that it is easier to prove their correctness. As a result, the program is easier to write, and the proof of correctness is immediately obtained.These are my words.
# -*- coding: utf-8 -*- # def power(a, n): """ a n """ assert n > 0 or (a != 0 or n != 0) r, a0, n0 = 1, a, n # r == 1 and a0 == a and n0 == n and n >= 0 # _: a0**n0 == r*a**n # _(n): n while n > 0: # n > 0 and # _(n) > 0 and # _ if n & 1: r *= a #(n - and a0**n0*a == r*a**n) or # _ n >>= 1 # _(n) > _(n/2) and # a0**n0 == r*a**(2*n) a *= a # _ # n == 0 and # _ and # _(n) == 0 # a0**n0 == r return r if __name__ == '__main__': for i in range(14): print "2**%d" % i ,"=", power(2, i) print "2**%d" % i ,"=", power(-2, i)
#include <cassert> #include <cstdlib> #include <iostream> // int power(int a, int n) { // a n assert(n > 0 || (a != 0 || n != 0)); int r = 1, a0 = a, n0 = n; /* r == 1 and a0 == a and n0 == n and n >= 0 _: a0**n0 == r*a**n _(n): n */ while(n > 0) { /* n > 0 and _(n) > 0 and _ */ if (n & 1) r *= a; /* (n - and a0**n0*a == r*a**n) or _ */ n >>= 1; /* _(n) > _(n/2) and a0**n0 == r*a**(2*n) */ a *= a; // _ } /* n == 0 and _ and _(n) == 0 */ // a0**n0 == r return r; } int main(int argc, char *argv[]) { for(int i=0; i < 14; i++) { std::cout << "2**" << i << " = " << power(2, i) << std::endl; std::cout << "(-2)**" << i << " = " << power(-2, i) << std::endl; } return EXIT_SUCCESS; }
# -*- coding: utf-8 -*- # def power(a, n): """ a n """ assert n > 0 or (a != 0 or n != 0) r = 1 # _: a0**n0 == r*a**n while n > 0: if n & 1: r *= a n >>= 1 a *= a return r if __name__ == '__main__': for i in range(14): print "2**%d" % i ,"=", power(2, i) print "2**%d" % i ,"=", power(-2, i)
#include <cassert> #include <cstdlib> #include <iostream> // int power(int a, int n) { // a n assert(n > 0 || (a != 0 || n != 0)); int r = 1; // _: a0**n0 == r*a**n while(n > 0) { if (n & 1) r *= a; n >>= 1; a *= a; } return r; } int main(int argc, char *argv[]) { for(int i=0; i < 14; i++) { std::cout << "2**" << i << " = " << power(2, i) << std::endl; std::cout << "(-2)**" << i << " = " << power(-2, i) << std::endl; } return EXIT_SUCCESS; }
def bSearch(a, v, l, r): if l >= r: return -1 else: m = (l + r)/2 assert l <= m < r if v > a[m]: return bSearch(a, v, m + 1, r) elif v < a[m]: return bSearch(a, v, l, m) else: assert v == a[m] return m
int bSearch(int *a, int v, int l, int r) { if (l >= r) return -1; else { int m=(l + r)/2; assert(l <= m && m < r); if (v > a[m]) return bSearch(a, v, m + 1, r); else if (v < a[m]) return bSearch(a, v, l, m); else { assert(v == a[m]); return m; } } }
# -*- coding: utf-8 -*- # C a def heapsort(a): """ C a """ k, n = 1, len(a) # k == 1 and # _1: a[(i - 1)/2] >= a[i] i=1..k # _1(k, n): n - k while k < n: # k < n # and _1 # and _1(k, n) > 0 leaf = k k += 1 # k <= n # and _1 i == leaf # and _1(k, n) > _1(k+1, n) # _2: _1 i == leaf # _2(leaf): (_1 0) leaf-1 while leaf > 0: # leaf > 0 # and _2 # and _2(leaf) > 0 root = (leaf - 1)/2 if a[root] >= a[leaf]: # _2 # and _1 # and _(child) == 0 break else: a[root], a[leaf] = a[leaf], a[root] leaf = root # _2(leaf) > _2((leaf - 1)/2) # and _2 # _2 # and _2(child) == 0 # _1 # k == n # and _1 # and _1(k, n) == 0 # _3: a[(i - 1)/2] >= a[i] i=1..k # and a[j-1] <= a[j] j=k..n # and a[m] <= a[l] m=0..k, l=k..n # _3(k): k - 1 while k > 0: # k > 0 # and _3 # and _3(k) > 0 # and a[0] >= a[i] i=0..k k -= 1 a[k], a[0] = a[0], a[k] # _3 i=0 # and _3(k) > _3(k-1) root = 0 # _4: _3 i=root # _4(root, k): (_3 0) (k-(2*root+1)) while 2*root + 1 < k: # 2*root + 1 < k # and _4 # and _4(root, k) > 0 leaf = 2*root + 1 # _4 # and leaf == 2*root + 1 if (leaf + 1) < k and a[leaf] < a[leaf + 1]: leaf += 1 # _4 # and (2*((leaf-1)/2)+2 == k # or a[leaf] == max(a[2*((leaf-1)/2)+1], a[2*((leaf-1)/2)+2])) if a[root] >= a[leaf]: # _4 # and _3 # and _4(root, k) == 0 break else: a[root], a[leaf] = a[leaf], a[root] root = leaf # _4 # and _4(root, k) > _4(2*root + 1, k) # _4 # and _4(root, k) == 0 # _3 # k == 0 # and _3 # and _3(k) == 0 # a[j-1] <= a[j] j=0..n if __name__ == '__main__': import random a = map(lambda x: random.randint(-100, 100), range(20)) print a heapsort(a) print a
#include <cassert> #include <cstdlib> #include <ctime> #include <iostream> // C a void sortHeap(int *a, int n) { // C a assert(n >= 0); int k = 1; /* k == 1 and _1: a[(i - 1)/2] >= a[i] i=1..k _1(k, n): n - k */ while(k < n) { /* k < n and _1 and _1(k, n) > 0 */ int leaf = k; ++k; /* k <= n and _1 i == leaf and _1(k, n) > _1(k+1, n) */ /* _2: _1 i == leaf _2(leaf): (_1 0) leaf-1 */ while(leaf > 0) { /* leaf > 0 and _2 and _2(leaf) > 0 */ int root = (leaf - 1)/2; if (a[root] >= a[leaf]) /* _2 and _1 and _(child) == 0 */ break; else { int tmp = a[root]; a[root] = a[leaf]; a[leaf] = tmp; leaf = root; /* _2(leaf) > _2((leaf - 1)/2) and _2*/ } /* _2 and _2(child) == 0 */ } // _1 } /* k == n and _1 and _1(k, n) == 0 */ /* _3: a[(i - 1)/2] >= a[i] i=1..k and a[j-1] <= a[j] j=k..n and a[m] <= a[l] m=0..k, l=k..n _3(k): k - 1 */ while(k > 0) { /* k > 0 and _3 and _3(k) > 0 and a[0] >= a[i] i=0..k */ --k; int tmp = a[k]; a[k] = a[0]; a[0] = tmp; /* _3 i=0 and _3(k) > _3(k-1) */ int root = 0; /* _4: _3 i=root _4(root, k): (_3 0) (k-(2*root+1)) */ while(2*root + 1 < k) { /* 2*root + 1 < k and _4 and _4(root, k) > 0 */ int leaf = 2*root + 1; /* _4 and leaf == 2*root + 1 */ if ((leaf + 1) < k and a[leaf] < a[leaf + 1]) leaf += 1; /* _4 and (2*((leaf-1)/2)+2 == k or a[leaf] == max(a[2*((leaf-1)/2)+1], a[2*((leaf-1)/2)+2])) */ if (a[root] >= a[leaf]) /* _4 and _3 and _4(root, k) == 0 */ break; else { int tmp = a[root]; a[root] = a[leaf]; a[leaf] = tmp; root = leaf; /* _4 and _4(root, k) > _4(2*root + 1, k) */ } /* _4 and _4(root, k) == 0 */ } // _3 } /* k == 0 and _3 and _3(k) == 0 */ // a[j-1] <= a[j] j=0..n } int main(int argc, char *argv[]) { srand((unsigned)time(NULL)); const int n = 20; int a[n]; for(int i=0; i < 20; i++) a[i] = rand()/(RAND_MAX/200) - 100; for(int i=0; i < 20; i++) std::cout << a[i] << ' '; std::cout << std::endl; sortHeap(a, n); for(int i=0; i < 20; i++) std::cout << a[i] << ' '; std::cout << std::endl; return EXIT_SUCCESS; }
Source: https://habr.com/ru/post/268013/