たんでー のすべての投稿

codeiq @riverplus さんの「プラス・マイナス・ゼロ問題」を解いた。

問題&解法はこちら。
https://codeiq.jp/magazine/2016/02/37963/

問題は、大体下記のような感じ。

自然数 n に対して、次の等式を考えます。

    □1□2□3□4…□n = 0

四角の部分には、プラス(+)またはマイナス(-)の記号が入ります。

自然数 n に対し、等式を成立させる記号の入れ方の数を F(n) と定義します。

標準入力から、自然数 n(1 ≦ n ≦ 50)が与えられます。
標準出力に F(n) の値を出力するプログラムを書いてください。

提出コードはruby。(コメントだけ追加しました。)
基本的には、ひとつひとつ+-していったときの値を、まとめて勘定しているだけ。
一番最初に全通り数え上げてみるのを書いてみた後、それではとてもとても無理ということで書き直した感じ。

def solve(n)
  # 1..j の数字について処理した結果の値をキーに、そのキーの値になる
  # +-の組み合わせの数を値として持つ連想配列を考える。
  # (Arrayだとインデックスが負にならないような小細工が必要で面倒)
  ret = {1 => 1} # -1から始まるものは、対称性から最後に2倍してすます
  (2..n).each{|j|
    tmp = Hash.new{|h,k| h[k] = 0}
    # j番目のHashは、j-1 番目のHashの各要素{k=>v}について、
    # k+j, k-j の値にvを足していくことで得られる。
    ret.each{|k,v|
      tmp[k+j] += v
      tmp[k-j] += v
    }
    ret = tmp
  }
  ret[0] * 2
end
while str = STDIN.gets
  n = str.chomp.to_i
  puts solve(n)
end

最近のゲーム

フランスに来て時間ができそうなので、しばらくやっていなかったPSPのゲームでもやろうと、PSPgoを持ってきた。
普通にこちらでもストアにつなげることはわかっていたので、あとでいろいろと購入もしている。
(つうか、3DSを持ってこなかったのは、後から考えれば失敗だった、、、。)
続きを読む 最近のゲーム

ティファールの電気ケトルを買った

コチラに来て、初めてティファールの電気ケトルを買った。

これが思ったより便利。
使いたいときに水を入れてスイッチポンで1分くらいですぐにお湯が沸く。
必要な分だけお湯が沸かせるので、無駄になることが少ない。
前は、IHヒーターの上にやかんをおいて沸かしていたから、それと比べるとたぶん相当早くなった。

電気ポットによくあるプラスチック臭さのようなものもなくて、当たり。
こんなに使い勝手がよくてしかもそれほど高くないなら、もっと早めに買っておけばよかった。

値段としてはだいたい25ユーロくらい(日本で同等製品を買うより安い。)で、200Vの2400Wのシロモノでした。

フランスでの通信関係

電話を買ったので、当然SIMカードも用意した。
町中の各ブランドの店で買ったり、ネットでMVNOからSIMカードを取り寄せたりする感じでSIMカードは用意する形。

フランスの携帯会社では、2年縛りで端末値下げ、という売り方もあるけれども、最近では縛りなしで安いプランが多く出ていて、価格破壊が進んでいる模様。
通信会社は基本的には orange, SFR, Bouygues, free の4社と、MVNO各社がサービスを展開しているけれど、最後発のfreeが、€2/月の従量制通話中心プランと、€20/月の話放題&LTEデータ通信50gbプランの2本立て(いずれも契約期間の縛りなし)で、存在感がある。
(契約には住居の証明と銀行口座が必要なので、短期間の旅行とかだと使えないですよ)

これを追う形で、他の各社でも縛りなしの安いプランを出しており、しょっちゅうキャンペーンを張って頑張っている様子のようだ。
自分もこれの一つで契約したかんじ。
(ただ、SFRとかorangeとか、契約内容がわかりにくいのよね、、、、)

インターネットは、アパートまでファイバーが来ていて、ファイバーを敷設した業者にお願いしたら、つながるようになった。
フランスでは、インターネットのルータが、オープンWi-Fiをサービスしていて、結構使えるようになっている。(当然、オープンwifiがセキュリティ的に怖くなければ、という前提だけれども、背に腹は代えられないときもある。)
たとえば、SFRのルータは同時にFONのアクセスポイントになっており、SFRのインターネットを契約していると、ただでオープンwifiとして、他人のwifiアクセスポイントを使うことができる。これが結構町中だと馬鹿にならないくらいアクセスポイントがあって、場所によっては割とつながる、というわけ。(うちはSFRじゃないけど、他でも似たような感じ)

テレビもインターネット経由で配信しているものを見ることができて(というか、普通のアンテナの線がなかった)、セットトップボックスみたいなのがついてきた。
このインターネット経由テレビは、普通のリアルタイムの放送のほか、多くのチャンネルでオンデマンドで過去1週間分くらいめぼしい番組が見れるようになっていて、録画とかはたぶん不要なんだろうなぁ、とおもう。(さらに、1週間のうちに何度も似たような放送をやっている。簡単に見た感じだと、子供向けアニメとか、同じ話を何回も放送しているし、続き物であれば何本もぶっ続けで流したりとかしている。)

CSみたいな感じの映画チャンネルとか、日本のアニメ(日本語+フランス語字幕中心)のチャンネルとかもあるけど、別料金払ってまで見るものでもないので、見てはいない。
これでYouTubeもみれれば完璧なんだけど、そこまでではないようで、少し残念ではある。

Microsoft Lumia 640 を買った

Windows phone を試してみたかったので、Lumia640 dual SIMを買った。
この機種にしたのは、フランスで普通に変えるものの中では、通信バンドがかろうじて日本でも使えそうなものだったから(でもまぁ、対応バンドが多いわけではないので、過信はできない。)

買ってみていくらか使ってみて、割と気に入っている。
続きを読む Microsoft Lumia 640 を買った

codeiq @riverplusさんの 「スロット・マシン問題」を解いた。

解きました。フィードバックは大変なんでしょうね~。
最初に書いたコードでは、F(12)までとてもとてもまともな時間で計算できなかった。
想定時間30分で12のときまで解くのは結構ハードだと思う。

恥ずかしながら半日~1日くらい??

【問題】

n 個のリール(数字が描かれている部分です)を持つスロットマシンを回します。

各リールには、0 から 9 のいずれかの数字がランダムに出ます。

このとき、「最も多く出現した数字の出現回数」に等しいドルが賞金として得られます。

例えば n = 6 のスロットマシンを考えましょう。

各リールに、左から順に 7 7 5 1 0 7 という数字が出たとします。

このとき、7 の数字が最も多く 3 回出現していますので、賞金は 3 ドルです。

リールの数字が 0 2 0 9 2 6 のとき、賞金は 2 ドルです。

リールの数字が 1 2 3 4 5 6 のとき、賞金は 1 ドルです。

リールの数字が 8 8 8 8 8 8 のとき、賞金は 6 ドルです。

このスロットマシンを 1 回まわしたときの賞金の期待値を F(n) とします。

例えば F(1) = 1,F(2) = 1.1,F(3) = 1.29 となることが確かめられます。

■ 第1問 (Normal)

F(6) の値を求めて下さい(四捨五入は不要です)。

■ 第2問 (Hard)

F(12) の値を求めて下さい(四捨五入は不要です)。

【方針】
○ nをn以下で10個までの自然数の和に分割する方法が何通りあるかを計算する。
(このとき、同時に賞金ごとに分類しておく)
○ 上で計算した分割方法ごとに、リールの数字が何通りあるかを計算し、期待値を求める。
○ たとえば、n=6で4点のときは、[4, 1, 1], [4, 2] の2通りの分割があり、
それぞれ、 (10*9*8)*(6!/4!)/2!, (10*9)*(6!/4!/2!)/1!通りの組み合わせになる。
配列の長さmについて、(10からmとる順列)*(並べ方の数)/(配列中に同じ数字があれば割引く)通り。(うーん、我ながらわかりにくいか。)

【rubyの提出コード】

#!/usr/bin/env ruby
# -*- coding: utf-8 -*-
BASE=10 # スロットが10進数で回る。
def solve(n)
  score_sum=0 # スコアの総和
  count_sum=0 # (デバッグ用)スロットの並び方の総和
  make_array(n).each{|score, arrays|
    arrays.each{|arr| # nと賞金で決まる配列ごとにループ
      # 対称性を考慮して、並べ方の数を数える。
      # 配列の中の同じ数字があるかどうか。
      sym=(1..n).map{|i| arr.count(i)>1 ? arr.count(i) : nil }
        .compact.map{|i| facto(i)}.reduce(&:*) || 1
      # 上の対称性も考慮した、並べ方の数。
      part = facto(n)/arr.map{|i| facto(i)}.reduce(&:*) / sym
      # 配列の中の数字にそれぞれ0-9の数字を当てはめる
      count = permu(arr.length) * part
      count_sum += count
      score_sum += score*count
    }
  }
  #  print "count(#{n}) = #{count_sum}\n"
  score_sum.to_f / BASE**n
end
# 普通の階乗計算
def facto(n)
  $facto||=[1]
  $facto[n]||=n*facto(n-1)
end
# BASE個の中からn個とる順列
def permu(n)
  ((BASE + 1 -n)..BASE).reduce(&:*)
end
# nをBASE個までの整数の和に分割し、賞金ごとに分けたHashに配列の配列として格納。
# たとえば n=3 のとき、{1=>[[1, 1, 1]], 2=>[[2, 1]], 3=>[[3]]}を返す。
def make_array(n)
  ret = Hash.new{|h,k| h[k]=[] }
  min = 1 + (n-1)/BASE
  (min..n).map{|sc|
    tmp = rec(sc,n).reject{|arr| arr.length > BASE }
    ret[sc].push(*tmp)
  }
  ret
end
# nと賞金が決まった時の、可能な自然数への分割を配列の配列で返す。
def rec(sc,n,ret=[],all=[])
  sum = ret.reduce(&:+) || 0
  num = n-sum
  if n == sum
    all << ret
  elsif num == sc
    ret << sc
    all << ret
  elsif sc == 1
    num.times{ ret << 1 }
    all << ret
  elsif num > 0 && num >= sc
    ret << sc
    (1..[sc,n-sc].min).each{|_sc|
      rec(_sc,n,ret.dup,all) # 次の数は直前に格納した数字と同じか少ない。
    }
  else
    nil
  end
  all
end

(1..20).each{|i|
  print "F(#{i}) = #{solve(i)}\n"
}

sheevaplug をついに手放した。

手放した、といっても、手元に置かなくなった、くらいの意味だったりする。
2009年8月くらいからずっと家において、NASの頭やバックアップとかのちょっとしたcronを仕込んで使っていたsheevaplugをついに実家においてきた。

実家側でIPアドレスをダイナミックDNSサーバに通知しておいて、必要に応じてバックアップ等のために遠隔で入っていろいろ手当てする予定。
とりあえずログインはできている。

core2duo P8700 のノートPCにwindows10を入れた話

実家においてある、少し古いノートPCにウインドウズ10を入れたら、Edgeとかinternetexplorerとかを立ち上げている時に、しょっちゅう画面が暗転してしまっていた。(そしてたまに戻らなくなって、再起動が必要になってしまう、、、。)

これはどうも、Core2Duoのグラフィックドライバが古いせいらしいが、すでにそれは更新されていないので、どうしようもない。
とりあえずは、「インターネットオプション」の詳細設定タブで「GPUレンダリングではなくてソフトウェアレンダリングを使用する」をチェックして再起動したら、問題なく動くようになったので、これでOK。

windows10 にしたらいろいろとドライバまわりで苦労する。。。そのためのアップグレード予約だったのかも。。。

venue8pro で、 3Gネットワークを誤ってプライベートネットワークにしたら戻せなくなってしまった話。

windows10 にしたvenue8proで、VPN接続したつもりでファイル共有等いろいろあれこれしたら、間違えて3Gネットワークの接続をプライベートネットワークにしてしまい、どうにも戻せなくなってしまった。VPN接続とかWiFi接続とかだと、設定→詳細オプション→デバイスとコンテンツの検索 で切替えできるはずが、携帯電話ネットワークでは選べるスイッチが出てこなかった。

というわけで、http://answers.microsoft.com/en-us/insider/forum/insider_wintp-insider_security/how-do-you-change-from-public-to-private-network/106c320f-7d40-40a8-b428-11976b82fcaeこのあたりを参照して、レジストリを直にいじって解決。やれやれやれやれ、、、。

codeiq 「カット・アンド・スクエア問題」

問題はこちら
http://riverplus.net/codeiq/CutAndSquare.pdf

かいつまんで言うと、
[偶数 n に対して、先頭にゼロを持たない n 桁の整数で上 n/2 桁と下 n/2 桁とに分け、それぞれを 2 乗して和をとると、元の数に戻るような数で、n=6, n=10の場合を求めよ。]という感じ。
色々と回答があるようで、参考になったな~。

で、Rubyで書いた提出コードが下記。
sqrtの結果を整数に丸めるあたりが怪しい気がするが、まぁ、当たりでないときは外れるはずだからOKのはず。

ideone.comにも置きました。便利だね。
http://ideone.com/eMPnrv

【方針】
求めるN桁の数をnとし、 n = a * 10**(N/2) + b とする。
n = a**2 + b**2 (b>0, a>10**(N/2 – 1)) の条件を満たす整数a,bを見つける方針でとく。
1. n = a**2 + b**2 の1桁目に注目すると、aの1桁目の数字は0,2,8のみとなる。
   (Excelで100通りをすべてチェックしましたが、a,bの下1桁の値の組み合わせは8通りしかありません。)
2. 条件の式からbについて解くことができるので、各aについて、bが条件を満たす整数かどうかをチェックする。
   (bについてはループしなくて済む。)

N=10
Base2=10**(N/2)

result = []
((Base2/10)...Base2).select{|a| # aの下1桁を0, 2, 8に絞る。
  tmp = a%10
  tmp == 0 or tmp == 2 or tmp ==8
}.each{|a| # aについてのループ。
  # bは、aについて解いておく。(b>0なので、一意にさだまる。)
  b=(1 + Math.sqrt(1+4*Base2*a -4*a*a)).round/2
  n = a*Base2 + b
  result << n if a*a + b*b == n # 条件を満たすかどうかをチェック。
}
p result
p result.reduce(&:+)

windows10 を dell venue8 pro に入れた

こないな~と、待っていたら、タブレットの方に windows10 へのアップグレードが来ていたので入れてみた。

見た目や設定の場所などは今までと変わったものの、アクションセンターの表示がandroidタブレットのように一覧性よく見やすくなったし、右からのスワイプだけで出せるから感じ。
新しいブラウザはまだあんまり使っていないけれど、トップページにニュースがつらつら並ぶのは、結構便利かも。
windows8.1 のチャームの共有メニューみたいなのが、ブラウザの中から選べるのがよさげ。

なんだか、タブレットを横にして持つと、下が少し詰まって画面がほんの少し小さく感じるかも。

タブレットモードだと、本当にwindowsのデスクトップにアクセスできないようで、タスクバーにピン止めしてるだけだったやつは使えない感じ。どうだろか。

あとは、アクティブスタイラスがちゃんと認識するようになってた。今まではなんかよく使えなくなってた。
なんか、スタイラスがなくても、指で結構ちゃんと選べるようになっている気がする。
スタート画面は一覧性がいいように全画面にするのかなぁ。 設定→パーソナル設定→スタートで設定できる。

仮想デスクトップはまだ試していない。どんなもんじゃろか。

=======
通信関係がちょくちょく切れてイラついたけど、ドライバを更新したらこれは解決した。
あとは、なんだかスリープからの復帰で画面が戻ってこない時があるのが気になるが、、、。

年次

年次がどうか、ということが人間関係構築の上で大事な情報と思っている人に久々に出会った。
というか紹介の時にそこから入る人間の存在を再認識した。

当然それが重要な場面もあることは言うまでもないが、はじめましての場面でいきなりそれから入るのは相当ばかげていると思う。その前後で言葉遣いが変わるの?初対面なのに??人間性とも能力ともほとんど相関がない(と思う)属性なのに???

一言で言うとあきれた。あほくさ。

続codeiq

前の記事

スカウトメールがすぐに来た。まぁ、今のところ予定はないんで辞退申し上げるのですが、、、。

pythonやocamlでも解いてみたりしたが、ocamlやばい。intが31bitしかなくて?オーバーフローしても警告もなく実行が続いて気付かない、、、。
手元のocaml4では動くけど、ideoneに突っ込むと、バージョンが古いためか対応できない!やれやれ、、、。

いつもとちょっと違う言語を触ってみる気になるのはいいなぁ。別な関数型言語に手を出してみるべか。

codeiq

しばらく前から気になる広告がいくつか出ていたので、連休の暇つぶしにやってみた。

サクサクっと解けるものは解けるのだけれども、なかなか早く解くアルゴリズムを、想定時間(30分とか)で考えてコードしてテストするのは、結構厳しい感じ。

まぁ、暇つぶしとしてはそれなりによさそうかな。
企業からのスカウトというのが来てしまっても、今のところは困ってしまうのだけれども、暇つぶしとして、ということで、、、。

「できかねないです」→じゃぁやってくれよ、、、。

今日、歯医者に予約の電話を入れようとしたら、「明日はいっぱいだから予約をできかねないです。」という内容のことを言われた。

思わず、「え、それってできるってことですよね?」と聞き返した。
前から受付の人の手際が悪いと思っていたが、ここまでとは、、、。
別にそこ以外はきになってないけど、次回以降は別な歯医者にするかな。

ちらし寿司と刺身と醤油、漬け丼とご飯

少し前に、刺身がそのまま乗っているようなちらし寿司に、上からわさびを溶いた醤油をかけようとしたら、ものすごい勢いでやめてください、といわれた。

いや、言わんとすることはわかるんだけど、そのくらい好きにさせてほしかった。
認識している流儀は3通り。

  • わさびを醤油に溶いて、ちらしずしにかける!
  • わさびを醤油に溶いて、ちらしずしのネタだけをつけて食べる!
  • はしでネタにわさびを乗せて、まるごと醤油につける!

「目玉焼きの黄身、いつつぶす?」でもネタがあったから、よく覚えている、、。
これで見た。 http://www9.nhk.or.jp/anime/medamayaki/

世の中にはいろんな人がいるんだから、このくらいは好きにさせてほしいものです。親は、わさびを醤油に溶いて、ちらしずしにかける派だった、、、。この流儀が唯一、どんぶりものでよくあるようにご飯にタレ的なものを絡めて食べられるので、寿司飯をおいしく食べられるのだと思うのですよ、はい。
まぁ、おいしく食べられれば細かいことはどうだっていいんだよ、、、。

ところで、今日の昼に入った店で頼んだサーモンの漬け丼、熱いご飯の上に乗っていたから、せっかくのネタに熱が通ってしまっていた。海鮮丼とかでもそういうのがあるけど、せっかくのネタが残念な感じになると思う。もう2度とあんなのは食べるまい。

佐々木正美「子どもへのまなざし」福音館書店

http://www.fukuinkan.co.jp/bookdetail.php?isbn=978-4-8340-1473-0

読んだ。語り口調で、ポイントは繰り返し出てくるので、そういうのが読みやすい人には読みやすいと思う。

子どもがちゃんと育つには、乳幼児期がだいじ。特に、乳児期に親を信頼できるようになることで、ゆくゆくは人を信頼できるようになるということはすごく大事。幼児期はソーシャルリファレンス。新しい体験があるとどう反応したらいいかを周囲から(親から)真似して理解する。そこから先は友達。
過剰干渉は絶対ダメ。過保護はよい。こどもを受容する。

基本的には、まぁそうだよねっていう感じ。あまり新鮮さはなかったかも。
自分はまともに育てられてきたんだろうか、、、というのが気になる。ちゃんと育てられなかった、というのは、世代を超えて伝わってしまうわけだ。

「コインの表が出たら1の権利を得て、裏が出たら-1失う」、ということが書いてある本。

最近、本を読んでいたらこんな表現が出てきて、頭を抱えた。

「コインの表が出たら1の権利を得て、裏が出たら-1失う」(引用は正確ではありません!)

ほかにも、「好況時には1000を得て、不況時には-1000を失う」などの表現がいくつか出ており、誤植ではなくそういったものとして書いていたわけだ。著者は、肩書も立派な大学教授なのだが、マイナスの概念を理解しているとは思えない。「得る」と「失う」では変化の方向が反対なのだから、失うにさらにマイナスをつけたら、1得るのと変わらないではないか!
ひょっとしたら、この分野ではこういうコンベンションに従っているのかもしれないが、気が狂いそうにならないのかなぁ。

仕事の役に立つかもと思って数年寝かして置いた本だが、破り捨てたい衝動にかられながらざっと流し読みして、もう二度と読まないと思った。