CUBE

CUBEに閉じ込められた人が脱出する話
CUBE ZEROを見た後に見返したことはなかったハズ
確か脱出後にあなたは神を信じますか?って聞かれていいえと答えたらハズレなんだったっけ?



因数分解をするのが天文学的な数字よっていうので、てっきり9桁の数字の因数分解だと思ってた
見返してみたら3桁の数字の因数分解やないか
時間かかるけどできんじゃない?
っていうか、できないで数学少女はどうやって素数かどうか判断してたの?
3桁の素数くらい暗記しているってなら、それはそれで変態だ
仮に素数を暗記してるんなら、合成数の場合は素数のべき乗だけ考えればいいんだし、やっぱりできると思う

switch対応 その2

型によるcase式に対応できた
参照型変数は「ldloc→isinst→ldnull→cgt.un」でいいんだけど値型変数だとうまくいかない
結局、値型変数は「ldloc→box→isinst→ldnull→cgt.un」にした
boxが出てくるのはどーよって気がしなくもないけど、まぁいっか

f:id:zenu:20171010212115p:plain

しかし、caseとその後ろの式の区切りに「:」を使ったのは失敗だったかなぁ
ほかんところはPascal式の「var n: Int」なのにcase部分だけコロンが使えないせいでC式?の「Int n」っちゅー不思議文法になってしまった

caseと式の区切りの記号は何がいいだろう
イコールはすっげー気持ち悪いしな、Haskellのガードとか
矢印かなー、こんな感じの

switch x
	n: Int    => print("Int")
	s: String => print("String " + s)
	h: Hoge   => print(h.i)

ゾンビーワールドへようこそ

高校生にもなってスカウトやっているってバカにされてる子達が秘密のパーティーに誘われる
キャンプを抜け出し街に戻るけど人がいない
ストリップ店に忍び込んだらZに襲われウェイトレスに助けられる
教えてもらったパーティ会場はウソだったけど、姉を助けるためにパーティー会場を探し助けに行く
ホームセンターで武装をしZをやっつける


ところどころギャグとお色気挟んでくるけどよくできている
ストリップ姉ちゃんZの血管とか

パンドラム

宇宙船でコールドスリープから目覚めたら記憶障害で自分だけ
すぐ中尉が起きるけど同じく記憶障害
ブリッジに行こうとするけどスカイリムのファルマーみたいな怪物がうろついてて襲われる
女と言葉の通じない農夫とであって原子炉を再起動しに行く
途中でコックに捕まり地球が消し飛び狂ったクルーが残った人を皆殺しにした話を聞く
原子炉を再起動するけどファルマーの巣になってるので追いかけられる
中尉が狂ったクルーだったことが分かり、ついでに移住先の星についてるけど海に不時着し水没していることを知る
中尉と戦っている時に船を傷つけてしまい緊急脱出し地上に出られる


どう見てもファルマーやん

ソースコードに行番号

はてなブログのデザインとやらを弄ってソースコードに行番号を付けてみた
わりかしなんでも書けるのね、知らなかった
テーマ?変更したらええんかと思って色々変えてよく分かんなくなったけど
結局自分で書いた方が早いや(^^;

main = putStrLn "Hello World!"
<script>
var codes = document.getElementsByClassName("code");
for(var i = 0; i < codes.length; i++)
{
	var lines = codes[i].innerHTML.split("\n");
	var code = "";
	for(var j = 0; j < lines.length; j++)
	{
		if(j == lines.length - 1 && lines[j] == "") break;
		code += "<code>" + lines[j] + "</code>\n";
	}
	codes[i].innerHTML = code;
}
</script>
pre.code > code
{
    counter-increment: linenumber;
}

pre.code > code::before
{
    content: counter(linenumber) "|  ";
}

行番号との間の縦線が書けなくて適当やわ

switch対応

switch文に対応してみた
まだswitchは式にできてないので戻り値は返せないけども

とりあえず[x, xs]のxs部分にcdr相当を渡したいんだけど
めっちゃめんどくさいので単純に配列をGetRangeしてコピーすることにした
GetRangeはご丁寧にもMSDNにO(n)っすよって書いてあるけど、もうほんとめんどくさいしいいや

f:id:zenu:20170924230018p:plain

コンパイルした結果がこれ
わらっちゃうくらいザツい(^-^;

.method public static void  switch.show(class [mscorlib]System.Collections.Generic.List`1<int32> A_0) cil managed
{
  // コード サイズ       96 (0x60)
  .maxstack  7
  .locals init (int32 V_0,
           bool V_1,
           int32 V_2,
           int32 V_3,
           class [mscorlib]System.Collections.Generic.List`1<int32> V_4)
  IL_0000:  ldarg.0
  IL_0001:  call       instance int32 class [mscorlib]System.Collections.Generic.List`1<int32>::get_Count()
  IL_0006:  stloc.0
  IL_0007:  ldloc.0
  IL_0008:  ldc.i4.0
  IL_0009:  ceq
  IL_000b:  stloc.1
  IL_000c:  ldloc.1
  IL_000d:  brtrue     IL_0017

  IL_0012:  br         IL_001c

  IL_0017:  br         IL_005f

  IL_001c:  ldloc.0
  IL_001d:  ldc.i4.1
  IL_001e:  clt
  IL_0020:  ldc.i4.0
  IL_0021:  ceq
  IL_0023:  stloc.1
  IL_0024:  ldloc.1
  IL_0025:  brtrue     IL_002f

  IL_002a:  br         IL_005f

  IL_002f:  ldarg.0
  IL_0030:  ldc.i4.0
  IL_0031:  call       instance !0 class [mscorlib]System.Collections.Generic.List`1<int32>::get_Item(int32)
  IL_0036:  stloc.2
  IL_0037:  ldloc.0
  IL_0038:  ldc.i4.1
  IL_0039:  sub
  IL_003a:  stloc.3
  IL_003b:  ldarg.0
  IL_003c:  ldc.i4.1
  IL_003d:  ldloc.3
  IL_003e:  call       instance class [mscorlib]System.Collections.Generic.List`1<!0> class [mscorlib]System.Collections.Generic.List`1<int32>::GetRange(int32,
                                                                                                                                                         int32)
  IL_0043:  stloc      V_4
  IL_0047:  nop
  IL_0048:  nop
  IL_0049:  ldloc.2
  IL_004a:  call       void [mscorlib]System.Console::WriteLine(int32)
  IL_004f:  ldloc      V_4
  IL_0053:  nop
  IL_0054:  nop
  IL_0055:  call       void switch.show(class [mscorlib]System.Collections.Generic.List`1<int32>)
  IL_005a:  br         IL_005f

  IL_005f:  ret
} // end of global method switch.show

.NETのYieldが何をしているか

.NETのYieldがどんなふうにILを出力してるんか調べてみた
VBだけ調べたけどC#も多分一緒だろう
割とcall/ccするのめんどいな

1. Yieldの付いた関数毎にIEnumeratorなクラスを作る、とりあえずStateMachineと呼ぶ
2. Yieldの付いた関数の引数、ローカル変数を全部メンバ変数に持つ
3. 戻り値と状態もメンバ変数に持つ
4. Yieldの出現箇所にユニークな連番を振る
5. Yieldしている個所の前で次のことをする
・Yieldの値を戻り値のメンバ変数に入れる
・4.で付けたユニークな番号を状態のメンバ変数に入れる
・Return Trueしとく
・Returnの後にユニークな番号に対応したラベルを張る
6. 関数を抜けるときに次のことをする
・最終行でっせというラベルを張る
・状態のメンバ変数に最終行でっせという値を入れる
・Return Falseする

' 呼び出し側
For Each x In Cdr(xs)
    ' なんか処理
Next

Public Shared Iterator Function Cdr(xs As List(Of Integer))
	For i = 1 To xs.Count - 1
		Yield xs(i)
	Next
End Function' 呼び出し側
For Each x In New StateMachine With {._xs = xs}
    ' なんか処理
Next

' Yieldの関数展開結果
Class StateMachine
	Implements IEnumerator

	Private _i As Integer
	Private _xs As List(Of Integer)
	
	Private _value As Integer
	Private _state_machine As Integer = 0
	
	Public ReadOnly Property Current() As Boolean
		Get
			Return _value
		End Get
	End Property
	
	Public Function MoveNext() As Boolean
		
		If _state_machine = 1 Then Goto __STATE1
		If _state_machine = 2 Then Goto __STATE2
		
		_i = 1
		Do While _i <= _xs.Count - 1
			
			_value = _xs(_i)
			_state_machine = 1
			Return True
			__STATE1:
			
			_i += 1
		Loop
		
		__STATE2:
		_state_machine = 2
		Return False
	End Function
End Class

簡単にcdrするILの関数書きたいだけなんだけど難しいなー・・・