「+」を使わずに足し算する術。

今日も、FX とは無関係な話なので、プログラミングされない人は読み飛ばし推奨です。


将棋の世界では、「2枚落ち」と言って、飛車・角を抜いて勝負する形態があり、麻雀には、「二飜縛り」という二飜以上の役がないと和了できないとするルールがあります。このコンセプトをプログラミングの世界に持ち込むとどうなるか?考えてみました。


まず思いついたのが、「足し算縛り」。足し算記号の「+」を使わずにプログラムが書けたら勝ち..というパズル??です。

int a = 3,b = 5;
Print( a + b );

↑このプログラムを「+」を使わないで計算するようにしてください。


「+」を「-」にして、b に -1 を掛ける…等、いろいろな書き方が有り得るので正解の1例を示すと以下のようになります。お暇な人は、「+」が何処にも無いのに足し算できていることを確認してみてください。

int a = 3,b = 5;
Print( Add_(a,b) );

int Add_(int a,int b)
{
   int c = ( a & b ) << 1;
   if(c == 0){
      return(a | b);
   }
   return( Add_(a ^ b,c));
}

実は、これはパズルでもなんでもなくて、ビット演算の組合せで整数の足し算を表現しただけです。CPU の内部で行われている足し算のようなモノだと思えばOKです。


続いて、「掛け算縛り」の例です。

int a = 3,b = 5;
Print( a * b );


内部で使用する足し算関数 Add は、上で使った再帰的な Add_ でも構わないのですが、せっかくなので while ループで求める例を入れています。

int a = 3,b = 5;
Print( Multi(a , b) );

int Add(int a,int b)
{
   int c;
   while((a & b)!=0){
      c = ( a & b) << 1;
      b = b ^ a;
      a = c;
   }
   return(a | b);
}

int Multi(int a,int b)
{
   int d=0;
   while(b!=0){
      if(b & 1 !=0) d = Add(d,a);
      a = a << 1;
      b = b >> 1;
   }
   return(d);
}

そんな足し算や掛け算をややこしく書いて何の意味があるの?と思われるのは当然ですが、逆に考えると、素人には何の計算をしているのか意味不明に見えるようにする効果があるのではと思ったりします。例えば、以下の計算式です。

int g=0;
int start()
{
   int x=-2,y=-15;g=1;
   int z = SuperSolenoid(x,y,z);
   Alert(z);
}

int SuperSolenoid(int a,int b,int c,int d=0)
{
   while(b!=0){
      if(b & g !=0){
         int a1,b1,c1;
         a1 = d;
         b1 = a;
         c1 = c;
         while((a1 & b1)!=0){
            c1 = ( a1 & b1) << g;
            b1 = b1 ^ a1;
            a1 = c1;
            c1 = c1 & b1;
         }
         d = a1 | b1;
      }
      a = a << g;
      b = b >> g;
      c = c << g;
   }
   return(d);
}

これはスーパーソレノイド理論を実装した唯一最強のEAです。なんて説明されたら、ころっと騙されてしまう人が大半のではないかと思うのです。
元の計算ロジックは下枠内に書いてあります。

int start()
{
int x=-2,y=-15;
int z = x*y;// ただの掛け算!
Alert(z); // Add と Multi の組合せにダミーの計算を混ぜています。
} //

くれぐれも変なコードを書くプログラマには用心しましょう。笑。