ある連続値が区間集合のどの位置に含まれるか

  • 問題: 区間の上界と下界の属性を元に、何かを計算する
    • 例えば、区間集合{ 3: {3の属性}, 5: {5の属性}, 8: {8の属性}, ... }
    • 4を与えると、4は3と5の区間に含まれるから、3の属性と5の属性から、4の属性を新たに計算したい
  • 解決1: 素朴に indexOf
    • 4が区間(3, 5)に含まれることを検索するのに線形探索?
    • 区間が少ないならあるいは。 それでも、10個の区間で、80の点で同じ処理をするなら? うーん。比較数n x m
  • 解決2: 切断点集合を与えて、まとめて処理
    • {10, 11, 29, 30, ...}求めたい切断点はたくさんあるなら、まとめて処理した方が比較数が減る
    • 多分比較数log(n) x m
var sections = [{"距離": 0, "高さ": 10}, {"距離": 2, "高さ", 12}, {"距離": 8, "高さ": 14},,,];
var dists = [4, 9, 10]; // 切断点集合

sections.inject([], function(list, section, i, self){
   for (var dist = dists[0]; dist != null && (section["距離"] <= dist); dist = dists[0]){
      if (i+1<self.length ? (dist < self[i+1]["距離"]) : true){
    var grad = (self[i+1]["高さ"]-section["高さ"])/(self[i+1]["距離"]-section["距離"];        
        list.push({"距離": dist, "高さ": section["高さ"] + grad * (dist - section["距離"])})
      }else
        break;
      dist = dists.shift();
    }
  return list;
});

これでOK。

dist = dists.shift()とdist = dists[0]を分けてあるのがミソ。

プログラミング言語、構文メモ

Javascript構文で、イラッとする細かいところ。

  • hoge = this;
    • コールバック中のthisが呼び出し元スコープのthisではない
    • そのため、既存のオブジェクト志向記述にするとよくundefでエラー停止
    • Arrayのmap, reduce, forEachの最後の引数にthisを渡さないといけない
    • さらにコールバックなら、.bind(this)にする必要がある
  • Arrayのpushの戻り値がArrayでない
    • そのため、reduceのコールバックでarr.push(element); return arr
    • 素直に、return arr._push(element)でメソッドチェーンできるようにしといてほしい
  • 代入式の戻り値が右辺
    • そのため、{}.value = obj の代入式の戻り値が{}のオブジェクトではなくobjオブジェクト
    • そのため、reduceのコールバックで、o.value = obj ; return oとか
    • 素直に、return o._assign(value, obj) とかでメソッドチェーンできるようにしといてほしい

艦これ改レビュー(1)

ひとまず、ネットゲームじゃなかったらやってたんだけど、待望のPSVita版ということで購入。10年ぶりくらいのコンシューマゲームかもしれん。

大きくターン制にかわったのだが、これはリアルタイム時間でいろいろをこなさないといけない原版では、コンシューマにはそぐわないとの判断であろう。ここは英断と思う。それに伴って、開発、入渠、建造などが一ターン単位で進む。建造2日なら駆逐艦、4日なら軽巡洋艦という具合。

UI操作がどうもスムーズにいかない。

  1. 操作主体で、データ(ここでは艦娘)中心の操作メニュー体系になってないから

艦隊の編成や装備の換装などが統一的にできず、編成メニューをいったん終了しないと換装できない。
全部の艦娘の一覧からの操作にすればよかろうと思ったが…いうなれば、ファイアーエンブレムのUIメニューを参考にぜひして欲しい。

輸送艦の配置と輸送艦護衛艦隊を配備することで、海域ごとに定収としてえられる資源が増える。これは、あまりがちの艦娘の有効活用ということであろう。Good!
でも、海上護衛艦隊をそのまま機動艦隊に振り替えられたりしてもよかったんじゃないのとか思ったり。

戦闘ではLボタンで省略いう説明があるけど、アニメ省略されないんだけど何が悪いんだろう。

あと海域ごとに入渠ドック数が違うのな。
色が変わるのはどういうことやろ?

ひとまず、五十鈴の爆雷投下は半端ないねと。そんなこんな。

戦闘陣形の効果がちょっとでてるのかでてないのかわかんないな…

10/18は大宰府で特別受験合格祈願大祭

学問の神様である,菅原道真公が若くして文章博士に任じられた日,ということだそうです.

縁あって,道真公とお話ができたので,記して道真公へ感謝いたしましょう.

  1. 10月18日に特別受験合格祈願大祭ではエネルギー使う
  2. 受験合格・学業上達祈願の神様とはいえ,最近は信仰心のあるお年寄りがこない
  3. 受験のときばかり若い子が来てそのあと全然来てくれない
  4. パワーがみなぎる方法は自分の家が昔からひいきにしている神様が必ずいるから、その人を拝んで、ちゃんと運動をして勉強をしろ!
  5. 花、月、をみながら酒を飲む事が一番の贅沢.しかし,時代の流れがあるから無理をするな…ただ暇があれば一人で晩酌をする時は対面に自分が居ると思って飲んでくれればそれでうれしい!
  6. 年に一度でいいから天満宮に遊びに来てもらえたらもっとうれしいぞ!
  7. 後悔する人生は送るなよ!と…気持ち若ければ今からでもやり直せる、挑戦できる!とにかく学べ!そして昔の夢を思い出せ!生きる事、それは挑戦する事、学ぶ事…若人よ男ならやりたいようにやってみよ!


さすが,学問の神様です.心当たりのある人,意欲的に挑戦していきましょう.

でも,運動せんといかんのか.そこだけ違和感あり.オカルトオカルト

データ構造の変換に畳み込み関数

関数型言語で非常に重要なfold(あるいはreduce,inject)を使うと初期化あり変数宣言を削除できる

たとえば,二次元配列を一次元にするflattenをJavaScript

var ret = [];
aList.forEach(function(e, i, arr){
  arr.push.call(ret, e);
});

// これが

var ret = aList.reduce(function(acc, e, i, arr){
  arr.push.call(acc, e);
  return acc;
},[]);

あまり記述量に変化なしか.しかし,2文になっていた,宣言と変化する部分が一式となることで,
よりコンパクト簡潔に記述を納めることができた.

規定数のリトライ成功失敗における反復「式」の効用

Rubyでは反復は文でなく式である.そのため,途中で中断した場合,反復式として戻り値を持てる.すると,規定数のリトライ処理を,成功した場合と失敗した場合で,論理的に整合するよううまく記述できる.

ネットワーク越しのデータ取得は,必ずしも成功せずタイムアウトする場合があるからね...

  json = nil
  if [1, 2, 3].each {|t|
      if t > 1
        LOG.info msg + "retry"
        sleep t
      end
      json = JSON.parse(`wget -q -t 2 #{uri} -O - | ./html2json.rb`)
      break if json["itemID"] > 0 # 在庫あり
    }.nil?

    LOG.debug msg + json["itemID"].to_s

  else # 在庫なし

    LOG.info msg + "no stock"
    
    row[0] = 'd' if opts.isRakuten
    puts CSV.generate_line(row, {force_quotes: true})
  end

もし,反復式であることを知らないと,例外構文使っちゃうかも.
あるいは,反復が文しかない言語であれば,例外構文を使わざるを得ない.
この場合,在庫なしが正常ケースで,在庫ありが例外ケースとなる.

これは論理的に正しいプログラムといえるだろうか?

こういう場合,いちいち例外にするのは,大仰すぎないだろうかと.
なんとなれば,外部へ通信する部分にはすべて,例外構文にするべきだろうか?
論理的には,在庫有りも在庫なしも,正常ケースとみなすのが仕様として妥当な気がする.

begin
  json = nil
  [1, 2, 3].each {|t|
      if t > 1
        LOG.info msg + "retry"
        sleep t
      end
      json = JSON.parse(`wget -q -t 2 #{uri} -O - | ./html2json.rb`)
      raise unless json["itemID"] > 0 # 在庫あり
  }

  LOG.debug msg + json["itemID"].to_s

rescue # 在庫なし
  LOG.info msg + "no stock"
  ...略
end

例外構文ではなく,フラグを使ってもよい.

  json = nil
  found = false
  [1, 2, 3].each {|t|
      if t > 1
        LOG.info msg + "retry"
        sleep t
      end
      json = JSON.parse(`wget -q -t 2 #{uri} -O - | ./html2json.rb`)
      if json["itemID"] > 0 # 在庫あり
        found = true
        break
      end
  }
  
  if found 

    LOG.debug msg + json["itemID"].to_s

  else # 在庫なし
    ... 略
  end

さらにフラグが気持ち悪い人は,フラグの代わりに番兵を使う人もいるかも.