マッカーシー 91 関数

 McCarthy 91 function は次の計算式で定義される関数で、整数引数 n≦101 に対して 91 を返し、n>101 に対して n - 10 を返します。

定数の 1011 a+1100 関数が返す値を とすると

 a  N+1-y

で任意の整数値 を返す様に簡単に設定が出来ます。
の値はの値より大きく設定します。

n ≦ N+1 の時に設定した の値をかえします。

 プログラムには、再帰の上記計算式と、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.


download McCarthy_91_function.zip

  三角関数、逆三角関数、その他関数 に戻る