Hatena::ブログ(Diary)

タイトル

2011-12-26

[][][]等差数列

目標

配列の隣接する2項にそれぞれ演算を施した配列を得たい。つまり、
f (+) [1,2,3,4,5] = [3,5,7,9]
のような f が欲しい。

結果

OCaml はオワコンだった
(こうすればうまく書けるよ、というのがあれば教えてください)

愚直(Haskell)
f g []       = []
f g [_]      = []
f g (x:y:zs) = g x y : f g (y:zs)

Haskell
f g x = zipWith g x (tail x)

F#
let uncurry g (a, b) = g a b
let f g x = Seq.map (uncurry g) (Seq.pairwise x)

Ruby

keyesberry さんより

def f(x)
   x.each_cons(2).map{|y,z| yield(y,z)}
end

Ruby(無理やり)
def f(x, &b)
   x[0..-2].zip(x.drop(1)).map { |y, z| b.call(y, z) }
end

keyesberrykeyesberry 2011/12/27 00:26 RubyにはEnumerable#each_consというのもありますね
def f(x)
x.each_cons(2).map{|y,z| yield(y,z)}
end

osiireosiire 2011/12/27 00:43 えぇ、OCamlにも遅延リストくらい標準で入れてほしいですよね。

let f g l =
let rec loop r = function
[] -> r
| _ :: [] -> r
| x :: y :: tl -> loop (g x y :: r) (y :: tl)
in
List.rev (loop [] l)

mkutmkut 2011/12/27 03:15 > keyesberryさん
each_consかっこいいですね!
さすがrubyの記述力は半端ない

> osiire さん
使いやすさでは群を抜くと思うんですけどねえ…

yoshihiro503yoshihiro503 2011/12/27 13:17 ocamlでfold_leftを使って。

let f g = function
| [] -> []
| x::xs -> List.fold_left (fun (x,store) y -> (y, g x y :: store)) (x,[]) xs
|> snd
|> List.rev;;

taraotarao 2011/12/30 13:53 ocamlでrevがありならfold_rightでもよさそうなので書いてみました.

let f g l = List.tl (List.fold_right (fun x -> function [] -> [x] | y::ys -> x :: g x y :: ys) l []);;

mkutmkut 2011/12/30 20:39 OCaml も強かった

simezi_tansimezi_tan 2012/02/13 21:58 rubyのコード実行してみたらエラーになりました。
def f(x)
x.each_cons(2).map{ |a, b| a + b }.to_a
end
とかだとちゃんと実行される模様。
f [1, 2, 3, 4, 5]
=> [3, 5, 7, 9]

mkutmkut 2012/02/26 00:12 def f(x)
x.each_cons(2).map{|y,z| yield(y,z)}
end
f [1, 2, 3, 4, 5] {|x, y| x + y}
で試してみてくださいな

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証