2014年12月28日日曜日

141228

Haskell


union

Prelude> :m + Data.List
Prelude Data.List> :t union
union :: Eq a => [a] -> [a] -> [a]
Prelude Data.List> union [1,2,2,3,3,3,4,4,4,4] [3,4,4,5,6,6]
[1,2,2,3,3,3,4,4,4,4,5,6]
Prelude Data.List> union [3,4,4,5,6,6] [1,2,2,3,3,3,4,4,4,4]
[3,4,4,5,6,6,1,2]

foldl1

Prelude> foldl1 (+) [1..10]
55
Prelude> foldl1 (*) [1..10]
3628800
Prelude> foldl1 (lcm) [1..10]
2520
Prelude> foldl1 (gcd) [8,12,36]
4

2014年12月24日水曜日

141224

Haskell


リストの差

\\はPreludeListではなく、Data.Listに含まれている関数。

Prelude> import Data.List
Prelude Data.List> [x | x <- [220,230..320]] \\ [x+y | x <- [0,50..300], y <- [0
,80..320]]
[220,270]

2014年12月7日日曜日

141207(4)

NumPy


分割

>>> ary = np.arange(20).reshape(5, 4)
>>> first, second, third, forth = np.split(ary, [1,2,3])
>>> first
array([[0, 1, 2, 3]])
>>> forth
array([[12, 13, 14, 15],
       [16, 17, 18, 19]])
>>> first, second, third = np.split(ary, [1,2], axis=1)
>>> first
array([[ 0],
       [ 4],
       [ 8],
       [12],
       [16]])
>>> third
array([[ 2,  3],
       [ 6,  7],
       [10, 11],
       [14, 15],
       [18, 19]])

141207(3)

Pandas


パネル

>>> import pandas as pd
>>> import pandas.io.data as web
>>> pdata = pd.Panel(dict((stk, web.get_data_yahoo(stk, '12/1/2014', '12/5/2014'
)) for stk in ['AAPL', 'IBM', 'MSFT']))
>>> pdata
<class 'pandas.core.panel.Panel'>
Dimensions: 3 (items) x 5 (major_axis) x 6 (minor_axis)
Items axis: AAPL to MSFT
Major_axis axis: 2014-12-01 00:00:00 to 2014-12-05 00:00:00
Minor_axis axis: Open to Adj Close
>>> pdata = pdata.swapaxes('items','minor')
>>> pdata['Adj Close']
              AAPL     IBM   MSFT
Date
2014-12-01  115.07  161.54  48.62
2014-12-02  114.63  162.67  48.46
2014-12-03  115.93  164.52  48.08
2014-12-04  115.49  164.05  48.84
2014-12-05  115.00  163.27  48.42

141207(2)

Pandas


インデックス参照

>>> from pandas import Series, DataFrame
>>> frame = DataFrame(np.arange(6). reshape(3,2), index=[3,2,1])
>>> frame
   0  1
3  0  1
2  2  3
1  4  5
>>> frame.irow(0)
0    0
1    1
Name: 3, dtype: int32
>>> frame.irow(1)
0    2
1    3
Name: 2, dtype: int32
>>> frame.irow(2)
0    4
1    5
Name: 1, dtype: int32
>>> frame.icol(0)
3    0
2    2
1    4
Name: 0, dtype: int32
>>> frame.icol(1)
3    1
2    3
1    5
Name: 1, dtype: int32

141207

Pandas


相関と共分散

>>> import pandas.io.data as web
>>> for ticker in ['AAPL', 'IBM', 'MSFT', 'GOOG']:
...     try:
...         all_data[ticker] = web.get_data_yahoo(ticker, '1/1/2005', '1/1/2010')
...         price = DataFrame({tic: data['Adj Close'] for tic, data in all_data.
iteritems()})
...         volume = DataFrame({tic: data['Volume'] for tic, data in all_data.it
eritems()})
...     except:
...         print "Cant find ", ticker
...
Cant find  GOOG
>>> returns = price.pct_change()
>>> returns.tail()
                AAPL       IBM      MSFT
Date
2009-12-24  0.034382  0.004402  0.002582
2009-12-28  0.012376  0.013315  0.005519
2009-12-29 -0.011876 -0.003410  0.006952
2009-12-30  0.012018  0.005424 -0.013808
2009-12-31 -0.004191 -0.012616 -0.015475
>>> returns.corr()
          AAPL       IBM      MSFT
AAPL  1.000000  0.497221  0.445868
IBM   0.497221  1.000000  0.559678
MSFT  0.445868  0.559678  1.000000
>>> returns.cov()
          AAPL       IBM      MSFT
AAPL  0.000716  0.000206  0.000236
IBM   0.000206  0.000240  0.000171
MSFT  0.000236  0.000171  0.000390
>>> returns.corrwith(volume)
AAPL   -0.010122
IBM     0.031356
MSFT   -0.056822
dtype: float64

2014年12月6日土曜日

141206(2)

Pandas


sum, meanの使い方

>>> a = np.arange(24).reshape((6,4))
>>> a
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15],
       [16, 17, 18, 19],
       [20, 21, 22, 23]])
>>> df = DataFrame(a, index=['a','b','c','d','e','f'], columns=['one','two','thr
ee','four'])
>>> df
   one  two  three  four
a    0    1      2     3
b    4    5      6     7
c    8    9     10    11
d   12   13     14    15
e   16   17     18    19
f   20   21     22    23
>>> df.sum()
one      60
two      66
three    72
four     78
dtype: int64
>>> df.mean()
one      10
two      11
three    12
four     13
dtype: float64
>>> df.sum(axis=1)
a     6
b    22
c    38
d    54
e    70
f    86
dtype: int64
>>> df.mean(axis=1)
a     1.5
b     5.5
c     9.5
d    13.5
e    17.5
f    21.5
dtype: float64

141206

Pandas


ラベルを使ったスライシング

>>> obj = Series(np.arange(4), index = ['a', 'b', 'c', 'd'])
>>> obj[1:2]
b    1
dtype: int32
>>> obj['b':'c']
b    1
c    2
dtype: int32

2014年11月30日日曜日

141130(4)

NumPy


多重ランダムウォーク

>>> nwalks = 5
>>> nsteps = 50
>>> draws = np.random.randint(0, 2, size=(nwalks, nsteps))
>>> steps = np.where(draws > 0, 1, -1)
>>> steps
array([[-1, -1, -1,  1,  1,  1,  1, -1, -1, -1, -1, -1,  1, -1,  1, -1, -1,
         1, -1,  1,  1,  1,  1,  1, -1,  1,  1,  1,  1, -1, -1,  1, -1, -1,
        -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,  1,  1, -1,  1,  1,  1],
       [-1,  1,  1, -1,  1, -1,  1, -1,  1, -1, -1,  1, -1, -1, -1, -1,  1,
         1,  1,  1,  1,  1, -1, -1,  1,  1, -1, -1, -1,  1, -1,  1, -1,  1,
        -1,  1, -1, -1,  1,  1,  1,  1, -1, -1, -1,  1,  1,  1, -1,  1],
       [ 1,  1, -1, -1, -1, -1,  1,  1, -1, -1, -1, -1,  1, -1,  1,  1,  1,
         1, -1, -1,  1, -1, -1, -1,  1, -1, -1,  1, -1,  1, -1, -1, -1, -1,
         1, -1,  1, -1,  1,  1, -1, -1, -1,  1, -1,  1,  1,  1,  1,  1],
       [-1, -1, -1, -1, -1,  1,  1, -1, -1, -1,  1,  1,  1, -1, -1, -1, -1,
         1,  1, -1, -1, -1,  1, -1,  1, -1, -1,  1, -1, -1,  1, -1, -1, -1,
        -1,  1,  1, -1, -1,  1, -1,  1, -1,  1, -1, -1, -1,  1,  1,  1],
       [-1, -1,  1,  1,  1, -1,  1, -1,  1, -1,  1, -1, -1, -1,  1, -1, -1,
         1,  1, -1, -1,  1,  1, -1,  1, -1,  1,  1, -1, -1, -1,  1,  1, -1,
         1, -1, -1, -1,  1,  1,  1,  1,  1,  1,  1, -1,  1,  1, -1,  1]])
>>> walk = steps.cumsum(1)
>>> walk
array([[ -1,  -2,  -3,  -2,  -1,   0,   1,   0,  -1,  -2,  -3,  -4,  -3,
         -4,  -3,  -4,  -5,  -4,  -5,  -4,  -3,  -2,  -1,   0,  -1,   0,
          1,   2,   3,   2,   1,   2,   1,   0,  -1,  -2,  -3,  -4,  -5,
         -6,  -7,  -8,  -9, -10,  -9,  -8,  -9,  -8,  -7,  -6],
       [ -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,  -1,   0,  -1,
         -2,  -3,  -4,  -3,  -2,  -1,   0,   1,   2,   1,   0,   1,   2,
          1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,   0,  -1,  -2,  -1,
          0,   1,   2,   1,   0,  -1,   0,   1,   2,   1,   2],
       [  1,   2,   1,   0,  -1,  -2,  -1,   0,  -1,  -2,  -3,  -4,  -3,
         -4,  -3,  -2,  -1,   0,  -1,  -2,  -1,  -2,  -3,  -4,  -3,  -4,
         -5,  -4,  -5,  -4,  -5,  -6,  -7,  -8,  -7,  -8,  -7,  -8,  -7,
         -6,  -7,  -8,  -9,  -8,  -9,  -8,  -7,  -6,  -5,  -4],
       [ -1,  -2,  -3,  -4,  -5,  -4,  -3,  -4,  -5,  -6,  -5,  -4,  -3,
         -4,  -5,  -6,  -7,  -6,  -5,  -6,  -7,  -8,  -7,  -8,  -7,  -8,
         -9,  -8,  -9, -10,  -9, -10, -11, -12, -13, -12, -11, -12, -13,
        -12, -13, -12, -13, -12, -13, -14, -15, -14, -13, -12],
       [ -1,  -2,  -1,   0,   1,   0,   1,   0,   1,   0,   1,   0,  -1,
         -2,  -1,  -2,  -3,  -2,  -1,  -2,  -3,  -2,  -1,  -2,  -1,  -2,
         -1,   0,  -1,  -2,  -3,  -2,  -1,  -2,  -1,  -2,  -3,  -4,  -3,
         -2,  -1,   0,   1,   2,   3,   2,   3,   4,   3,   4]])

141130(3)

NumPy


行列計算

>>> from numpy.linalg import inv, qr
>>> mat = np.array([[1, 2, 3], [2, 4, 5], [3, 5, 7]])
>>> mat.dot(inv(mat))
array([[  1.00000000e+00,   0.00000000e+00,   2.22044605e-16],
       [  0.00000000e+00,   1.00000000e+00,   4.44089210e-16],
       [  0.00000000e+00,   0.00000000e+00,   1.00000000e+00]])
>>> q,r = qr(mat)
>>> q
array([[ -2.67261242e-01,  -3.58568583e-01,  -8.94427191e-01],
       [ -5.34522484e-01,  -7.17137166e-01,   4.47213595e-01],
       [ -8.01783726e-01,   5.97614305e-01,  -1.22124533e-15]])
>>> r
array([[-3.74165739, -6.68153105, -9.08688223],
       [ 0.        , -0.5976143 , -0.47809144],
       [ 0.        ,  0.        , -0.4472136 ]])
>>> q.dot(r)
array([[ 1.,  2.,  3.],
       [ 2.,  4.,  5.],
       [ 3.,  5.,  7.]])

141130(2)

NumPy


sum, meanの使い方

>>> a = np.arange(24).reshape((2,3,4))
>>> a
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])
>>> a.sum()
276
>>> a.mean()
11.5
>>> a.sum(0)
array([[12, 14, 16, 18],
       [20, 22, 24, 26],
       [28, 30, 32, 34]])
>>> a.mean(axis=0)
array([[  6.,   7.,   8.,   9.],
       [ 10.,  11.,  12.,  13.],
       [ 14.,  15.,  16.,  17.]])
>>> a.sum(1)
array([[12, 15, 18, 21],
       [48, 51, 54, 57]])
>>> a.mean(axis=1)
array([[  4.,   5.,   6.,   7.],
       [ 16.,  17.,  18.,  19.]])
>>> a.sum(2)
array([[ 6, 22, 38],
       [54, 70, 86]])
>>> a.mean(axis=2)
array([[  1.5,   5.5,   9.5],
       [ 13.5,  17.5,  21.5]])

load, savez, loadtxtの使い方

>>> ary1 = np.arange(10)
>>> ary2 = np.arange(3)
>>> np.savez('data', a = ary1, b = ary2)
>>> npz = np.load('data.npz')
>>> npz['a']
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
>>> npz['b']
array([0, 1, 2])

(data.txt
 1, 2, 3
 10,20,30
 が保存している状況で)
>>> ary = np.loadtxt('data.txt', delimiter=',')
>>> ary
array([[  1.,   2.,   3.],
       [ 10.,  20.,  30.]])

141130

NumPy, Matplotlib


山の描画

>>> import pylab as pl
>>> import numpy as np
>>> points = np.arange(-5,5,0.1)
>>> xs, ys = np.meshgrid(points, points)
>>> z = np.sqrt(xs**2 + ys**2)
>>> pl.imshow(z, cmap=pl.cm.gray); pl.colorbar()
<matplotlib.image.AxesImage object at 0x034EBA90>
<matplotlib.colorbar.Colorbar instance at 0x03550850>
>>> pl.title("Image plot of sqrt(x**2 + y**2) for a grid of values")
<matplotlib.text.Text object at 0x034DE730>
>>> pl.show()

2014年11月29日土曜日

141129

NumPy


reshapeの使い方

>>> a = np.arange(16).reshape((2,8))
>>> a
array([[ 0,  1,  2,  3,  4,  5,  6,  7],
       [ 8,  9, 10, 11, 12, 13, 14, 15]])
>>> a.reshape((4,4))
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11],
       [12, 13, 14, 15]])

transposeの使い方

>>> a = np.arange(120).reshape((2,3,4,5))
>>> a
array([[[[  0,   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,  32,  33,  34],
         [ 35,  36,  37,  38,  39]],

        [[ 40,  41,  42,  43,  44],
         [ 45,  46,  47,  48,  49],
         [ 50,  51,  52,  53,  54],
         [ 55,  56,  57,  58,  59]]],


       [[[ 60,  61,  62,  63,  64],
         [ 65,  66,  67,  68,  69],
         [ 70,  71,  72,  73,  74],
         [ 75,  76,  77,  78,  79]],

        [[ 80,  81,  82,  83,  84],
         [ 85,  86,  87,  88,  89],
         [ 90,  91,  92,  93,  94],
         [ 95,  96,  97,  98,  99]],

        [[100, 101, 102, 103, 104],
         [105, 106, 107, 108, 109],
         [110, 111, 112, 113, 114],
         [115, 116, 117, 118, 119]]]])
>>> a.transpose((0,1,2,3)).shape
(2, 3, 4, 5)
>>> a.transpose((0,1,3,2)).shape
(2, 3, 5, 4)
>>> a.transpose((0,2,1,3)).shape
(2, 4, 3, 5)
>>> a.transpose((0,2,3,1)).shape
(2, 4, 5, 3)

2014年11月24日月曜日

141124

クローラー(開発言語:Ruby)


今日「Rubyによるクローラー開発技法」という本を買ってきた。

第1章に「10分クローラーの作成」と書いてあるし、
amazonのレビューを見ても、親切で初心者向けと書いてあったので、
「よし!クローラーが作ってみよう!!」と意気込んでいたのですが、
結構つまづいている感じ…。

今日の進捗を大まかに記してみる。

1.wgetのインストール
2.wgetの簡単な使い方はわかっていないがすっとばす。
3.Rubyの基礎はわかっているのですっとばす。
4.webrick0.rb 実行
5.webrick-template.rb 実行
6.test-webserver0.rb 実行
7.再帰ダウンロードの検証には、
  2.がわかっていないといけないことに気付く。

  本書ではwgetは
  C:\wget\bin
  の直下にあるので、wgetを使用するときは
  cd /d 〜
  を使って移動。

  また、検証の際、立ち上げたページは閉じてしまわない。
8.10分クローラーの作成
  WebサイトのエンコードはUTF-8。
  本書では、
  そのまま処理できる
  と書いてあるが、
  Windowsではどのように標準出力してよいかわからない。
  ↑
  挫折気味。

2014年10月27日月曜日

141027

Python


Partition (number theory)

140823(3)のPython版。

n = 6
ps = [0 for i in xrange(n + 1)]
ps[0] = 1
for j in xrange(1,n + 1):
    for i in xrange(j,n + 1):
        ps[i] += ps[i - j]
        
print ps[n]

2014年10月20日月曜日

141020

Ruby


区分求積法

会社に行く前に以下の問題にトライしてみた。
https://codeiq.jp/ace/cielavenir/q1120

「y = x^x を x で 1 から 6 まで積分した値を

 1から 6 までを n 分割したものを
 ・台形公式(Trapezoid rule)  
 ・シンプソンの公式(Simpson's rule)  
 ・シンプソンの3/8公式(Simpson's 3/8 rule)  
 ・ブールの公式(Boole's rule)

 で近似する。

 真の値 17128.111274826415512 から0.1未満の誤差にするには
 少なくとも何分割必要か求めよ」
という問題。

実質1時間しかなく台形の場合しか正解しなかったが、
ようやく答えがあったのでコードを晒しておく。

def f(i)     # i番目の高さ
  x = 1 + (i - 1) * @d
  x ** x
end

n = 5
@d = (6.0 - 1.0) / n
sum = 0
for j in (1..n)
  sum += (f(j) + f(j + 1)) / 2 * @d
end
while sum - 17128.111274826415512 >= 0.1
  n += 1
  @d = (6.0 - 1.0) / n
  sum = 0
  for j in (1..n)
    sum += (f(j) + f(j + 1)) / 2 * @d
  end
end
p n

n = 5
@d = (6.0 - 1.0) / (n * 2)
sum = 0
for j in (1..n)
  sum += (f(j * 2 - 1) + 4 * f(j * 2) + f(j * 2 + 1)) / 3 * @d
end
while sum - 17128.111274826415512 >= 0.1
  n += 1
  @d = (6.0 - 1.0) / (n * 2)
  sum = 0
  for j in (1..n)
    sum += (f(j * 2 - 1) + 4 * f(j * 2) + f(j * 2 + 1)) / 3 * @d
  end
end
p n

n = 5
@d = (6.0 - 1.0) / (n * 3)
sum = 0
for j in (1..n)
  sum += (f(j * 3 - 2) + 3 * f(j * 3 - 1) + 3 * f(j * 3) + f(j * 3 + 1)) * 3 / 8 * @d
end
while sum - 17128.111274826415512 >= 0.1
  n += 1
  @d = (6.0 - 1.0) / (n * 3)
  sum = 0
  for j in (1..n)
    sum += (f(j * 3 - 2) + 3 * f(j * 3 - 1) + 3 * f(j * 3) + f(j * 3 + 1)) * 3 / 8 * @d
  end
end
p n

n = 5
@d = (6.0 - 1.0) / (n * 4)
sum = 0
for j in (1..n)
  sum += (7 * f(j * 4 - 3) + 32 * f(j * 4 - 2) + 12 * f(j * 4 - 1) + 32 * f(j * 4) + 7 * f(j * 4 + 1)) * 2 / 45 * @d
end
while sum - 17128.111274826415512 >= 0.1
  n += 1
  @d = (6.0 - 1.0) / (n * 4)
  sum = 0
  for j in (1..n)
    sum += (7 * f(j * 4 - 3) + 32 * f(j * 4 - 2) + 12 * f(j * 4 - 1) + 32 * f(j * 4) + 7 * f(j * 4 + 1)) * 2 / 45 * @d
  end
end
p n

出力結果
1648
40
32
10

2014年10月19日日曜日

141019

Python


複数行のコメントの仕方

""" 
ここは 
複数行コメント
"""

2014年10月18日土曜日

141018

Python


140511と以下を比較して、
Pythonはコードの短さについては言及していないのかな…と思った。

>>> import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

2014年10月5日日曜日

141005

Python


タートルグラフィックス

turtle.xcor()
タートルの x 座標を返す。

turtle.ycor()
タートルの y 座標を返す。

2014年10月4日土曜日

141004

Python


今日の夕方からPythonを勉強し始める。
新しいことばかりだったので、忘れないうちに記しておくことにする。

インストールについて
DLしたのはいいが、そのままだと上手くインストールできず。
デスクトップにファイルを移動後、インストール。

ファイルの開き方
pyファイルはEdit with IDLEで開かないと一瞬で開いた画面が消える。

ファイルの保存
エディタはRubyのときからTeraPadを使用しているが、
ファイルの種類は「すべてのファイル」を選択し、
名前を「〜.py」にする。

2014年9月27日土曜日

140927(2)

Ruby


Lucky prime

Wikipediaによれば、Lucky primeが無限に存在するかどうかは分かっていないらしい。
それはさておき、オンライン整数列大辞典の
A031157(http://oeis.org/A031157/list)
と比較し、答え合わせしてみる。

require 'prime'

# Nは3以上
N = 1123
ary = (1..(N / 2.0).ceil).map{|i| i * 2 - 1}

m = 1
n = ary[m]
while 2 * n <= N   # 次に取り除く数がNを超えなくなるまで続ける。
  ary0 = []
  ary.each_with_index{|e, i|
    if e <=  n
      ary0 << e
    elsif
      if (i + 1) % n != 0
        ary0 << e
      end
    end
  }
  ary = ary0
  m += 1
  n = ary[m]
end

l_prime = []
ary.each{|i|
  l_prime << i if i.prime?
}

# OEIS A031157のデータ
l_prime0 =
[3,7,13,31,37,43,67,73,79,127,151,163,193,211,223,
 241,283,307,331,349,367,409,421,433,463,487,541,
 577,601,613,619,631,643,673,727,739,769,787,823,
 883,937,991,997,1009,1021,1039,1087,1093,1117,
 1123]
# 一致の確認
p l_prime == l_prime0

140927

Ruby


Lucky number

ハッピー数の生成はよく見かけるので、幸福数を生成してみる。
オンライン整数列大辞典の
A000959(http://oeis.org/A000959/list)
と比較し、答え合わせしてみる。

# Nは3以上
N = 303
ary = (1..(N / 2.0).ceil).map{|i| i * 2 - 1}

m = 1
n = ary[m]
while 2 * n <= N   # 次に取り除く数がNを超えなくなるまで続ける。
  ary0 = []
  ary.each_with_index{|e, i|
    if e <=  n
      ary0 << e
    elsif
      if (i + 1) % n != 0
        ary0 << e
      end
    end
  }
  ary = ary0
  m += 1
  n = ary[m]
end

# OEIS A000959のデータ
ary0 =
[1,3,7,9,13,15,21,25,31,33,37,43,49,51,63,67,69,
 73,75,79,87,93,99,105,111,115,127,129,133,135,141,
 151,159,163,169,171,189,193,195,201,205,211,219,
 223,231,235,237,241,259,261,267,273,283,285,289,
 297,303]
# 一致の確認
p ary == ary0

2014年9月21日日曜日

140921

Ruby


約数の和(自身を含む)(ver.2.0)

140823(2)分より短く書いてみた。

require 'prime'

def sum2(i)
  list = [1]
  for a in (i.prime_division.to_a)
    list += list.product((1..a[1]).map{|e| a[0] ** e}).map{|e| e.inject(:*)}
  end
  list.inject(:+)
end

p sum2(24)

出力結果
60

2014年9月7日日曜日

140907(2)

Ruby


経路の和(ver.2.0)
テキストファイルに以下のような行列が書かれている。

11,66,55,33, 1
22,20, 1,99, 2
66,46,42,99, 3
99,44,99,96, 4
88,20,99,33,30
44,44,44,44,44

左上から右下までを上下左右方向(ただし、全ての方向を使用しなくてもよい。)
に移動するとき、経路の和の最小値を求めよ。

ver.1.1を少し変更するだけでよい。

a = []
size = 0
ARGF.each_line{|line|
  ary = line.chomp.split(/,/).map(&:to_i)
  @size = ary.size
  a << ary
  size += 1
}
if size < @size
  (@size - size).times{
    a0 = []
    @size.times{a0 << 1.0 / 0}
    a << a0
  }
elsif size > @size
  for i in (0..size - 1)
    (size - @size).times{
      a[i] << 1.0 / 0
    }
  end
else
end

Size = [size, @size].max
b = Array.new(Size){Array.new(Size){1.0 / 0}}

# スタート
si = 0
sj = 0
# ゴール
gi = size - 1
gj = @size - 1

b[si][sj] = a[si][sj]
q = [[si, sj]]
until q.empty?
  i, j = q.pop
  for ni, nj in [
    ([i + 1, j] if i + 1 < Size),
    ([i, j + 1] if j + 1 < Size),
    ([i - 1, j] if i > 0),
    ([i, j - 1] if j > 0)
  ].compact
    if (new_sum = b[i][j] + a[ni][nj]) < b[ni][nj]
      b[ni][nj] = new_sum
      q.unshift([ni, nj])
    end
  end
end

p b[gi][gj]

出力結果
226

ちなみに以下の経路

11,66,55,33, 1
22,20, 1,99, 2
66,46,42,99, 3
99,44,99,96, 4
88,20,99,33,30
44,44,44,44,44


応用
テキストファイルに以下のような行列が書かれている。

11,66,55,33, 1
22,20, 1,99, 2
66,46,42,99, 3
99,44,99,96, 4
88,20,99,33,30
44,44,44,44,44

(1,0)から(4,4)までを上下左右方向(ただし、全ての方向を使用しなくてもよい。)
に移動するとき、経路の和の最小値を求めよ。

上のコードにおいて
# スタート
si = 1
sj = 0
# ゴール
gi = 4
gj = 4
と変更すると、「171」と求まる。

ちなみに以下の経路

11,66,55,33, 1
22,201,99, 2
66,46,42,99, 3
99,44,99,96, 4
88,20,99,33,30
44,44,44,44,44

140907

Ruby


経路の和(ver.1.1)
テキストファイルに以下のような行列が書かれている。

11,66,55,33, 1
22,20, 1,99, 2
66,46,42,99, 3
99,44,99,96, 4
88,20,99,33,30
44,44,44,44,44

左上から右下までを下方向と右方向のみ移動するとき、
経路の和の最小値を求めよ。

昨日のコードでも「236」と求まるが、
より汎用性のあるコードを書いてみた。

a = []
size = 0
ARGF.each_line{|line|
  ary = line.chomp.split(/,/).map(&:to_i)
  @size = ary.size
  a << ary
  size += 1
}
if size < @size
  (@size - size).times{
    a0 = []
    @size.times{a0 << 1.0 / 0}
    a << a0
  }
elsif size > @size
  for i in (0..size - 1)
    (size - @size).times{
      a[i] << 1.0 / 0
    }
  end
else
end

Size = [size, @size].max
b = Array.new(Size){Array.new(Size){1.0 / 0}}

# スタート
si = 0
sj = 0
# ゴール
gi = size - 1
gj = @size - 1

b[si][sj] = a[si][sj]
q = [[si, sj]]
until q.empty?
  i, j = q.pop
  for ni, nj in [
    ([i + 1, j] if i + 1 < Size),
    ([i, j + 1] if j + 1 < Size)
  ].compact
    if (new_sum = b[i][j] + a[ni][nj]) < b[ni][nj]
      b[ni][nj] = new_sum
      q.unshift([ni, nj])
    end
  end
end

p b[gi][gj]

ちなみに以下の経路

11,66,55,33, 1
22,20, 1,99, 2
66,46,42,99, 3
99,44,99,96, 4
88,20,99,33,30
44,44,44,44,44


応用
テキストファイルに以下のような行列が書かれている。

11,66,55,33, 1
22,20, 1,99, 2
66,46,42,99, 3
99,44,99,96, 4
88,20,99,33,30
44,44,44,44,44

(1,0)から(2,2)までを下方向と右方向のみ移動するとき、
経路の和の最小値を求めよ。

上のコードにおいて
# スタート
si = 1
sj = 0
# ゴール
gi = 2
gj = 2
と変更すると、「85」と求まる。

ちなみに以下の経路

11,66,55,33, 1
22,20, 1,99, 2
66,46,42,99, 3
99,44,99,96, 4
88,20,99,33,30
44,44,44,44,44

2014年9月6日土曜日

140906

Ruby


経路の和(ver.1.0)
テキストファイルに以下のような行列が書かれている。

11,66,55,33
22,20,99,77
66,46,42,11
99,44,21,96
88,20,70,33

左上から右下までを下方向と右方向のみ移動するとき、
経路の和の最小値を求めよ。

a = []
size = 0
ARGF.each_line{|line| 
  ary = line.chomp.split(/,/).map(&:to_i)
  @size = ary.size
  a << ary
  size += 1
}

for i in (0..size - 1)
  for j in (0..@size - 1)
    if i == 0                # 一行目二列目以降は左だけ
      if j != 0
        a[i][j] += a[i][j - 1]
      end
    elsif j == 0             # 二行目以降の一列目は上だけ
      a[i][j] += a[i - 1][j]
    else                     # 二行目以降の二列目以降は左と上
      a[i][j] += [a[i][j - 1], a[i - 1][j]].min
    end
  end
end

p a[-1][-1]

出力結果
265

ちなみに以下の経路

11,66,55,33
22,20,99,77
66,46,42,11
99,44,21,96
88,20,70,33

2014年9月2日火曜日

140902

Ruby


BigMath

require 'bigdecimal'
require 'bigdecimal/math'

include BigMath

p PI(10).to_s
p PI(20).to_s

p E(10).to_s
p E(20).to_s

a = BigDecimal((PI(100) / 3).to_s)
p sin(a, 10).to_s
p sin(a, 20).to_s
p cos(a, 10).to_s
p cos(a, 20).to_s

p BigDecimal.new(2).sqrt(10).to_s
p BigDecimal.new(2).sqrt(20).to_s

出力結果
"0.3141592653589793238462643388813853786957412E1"
"0.3141592653589793238462643383279502883919859293521427E1"
"0.271828182845904523536028752390026306410273E1"
"0.2718281828459045235360287471352662501431940501312544E1"
"0.86602540378443864676372317195984839934691003312503527365831486410260546876206
96662093449417807056893273826955044274342879543627868976E0"
"0.86602540378443864676372317075293618360922677726177827365831486410260546876206
96662093449417807056893273826955044274342879543627868976E0"
"0.499999999999999999999999989308915718660433E0"
"0.50000000000000000000000000000000000112254582427634098E0"
"0.1414213562373095048690567017E1"
"0.141421356237309504880168872420969807825E1"

2014年8月31日日曜日

140831

Ruby


140823(3)  Partition
 ↓ 手をくわえる。
140823(4)  Prime Partition

汎用性はないが、140823(3)分よりも分割数を速く求めることができるコードを書いてみた。
(以下において、
p(i) = p(i - 1) + p(i - 2) - p(i - 5) - p(i - 7) + ...
を用いている。)

n = 10000

@part = [1, 1]
def part(i)
  sum = 0
  for j in (0..i)
    i1 = (1 - 2 * (j % 2)) * ((j + 2) / 2) # 1, -1, 2, -2, 3, -3, ...
    i1 = i1 * (3 * i1 - 1) / 2             # 1, 2, 5, 7, 12, 15, ...
    break if i1 > i
    if (j / 2).even?
      sum += @part[i - i1]
    else
      sum -= @part[i - i1]
    end
  end
  @part[i] = sum
end
for i in (1..n)
  part(i)
end

p @part[n]

2014年8月24日日曜日

140824

Ruby


循環節

dを「2からnまでの2でも5でも割り切れない整数」とする。
n = 20 のとき、d,1/dの循環節の長さ,1/dの循環節を出力せよ。

n = 20
(2..n).each{|d|
if d % 2 != 0 && d % 5 != 0
  cnt = 1
  x = (10 ** cnt) - 1
  while x % d != 0
    cnt += 1
    x = (10 ** cnt) - 1
  end
  puts "#{d}  #{(x / d).to_s.size}  #{(x / d).to_s}"
end
}

出力結果
3  1  3
7  6  142857
9  1  1
11  1  9
13  5  76923
17  15  588235294117647
19  17  52631578947368421

2014年8月23日土曜日

140823(4)

Ruby


Prime Partition

require 'prime'

n = 11
ary = []
Prime.each(n){|pr| ary << pr}

ps = Array.new(n + 1){0}
ps[0] = 1
ary.each{|num|
  (num..n).each{|i|
    ps[i] += ps[i - num]
  }
}
p ps[n]  # 2+2+2+2+3 = 2+3+3 = 2+2+2+5 = 3+3+5 = 2+2+7 = 11

140823(3)

Ruby


Partition (number theory)

以下の2つのコードのうち下の方が断然はやい。

n = 6
numbers = (1..n).to_a
cnt = 0
for i in (1..n)
numbers.repeated_combination(i){|j|
  if j.inject(:+) == n
    cnt += 1
  end
}
end
p cnt

n = 6
nums = (1..n).to_a
ps = Array.new(n + 1){0}
ps[0] = 1
nums.each{|num|
  # 末尾がnumなるものをカウント
  (num..n).each{|i|
    ps[i] += ps[i - num]
  }
}
p ps[n]

140823(2)

Ruby


約数の和(自身を含む)

require 'mathn'

# a^1+a^2+......a^x
def sum1(i, j)
  power = 1
  sum = 1
  for k in (1..j)
    power *= i
    sum += power
  end
  return sum
end

# (a^1+a^2+......a^x)(b^1+b^2+......b^y)......
def sum2(i)
  sum = 1
  pq = i.prime_division
  pq.each{|tes| sum *= sum1(tes[0], tes[1])}
  return sum
end

p sum2(24)  # 1, 2, 3, 4, 6, 8, 12, 24

出力結果
60

140823

Ruby


配列の結合について

ary1 = []
for i in (1..8)
p ary1
ary1 |= [2 * i, 3 * i, 5 * i]
end
p ary1

ary2 = []
for i in (1..8)
p ary2
ary2 += [2 * i, 3 * i, 5 * i]
end
p ary2

出力結果
[]
[2, 3, 5]
[2, 3, 5, 4, 6, 10]
[2, 3, 5, 4, 6, 10, 9, 15]
[2, 3, 5, 4, 6, 10, 9, 15, 8, 12, 20]
[2, 3, 5, 4, 6, 10, 9, 15, 8, 12, 20, 25]
[2, 3, 5, 4, 6, 10, 9, 15, 8, 12, 20, 25, 18, 30]
[2, 3, 5, 4, 6, 10, 9, 15, 8, 12, 20, 25, 18, 30, 14, 21, 35]
[2, 3, 5, 4, 6, 10, 9, 15, 8, 12, 20, 25, 18, 30, 14, 21, 35, 16, 24, 40]
[]
[2, 3, 5]
[2, 3, 5, 4, 6, 10]
[2, 3, 5, 4, 6, 10, 6, 9, 15]
[2, 3, 5, 4, 6, 10, 6, 9, 15, 8, 12, 20]
[2, 3, 5, 4, 6, 10, 6, 9, 15, 8, 12, 20, 10, 15, 25]
[2, 3, 5, 4, 6, 10, 6, 9, 15, 8, 12, 20, 10, 15, 25, 12, 18, 30]
[2, 3, 5, 4, 6, 10, 6, 9, 15, 8, 12, 20, 10, 15, 25, 12, 18, 30, 14, 21, 35]
[2, 3, 5, 4, 6, 10, 6, 9, 15, 8, 12, 20, 10, 15, 25, 12, 18, 30, 14, 21, 35, 16,
 24, 40]

2014年8月17日日曜日

140817

Ruby


gets, each_line, readlines

以下において、Inputは
3776
1111
645
2222
333
とする。

n = gets.to_i
p n
p ""
n = gets.to_i
p n
p ""
ARGF.each_line{|line|
  p line.to_i
}

出力結果
3776
""
1111
""
645
2222
333

n = gets.to_i
p n
p ""
n = gets.to_i
p n
p ""
readlines.each{|line|
  p line.to_i
}

出力結果
3776
""
1111
""
645
2222
333

ARGF.each_line{|line|
  p line.to_i
}

出力結果
3776
1111
645
2222
333

readlines.each{|line|
  p line.to_i
}

出力結果
3776
1111
645
2222
333

2014年8月13日水曜日

140813

Ruby


最大増加部分列(longest increasing subsequence)

「Rubyによる情報科学入門」で最大増加部分列の問題と出会う。
以下のコード(http://133.11.50.227/~kuno/is11/siryou/ohp12.pdf)
に間違いを見つける。

def lis(a)
  l = Array.new(a.length); t = Array.new(a.length)
  m = 1; p = 0
  a.each_index do |i|
    l[i] = 1; t[i] = i+1
    (i-1).step(0, -1) do |j|
      if a[i] > a[j] && l[i] < l[j]+1
        l[i] = l[j]+1; t[i] = i-j
        if m < l[i] then p = i; m = l[i] end
      end
    end
  end
  puts "a: #{a}"  #コードの間違いを発見するために追加
  puts "l: #{l}"  #   〃
  puts "t: #{t}"  #   〃
  showlis(a, t, p); puts
end
def showlis(a, t, p)
  if p > 0 then showlis(a, t, p-t[p]) end
  print(" #{a[p]}")
end
# 実験
a = [1, 5, 7, 2, 6, 3, 4, 9]
lis(a)
b = [4, 1, 6, 2, 8, 5, 7, 3]
lis(b)
c = [4, 1, 6, 2, 8, 0, 5, 7, 3]
lis(c)
d = [4, 1, 6, 2, 8, 0, 5, 7, 3, 1, 2, 3, 4]
lis(d)

出力結果
a: [1, 5, 7, 2, 6, 3, 4, 9]
l: [1, 2, 3, 2, 3, 3, 4, 5]
t: [1, 1, 1, 3, 1, 2, 1, 1]
 1 2 3 4 9
a: [4, 1, 6, 2, 8, 5, 7, 3]
l: [1, 1, 2, 2, 3, 3, 4, 3]
t: [1, 2, 1, 2, 1, 2, 1, 4]
 3 1 2 5 7
a: [4, 1, 6, 2, 8, 0, 5, 7, 3]
l: [1, 1, 2, 2, 3, 1, 3, 4, 3]
t: [1, 2, 1, 2, 1, 6, 3, 1, 5]
 3 1 2 5 7
a: [4, 1, 6, 2, 8, 0, 5, 7, 3, 1, 2, 3, 4]
l: [1, 1, 2, 2, 3, 1, 3, 4, 3, 2, 3, 4, 5]
t: [1, 2, 1, 2, 1, 6, 3, 1, 5, 4, 1, 1, 1]
 4 0 1 2 3 4

修正
def lis(a)
  l = Array.new(a.size); t = Array.new(a.size)
  m = 1; p = 0
  a.each_index{|i|
    l[i] = 1; t[i] = 0
    (i - 1).step(0, -1){|j|
      if a[i] > a[j] && l[i] < l[j] + 1
        l[i] = l[j] + 1; t[i] = i - j
        if m < l[i]
          p = i; m = l[i]
        end
      end
    }
  }
  puts "a: #{a}"
  puts "l: #{l}"
  puts "t: #{t}"
  showlis(a, t, p); puts
end
def showlis(a, t, p)
  if t[p] > 0
    showlis(a, t, p - t[p])
  end
  print(" #{a[p]}")
end

a = [1, 5, 7, 2, 6, 3, 4, 9]
lis(a)
b = [4, 1, 6, 2, 8, 5, 7, 3]
lis(b)
c = [4, 1, 6, 2, 8, 0, 5, 7, 3]
lis(c)
d = [4, 1, 6, 2, 8, 0, 5, 7, 3, 1, 2, 3, 4]
lis(d)

出力結果
a: [1, 5, 7, 2, 6, 3, 4, 9]
l: [1, 2, 3, 2, 3, 3, 4, 5]
t: [0, 1, 1, 3, 1, 2, 1, 1]
 1 2 3 4 9
a: [4, 1, 6, 2, 8, 5, 7, 3]
l: [1, 1, 2, 2, 3, 3, 4, 3]
t: [0, 0, 1, 2, 1, 2, 1, 4]
 1 2 5 7
a: [4, 1, 6, 2, 8, 0, 5, 7, 3]
l: [1, 1, 2, 2, 3, 1, 3, 4, 3]
t: [0, 0, 1, 2, 1, 0, 3, 1, 5]
 1 2 5 7
a: [4, 1, 6, 2, 8, 0, 5, 7, 3, 1, 2, 3, 4]
l: [1, 1, 2, 2, 3, 1, 3, 4, 3, 2, 3, 4, 5]
t: [0, 0, 1, 2, 1, 0, 3, 1, 5, 4, 1, 1, 1]
 0 1 2 3 4

2014年8月12日火曜日

140812

Ruby


処理される順番について

すごく基本的なことだが、次の二つは処理される順番が異なる。

def zyunban0(a, p)
  if p > 0
    zyunban0(a, p - 1)
  end
  puts "#{p}: #{a[p]}"
end

a = [100, 101, 102, 103]
b = a.size
zyunban0(a, b - 1)

出力結果
0: 100
1: 101
2: 102
3: 103

def zyunban1(a, p)
  while p > 0
    puts "#{p}: #{a[p]}"
    p = p - 1
  end
end

a = [100, 101, 102, 103]
b = a.size
zyunban1(a, b - 1)

出力結果
3: 103
2: 102
1: 101

2014年7月24日木曜日

140724

Ruby


条件演算子(式が複雑な場合)

「VisualC++2013パーフェクトマスター」で次のコードと出会う。

#include <iostream>
using namespace std;

struct dt1 {
int a;
double b;
};

int main()
{
int a = 1, b;

if (a < 5)
b = 10;
else
b = 50;

b = a<5 ? 10 : 50;

if (a < 10)
b = 1;
else if (a < 100)
b = 2;
else if (a < 500)
b = 3;
else
b = 4;

b = (a < 10) ? 1 : (a < 100) ? 2 : (a < 500) ? 1 : 4;

getchar();
return 0;

}

要するに、赤の部分が条件演算子を使って青の部分のように
1行で書けるということなのだが、
Rubyでも同じようにしてみる。

a = 3
if a < 10
  b = 1
elsif a < 100
  b = 2
elsif a < 500
  b = 3
else
  b = 4
end
puts b

a = 33
if a < 10
  b = 1
elsif a < 100
  b = 2
elsif a < 500
  b = 3
else
  b = 4
end
puts b

a = 333
if a < 10
  b = 1
elsif a < 100
  b = 2
elsif a < 500
  b = 3
else
  b = 4
end
puts b

a = 3333
if a < 10
  b = 1
elsif a < 100
  b = 2
elsif a < 500
  b = 3
else
  b = 4
end
puts b

a = 3
puts b = (a < 10)? 1 : (a < 100)? 2 :(a < 500)? 3 : 4

a = 33
puts b = (a < 10)? 1 : (a < 100)? 2 :(a < 500)? 3 : 4

a = 333
puts b = (a < 10)? 1 : (a < 100)? 2 :(a < 500)? 3 : 4

a = 3333
puts b = (a < 10)? 1 : (a < 100)? 2 :(a < 500)? 3 : 4

出力結果
1
2
3
4
1
2
3
4

2014年7月20日日曜日

140720

Ruby


Hashクラスのsortメソッド?

Ruby 1.9では、Hashクラスのsortメソッドは廃止され、
Hashのキーと値をソートした配列を作成して返す。

i_ary = [4, 1, 3, 2] 
w_ary = ["GABLES", "ANNE", "GREEN", "OF"]
hash = Hash[i_ary.zip(w_ary)]
p hash
p hash.sort
p hash.sort.map{|i| i[1]}.join(" ")

出力結果
{4=>"GABLES", 1=>"ANNE", 3=>"GREEN", 2=>"OF"}
[[1, "ANNE"], [2, "OF"], [3, "GREEN"], [4, "GABLES"]]   ←配列
"ANNE OF GREEN GABLES"

2014年7月13日日曜日

140713(2)

Ruby


Hashのキーや値をまとめて取り出す。

w = 'a1bxkk3k'
h = w.scan(/[a-z]/).join.chars.group_by(&:to_sym)
p h
p h.keys
p h.map{|f| f.first}                 ←これでもOK
p h.values
p h.map{|f| f.last}                 ←これでもOK

出力結果
{:a=>["a"], :b=>["b"], :x=>["x"], :k=>["k", "k", "k"]}
[:a, :b, :x, :k]
[:a, :b, :x, :k]
[["a"], ["b"], ["x"], ["k", "k", "k"]]
[["a"], ["b"], ["x"], ["k", "k", "k"]]

140713

Ruby


each_charメソッドは、charsメソッドと同じだが、今のところ後者の方が好きだ。

w = 'a1bxkk3k'
p w.scan(/[a-z]/).join.chars.group_by(&:to_sym)
p w.scan(/[a-z]/).join.each_char.group_by(&:to_sym)
# 途中で切ると…
p w.scan(/[a-z]/).join.chars
p w.scan(/[a-z]/).join.each_char

出力結果
{:a=>["a"], :b=>["b"], :x=>["x"], :k=>["k", "k", "k"]}
{:a=>["a"], :b=>["b"], :x=>["x"], :k=>["k", "k", "k"]}
["a", "b", "x", "k", "k", "k"]
#<Enumerator: "abxkkk":each_char>           ←何か汚い。

2014年6月15日日曜日

140615

Ruby


Hashの値の設定

既にあるキーに対して値を設定すれば格納されていた値が上書きされる。
maps1 = {1010 => false}
maps1[1100] = false
p maps1

maps2 = {1010 => false}
maps2[1100] = false
maps2[1010] = false  # 再度同じ値を指定
p maps2

maps3 = {1010 => false}
maps3[1100] = false
maps3[1010] = true  # 異なる値を指定
p maps3

出力結果
{1010=>false, 1100=>false}
{1010=>false, 1100=>false}
{1010=>true, 1100=>false}

この性質を使うと
状態 {101000=>false, 110000=>false} から
状態 {111000=>false, 101010=>false, 101100=>false, 110100=>false} へ
移行するプログラムを作ることは容易なことがわかる。

2014年6月2日月曜日

140602

誤差について


140315(2)について、数学的には正しいが、プログラミングのうえでは不完全な部分があった。

z = Math.sqrt(x**2+y**2)
  if z == z.to_i && z < 101 then

上記はzが整数になるときについて考えようとしているわけだが、
x**2+y**2が平方数に非常に近い場合、(数学的にz == z.to_i が偽であっても)
z == z.to_i が真となりうる。
よって、
z = Math.sqrt(x**2+y**2)
  if x**2+y**2 == (z.to_i)**2 && z < 101 then
とすべきである。

このことは、次のフェルマーが出した問題を解いているときに気づいた。
x^2 - 61y^2 = 1 の自然数解を求めよ。

y = 1
num = Math.sqrt(61*y**2+1)
while !(num == num.to_i)
  y += 1
  num = Math.sqrt(61*y**2+1)
end
p num
p y

とすると、誤った最小の自然数解
335159612.0
42912791
が出力される。
正しくは次のとおりである。

y = 1
num = Math.sqrt(61*y**2+1)
while !((num.to_i)**2 - 61*y**2 == 1)
  y += 1
  num = Math.sqrt(61*y**2+1)
end
p num
p y

出力結果
1766319049.0
226153980

2014年5月17日土曜日

140517

Excelのシートにおいて、数式を含んでいるか調べる。


セル(1,1)からセル(100,100)までのシートの保護のかかっていない
セルについて、数式を含んでいるかを調べ、
数式を含んでいるセルは数式と表示する。

Sub 数式()
For i = 1 To 100
For j = 1 To 100
  If Cells(i, j).Locked = False Then
    If Cells(i, j).HasFormula Then
      Cells(i, j).Value = "数式"
    End If
  End If
Next
Next
End Sub

2014年5月11日日曜日

140511(2)

複数のファイルの名前を変更する方法


マクロを組む以外に単純な方法に今更ながら気づいたので記しておく。
①複数のファイルを選択。
②名前を変更。
すると、自動的に複数のファイルの名前が〇〇(1)、〇〇(2)、…に変更される。

きっかけ
同じものをダウンロードしたときや、複数のファイルを同じフォルダ内に保存するとき
に自動的に名前が付けられるのはなぜか不思議に思ったことから。

140511

証明もプログラムも簡潔な方がよい。

簡潔
=美しい+短い+わかりやすい
 質    量

わかりやすさを加えたのは、とりわけプログラミングにおいて、
「美しいまたは短い」からといっても「わかりやすい」とも限らないからだ。

2014年5月5日月曜日

140505

Ruby


140306でもArray#permutationを用いたが、また別の問題を解いてみよう。

1〜8を下のa〜hに「右にいくほど大きくなり、下にいくほど大きくなる」ように
書き込む方法は何通りあるか?

a,b,c,d
e,f,g
h

i = 0
(1..8).to_a.permutation do |a, b, c, d, e, f, g, h|
  if a<b and b<c and c<d and e<f and f<g and a<e and e<h and b<f and c<g then
    i += 1
    puts i
    puts "[#{a},#{b},#{c},#{d}],[#{e},#{f},#{g}],[#{h}]"
  end
end

これを実行すると、70通りであることがわかる。

ちなみに、(Frame-Robinson-Thrall による鉤公式を用いれば)
λ=(4,3,1)のとき、
dim Sλ = 8!/(6*4*3*1*4*2*1*1) = 70
となり、
#STab(λ) = dim Sλ = 70

2014年4月5日土曜日

140405

Ruby


0〜9までを数える。

10.times{|i|
  p i
  p ('%08b' % i)
  p ('%8b' % i)
}

出力結果
0
"00000000"
"       0"     ←左に7個のすきま
1
"00000001"
"       1"     ←左に7個のすきま
2
"00000010"
"      10"     ←左に6個のすきま
3
"00000011"
"      11"
4
"00000100"
"     100"
5
"00000101"
"     101"
6
"00000110"
"     110"
7
"00000111"
"     111"
8
"00001000"
"    1000"
9
"00001001"
"    1001"     ←左に4個のすきま

2014年3月21日金曜日

140321(2)

Ruby


Hashのキーや値の設定の練習

h0 = Hash.new
x = 1
while 2**x < 1000 do
  h0[x] = 2**x
  x +=1
end
p h0

出力結果
{1=>2, 2=>4, 3=>8, 4=>16, 5=>32, 6=>64, 7=>128, 8=>256, 9=>512}

for i in (2..10) do
  h1 = Hash.new
  x = 1
  while i**x < 1000 do
    h1[x] = i**x
    x +=1
  end
  p h1
end

出力結果
{1=>2, 2=>4, 3=>8, 4=>16, 5=>32, 6=>64, 7=>128, 8=>256, 9=>512}
{1=>3, 2=>9, 3=>27, 4=>81, 5=>243, 6=>729}
{1=>4, 2=>16, 3=>64, 4=>256}
{1=>5, 2=>25, 3=>125, 4=>625}
{1=>6, 2=>36, 3=>216}
{1=>7, 2=>49, 3=>343}
{1=>8, 2=>64, 3=>512}
{1=>9, 2=>81, 3=>729}
{1=>10, 2=>100}

140321

Ruby


Stringクラスで用意されているincludeメソッドを使用する問題

「3の倍数と3の付く数字の時だけアホになります」という男がいたとして、
1から1000まで数字を数えた場合、アホになった回数を求めよ。

N=1000
s=0
for i in (1..N) do
if i%3 == 0 || i.to_s.include?('3') then
s += 1
end
end
p s

出力結果
513

2014年3月16日日曜日

140316

Ruby


「数の事典」に
548,834
   548,834=5^6+4^6+8^6+8^6+3^6+4^6
と載っていた。

「6桁の数字で各桁の6乗の和が元の数字になるものは、
548,834だけである」
ということを確かめてみる。

for a in 1..9
  for b in 0..9
    for c in 0..9
      for d in 0..9
        for e in 0..9
          for f in 0..9
          x=a**6+b**6+c**6+d**6+e**6+f**6
          y=a*10**5+b*10**4+c*10**3+d*10**2+e*10+f
            if x == y then
            puts "#{x}"
            end
          end
        end
      end
    end
  end
end

出力結果
548834

2014年3月15日土曜日

140315(2)

Ruby


原始ピタゴラス数の思い出

小学生の頃
算数や図工の時間になんとなく使用していたが、証明には至らず。

中学生の頃
ぶっ飛んだ授業(数学)で一般的に
{x,y}={2ab,a^2-b^2},z=a^2+b^2
と表されることを習う。

思い出はこれくらいにして、
1≦x<y<z≦100なる原始ピタゴラス数を求めてみる。

for x in 1..98
  for y in x..99
    z = Math.sqrt(x**2+y**2)
    if z == z.to_i && z < 101 then
      z = z.to_i
      if x.gcd(y) == 1 && y.gcd(z) == 1 && z.gcd(x) == 1 then
        puts "#{x},#{y},#{z}"
      end
    end
  end
end

互いに素の部分がカッコ悪いので、injectメソッドを使うと、

class Array
  def gcd
    self.inject{|a, b| a.gcd(b)}
  end
end

for x in 1..98
  for y in x..99
    z = Math.sqrt(x**2+y**2)
    if z == z.to_i && z < 101 then
      z = z.to_i
      if [x, y, z].gcd == 1 then
        puts "#{x},#{y},#{z}"
      end
    end
  end
end

となりスッキリする。

出力結果
3,4,5
5,12,13
7,24,25
8,15,17
9,40,41
11,60,61
12,35,37
13,84,85
16,63,65
20,21,29
28,45,53
33,56,65
36,77,85
39,80,89
48,55,73
65,72,97

140315

Ruby


他の勉強が全く出来なかったが、「たのしいRuby第4版」を読み終える。
分からないところはネットで調べながらだったが、少なくとも書いてある
内容については、この書籍一冊で理解できた。   

【注意点】

書籍とサポートページのプログラムリストに多少の誤植あり。

【スケジュール】

仕事の日は、
「昼食休みにプログラムリスト以外の部分を読み、
帰って、実際に実行して確認」
というやり方で勉強。

2/23 1〜5章   ←挿絵があったのは、最初のページだけだったな…
2/24 6章
2/25 7章
2/26 8章の途中
2/27
2/28
3/ 1 8章の途中〜9章
3/ 2 10〜12章
3/ 3 13章       ←この章の図がとても親切だと感じた。
3/ 4 14章
3/ 5 15章
3/ 6 
3/ 7
3/ 8
3/ 9 16〜17章   ←16章(正規表現)は大事。
3/10 18章
3/11 19章
3/12 20章
3/13 21章
3/14 
3/15 22〜23章

2014年3月10日月曜日

140310

Ruby


Dir.globメソッドを勉強中、ワイルドカードで混乱。

*
空文字列を含む任意の文字列と一致。

**/
 */ の0回以上の繰り返しを意味し、 ディレクトリを
再帰的にたどってマッチを行う。
例えば、foo/**/ はfoo/bar/、foo/bar/hogeなど、
配下の全サブディレクトリとマッチ。

2014年3月9日日曜日

140309

Ruby  


配列から要素の取り出し

140302でも同じことをしたが、もう一度やってみる。

ary=[0,1,1,2,3,5,8,13,21,34,55,89,144]
puts "#{ary}"

puts "#{ary.select{|i| i%2==1 }}"

ary.each_with_index do |i, j|
 if i%2==1 then
 puts "#{j+1},#{i}"
 end
end

出力結果
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144]
[1, 1, 3, 5, 13, 21, 55, 89]
2,1                ←元の配列における順番も出力。
3,1
5,3
6,5
8,13
9,21
11,55
12,89

2014年3月6日木曜日

140306

Ruby


Array#permutationを用いて、下の覆面算を解いてみる。

  SEND
+MORE
-----
 MONEY

(0..9).to_a.permutation(8) do |s, e, n, d, m, o, r, y|
  next if s == 0 or m == 0
  send = s*1000 + e*100 + n*10 + d
  more = m*1000 + o*100 + r*10 + e
  money = m*10000 + o*1000 + n*100 + e*10 + y
  if send+more == money then
  print "#{send} + #{more} = #{money}" 
  end
end

2014年3月2日日曜日

140302

Ruby


イテレータ

irb(main):001:0> [1,2,3,4,5].map{|i|i*2}
=> [2, 4, 6, 8, 10]
irb(main):002:0> [1,2,3,4,5].map{|i|i%2==1}
=> [true, false, true, false, true]
irb(main):003:0> [1,2,3,4,5].select{|i|i%2==1}
=> [1, 3, 5]

2014年3月1日土曜日

140301

Ruby


コマンドプロンプトの画面のコピー

1.右クリック 範囲指定
2.範囲指定してEnter
3.保存先(メモ帳、TeraPad)に貼り付け

2014年2月24日月曜日

140224

Ruby


正規表現

「/^\s*$/」の意味

^           行頭とマッチするパターン
\s          空白文字
*           0回以上の繰り返し
$           行末とマッチするパターン

以上より、
/^\s*$/   空白のみの行にマッチ

2014年2月23日日曜日

140223(2)

Ruby


pメソッドでつまづく。

具体的には、
a,b,*c=1,2,3,4,5
p [a,b,c]
とすべきところ(ちなみに、出力結果は[1,2,[3,4,5]])を
a,b,*c=1,2,3,4,5
p[a,b,c]
としていた。

学んだこと
「かっこがあっても、詰めてはいけない!」

140223

「たった2日でできるRuby」


一昨日、Rubyが使えるようになりたいと思い、
早速、昨日上記の本を買ってきて、
全部読んでみた。
以下のページに誤植があった。

p.98~p.99
プログラム内の「:」は「;」の誤り。  (サポートページに指摘されている。)

p.128
puts("#{m-1} 月は #{n}")はputs("#{n+1} 月は #{m}")の誤り。

p.188
purs(array.sort)はputs(array.sort)の誤り。