技術をかじる猫

適当に気になった技術や言語、思ったこと考えた事など。

投票が近づいて来たので、40代以下に言っておこうか

なんで皆の税率が上がって、将来の年金まで気にするようになるのか、その理由をざっくり説明する。

なんで老人向けの介護とか福祉がこの時期叫ばれるのか?

まず、この時期になると声高に叫ばれることがある。それは高齢者福祉だ。
最近では少子化対策で児童福祉というパターンも多い。
そんな中気にして欲しいのは、「働く世代である 20-40 に対する内容が声高に叫ばれないのは何故か?」だ。

結論から言おう。

その世代は投票しないから色々言っても無駄だとどの政党も諦めてるからだ

公益財団法人、明るい選挙推進協会 のデータを見ればわかる。

もっとも投票しているのは 60 代を筆頭に、50,70,40 代と続いている(平成26年度)。
つまり政治家は、この年代にアピールした方が当選しやすいって寸法だ。

邪推かもしれないが、少子化対策云々を声高にする背景すら、50 代が 2 位という数字を見れば、「そろそろ引退するし、今後養ってくれる世代を増やしたい」と思っている世代の投票を拾いたいという意図が見え隠れしてるとも言えないだろうか?

そうは言ってもこれまでやってこれたんじゃない?

そういう人は多そうだ。

だが、英国の離脱を機に、続々離脱しようかという声が上がり始め、EU 自体崩壊し始めてる。
要するに目に見える世界経済の混乱が迫ってるんだ。

さぁこれで働く世代だけ割を食う構造で、不幸にならないと言い切れるのか?

ここで怖い話を教えておこう。

そんな状況を生み出した英国の EU 離脱なのだが、その原因は ご老人達 だという事実を。

6/25 日の 日本経済新聞 の記事を抜粋しよう。

欧州連合(EU)離脱の是非を問いかけた23日の英国民投票では、英国人の世代間の意識の違いが浮き彫りになった。52%対48%と僅差で離脱派が勝利したが、投票先を年代別にみた各種調査では、年齢が高くなるほど離脱を支持し、逆に30代以下の若年層は残留が多かった。

ニュースサイトが消えた場合も考えて、失礼かもしれないがグラフも転載させてもらう。

f:id:white-azalea:20160702003100j:plain

そう、離脱を望んだのは紛れもなくご老人達だ。

ではご老人達はなぜ離脱に傾いたのだろうか?それは英国ご当地新聞の BBC に聞いてみる。

  • 離脱すれば経済打撃があるという残留派、離脱の影響を悪しざまに言うのは、私利私欲から英国を批判する無責任な金持ちエリートだと一蹴する離脱派確執があった
  • EU 離脱で浮いた金をNHS(国民医療サービス)に3億5000万ポンド突っ込むと公約があった
  • 移民が増えたら混乱するけど、拒否するなら EU の協調ルールは邪魔

なんてのがある。
残留派が若い世代というのは、自由移動と経済域が広ければ、その分雇用があるからだ。

しかし既に引退したご老人に雇用なんざ知った事ではない。そんな事より老後衰えた体に福祉を欲しがったんだ。

それを引き起こしたのは投票を軽く見た若い世代の責任もある

政治に興味がないと放置した挙句、楽観視してたら後になって慌てたわけだ。

www.itmedia.co.jp

そして投票のやり直しを求めた

http://news.tbs.co.jp/newseye/tbs_newseye2806734.htmlnews.tbs.co.jp

しかしそれは叶わない。

www.sankei.com

覆水盆に返らずとはこのことだ。

ご老人の方が投票率が高い日本でも同じ事は起こり得る

どうだろう?日本は周囲に気を使うとも言われているが、 こんな記事 だってある。

「騒がしい」など従来の静かな環境を維持したい高齢者らの苦情を受けて開園を延期したり、「平穏な日常生活が侵害された」として、開園後に訴訟に発展したりするケースもある。

誰もが好々爺なんていいもんじゃない(もちろん居ないとは言わないが)。
彼らも一人の人だ。散々働いた後の老後なんだし好きにしたいという気持ちだってあるだろう。

悪いがこんな記事を書いている自分だって、投票先は自分の利害で決める。

止める手はあるのか?

はっきり言えば今すぐの改善はできない。

しかし、動かなければ永久に改善できない問題でもある。

どうするか?
わかりきった事だ。

「白紙でも良いから若い世代が投票すれば良い」

今からマニフェスト読み直して吟味して…なんてのは正直難しいだろう。
だから今すぐそんな事をするくらいなら白紙で良いんだ。

少なくとも若い世代は投票する意思があるという事を示すんだ。

若い世代が白紙(支持政党はない)と投票した事になる。
そうすればその票は要するに浮動票なんだ。
票集めが必要な政治家はその票を無駄にはしたくない。

「この世代は取り込む価値がある」

と思わせる事が出来れば良いのだ。
そうすれば、働く世代に有利な条件を提示してくるようになる。

当然ながらその後も継続しないと「なんだ一過性かよ」と見放されること請け合いなのだが…

投票所まで歩って何分だろう?移動は面倒かも知れないが、建物の中に入って白紙でも出して出てくるなんてものの十分の話だ。

「自分一人がやったって変わらないでしょう?」そういうから阿呆なのだ。

有権者は無数にいるんだが、さっきの話を思い出そう。

黙ってれば老人共の為だけに君らの生活が犠牲になっていくという事実を。

みんな言ってる事だけど、投票にも参加しない奴に、政治や税金の愚痴を言う資格なんざない。

愚痴を言う位なら数年に1回の数時間位、白紙投票でもして「俺はお前らを支持しない!」と声高に言ってみてはどうだろう?

一応

煽るような事ばかり書いてすまないとは思う。

しかし 現実問題 なんだ。

僕もそうだが、これからも日本で生きるなら避け続けるほど事態は悪化する。
そんな危機感を持ってるのは僕だけではないはずだ。

願わくば、少しでも気にしてくれる若者の目に留まる事を祈ろう。

Scala 関数型デザイン&プログラミング:Exercize2.1

真面目にやろうかと思った。

書籍はこれ

まずは指定 N 番目のフィボナッチ数計算関数を tail call recursive (末尾再帰)な関数で実装しろとのこと。
まず単純にフィボナッチ数列の実装をしてみる。

Wikipedia 先生 にお越しいただこう。

フィボナッチ数 - Wikipedia

object Exercise2_1 extends App {

  def fib(n: Long): Long = n match {
    case 0 => 0
    case 1 => 1
    case _ => fib(n - 2) + fib(n - 1)
  }

  for (i <- (0 to 10)) {
    println(s"$i : ${fib(i)}")
  }
}

これが末尾再帰かを判定するには、Scala の「scala.annotation.tailrec」を使えばいい。

  import scala.annotation.tailrec

  @tailrec
  def fib(n: Long): Long = n match {
    case 0 => 0
    case 1 => 1
    case _ => fib(n - 2) + fib(n - 1)
  }

  for (i <- (0 to 10)) {
    println(s"$i : ${fib(i)}")
  }

コンパイルすると、下記のエラーだ

[info] Compiling 1 Scala source to /Users/xxxx/Documents/projects/scala-function/part1/target/scala-2.11/classes...
[error] /Users/xxxx/Documents/projects/scala-function/part1/src/main/scala/Excercise2_1.scala:24: could not optimize @tailrec annotated method fib: it contains a recursive call not in tail position
[error]     case _ => fib(n - 2) + fib(n - 1)

it contains a recursive call not in tail position 最後の処理(return 前の最後の処理)で再起してないと言われた。

こう読み替えるとわかりやすいが、再起した結果に何らかの処理を加えてはならないということだ。

で、1時間位悩んだわけなのだが、結論から行こう。

考え方を改めないといけないのだ。n は「n 番目の計算結果を得る」という考え方をするのではなくて、「後 n 回計算する」と考える。
その上で、引数を考えると、下記で計算できるのではないだろうか?

後 5 回計算すると考えた時、

  1. 残 5 回、初期値 0
  2. 残 4 回、初期値 1 こう考えれば初期2回は特別なんだと考えて良さそうだ。
  3. 残 3 回、2 回目の値 + 1回目の値
  4. 残 2 回、3 回目の値 + 2回目の値 = (2 回目の値 + 1回目の値) + 2回目の値
  5. 残 1 回、4 回目の値 + 3回目の値 = ((2 回目の値 + 1回目の値) + 2回目の値) + (2 回目の値 + 1回目の値)

これを一般化して考えると、

  • 残り 1 回 = 前回 + 前々回
  • 残り 2 以上 = カウント減算、前回 + 前々回、前回

これを愚直に再起に書くとこうなる。普通に tailrec でコンパイル可能だ。

    @tailrec
    def fib(n: Long, n1: Long, n2: Long): Long = {
      n match {
        case 1 => n1 + n2
        case _ => sub(n - 1, n1 + n2, n1)
      }
    }

しかし、計算回数 0 回目、1回目という特殊ケースもあるので、事前にその答えを設定する。

  def fib(n: Long): Long = {

    @tailrec
    def sub(n: Long, n1: Long, n2: Long): Long = {
      n match {
        case 1 => n1 + n2
        case _ => sub(n - 1, n1 + n2, n1)
      }
    }

    n match {
      case 0 => 0
      case 1 => 1
      case _ => sub(n - 1, 1, 0)
    }
  }

こうなるはず。

試してみようか

  for (i <- (1 to 20)) {
    println(s"$i : ${fib(i)}")
  }

実行

$ sbt run
[info] Loading global plugins from /Users/xxxx/.sbt/0.13/plugins
[info] Set current project to sample (in build file:/Users/azalea/Documents/projects/scala-function/part1/)
[info] Compiling 1 Scala source to /Users/xxxx/Documents/projects/scala-function/part1/target/scala-2.11/classes...
[info] Running Excercise2_1 
1 : 1
2 : 1
3 : 2
4 : 3
5 : 5
6 : 8
7 : 13
8 : 21
9 : 34
10 : 55
11 : 89
12 : 144
13 : 233
14 : 377
15 : 610
16 : 987
17 : 1597
18 : 2584
19 : 4181
20 : 6765

正しそうだ

Scala 関数型デザイン&プログラミング:Exercize2.2 - 2.5

引き続き勉強がてら Exercise をやってみる。

Exercise 2.2

お題:配列が任意の比較関数でソートされているか判定せよ
ただし、メソッドシグネチャdef isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean 固定。

…generic な高階関数なだけか…

object Exercise2_2 extends App {
  def isSorted[A](as: Array[A], ordered: (A, A) => Boolean): Boolean = {
    if (as.size < 2) {
      true
    } else {
      ordered(as.head, as.tail.head) &&
        isSorted(as.tail, ordered)
    }
  }

  def isOrdered(a: Int, b: Int) = a < b

  println(s"test 1 to 10 ordered ${isSorted((1 to 10).toArray, isOrdered)}")
  println(s"test 10 to 1 ordered ${isSorted((1 to 10).reverse.toArray, isOrdered)}")
}

まぁこれ位なら…

Exercise 2.3

お題:この関数を実装しろ

def curry[A, B, C](f: (A, B) => C): A => (B => C)

なんだ、ただのカレーか

object Exercise2_3 extends App {
  def curry[A, B, C](f: (A, B) => C): A => (B => C) = {
    def curried(a1: A) = (a2: B) => f(a1, a2)
    curried
  }

  def createFilledArray(i: Int, b: Boolean): Array[Boolean] = Array.fill(i)(b)

  val curried = curry(createFilledArray)
  val arr: Array[Boolean] = curried(10)(true)

  println(arr.toSeq)
}

Exercise 2.4

お題: curry の逆向きを行う、uncurryを作成せよ

object Exercise2_4 extends App {
  def uncurry[A, B, C](f: A => (B => C)): (A, B) => C = {
    def unc(a1: A, a2: B) = f(a1)(a2)
    unc
  }

  def createFilledArray(i: Int)(b: Boolean): Array[Boolean] = Array.fill(i)(b)

  val curried = uncurry(createFilledArray)
  val arr: Array[Boolean] = curried(10, true)

  println(arr.toSeq)
}

Exercise 2.5

お題:二つの関数を合成する高階関数を作成せよ。

object Exercise2_5 extends App {
  def compose[A, B, C](f1: B => C, f2: A => B): A => C = {
    def com(v: A) = f1(f2(v))
    com
  }

  def toStr(d: Double) = d.toString
  def toDouble(i: Int) = i.toDouble

  println(compose(toStr, toDouble)(65535).getClass)
}

末尾再起に比べたら緩い…。