裏 RjpWiki

文字通り,RjpWiki の裏を行きます
R プログラム コンピュータ・サイエンス 統計学

掛け算の筆算

2015年04月30日 | ブログラミング

掛け算を筆算で行うとき,0 ~ 9 までの数字をすべて使う筆算のうち,
掛け算の結果が最も小さくなるものを求めよ。

lim = 245 # 後で再設定した
min.ans = lim^2
for (i in 1:lim) {
  a = unlist(strsplit(as.character(i), ""))
  for (j in 1:lim) {
    n = as.numeric(unlist(strsplit(as.character(j), "")))
    b = c(a, n)
    for (k in seq_along(n)) {
      b = c(b, unlist(strsplit(as.character(i * n[k]), "")))
    }
    if (length(table(b)) == 10 && min.ans >= i * j) {
      min.ans = i * j
      if (j > 99) {
        cat(sprintf("\n\n%5i\nx%4i\n-----\n%5i\n%4i\n%3i\n-----\n%5i\n",
                    i, j, i * (j%%10), i * ((j%/%10)%%10), i * j%/%100, i * j))
      } else {
        cat(sprintf("\n\n%5i\nx%4i\n-----\n%5i\n%4i\n-----\n%5i\n",
                    i, j, i * (j%%10), i * (j%/%10), i * j))
      }
    }
  }
}

   18
x 245
-----
   90
  72
 36
-----
 4410




コメント

2 進数の 1 の数

2015年04月28日 | ブログラミング

10 進数の整数 n に対し,1 から n の整数を 2 進数で表したときの各々の 1 の個数の和を求めよ。

F = function(n) { # 再帰関数
  if (n <= 2) return(n)
  k = floor(log(n, base=2)) # 2 進数で表現したときの桁数 - 1
  ones = numeric(k) # k 桁で表現される 0 ~ 2^k - 1 の整数に含まれる 1 の数
  ones[1] = 1
  if (k > 1) for (i in 2:k) ones[i] = 2*ones[i-1] + 2^(i-1)
  return(Recall(n-2^k) + ones[k] + n-2^k+1) # 2^k ~ n までを再帰呼び出し
}
F0 = function(n) { # n が小さいときにしか使えない,馬鹿正直に計算する関数
  sum(sapply(0:n, function(m) sum(as.integer(intToBits(m)))))
}
F(3)
F(13)
n = 37; cat(F(n), F0(n), "\n")
n = 370; cat(F(n), F0(n), "\n")
n = 3700; cat(F(n), F0(n), "\n")
system.time(print(F(10^3)))
system.time(print(F(10^10)))

実行結果

> F(3)
[1] 4

> F(13)
[1] 25

> n = 37; cat(F(n), F0(n), "\n")
93 93

> n = 370; cat(F(n), F0(n), "\n")
1518 1518

> n = 3700; cat(F(n), F0(n), "\n")
21475 21475

> system.time(print(F(10^3)))
[1] 4938
   ユーザ   システム       経過  
     0.008      0.001      0.020 # 所要時間はゴミみたいなもの

> system.time(print(F(10^10)))
[1] 164293127179
   ユーザ   システム       経過  
         0          0          0 # 所要時間はゴミみたいなもの

コメント

ゴールドバッハの予想

2015年04月20日 | ブログラミング

全ての 2 よりも大きな偶数は二つの素数の和として表すことができる

2 つの素数の和が 2014 になるのは?

func = function(n = 2014) {
  tbl = 1:n
  tbl[1] = 0
  for (i in 2:floor(sqrt(n))) {
    if (tbl[i]) tbl[2:(n%/%i) * i] = 0
  }
  prime = tbl[tbl > 0]
  a = apply(which(outer(prime, prime, "+") == n, arr.ind=TRUE), 1, function(n) prime[n])
  t(a[,a[1,] > a[2,]])
}

func(2014)

35 通りもあるぞ

     [,1] [,2]
 [1,] 2011    3
 [2,] 2003   11
 [3,] 1997   17
 [4,] 1973   41
 [5,] 1931   83
 [6,] 1913  101
 [7,] 1907  107
 [8,] 1901  113
 [9,] 1877  137
[10,] 1847  167
[11,] 1823  191
[12,] 1787  227
[13,] 1733  281
[14,] 1721  293
[15,] 1697  317
[16,] 1667  347
[17,] 1613  401
[18,] 1583  431
[19,] 1571  443
[20,] 1553  461
[21,] 1523  491
[22,] 1511  503
[23,] 1493  521
[24,] 1451  563
[25,] 1427  587
[26,] 1373  641
[27,] 1367  647
[28,] 1361  653
[29,] 1217  797
[30,] 1193  821
[31,] 1187  827
[32,] 1151  863
[33,] 1103  911
[34,] 1061  953
[35,] 1031  983

コメント

陰徳?

2015年04月17日 | 雑感

そんな言葉,聞いたことないよな~ということで調べてみたら,

「人に知られないようにひそかにする善行。隠れた、よい行い。「―を積む」⇔陽徳。」

そう。あなた,その意味がわかっていて使ったの?

それは,ほかの人からの賞賛の言葉。,

それは,自分自身のことを自分でいうことではないでしょう。はずかしい。

自分で「陰徳を積んだ」なんて,恥ずかしくていえないことじゃない?

 

コメント

何回いえば...

2015年04月17日 | 統計学

何回いえばわかるんだ?

あなたのその文脈での「標本数」の使い方は,間違えている。サンプルサイズといいなさい。

>  AIC で選ばれる統計モデルは標本数に影響されますか?
>
>     はい,影響されます
>         標本数が少ないとき (情報が少ないとき): より単純なモデルが選ばれる傾向がある
>         標本数が多いとき (情報が多いとき): より複雑なモデルが選ばれる傾向がある
>             つまり AIC は「この手もちのデータがもつ情報量はどこまで複雑な統計モデルを許容しているのか」をあらわす規準だと考えてよいのかもしれません

「サンプル数」というのも,可笑しい。これも,サンプルサイズな。

>  サンプル数が少ないときには AIC ではなく AICc を使うべきですか?
>
>     ワケもわからぬまま AICc を使うのは ヤメてください
>         AICc は「ばらつき」が正規分布と仮定したときに導出された「補正案」のひとつです
>         正規分布を使ってない統計モデルではおそらく意味のない「補正」でしょう
>             少なくとも統計学的な正当化はありません

ワケのわからぬ「学術用語もどき」を使うのは,ヤメてください

コメント

因数分解

2015年04月14日 | ブログラミング

二次式 αx^2+βx+γ を (ax+b)(cx+d) の形に因数分解せよと

func = function(a, b, c) {
##
  factorize = function(n) {
    div = function(n) {
      if (n%%2 == 0) return(2)
      else if (n%%3 == 0) return(3)
      maxitr = floor(sqrt(n))
      i = 1
      repeat {
        i = i + 4
        if (i > maxitr) return(n)
        else if (n%%i == 0) return(i)
        i = i + 2
        if (i > maxitr) return(n)
        else if (n%%i == 0) return(i)
      }
    }
    result = NULL
    repeat {
      d = div(n)
      result = append(result, d)
      n = n/d
      if (n == 1) break
    }
    return(result)
  }
##
  is.int = function(x) {
      result = all.equal(x, floor(x))
      return(ifelse(class(result) == "character", FALSE, TRUE))
  }
##
  if (0 > a) {
      a = -a; b = -b; c = -c
  }
  if (a == 0) return("Error")
  d = b^2-4*a*c
  if (0 > d) return("Error")
  if (b >= 0) {
    x1 = (-b - sqrt(d)) / 2 / a
  } else {
    x1 = (-b + sqrt(d)) / 2 / a
  }
  x2 = (c / a) / x1
##
  result = factorize(a)
  n = length(result)
  ans = ""
  for (i in 1:2^n) {
    factor = prod(result[as.integer(intToBits(i-1))[1:n] == 1])
    if (is.int(factor * x1) && is.int((a / factor) * x2)) {
      ans = c(factor, -factor * x1, a / factor, -(a / factor) * x2)
      break
    }
  }
  return(ans)
}

> func(4, -23, 15) # 1, -5, 4, -3
[1]  1 -5  4 -3


> func(-4, 23, -15) # 1, -5, 4, -3
[1]  1 -5  4 -3

> func(3, 10, 3)   # 1,  3, 3,  1
[1] 1 3 3 1

> func(6, -1, -15) # 3, -5, 2,  3
[1]  3 -5  2  3

> func(12, -1, -6) # 4, -3, 3,  2
[1]  4 -3  3  2

> func(3, -8, 4)   # 1, -2, 3, -2
[1]  1 -2  3 -2

> func(3, 5, 7)    # Error 実数解はない
[1] "Error"

> func(268231, -374150, 128851) # 347, -269, 773, 479
[1]  347 -269  773 -479

> func(1, 1.0000000000000001, 0.0000000000000001) # "" 適切な解はない
[1] ""

コメント

暗号を解けという問題

2015年04月14日 | ブログラミング

長い文章があって,その後に数字ベクトルが来れば,そのベクトルは一番単純には文章中の文字の位置番号を表しているのだろうと思う罠。

> s = "春は、あけぼの。やうやう白くなりゆく、山ぎは少し明りて、紫だちたる雲のほそくたなびきたる。 夏は、夜。月のころはさらなり、闇もなほ、蛍の多く飛びちがひたる。また、ただ一つ二つなど、ほのかにうち光りて行くも、をかし。雨など降るも、をかし。 秋は、夕暮れ。夕日のさして、山の端いと近うなりたるに、烏の寝どころへ行くとて、三つ四つ、二つ三つなど、飛び急ぐさへあはれなり。まいて、雁などのつらねたるが、いと小さく見ゆるは、いとをかし。日入り果てて、風の音、虫の音(ね)など、はた言ふべきにあらず。 冬は、つとめて。雪の降りたるは言ふべきにもあらず。霜のいと白きも、またさらでも、いと寒きに、火など急ぎおこして、炭持て渡るも、いとつきづきし。昼になりて、ぬるくゆるびもていけば、火桶の火も白き灰がちになりて、わろし。"
> w = unlist(strsplit(s, ""))
> w[c(85,42,241,10,7,104,17,195,37,95,244,235,30,212,197,25,195,137,140,31,94,266,89,33,298,138,107)]
 [1] "つ" "き" "あ" "う" "の" "を" "ゆ" "る" "そ" "う" "。" "た" "だ" "し" "、" "明" "る" "い" "う" "ち" "に" "も" "ど"
[24] "る" "こ" "と" "。"
> w[c(279,202,58,68,37,140,24)]
[1] "ま" "く" "ら" "の" "そ" "う" "し"

コメント

ggplot2(その2)

2015年04月03日 | ブログラミング

> 昔もつぶやいた気がするけど、ggplot2の真の価値は見た目の美しさではないんだけどな。

「見た目も汚い!!」っていっているんだけど,わかってもらえないかな。

> 2変数だったらbaseでもどっちでもいい。でも多変数にな るとfacet、グラフタイプの入れ替え、簡単なaes mapping、stat_summary等々、使い込むほどデータ探索に役立つ。

何変数だろうと,どのようなグラフだろうと,base で十分(それ以上に)対応できるレベルだということ。

あるユーザが必要とするグラフ表現って,そんなに多種類な訳ではないのが普通で,それ用のグラフプログラムを書けば必要十分なのではないか?

必要なグラフを描くプログラムを base を使って自分で書くことが出来ないユーザが,相当高級な機能を持つ描画システムを自分の用途に合うように組み合わせて必要なグラフを描くことができるのか?

出来るのかも知れないけど,それは,base 機能を使っても同じように出来ることであろう。

 

まあ,お好きなようにとしかいいようがないと思う。

 

ちなみにではあるが,base ではとても描けないだろうという「とっても美しいグラフ」の例を,プログラム例を添えて示してもらえないだろうか。

コメント

確かに官庁統計のExcelデータはひどいけど...

2015年04月02日 | ブログラミング

邪智暴虐なエクセル王を倒そう
だの
邪智暴虐なエクセル王を倒そう readxl版
だのと R で Excel データを読むというのがあるけど...

いずれも dplyr を使っているのも鼻につく(笑)

生け贄にされた Excel ファイルなんて,かわいいもんですよ。

こんなチンケな表を xlsx や readxl で読むなんざ,まさに牛刀割鶏(鶏を割くに牛刀を用いる)たる愚策。

表の本体部分をコピーして,x <- matrix(scan("clipboard"), ncol=18, byrow=TRUE) で十分。colnames, rownames でちょっとお化粧して dataframe にしてやっても,5 分とはかからないだろう。

コメント

ggplot2

2015年04月01日 | ブログラミング

きれいなグラフ」の評価基準が理解できない。

パワーポイントの発表なら自己満足できるだろうけど,論文投稿や本に載せるとき,きっと編集者からクレームがつくだろう。そのままでは版下に使えない。

そもそも,Windows ではどうあがいても,フォント自体が汚い。

デフォルトのままで背景がグレーなんて,問題外と思う。白地にしなさいな。それに,グリッドが描かれているのもダサイと思うがなぁ。

ダメ出しポイント満載なんだけど。

 english.exam = data.frame(
  Reading = c(54, 23, 82, 38, 49, 53),
  Writing = c(61, 35, 47, 52, 38, 66)
)
plot(Writing ~ Reading, english.exam, pch=19) # この一行で十分だ!


分析結果確認用のグラフなんか,凝ったものである必要はないし,ゴテゴテのグラフなんか要らない。

グラフに必要なことは何か。データ(情報)を正確に表現すること。一般受け(?)すること,お化粧することではない。

コメント

分数の計算(和)(その2)

2015年04月01日 | ブログラミング

AWK(GAWK) で書いてみた。

このような場合は AWK の方がすっきり書ける。

#!/usr/local/bin/gawk -f
function euclid(m, n,     temp) {
  while ((temp = n % m) != 0) {
    n = m
    m = temp
  }
  return m
}

function prog(s1, s2,     a, b, gcm, denominator, numerator) {
  split(s1, a, "/")
  split(s2, b, "/")
  denominator = a[2] * b[2]
  numerator = a[1] * b[2] + b[1] * a[2]
  gcm = euclid(denominator, numerator)
  denominator = denominator / gcm
  numerator = numerator / gcm
  if (denominator == 1)
    print numerator
  else
    print numerator "/" denominator
}

BEGIN {
  prog("5/6", "1/10") # 14/15
  prog("1/3", "2/3")  # 1
  prog("1/3", "2/7")  # 13/21
  prog("2/8", "3/5")  # 17/20
  prog("3/10", "1/6") # 7/15
  prog("3/4", "5/8")  # 11/8
  prog("2/5", "2/3")  # 16/15
}

コメント