第3章

p.19
問1
for n in range(1,32):
  print n

結果は省略:同じ表示が得られた

問2
for n in range(3,31):
  print n,

結果:
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30

問3
for n in range(1,32,3):
  print n, 

結果:
1 4 7 10 13 16 19 22 25 28 31

問4
for n in range(1,32):
  print n,

結果:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31

p.21

問1

wday=("sun","mon","tue","wed","thu","fri","sat")

def cal0(n,m):
  for x in wday: print " ",x,
  print
  #### for x in range(0, n): print "  ---",
  for x in range(1, m+1):
    print "%5d"%x,
    #### if (x+n)%7==0 : print
  print

結果:
>>> cal0(6,31)
  sun   mon   tue   wed   thu   fri   sat
    1     2     3     4     5     6     7     8     9    10    11    12    13
 14    15    16    17    18    19    20    21    22    23    24    25    26    2
7    28    29    30    31

問2
print range(1,6)

結果:
[1, 2, 3, 4, 5]

したがって、リストである


p.22
問1
def kadai3_5_1(start):
  for x in range(1,32):
    print x,
    if (start+x)%7 == 0:
      print
  print

kadai3_5_1(3)

結果:

1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31

p.24
問1

def kadai_3_6_1(m=31):
  wday=("sun","mon","tue","wed","thu","fri","sat")
  for x in wday: print " ",x,
  print
  #### for x in range(0, n): print "  ---",
  for x in range(1, m+1):
    print "%5d"%x,
    if x%7==0 : print
  print

kadai_3_6_1()

結果:
  sun   mon   tue   wed   thu   fri   sat
    1     2     3     4     5     6     7
    8     9    10    11    12    13    14
   15    16    17    18    19    20    21
   22    23    24    25    26    27    28
   29    30    31

問2

def kadai_3_6_2(m=31,n=3):
  wday=("sun","mon","tue","wed","thu","fri","sat")
  for x in wday: print " ",x,
  print
  for x in range(0, n): print "  ---",
  for x in range(1, m+1):
    print "%5d"%x,
    if (x+n)%7==0 : print
  print

kadai_3_6_2()


結果:
  sun   mon   tue   wed   thu   fri   sat
  ---   ---   ---     1     2     3     4
    5     6     7     8     9    10    11
   12    13    14    15    16    17    18
   19    20    21    22    23    24    25
   26    27    28    29    30    31


p.25
問1
def kadai_3_7_1():
  n=3
  for x in range(0,n):
     print "%5s"%"---",
  for x in range(1,32):
     print "%5d"%x,
     if (x+n)%7 == 0:
        print
  print

結果:
>>> kadai_3_7_1()
  ---   ---   ---     1     2     3     4
    5     6     7     8     9    10    11
   12    13    14    15    16    17    18
   19    20    21    22    23    24    25
   26    27    28    29    30    31


p.27

問1

def f(x,y):
  print (x+y)*y

f(2,3)
print f(2,5)

結果
15
35
None # 関数fが返した値Noneをprintしたもの


p.28
問1

def f(x):
  return(1.0/(x*x + 1))

f(2)

f(3)

結果:
0.2  # 1/5
0.1  # 1/10


問2

def V(r):
  from math import pi
  return(4.0*pi*r**3/3.0)

>>> V(2)
33.510321638291124
>>> V(3)
113.09733552923255


p.33
問1
def leap(x):
  if (x % 4 != 0):
     return 0
  if (x % 400 == 0) or (x % 100 != 0):
     return 1
  return 0

問2

400年間で146097日
(17*365+4) % 7 = 0
したがって、 1583年1月1日は2000年の1月1日と同じ曜日、土曜日
1582年10月15日は、1+16+30+31=78日前。これは7で割ると1余る、よって金曜日


問3

def leap(x):
  if (x % 400 == 0) or ((x % 4 == 0) and (x % 100 != 0)):
     return 1
  return 0


p.35

問1

def h(y,m,d):
  # h(y,m,d): day of week (Zeller's formula)
  # 奥村晴彦「コンピュータアルゴリズム辞典」(技術評論社,1989)
  # y: year, 0,1,2,..
  # m: month, 1,2,..,12
  # d: day of month, 1,2,..31
  # return: day of week, 0,1,2,..,6
  # example: h(2000,1,1) -> 6 # Saturday
  if m<3: y=y-1; m=m+12
  return (y+y/4-y/100+y/400+(13*m+8)/5+d)%7

def h0(y,m,d):
  if m<3: y=y-1; m=m+12
  return (y+y/4+(13*m-2)/5+d)%7

def cal0(n,m):
  # cal0(n,m)は1つの月のカレンダーを作成する。
  # nは月の開始日の曜日を表す数字(0,1,..,6)であり、0が日曜日を意味する
  # mはその月の日数である。例えば1月はm=31である
  #従って2000年1月のカレンダーはcal0(6,31)で印刷される
  for x in ("sun","mon","tue","wed","thu","fri","sat"): print " ",x,
  print
  for x in range(0, n): print "  ---",
  for x in range(1, m+1):
    print "%5d"%x,
    if (x+n)%7==0 : print
  print

def cal_1582_10(n,m,n1):
  for x in ("sun","mon","tue","wed","thu","fri","sat"): print " ",x,
  print
  for x in range(0, n): print "  ---",
  for x in range(1, 5):   # 1..4
    print "%5d"%x,
    # if (x+n)%7==0 : print
  for x in range(15, m):  # 15..31
    print "%5d"%x,
    if (x+n1)%7==0 : print
  print

def cal(y,m):
  # y: year, 0,1,2,..
  # m: month, 1,2,..,12
  if (y > 1582) or  ((y == 1582) and (m >= 11)):
     n=h(y,m,1)
     n1=h(y,m+1,1)
  elif (y <= 1582):
     n = h0(y,m,1)
     n1 = h0(y,m+1,1)
     if ((y == 1582) and (m == 10)):
        return(cal_1582_10(n, 28+(n1-n)%7, h(y,m,1)))
  r=(n1-n)%7
  d=28+r
  cal0(n,d)

>>> cal(1582,9)
  sun   mon   tue   wed   thu   fri   sat
  ---   ---   ---   ---   ---   ---     1
    2     3     4     5     6     7     8
    9    10    11    12    13    14    15
   16    17    18    19    20    21    22
   23    24    25    26    27    28    29
   30

>>> cal(1582,10)
  sun   mon   tue   wed   thu   fri   sat
  ---     1     2     3     4    15    16
   17    18    19    20    21    22    23
   24    25    26    27    28    29    30


p.37
問1
1 1 2 3 5 8
13 21 34 55 89


p.39

問2
x=1
y=1
while x < 10000:
  print x
  z = x + y
  x=y
  y=z


結果:
1
1
2
3
5
8
13
21
34
55
89
144
233
377
610
987
1597
2584
4181
6765

何番目の数かも合わせて表示すると良い

x=1
y=1
for n in range(1,31):
  print "Fib(",n,")=",x
  z = x + y
  x=y
  y=z

結果:
Fib( 1 )= 1
Fib( 2 )= 1
Fib( 3 )= 2
Fib( 4 )= 3
Fib( 5 )= 5
Fib( 6 )= 8
Fib( 7 )= 13
Fib( 8 )= 21
Fib( 9 )= 34
Fib( 10 )= 55
Fib( 11 )= 89
Fib( 12 )= 144
Fib( 13 )= 233
Fib( 14 )= 377
Fib( 15 )= 610
Fib( 16 )= 987
Fib( 17 )= 1597
Fib( 18 )= 2584
Fib( 19 )= 4181
Fib( 20 )= 6765
Fib( 21 )= 10946
Fib( 22 )= 17711
Fib( 23 )= 28657
Fib( 24 )= 46368
Fib( 25 )= 75025
Fib( 26 )= 121393
Fib( 27 )= 196418
Fib( 28 )= 317811
Fib( 29 )= 514229
Fib( 30 )= 832040

問3

y=z としたときに元のyの値は消されてzの値が代入される
したがって次のx=yで代入されるのはzの値になってしまう

p.40
問4

5442853 を 4555013で割った余り: 887840
4555013 を 887840 で割った余り: 115813
887840 を  115813 で割った余り: 77149
115813 を 77149 で割った余り: 38664
77149  を  38664 で割った余り:38485
38664 を 38485 で割った余り:179
38485 を 179 で割った余り: 0
ゆえに 179が最大公約数

問5

def gcd(x,y):
  if (y > x):
     z = x; x = y; y = z
  r = x % y
  if (r == 0):
     return(y)
  return(gcd(y,r))

gcd(11349,6201)

gcd(6201,11349)

gcd(5442853, 4555013)

結果:
117
117
179


問6
y = 30000000
for x in range(1,30):
  y = y*1.05
  y = y-2000000
  if y < 0:
    break
  print x," ",y

1   29500000.0
2   28975000.0
3   28423750.0
4   27844937.5
5   27237184.375
6   26599043.5938
7   25928995.7734
8   25225445.5621
9   24486717.8402
10   23711053.7322
11   22896606.4188
12   22041436.7398
13   21143508.5768
14   20200684.0056
15   19210718.2059
16   18171254.1162
17   17079816.822
18   15933807.6631
19   14730498.0462
20   13467022.9486
21   12140374.096
22   10747392.8008
23   9284762.44082
24   7749000.56286
25   6136450.59101
26   4443273.12056
27   2665436.77658
28   798708.615414

28年間、798,709円

p.41

問
d=[31,29,31,30,31,30,31,31,30]
>>> sum(d)
274

d=[31,29,31,30,31,30,31,31,30,31,30,31]
>>> sum(d[0:9])
274

p.47
問1

from math import *
def f(x):
  return cos(x)-x

x0=0
x1=pi/2


def solve(x0, x1):
  if f(x0)*f(x1) > 0:
     print "f(x0) = ",f(x0), ", f(x1) =",f(x1)
     return("wrong parameger")
  if f(x0) < 0:
      x1, x0 = x0, x1
  while abs(x1 - x0) > 1.0e-8:
    x = (x0+x1)/2.0
    y = f(x)
    # print x,y,x0,x1
    if y > 0: x0=x
    elif y < 0: x1=x
    else: break
  return(x1)

def f(x):
  return(-x**2+1.0 - x)


>>> solve(0,1)
0.6180339902639389
>>> solve(-3,0)
-1.6180339939892292
>>> f(0.618)
7.6000000000076e-05
>>> f(-1.618)
7.599999999974294e-05



4.5
>>> n = 365
>>> p = 1.0
>>> for x in range(1,30)
...   print x,p
...   p *= float(n-x)/n

1 1.0
2 0.997260273973
3 0.991795834115
4 0.983644087533
5 0.9728644263
6 0.959537516351
7 0.943764296904
8 0.925664707648
9 0.905376166111
10 0.883051822289
11 0.858858621678
12 0.832975211162
13 0.805589724768
14 0.776897487995
15 0.747098680236
16 0.716395994747
17 0.684992334703
18 0.653088582128
19 0.620881473968
20 0.588561616419
21 0.556311664835
22 0.524304692337
23 0.492702765676


for z in range(1,20):
  for y in range(1,z+1):
    for x in range(1,y+1):
      v = x**3 + y**3+z**3
      u = int(v**(1.0/3)+0.5)
      if u**3 == v: print x,y,z,u

for z in range(1,500):
  for y in range(1,z+1):
    for x in range(1,y+1):
      v = x**4 + y**4+z**4
      u = int(v**(1.0/4)+0.5)
      if u**4 == v: print x,y,z,u

みつからず。。。

Program 4.14
-----
from copy import *

def put(d,p):
  for i in -1,0,1:
    for j in -1,0,1:
      q=(p[0]+i,p[1]+j)
      if d.count(q): d.remove(q)

def pr(d):
  for p in d: print p,

def next(d,lv):
  if len(d)==0: 
     print " "*lv,"========================="
     return None # No space to put a stone. I've lost.
  print " "*lv,"[",
  pr(d)
  print "]"
  for p in d:
    print " "*lv,p,":",
    e=copy(d) # make a copy of d to protect from modification.
    put(e,p)  # put a stone
    if next(e,lv+1)==None: # and glance at Frank
      return p    # he looks pale. I will win.
  print " "*lv,"---------------------"
  return None # Frank is smiling for my all trials. He will win.

# initialize
m=5
d=[]
for i in range(0,m):
  for j in range(0,m):
    d.append((i,j))

print "RESULT:", next(d,0)