裏 RjpWiki

Julia ときどき R, Python によるコンピュータプログラム,コンピュータ・サイエンス,統計学

コラッツの問題(2)

2014年11月06日 | ブログラミング

単純に,10 進数一桁を要素とするベクトルを使って,掛け算も,割り算も,自前でやるプログラムを書く。10 進数は,1 の位が添え字 1 になるように(逆順)にすると,プログラムが書きやすい。

途中経過をプリントするのを含めて,余裕の 24 行だ。

n = rep(9, 50)
print(sub("^0*", "", paste(rev(n), collapse="")))
repeat {
  if (n[1] %% 2 == 1) {
    n = 3 * n
    n[1] = n[1] + 1
    carry = 0
    for (i in seq_along(n)) {
      n[i] = n[i] + carry
      carry = n[i] %/% 10
      n[i] = n[i] %% 10
    }
  } else {
    borrow = 0
    for (i in rev(seq_along(n))) {
      n[i] = borrow * 10 + n[i]
      borrow = n[i] %% 2 == 1
      n[i] = n[i] %/% 2
    }
  }
  string = sub("^0*", "", paste(rev(n), collapse=""))
  print(string)
  if (string == "1") break
}

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

コラッツの問題

2014年11月06日 | ブログラミング

自然数 n に対して,n が奇数なら 3 をかけて 1 を加える。偶数なら 2 で割る。
この処理を繰り返すといずれは 1 になる。

これを,n = 99999999999999999999999999999999999999999999999999 についてやってみよという問題。

ただし,「言語は Object Pascal(Delphi) 。Windows 向けコンソールプログラムで,ソースコードは、50 行以内,かつ,Delphi XE7 または Appmethod に標準搭載されているデータ型,クラス,ライブラリのみを使用」という条件がついている。

でもまあ,そんな条件なんかどうでもよいでしょ。

library(gmp)
n = as.bigz(paste(rep("9", 50), collapse=""))
repeat {
  if (n %% 2 == 1) {
    n = 3 * n + 1
  } else {
    n = n %/% 2
  }
  print(n, initLine=FALSE)
  if (n == 1) break
}

で確かめられるんだから。

注意点は,演算を Big Integer ('bigz')  でやるんだけど,2 で割るときに n %/% 2 としないと,結果が Big Rational ('bigq') になってしまうよというところ。

gmp を使わないでもできるだろう。

コメント
  • X
  • Facebookでシェアする
  • はてなブックマークに追加する
  • LINEでシェアする

PVアクセスランキング にほんブログ村

PVアクセスランキング にほんブログ村