パナソニック“脱家電”路線の衝撃度 松下翁の「水道哲学」は消えるのか
えー。脱家電じゃなくて、脱黒物家電でしょう。
赤字5兄弟が「テレビ、半導体、携帯、回路、光ピック」ならば、携帯以外は全部テレビ関連じゃないですか。脱テレビといっても過言じゃないです。
メモ: 技術系?の話はFacebookから転記しておくことにした。
ScalaにてBooleanのリストをビット列に見立てて、任意のビット数を上位ビット〜下位ビットにOR演算し、Intのリストとして返すという処理をやりたいのです。
ビット列 (0, 1, 0, 0, 1, 1, 0, 0, 0) に対して、(1ビット取る, 3ビット取る, 5ビット取る) という処理を行って、結果として (0, 4, 24) が返る、そんなイメージです。
いきなり作るとコケたときショックがデカいので、まずは単純化して必ず8ビットずつ取る処理で考えてみます。入力、出力は下記の通りです。
(入力)
List(
true, false, false, true, true, false, true, false,
true, true, true, false, true, false, true, true
)
(出力)
List(154, 235)
やりたいことはシンプルなのですが、あまりスマートな書き方が思いつきません。
まず思いついたのがforeachです。
val a = List(
true, false, false, true, true, false, true, false,
true, true, true, false, true, false, true, true
)
var acc = 0
var p = 0
var b: List[Int] = List()
a.foreach { it =>
acc <<= 1
if (it) acc |= 1
p += 1
if (p >= 8) {
b = b :+ acc
acc = 0
p = 0
}
}
println(b)
動くには動きますが、8ビット読むごとにリストのコピー処理が走るという、富豪プログラミングの限界に挑戦しているようなプログラムです。
次に思い浮かぶのはmap関数ですが、基本的にforeachと変わらないように思います。変換前と変換後が1:1対応するなら簡単に書けますが、n:1対応させると一時変数の隠蔽が必要になり面倒です。
object BooleanToByte {
def apply(): (Boolean => Option[Int]) = {
val o = new BooleanToByte()
o.mapper
}
}
class BooleanToByte() {
private var v = 0
private var p = 0
def mapper(b: Boolean): Option[Int] = {
v <<= 1
if (b) v |= 1
p += 1
if (p >= 8) {
val result = Some(v)
v = 0
p = 0
result
} else {
None
}
}
}
val a = List(
true, false, false, true, true, false, true, false,
true, true, true, false, true, false, true, true
)
val b = a.map(BooleanToByte()).flatten
println(b)
ひとまず見た目をa.map(f) の形に近づけるためだけに頑張りました。コードがダサいというか、Scala初心者感が丸出しというか。もっとスマートに書けるはずですが、今の私のレベルではなんとも…。
ちなみに最後のflattenはSomeオブジェクトを展開して中身の値を取り出すために使っています。ついでにNoneも消してくれるナイスな奴です。
最後にリストの要素を列挙するもう一つの手段、イテレータが思いつきました。foreachと異なりn:1対応に融通が利きます。いや…融通が利くというより、自由に記述できてしまうが故にn:1だろうとn:mだろうと、もはや何でもアリと言った方が正しいですね。
val a = List(
true, false, false, true, true, false, true, false,
true, true, true, false, true, false, true, true
)
val it = a.iterator
var b: List[Int] = List()
while (it.hasNext) {
var acc = 0
var p = 0
while (p < 8) {
acc <<= 1
if (it.next()) acc |= 1
p += 1
}
b = b :+ acc
}
println(b)
先ほどのforeachやmapのような、無理やり頑張った感はなくなったように思いますが、今度は変換元に8未満の要素数が残っているとき、例外がスローされてしまうという欠点もあります。
これがforeachを差し置いてベストか?と言われると、何とも言い難い、難しいですね。
< | 2013 | > | ||||
<< | < | 12 | > | >> | ||
日 | 月 | 火 | 水 | 木 | 金 | 土 |
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 | - | - | - | - |
合計:
本日: