2010年09月03日 05:30 [Edit]
Algorithm - 0と1を次々と返す簡単なお仕事
ごもっとも。
0と1を次々返す方法 - a2c.get.diaryTrueだったらFalseで、FalseだったらTrueにしたい。
なんかそんなことそこかしこで必要で、その為の便利なものが
あるのかなぁと思ったんだけど無いぽい
Closure
本来は一番おすすめなのだが…
JavaScript
()が煩わしいが、perlやrubyよりは自然。
#!/usr/bin/js
var flipflop = function(p){
p = !p;
return function(){
return p = !p;
};
};
var fl = flipflop();
print(fl());
print(fl());
print(fl());
print(fl());
Perl
->()がわずらわしい。
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
sub flipflop{
my $p = !shift;
sub { $p = !$p }
}
my $fl = flipflop();
say $fl->();
say $fl->();
say $fl->();
say $fl->();
Ruby
callは煩わしいし[]はきしょい。
#!/usr/bin/ruby
def flipflop(p=false)
p = !p
Proc.new{ p = !p }
end
fl = flipflop()
puts fl.call
puts fl.call
puts fl[] # .call の代わりにOK
puts fl[]
Python
Pythonの鬼門はClosureかも知れない。なんとこれが動かない。
def flipflop(p=False):
p = not p
def ret():
p = not p
return p
return ret
fl = flipflop()
print fl()
print fl()
print fl()
print fl()
Python 3だと何とか書けるが…
def flipflop(p=False):
p = not p
def ret():
nonlocal p
p = not p
return p
return ret
fl = flipflop()
print(fl())
print(fl())
print(fl())
print(fl())
nonlocalがきしょい。
Class + Operator Overloading
Perl
実装はとにかく、利用はこれが一番自然かも知れない。
#!/usr/bin/perl
use 5.010;
use strict;
use warnings;
{
package FlipFlop;
use overload
'bool' => \&fetch,
'0+' => \&numify,
'""' => \&numify
;
sub new {
my $class = shift;
my $self = !shift;
bless \$self, $class;
}
sub fetch {
my $self = shift;
$$self = !$$self;
}
sub numify {
shift->fetch + 0;
}
}
my $fl = new FlipFlop;
say $fl;
say $fl;
say $fl;
say $fl;
python
bool()でキャストしなければならないのが煩わしい。
#!/usr/bin/python
class FlipFlop:
def __init__(self, v=False):
self.x = not bool(v)
def __nonzero__(self):
self.x = not self.x
return self.x
fl = FlipFlop()
print bool(fl)
print bool(fl)
print bool(fl)
print bool(fl)
print fl
ruby
puts oでo.to_sが暗黙で呼ばれるのと異なり、#to_boolに相当するメソッドが論理演算の時に暗黙で呼ばれるということはない。後述のYieldの例に似てしまう。
#!/usr/bin/ruby
class FlipFlop
def initialize(init=false)
@p = !init
end
def to_b
@p = !@p
end
end
fl = FlipFlop.new()
puts fl.to_b
puts fl.to_b
puts fl.to_b
puts fl.to_b
puts fl && true # false になってはくれない
Yield
python
実装は自然だが、next()がわずらわしい。
#!/usr/bin/python
def flipflop(p=False):
p = not not p
while True:
yield p
p = not p
fl = flipflop();
print fl.next();
print fl.next();
print fl.next();
print fl.next();
JavaScript 1.7(参考)
現状Firefox/SpiderMonkeyしかサポートしていない。
var flipflop = function(p){
p = !!p;
while(true){
yield p;
p = !p;
};
};
var fl = flipflop();
console.log(fl.next());
console.log(fl.next());
console.log(fl.next());
console.log(fl.next());
Macro
C
意外といける?
#define flip(p) !((p) = !(p))
void main(){
int p = 0;
printf("%d\n", flip(p));
printf("%d\n", flip(p));
printf("%d\n", flip(p));
printf("%d\n", flip(p));
}
回数を気にしなければこれでも。
#define flip(p) ((p)++ & 1)
void main(){
int p = 0;
printf("%d\n", flip(p));
printf("%d\n", flip(p));
printf("%d\n", flip(p));
printf("%d\n", flip(p));
}
簡単なお仕事だけあって、やり方も多すぎる…
Dan the Binary Blogger
追記
Perl
Re: Algorithm - 0と1を次々と返す簡単なお仕事 - TokuLog 改メ tokuhirom’s blogPerl5.10 なら state がつかえるから、以下のように書けるのではないか。#!/usr/bin/perl use 5.010; use strict; use warnings; use Test::More; sub flipflop { state $p = !shift; $p = !$p } ok !flipflop(); ok flipflop(); ok !flipflop(); ok flipflop(); done_testing;
stateを避けたのは、$pを共有したくない、要するにsingletonにしたくなかったから。要は
my $true1st = flipflop(1); my $false1st = flipflop(0);
としたかった、と。でもsingletonでいいならstateがベストプラクティスだと私も思う。
Python
@dankogai python版は__nonzero__ではなく__call__を定義すればboolにキャストする必要ないのでは。 QT: 404 Blog Not Found:Algorithm - 0と1を次々と返す簡単なお仕事 http://htn.to/bGWDnq
()が必要とはいえ、これが一番よさげ。
#!/usr/bin/python
class FlipFlop:
def __init__(self, v=False):
self.x = not bool(v)
def __call__(self):
self.x = not self.x
return self.x
fl = FlipFlop()
print fl()
print fl()
print fl()
print fl()
print fl
JavaScript
Re: Algorithm - 0と1を次々と返す簡単なお仕事 - 葉っぱ日記JavaScript で呼び出しの () が煩わしいなら、以下のように書けるのではないか。
というわけで少し改変。JSはこれで決定かな?
#!/usr/bin/js
var flipflop = function(p){
return {
p : 0,
valueOf : function(){ return this.p = !this.p; },
toString : valueOf
};
};
var fl = flipflop();
print(fl);
print(fl);
print(fl);
print(fl);
print(uneval(fl));
Posted by dankogai at 05:30│Comments(1)│TrackBack(9)
この記事へのトラックバックURL
この記事へのトラックバック
初トラックバックだ。 ブログ読んでたら0と1を次々と返したいなんていうのがあったのでやってみた。 Algorithm - 0と1を次々と返す簡単なお仕事 class Cycle(object): def __init__(self, vals=[0,1]): import itertools self.it = itertools.cycle(vals) def __call__(self
0と1を次々と返す【yanolabの日記】at 2010年09月03日 11:18
TrueだったらFalseで、FalseだったらTrueにしたい。 なんかそんなことそこかしこで必要で、その為の便利なものが あるのかなぁと思ったんだけど無いぽい。 0と1を次々返す方法 - a2c.get.diary Yield python 実装は自然だが、next()がわずらわしい。 404 Blog Not Found:Alg
[Python] Function that returns function that repeats boolean results【agwの日記】at 2010年09月03日 14:48
http://blog.livedoor.jp/dankogai/archives/51512419.html JavaScript で呼び出しの () が煩わしいなら、以下のように書けるのではないか。 #!/usr/bin/js var fl = { p : 0, valueOf : function(){ return this.p = !this.p; }, toString:valueOf }; print(fl); print(fl)
[JavaScript] Re: Algorithm - 0と1を次々と返す簡単なお仕事【葉っぱ日記】at 2010年09月03日 15:33
http://blog.livedoor.jp/dankogai/archives/51512419.html Perl5.10 なら state がつかえるから、以下のように書けるのではないか。 #!/usr/bin/perl use 5.010; use strict; use warnings; use Test::More; sub flipflop { state $p = !shift; $p = !$p } ok !flipflop();
Re: Algorithm - 0と1を次々と返す簡単なお仕事【TokuLog 改メ tokuhirom’s blog】at 2010年09月03日 15:35
Algorithm - 0と1を次々と返す簡単なお仕事にscheme版がなかったので、やってみた。 (define (make-flipflop p) (lambda () (set! p (not p)) p)) (define flfp (make-flipflop #f)) 実行。 gosh> (define (make-flipflop p) (lambda () (set! p (not p)) p)) make-flip
[プログラミング]Algorithm - 0と1を次々と返す簡単なお仕事 - scheme版【tmurataの日記】at 2010年09月03日 17:37
Algorithm - 0と1を次々と返す簡単なお仕事 なんとなくphpでも。 あんまりおもしろくないかな。 <?php function flipflop() { static $flipflop = false; $flipflop = !$flipflop; return $flipflop; } function printTrueOrFalse($p) { $str = $p ? "True¥n" ...
[プログラミング]Algorithm - 0と1を次々と返す簡単なお仕事 - php版【tmurataの日記】at 2010年09月03日 18:37
たまたま昨日クロージャを勉強したので書いてみた。 結果は同じようになってるけどあってるのかなぁ・・・? <?php $flipflop = function($p = false){ $p = !$p; return function() use (&$p) { return $p = !$p; }; }; $fl = $flipflop(); var_dump($fl()); var_d
[PHP]0と1を次々と返す簡単なお仕事を考えてみた【なげっぱなし日誌】at 2010年09月04日 10:46
Algorithm - 0と1を次々と返す簡単なお仕事 LLじゃないけど、C#でもやってみた。 using System; class FlipFlop { static void Main(string[] args) { Func<bool, Func<bool>> flipflop = f => () => {f = !f; return f;}; var ff = flipflop(false
[C#] FlipFlopワンライナー【espresso3389の日記】at 2010年09月05日 10:01
ネタ元:
a2c.get.diary ■[python] 0と1を次々返す方法
404 Blog Not Found - Algorithm - 0と1を次々と返す簡単なお仕事
すでに旬を過ぎたみたいだけど、C#で僕も書いてみました。
espresso3389の日記
で、espresso3389 さんが素晴らしいコードを紹介しているけど、...
falseとtrueを交互に返す簡方法(C#)【窓際プログラマーの独り言 -C#の話題を中心に】at 2010年10月04日 22:27
この記事へのコメント
ClosureのPythonですが、Python2.*でもそれっぽいものは書けます。きしょいことには変わりませんが。
def flipflop(p=False):
p = [not p]
def ret():
p[0] = not p[0]
return p[0]
return ret
Closureは確かにPythonの鬼門です。というかfunctional programmingそのものがPerlなんかに比べるとPythonの鬼門です。
def flipflop(p=False):
p = [not p]
def ret():
p[0] = not p[0]
return p[0]
return ret
Closureは確かにPythonの鬼門です。というかfunctional programmingそのものがPerlなんかに比べるとPythonの鬼門です。
Posted by eigonvalue at 2010年09月03日 20:12
