ab.com コミュニティ

ActiveBasicを通したコミュニケーション
現在時刻 - 2017年9月22日(金) 08:10

All times are UTC+09:00




新しいトピックを投稿する  トピックへ返信する  [ 2 件の記事 ] 
作成者 メッセージ
 記事の件名: いかに短く書くか
投稿記事Posted: 2008年8月09日(土) 20:19 
オフライン

登録日時: 2005年7月25日(月) 13:27
記事: 893
住所: 埼玉県東松山市
暇なので立ててみました。

目的
・コンパイラの限界とバグを知る
・短く簡潔に書く方法を学ぶ

ルール
・コンパイルが通る事
・正しいデータを渡した時、正しい結果を返す事
・あまりにも多くのメモリや時間を使わない事
・下記のような定義ファイルを除き、1つのファイルに全てを書くこと
[hide=・こんな内容の定義ファイルをインクルードしておいてください。]     Cや他の言語のライブラリで標準定義されているような関数は追加してもいいと思います。
コード:
'必ずインクルード元で
'Sub main(argc As Long,argv As **Byte)
'を定義する事。

#console

Declare Function PathGetArgsA Lib "shlwapi" (psz As *Byte) As *Byte
Declare Function atoi Lib "msvcrt" cdecl (buf As *Byte) As Long

_main()
Sub _main()
	Dim i As Long
	Dim argc As Long,argv As **Byte
	Dim CommandLine As *Byte

'コマンドラインの取得・整理
	CommandLine=GetCommandLine()
	argc=GetArgc(CommandLine)
	argv=calloc(argc*4)
	For i=0 To argc-1
		argv[i]=GetArgv(CommandLine,i)
	Next

'呼び出し
	main(argc,argv)

'解放
	For i=0 To argc-1
		free(argv[i])
	Next
	free(argv)
End Sub

'引数の総数を取得
'第一引数にコマンドライン文字列をぶち込む
Function GetArgc(CommandLine As *Byte) As Long
	Dim i=0 As Long,bufptr As *Byte
	GetArgc=1'呼び出し名含めかならず1つ以上ある筈
	bufptr=PathGetArgsA(CommandLine)
	Do
		If bufptr[i]=0 then
			If i then
				GetArgc++
				bufptr+=i
				i=0
			End If
			Exit Do
		ElseIf	bufptr[i]=10 Or bufptr[i]=32 Or bufptr[i]=40 Or bufptr[i]=44 Or bufptr[i]=47 Or _
				bufptr[i]=59 Or bufptr[i]=60 Or bufptr[i]=61 Or bufptr[i]=62 Or bufptr[i]=124 then'区切り文字
			GetArgc++
			bufptr+=i+1
			i=0
		Else
			i++
		End If
	Loop
End Function

'呼び出し名を取得する
'第一引数にコマンドライン文字列をぶち込む
'戻り値は自分でfreeする必要がある
Function GetArgv0(CommandLine As *Byte) As *Byte
	Dim i As Long
	If CommandLine[0]=34 then
		i=1
		Do
			If CommandLine[i]>=128 then'SHIFT-JIS文字対策
				i++
			ElseIf CommandLine[i]=34 then
				i++
				Exit Do
			ElseIf CommandLine[i]=0 then
				Exit Do
			End If
			i++
		Loop
	Else
		Do
			If CommandLine[i]>=128 then'SHIFT-JIS文字対策
				i++
			ElseIf	CommandLine[i]=0 Or CommandLine[i]=10 Or CommandLine[i]=32 Or _
					CommandLine[i]=40 Or CommandLine[i]=44 Or CommandLine[i]=47 Or _
					CommandLine[i]=59 Or CommandLine[i]=60 Or CommandLine[i]=61 Or _
					CommandLine[i]=62 Or CommandLine[i]=124 then'区切り文字
				Exit Do
			End If
			i++
		Loop
	End If
	GetArgv0=calloc(i+1)
	memcpy(GetArgv0,CommandLine,i)
End Function

'引数を取得する。
'第一引数にコマンドライン文字列をぶち込む
'戻り値は自分でfreeする必要がある
Function GetArgv(CommandLine As *Byte,ArgvIndex As Long) As *Byte
	Dim i As Long,bufptr As *Byte
	If ArgvIndex=0 then'呼び出し名を取得する場合
		GetArgv=GetArgv0(CommandLine)
		Exit Function
	ElseIf ArgvIndex<0 then'インデックスがおかしい
		Exit Function
	End If

	bufptr=PathGetArgsA(CommandLine)
	i=0
	Do
		If bufptr[i]=0 then
			If i then
				ArgvIndex--
				If ArgvIndex=0 then
					GetArgv=calloc(i+1)
					memcpy(GetArgv,bufptr,i)
					Exit Do
				End If
				bufptr+=i
				i=0
			End If
			Exit Do
		ElseIf bufptr[0]=34 then
			i=1
			Do
				If bufptr[i]>=128 then'SHIFT-JIS文字対策
					i++
				ElseIf bufptr[i]=34 then
					i++
					Exit Do
				ElseIf bufptr[i]=0 then
					Exit Do
				End If
				i++
			Loop
		ElseIf	bufptr[i]=10 Or bufptr[i]=32 Or bufptr[i]=40 Or bufptr[i]=44 Or bufptr[i]=47 Or _
				bufptr[i]=59 Or bufptr[i]=60 Or bufptr[i]=61 Or bufptr[i]=62 Or bufptr[i]=124 then'区切り文字
				ArgvIndex--
				If ArgvIndex=0 then
					GetArgv=calloc(i+1)
					memcpy(GetArgv,bufptr,i)
					Exit Do
				End If
			bufptr+=i+1
			i=0
		Else
			i++
		End If
	Loop
End Function

Sub putchar(a As Byte)
	Dim dwAccessBytes As DWord
	WriteFile(_System_hConsoleOut,VarPtr(a),1,VarPtr(dwAccessBytes),ByVal 0)
End Sub

Function getchar() As Byte
	Dim dwAccessBytes As DWord
	ReadFile(_System_hConsoleIn,VarPtr(getchar),1,VarPtr(dwAccessBytes),ByVal 0)
End Function
[/hide]・お題提供者はまず自分で簡単に作ったコードを投稿する(それが考えうる中での最短である必要はない)
・「TypeDefを定義ファイルに入れて3バイト短縮!」とかはしないでください

文字数の測り方は、
・上記のような定義ファイルをインクルードするための部分は無視
・改行コードは1バイト
・先頭のインデントは無視(ただし先頭以外の部分のスペースやタブ等は計算に含める)
でいきたいと思います。

例(おなじみのHello,World! 40バイト)
コード:
Sub main(a,b)
    Print"Hello,World!"
EndSub

_________________
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。


通報する
ページトップ
 記事の件名:
投稿記事Posted: 2008年8月09日(土) 20:29 
オフライン

登録日時: 2005年7月25日(月) 13:27
記事: 893
住所: 埼玉県東松山市
最初のお題は「brainfuckのインタプリタ」で
・メモリ空間は1000バイトくらいで
・AB424で動く事
[hide=サンプル]
コード:
Sub main(a As Long,b As **Byte)
	Dim o As *Byte,p As Long,l=1 As Long,m[999] As Byte,i As Long
	o=b[1]
	while o[l]<>0
		Select Case o[l]
			Case Asc("+")
				m[p]=m[p]+1
			Case Asc("-")
				m[p]=m[p]-1
			Case Asc(",")
				m[p]=getchar()
			Case Asc(".")
				putchar(m[p])
			Case Asc(">")
				p=p+1
			Case Asc("<")
				p=p-1
			Case Asc("[")
				If m[p]=0 then
					i=1
					while i<>0
						l=l+1
						If o[l]=Asc("[") then
							i=i+1
						Elseif o[l]=Asc("]") then
							i=i-1
						End If
					Wend
				End If
			Case Asc("]")
				If m[p]<>0 then
					i=1
					while i<>0
						l=l-1
						If o[l]=Asc("[") then
							i=i-1
						Elseif o[l]=Asc("]") then
							i=i+1
						End If
					Wend
					l=l-1
				End If
		End Select
		l=l+1
	Wend
End Sub
575バイト[/hide][hide=起動時入力のサンプル]DOS窓から入力。またはbatファイルにて
コード:
brainfuck.exe "+++++++++[>++++++++>+++++++++++>+++++<<<-]>.>++.+++++++..+++.>-.------------.<++++++++.--------.+++.------.--------.>+."
[/hide]自分で考えうる最短コードは364バイトです。

_________________
Website→http://web1.nazca.co.jp/himajinn13sei/top.html
ここ以外の場所では「暇人13世」というHNを主として使用。

に署名を書き換えて欲しいと言われたので暇だしやってみるテスト。


通報する
ページトップ
期間内表示:  ソート  
新しいトピックを投稿する  トピックへ返信する  [ 2 件の記事 ] 

All times are UTC+09:00


オンラインデータ

このフォーラムを閲覧中のユーザー: なし & ゲスト[1人]


トピック投稿:  可
返信投稿:  可
記事編集: 不可
記事削除: 不可
ファイル添付: 不可

検索:
ページ移動:  
cron
Powered by phpBB® Forum Software © phpBB Limited
Japanese translation principally by KONISHI Yohsuke