マッカーシー 91 関数
McCarthy 91 function は次の計算式で定義される関数で、整数引数 n≦101 に対して
91 を返し、n>101 に対して n - 10 を返します。
定数の 10 を a 、11 を
a+1、 100 を N 関数が返す値を y
とすると
a = N+1-y
で任意の整数値 y を返す様に簡単に設定が出来ます。
Nの値はyの値より大きく設定します。
n ≦ N+1 の時に設定した y の値をかえします。
プログラムには、再帰の上記計算式と、while
文による計算の選択が出来るようになっています。
プログラム
// マッカーシー91関数 // M(n) = | n-10, if n>100 // | M(M(n + 11) if n<=100 // で定義されていて91の値を返しますが // M(n) = | n-a, if n>b // | M(M(a + 11) if n<=b // とすることa,bの定数値と与える事により任意の値を返すようにできます。 // a = b+1-y yが関数が返す値です。 unit Main; interface uses Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Buttons, Vcl.ExtCtrls; type TForm1 = class(TForm) Memo1: TMemo; LabeledEdit1: TLabeledEdit; BitBtn1: TBitBtn; BitBtn2: TBitBtn; LabeledEdit2: TLabeledEdit; Label1: TLabel; LabeledEdit3: TLabeledEdit; Label2: TLabel; RadioGroup1: TRadioGroup; procedure BitBtn1Click(Sender: TObject); procedure BitBtn2Click(Sender: TObject); procedure FormCreate(Sender: TObject); procedure RadioGroup1Click(Sender: TObject); private { Private 宣言 } public { Public 宣言 } end; var Form1: TForm1; implementation {$R *.dfm} var N :integer = 100; // McCarthy 91 function // x≦101のa=10場合91の値を返します。 // N の値が101 で91 201で191 301で291を返します。 // 関数が返す値をy <= N+1 とすると a = N+1-y でaの値を求めることが出来ます。 function McCarthy91(x, a: integer): integer; begin if x > N then result := x - a else result := McCarthy91(McCarthy91(x + a + 1, a), a); end; // 基本的に上記計算と同じです // cでフローの制御をしています function McCarthy91c(x, a, c: integer): integer; begin if c = 0 then result := x else begin if x > N then result := McCarthy91c(x - a, a, c - 1) else result := McCarthy91c(x + a + 1, a, c + 1); end; end; // 再帰を使用せず上記と同じ計算です function McCarthy91d(x, a, c: integer): integer; begin while c <> 0 do if x > N then begin x := x - a; c := c - 1; end else begin x := x + a + 1; c := c + 1; end; result := x; end; // 計算処理 procedure TForm1.BitBtn1Click(Sender: TObject); var x, a, y, ch, ans : integer; begin val(labelededit3.Text, N, ch); if ch <> 0 then begin application.MessageBox('N 入力値に間違いが有ります。', '注意', 0); exit; end; val(labelededit1.Text, x, ch); if ch <> 0 then begin application.MessageBox('x 入力値に間違いが有ります。', '注意', 0); exit; end; val(labelededit2.Text, y, ch); if ch <> 0 then begin application.MessageBox('答えy 入力値に間違いが有ります。', '注意', 0); exit; end; if y > N + 1 then begin application.MessageBox('答えy の値が大きすぎます。' + #13#10 + 'N+1 を越えない様にして下さい。', '注意', 0); exit; end; a := N + 1 - y; label2.Caption := 'a = ' + intTostr(a); ans := 0; case radiogroup1.ItemIndex of 0: ans := McCarthy91(x, a); // 再帰1 1: ans := McCarthy91c(x, a, 1); // 再帰2 2: ans := McCarthy91d(x, a, 1); // 再帰無し while end; if radiogroup1.ItemIndex = 0 then memo1.Lines.Append(intTostr(ans) + '= Mc91(' + intTostr(x) + ',' + intTostr(a) + ')' ) else memo1.Lines.Append(intTostr(ans) + '= Mc91(' + intTostr(x) + ',' + intTostr(a) + ', 1)' ); end; procedure TForm1.BitBtn2Click(Sender: TObject); begin memo1.Clear; case radiogroup1.ItemIndex of 0 : begin memo1.Lines.Append('function Mc91(x, a : integer): integer;'); memo1.Lines.Append('begin;'); memo1.Lines.Append(' if x > N then result:= x-a'); memo1.Lines.Append(' else'); memo1.Lines.Append(' result := Mc91(Mc91(x+a+1,a),a);'); memo1.Lines.Append('end;'); memo1.Lines.Append('y := Mc91(x, a);'); memo1.Lines.Append(''); end; 1 : begin memo1.Lines.Append('function Mc91(x, a, c: integer): integer;'); memo1.Lines.Append('begin'); memo1.Lines.Append(' if c=0 then result := x'); memo1.Lines.Append(' else begin'); memo1.Lines.Append(' if x>N then result := Mc91(x-a, a,c-1)'); memo1.Lines.Append(' else result := Mc91(x+a+1,a,c+1);'); memo1.Lines.Append(' end;'); memo1.Lines.Append('end'); memo1.Lines.Append('y := Mc91(x, a, 1);'); end; 2 : begin memo1.Lines.Append('function Mc91(x, a, c: integer): integer;'); memo1.Lines.Append('begin'); memo1.Lines.Append(' while c <> 0 do'); memo1.Lines.Append(' if x > N then begin'); memo1.Lines.Append(' x := x - a; c := c - 1;'); memo1.Lines.Append(' end'); memo1.Lines.Append(' else begin'); memo1.Lines.Append(' x := x + a + 1; c := c + 1'); memo1.Lines.Append(' end;'); memo1.Lines.Append(' result := x'); memo1.Lines.Append('end;'); memo1.Lines.Append('y := Mc91(x, a, 1);'); end; end; end; procedure TForm1.FormCreate(Sender: TObject); begin BitBtn2Click(nil); end; procedure TForm1.RadioGroup1Click(Sender: TObject); begin BitBtn2Click(nil); end; end.
McCarthy_91_function.zip
三角関数、逆三角関数、その他関数 に戻る