LoginSignup
35
13

More than 5 years have passed since last update.

(a == 1 && a == 2 && a == 3) を常に真にできますか?

Last updated at Posted at 2018-01-21

頭の体操のために作ってみました。
特に意味はありませんが、GitHubにリポジトリを上げました。

元ネタ: Can (a ==1 && a== 2 && a==3) ever evaluate to true?

他の言語の先駆者:

追記:
別の書き方を思いついたので載せておきます。
(a == 1 && a == 2 && a == 3) を常に真にできますか? その2

簡単なあらまし

元ネタのサイトにありますが、変数aを1にも2にも3にも等しくするということです。
一見すると訳が分かりませんが、これを疑似コードで表すと、次の通りです。

要約
if a == 1 && a == 2 && a == 3:
    print("True!")

解法として様々あるようです。

  • aをオブジェクトとして呼ばれる度にaの戻り値を変更する
  • aの後ろの半角スペースをハングルの半角スペースにすることで別の変数として処理する

僕の考えた最強の解法

自分で考えて、とりあえず実装してみた2つを紹介します。

シジルの変更によって全ての真偽値判定を真にする

シジルとは、スカラや配列を表す$@といった、Perlにおいて変数の種類を表すために、変数の前に付ける記号のことです。

Perl固有の書き方ができます。

by_changing_sigil.pl
use strict;
use warnings;

my $a = 1;
my @a = (1, 2);
sub a { 3 };

if ($a == 1 and @a == 2 and &a == 3) {
    print "True!\n";
}
実行結果
$ perl by_changing_sigil.pl
True!

元ネタではJavascriptが対象のため、Perlを用いる場合は変数aにシジルを付けなければなりません。

この時にシジルを変更することで、簡単に戻り値を変えることができます。

解説
$a == 1;
# 変数$aと1が等しい場合は真を返す。

@a == 2;
# 配列@aの要素数と2が等しい場合は真を返す。

&a == 3;
# 関数&aの戻り値と3が等しい場合は真を返す。

ちなみにand演算子で繋げていますが、&aが見づらくなるために変更しているだけで、&&でも同じ動作をします。

==演算子のオーバーロードによって全ての真偽値判定を真にする

overloadモジュールを使うことで、オブジェクトにおける演算子のオーバーロードができます。
これを利用して、==演算子による処理を変更します。

by_overloading_operator.pl
package AllEqualObject;

use overload
"==" => \&operator_eq;

sub new {
    my $self = shift;
    bless [@_], $self;
}

sub operator_eq {
    my $self = shift;
    return 1;
}

1;



package main;

use strict;
use warnings;

my $a = AllEqualObject->new;

if ($a == 1 && $a == 2 && $a == 3) {
    print "True!\n";
}
実行結果
$ perl by_overloading_operator.pl
True!

ここでは、AllEqualObjectのインスタンスで==を利用すると、operator_eq関数を呼出し、数値1を返します。
Perlにおいて数値1は真なので、$a == 1でも$a == 0でも$a == -1でも真を返します。

終わりに

小さいことですが、いろいろ勉強になりました。

ここまで読んでくださってありがとうございました!

もしおかしい点、気づいた点がありましたら教えてください。
特に、もっと面白い解法がある場合は教えてくれると嬉しいです!

35
13
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
35
13