問題1.6

#lang racket

;;;;Newton法による平方根

;;;2乗
(define (square x)
  (* x x))

;;;平均
(define (average x y)
  (/ (+ x y) 2))

;;;予測値の2乗が近似値に近いか
(define (good-enough? guess x)
  (< (abs (- (square guess) x)) 0.001))

;;;予想値の商と平均で次の予想値を求める
(define (improve guess x)
  (average guess (/ x guess)))

;;;ifの新版を定義
(define (new-if predicate then-clause else-clause)
  (cond (predicate then-clause)
        (else else-clause)))

(define (sqrt-iter guess x)
  (new-if (good-enough? guess x)
      guess
      (sqrt-iter (improve guess x)
                 x)))

;;;平方根の近似値を求める
#|
(define (sqrt-iter guess x)
  (if (good-enough? guess x)
      guess
      (sqrt-iter (improve guess x)
                 x)))
|#
;;;開始
(define (sqrt x)
  (sqrt-iter 1.0 x))

(sqrt 2)
(sqrt 3)
(sqrt (+ 100 37))

実行結果は無限ループになりました。

;;;ifの新版を定義
(define (new-if predicate then-clause else-clause)
  (cond (predicate then-clause)
        (else else-clause)))

(define (sqrt-iter guess x)
  (new-if (good-enough? guess x)
      guess
      (sqrt-iter (improve guess x)
                 x)))

;;;平方根の近似値を求める
#|
(define (sqrt-iter guess x)
  (if (good-enough? guess x)
      guess
      (sqrt-iter (improve guess x)
                 x)))
|#

ifを新たに定義したnew-ifで置き換えてます。ifやcondは特殊形式ですが、new-ifは定義した関数のためすべての引数が評価されます。new-ifの呼び出しで引数が順番に評価されて、第3引数が評価されて無限ループになるのでしょうか。

貸借対照表とは

今、会社にどれだけ残高(資産)があるのかがわかる書類です。

一時地点の結果ですが、それは今までの経営で積み重ねたもの。

貸借対照表は資産と負債と純資産からなる。以下のような関係をもつ。

資産=負債+純資産

負債は銀行からの借入金。純資産は株主などから集めたお金や、どこからも借り入れていない返す必要のないお金です。

負債と純資産を足して資産になる。企業活業で資産を運用して、その残高が一時地点(3ヶ月・6ヶ月・12ヶ月など)会社にどれだけあるかを確認できるのが、貸借対照表です。

作用的順序と正規順序

#lang racket

;;;作用的順序と正規順序
;;;実行すると無限ループ

#|

(define (p) (p))

(define (test x y)
  (if (= x 0)
      0
      y))

;;testを作用するためには第2引数(p)を作用しなければならない。
;;(p)を作用すると(p)なので無限ループになる
(test 0 (p))

|#

;;;例

(define (square x) (* x x))

(define (sum-of-squares x y)
  (+ (square x) (square y)))

(define (f a)
  (sum-of-squares (+ a 1) (* a 2)))

(f 5)

;;;作用的順序
#|

(f 5)
(sum-of-squares (+ 5 1) (* 5 2))
作用するたびに評価する
(+ (square 6) (square 10))

(+ (* 6 6) (* 10 10))
(+ 36 100)
136

|#

;;;正規順序
#|

(f 5)
(sum-of-squares (+ 5 1) (* 5 2))
途中で評価しない
(+ (square (+ 5 1)) (square (* 5 2)))

基本的演算子だけをもつ式が出てくるまで
(* x x)で(+ 5 1) (* 5 2)が2度評価される
(+ (* (+ 5 1) (+ 5 1)) (* (* 5 2) (* 5 2))) 

(+ (* 6 6) (* 10 10))
(+ 36 100)
136

|#

宿命定数と運命変数について

●宿命定数

○宿命とは

宿る、命と合わさって、宿命と読む。つまり生まれて備わっているモノが宿命です。性別、性格、血液型、生年月日、干支、星座、親、戸籍、家系、血筋、歴史など、変えられないモノ。

○定数とは

定まる数、決まっている数、変化しない、固定、マジックナンバー。など既に定まっている変化しようのない数です。

○宿命+定数

人の姿形をした僕たち実態には、宿命定数が定義されています。

それは秘密で書き換えのできない、モノです。

変えられないモノは変えられないので無理して変えようとすると、あたまがくるくるぱーになります。受け入れましょう。

●運命変数

○運命とは

運ぶ、命と書いて運命と読みます。これは命の運び先は変えられるということです。つまり運命は自分で変えられます。たとえば、彼氏彼女、結婚、離婚、日程、食事、購買、睡眠、娯楽、ゲーム、映画、本、美容、理容、ジム、など変化する選択枠を自分自身に含んでいれば、運命です。

○変数とは

変数とは、変化する値。途中の結果、未知の値だから変化します。

○運命+変数

人の姿形をした僕たち実態にはアクション、行動することによって運命変数が書き換わります。それは生命(生きていること)や知性(考えること)、感情(日々触れるモノや物から感覚を受けとること)や仕事(発生から得られる報酬(モノや物))など生活を営む中で、触れるモノや物が運命変数です。ですから僕は運命変数の集まりです。運命変数も管理できる個数が限られてますので、いらない運命変数は削除しましょう。

手相教室に通ってます

●手相を学ぼうと思ったきっかけ

僕には悩みがあります。

  1. 感情的になりやすい
  2. AならばBだそうすべきだという決めつけ
  3. 僕ができることなら他の人もできますよねという押し付け

現職は接客業なので1や2だとクレームになりやすいです。1〜3は職場のみんなともうまくいかない原因となります。ところでうまくいかないのはコミニュケーションで自分の我を出すからです。自分の我を出さずに薄めて、相手に合わせて言葉を選ぶこと。これらを手相を通したお悩み相談で学べるのではないか。そう考えて、手相教室で手相を学始めました。

●現在

週1で3ヶ月間ぐらい通ってます。インプットは授業内容と、手相関連の書籍やYouTubeなどの動画。アウトプットは自分の手相を見る。現職では常連のお客さまの手相を本当に単純に簡単に見て一言添えるぐらいです。

●授業内容

授業内容はザックリここまで進める。という内容です。結構な授業料なのにその金額に比べると授業の内容は薄っぺらに感じます。知識がない状態だと最初の授業は新鮮でした。ですが授業内容や授業で使う教科書は同じような内容で進むにつれて各項目に新たにポツポツ追加されるだけ。先生の話す事例も同じような内容ばかりです。これなら書籍やYouTubeで動画を観てたほうがいいのでは?と授業を重ねるたびに最近思います。

とてもじゃないけど、これだけの金額をかけて学んで卒業しても何もできないまま現場に出れても、その状態でお客さまを鑑定することになる。だったら結局はその高額な授業料で現場に出れる枠を買っているだけ。また月に何日入れる枠があるのか。それに勤務をして時間給が発生するのかもわからずじまい。これは正直、やられたな〜という思いがモヤモヤしてます。

●商売としての側面

占いが全盛期のころは、繁盛していたそうです。ただ今は下火で、だから占い以外で利益を出さなきゃいけないようです。

そうなるとメンバー会員とか学校とかサークルとか、関連事業で利益出さないといけないのかな。モヤモヤするのは僕が神秘性やスピリチュアルな側面を期待しすぎた結果だと思います。相手も商売なので学習内容も小出しと引き伸ばしで、半年〜1年と期間を延長して授業料も高めに設定している。しかも本当に学びたい内容は、最後の最後なのでそこまでがお金も時間もモチベもかかります。

●思ったこと

本当に鑑定できる人を育てたいなら、よくあるような相談内容とそれに対応する4大基本線を重点的に教えて、早い段階で現場に出してOJTをして先生がフィードバックすればいいのでは?と思いますね。半年〜1年学んだとしてもインプットだけしてもアウトプットができる環境がなければ、人は育たないし定着もしない。ただ教室を卒業しただけの人が増えるばかり。人不足も解決しないのにな。と思います。

●今後

このまま続けるか続けないかは、判断に迷っています。

現場に出る経験はしたいけど、お金と時間が掛かりますし、体力的にもキツい。それに一番辛いのが、このまま続けても先が不透明すぎることです。先生からは現場で独り立ちするには、手相以外も学必要がある。だから手相以外を学ためには新たに結構な金額と期間がかかります。一通り学んで現場に出られる状態になったとしても不安な点があります。たとえばベテランで枠が埋まってて新人の枠は月に1〜2回しかないとか。そもそも現場の箱が利益でなくて撤退するなどです。

手相を学ことは良いことだと思います。手相で自分を知ることができる。相手も知ることができる(相手を知ることは良いことか悪いことかは難しいところです)費用に見合ったリターンを短期的に期待するのは難しそう。今後続けるかどうかはわからないですね。

ニュートン法

#lang racket

;;;;Newton法による平方根

;;;2乗
(define (square x)
  (* x x))

;;;平均
(define (average x y)
  (/ (+ x y) 2))

;;;予測値の2乗が近似値に近いか
(define (good-enough? guess x)
  (< (abs (- (square guess) x)) 0.001))

;;;予想値の商と平均で次の予想値を求める
(define (improve guess x)
  (average guess (/ x guess)))

;;;平方根の近似値を求める
(define (sqrt-iter guess x)
  (if (good-enough? guess x)
      guess
      (sqrt-iter (improve guess x)
                 x)))

;;;開始
(define (sqrt x)
  (sqrt-iter 1.0 x))

(sqrt 2)
(sqrt 3)
(sqrt (+ 100 37))

カラツバ法 正の整数範囲

#カラツバ法 正の整数範囲


import math


#多倍長整数
class Multiple:
    #数字列の各桁のリストを受け取る
    #1234 → 1 2 3 4
    #12 34 → 12 34
    def __init__(self, values):
        self.values = [v for v in reversed(values)]
        self.N = len(self.values)
        i = 1
        while(i < self.N):
            i = i * 2
        for j in range(i - self.N):
            self.values.append(0)
        self.N = len(self.values)

    def __str__(self):
        s = ''
        f = False
        for d in reversed(self.values):
            if 0 < d or f:
                s += str(d)
                f = True
        return s
    # +
    def __add__(self, a):
        self.setDigits(a)
        add = []
        for i in range(self.N):
            add.append(self.values[i] + a.values[i])
        return Multiple(list(reversed(add)))

    # -
    def __sub__(self, a):
        self.setDigits(a)
        sub = []
        for i in range(self.N):
            sub.append(self.values[i] - a.values[i])
        m = Multiple(list(reversed(sub)))
        #m.caryy()
        return m

    # <<
    def __lshift__(self, shift):
        ls = []
        #シフト後の空きスペースを0で埋める先頭の0は追加しない
        for i in range(shift):
            ls.append(0)

        #シフト後の値を下位桁から追加する
        head = 0
        for v in reversed(self.values):
            if v == 0:
                head += 1
            else:
                break
        for i in range(self.N - head):
            ls.append(self.values[i])

        #桁数を2の累乗に調整して空いたスペースは0で埋める
        size = self.N
        while(size < len(ls)):
            size *= 2
        space = size - len(ls)
        for i in range(space):
            ls.append(0)

        return Multiple(list(reversed(ls)))


    #計算する2つの値に桁数の違いがある場合、大きい桁数に揃える
    def setDigits(self, a):
        p = a if self.N <= a.N else self
        q = self if self.N <= a.N else a
        for i in range(p.N - q.N):
            q.values.append(0)
        q.N = p.N

    #selfとqについて,"桁ごとの加算"を行う
    def add(self, q):
        return self + q

    #"繰り上がり"・"繰り下がり"の処理を行う
    def caryy(self):
        #繰り上がり
        carry = 0
        for i in range(self.N):
            self.values[i] += carry
            if 10 <= self.values[i]:
                carry = int(self.values[i] / 10)
                self.values[i] = self.values[i] - (carry * 10)
            else:
                carry = 0
        if carry:
            self.values.append(carry)

        #繰り下がり
        for i in range(self.N - 1):
            if self.values[i] < 0:
                k = 0
                for j in range(i + 1, self.N):
                    if 0 < self.values[j]:
                        k = j
                        break
                if 0 < k:
                    self.values[k] -= 1
                    for n in range(k - 1, i, -1):
                        self.values[n] += 9
                    self.values[i] += 10

        return self


    #selfについてvaluesの添字が大きい方のk個の要素を返す
    def left(self, k):
        ret = Multiple(list(reversed(self.values[-k:])))
       # print('left:', ret)
        return ret

    #selfについてvaluesの添字が小さい方のk個の要素を返す
    def right(self, k):
        ret = Multiple(list(reversed(self.values[:k])))
       # print('right', ret)
        return ret

    #left(k) + right(k) の結果を返す
    def lradd(self, k):
        return self.left(k) + self.right(k)

    #selfを10^k倍する
    def shift(self, k):
        return self << k

    #selfとqについて,"桁ごとの減算"を行いself-qを返す
    def sub(self, q):
        return self - q


#カラツバ法
class Karatsuba:

    class Node:
        def __init__(self, n, val1, val2):
            self.N = n                     #最大の桁数
            self.val1 = val1               #左辺の値
            self.val2 = val2               #右辺の値
            self.result = Multiple([0,0])  #計算結果

        def printnode(self):
            print(self.N)
            print(self.val1)
            print(self.val2)
            print(self.result)

    def __init__(self, val1, val2):
        val1.setDigits(val2)
        self.root = Karatsuba.Node(val1.N, val1, val2)
        self.t_depth = int(math.log(self.root.N, 2) + 1)
        size = 0
        for i in range(self.t_depth):
            size += int(math.pow(3, i))
        self.elements = [0] * size
        self.layer_top = []

        self.newLayer_Top()
        self.newElements()
        self.bottomLayerResult()
        self.layerResult()
        self.result = self.carry()

     #ツリーの各層のエレメント配列上でのインデックスを算出する
    def newLayer_Top(self):
        self.layer_top.append(1)
        for i in range(self.t_depth - 1):
            self.layer_top.append(self.layer_top[i] + int(math.pow(3, i)))

    #ツリーを構築する
    #ルートノードを用意。桁数はval1の桁数を使う
    #ルートノードの層から、最下層以外の層を順に処理
    #親ノードになる層の要素数だけ繰り返す
    #親ノードの要素を取得
    #子ノードの桁数を算出
    #子ノード①へのインデックス
    #左:A*C
    #中央:B*D
    #右:(A+B)*(C+D)
    def newElements(self):
        self.elements[0] = self.root
        for dp in range(self.t_depth - 1):
            for i in range(int(math.pow(3, dp))):
                pe = self.elements[self.layer_top[dp] - 1 + i]
                cn = int(pe.N / 2)
                tidx = self.layer_top[dp + 1] - 1 + (i * 3)
                self.elements[tidx] = self.Node(cn, pe.val1.left(cn), pe.val2.left(cn))
                self.elements[tidx + 1] = self.Node(cn, pe.val1.right(cn), pe.val2.right(cn))
                self.elements[tidx + 2] = self.Node(cn, pe.val1.lradd(cn), pe.val2.lradd(cn))

    #最下層の計算
    def bottomLayerResult(self):
        for i in range(int(math.pow(3, self.t_depth - 1))):
            el = self.elements[self.layer_top[self.t_depth - 1] - 1 + i]
            mul = el.val1.values[0] * el.val2.values[0]
            el.result.N = 2
            el.result.values[0] = int(mul % 10)
            el.result.values[1] = int(mul / 10)

    #最下層以外の計算
    def layerResult(self):
        for dp in range(self.t_depth - 1, 0, -1):
            for i in range(int(math.pow(3, dp - 1))):
                el = self.elements[self.layer_top[dp - 1] - 1 + i]
                cidx = self.layer_top[dp] - 1 + (i * 3)
                s1 = self.elements[cidx + 2].result.sub(self.elements[cidx].result)
                s2 = s1.sub(self.elements[cidx + 1].result)
                p1 = self.elements[cidx].result.shift(el.N)
                p2 = s2.shift(int(el.N / 2))
                p3 = self.elements[cidx + 1].result
                el.result = (p1.add(p2)).add(p3)


    #キャリー処理
    def carry(self):
        return self.elements[0].result.caryy()

    def getresult(self):
        return self.root.result

    def printkara(self):
        self.root.printnode()



if __name__ == '__main__':
    #a, b = input().split()
    a = list(map(int, '123333333333321'))
    b = list(map(int, '900900900900990990990991'))
    mpl =  Multiple(a)
    mpl2 = Multiple(b)
    kara = Karatsuba(mpl, mpl2)
    kara.printkara()