(x == x + 2)はいつですか?[閉まっている]


90

課題:x(x == x+2)が真と評価されるような方法で定義します。

質問にCのタグを付けましたが、創造的であるか、言語の興味深い側面を強調している限り、他の言語での回答も歓迎します。

Cのソリューションを受け入れるつもりですが、他の言語でも投票できます。

  1. 正しい-標準に準拠した実装で動作します。例外-基本型の実装を想定し、それが一般的な実装である場合(たとえば、int32ビット2の補数であると想定する)は問題ありません。
  2. シンプル-小さく、基本的な言語機能を使用する必要があります。
  3. 興味深い-主観的だと認めます。私が面白いと思うもののいくつかの例がありますが、私はヒントを与えたくありません。更新:プリプロセッサを避けることは興味深いです。
  4. クイック-最初の良い回答が受け入れられます。

60の回答を得た後(そのような参加を期待していませんでした)、それらを要約するのは良いかもしれません。

60の回答は7つのグループに分けられ、そのうち3つはCで実装でき、残りは他の言語で実装できます。

  1. Cプリプロセッサ。#define x 2|0提案されましたが、他の多くの可能性があります。
  2. 浮動小数点。大きな数、無限大またはNaNはすべて機能します。
  3. ポインター演算。巨大な構造体へのポインタにより、2を追加してラップアラウンドします。

    残りはCでは機能しません。

  4. 演算子のオーバーロード- +追加しない、または==常にtrueを返す A。
  5. 作成x(一部の言語はせずに、それを許可する関数呼び出しをx()構文)。その後、毎回何か他のものを返すことができます。
  6. 1ビットのデータ型。その後x == x+2 (mod 2)
  7. 変更2-一部の言語では、それに割り当てること0ができます。

29
なんで4. Quick?「誰でも知っていて、この質問を最初に読むのに十分な幸運な人」という意味ですか
リュック

6
@ugorenコミュニティに投票させて(そして自分の好きなものに自分で投票して)、7日かそこら後にトップアンサーを選択してください:)
Luc

3
可能性2について:NaN は機能しません。NaN + 2は再びNaNですが、NaN == NaNはfalseです。
マーティンB

2
Scalaソリューションは、xが「2」を含むSetであり、+はadd to Set標準ライブラリによるものであり、+自分自身を再定義せずに、これら7つのカテゴリ(IMHO)に適合しません。
ユーザー不明

2
なぜこの質問とすべての回答がコミュニティWikiなのですか?
mbomb007

回答:


71
main()
{
double x=1.0/0.0;
printf("%d",x==x+2);
}

出力1。

リンク:http : //ideone.com/dL6A5


7
float x=1./0少し短く、おそらくよりエレガントです。しかし、とにかく、これは確かに最初の良い答えです。
ウゴレン

1
ああ、古き良きゼロ除算。それを認めるよりも、理解するのに時間がかかりました。ハハ
グラント

ああ、私もこれについてですが、Windowsではコンパイルできないため、削除しました。:( +1-
チューダー

x = 1e999は、これを行う別の方法です。
潮ona

4
@shiona float x=1e20で十分
l0n3sh4rk

125

Fortran IV:

2=0

この後、プログラムのすべての定数2はゼロです。私を信じて、私はこれをやった(OK、25年前)


23
私がFortranに触れない理由はまだまだあります。
C0deH4cker 14年

3
少なくとも警告をスローしますか?
マイケルスターン14年

15
@MichaelStern警告:2の値を変更しています!
たけ

100

これはうまくいくようです:

#define x 2|0

基本的に、式はに展開され(2|0 == 2|(0+2))ます。マクロを定義するときに括弧を使用する必要がある理由の良い例です。


3
確かに動作し、私はそれが最もエレガントなプリプロセッサベースのソリューションだと思います。しかし、プリプロセッサなしでそれを行う方が面白いと思います。
ウゴレン

それは私だけか、すべきである2|(0+2)こと1
プネヘヘ

1
@phunehehe:|あるビット単位のORは||論理ORです。
プリーズスタンド

20
これはどういうわけか小さなボビーテーブルを思い出させます。
-vsz

1
@rakeshNS:演算子の優先順位を示すために、括弧の追加セットを追加しました。それが私が「基本的に」と言った理由です。
プリーズスタンド

79

ブレインファック

x

もちろん、Brainfuckでは実際に何も評価されないため、テープを操作するだけなので、これはもちろん「真に評価」されます。しかし、今あなたの表現を追加する場合

x
(x == x+2)

プログラムは次と同等です

+

(すべてが<>+-[],.コメントであるため)。これは、現在の値を増やすこと以外は何もしません。テープはすべてゼロで初期化されているため、カーソル位置で1になります。これは、「true」を意味し[]ます。


12
+1ルールを最も創造的に曲げる必要があります。
-ninjalj

3
なぜあなたは必要xですか?
ジェームズ

3
@James質問は定義するxように言っているので、ここでxはと定義されていxます。
user80551

1
答えはない@James need以外のものを+
たけ

56

F#

let (==) _ _ = true
let x = 0
x == (x + 2) //true

13
私はこれが好きです。数字をジャグリングする代わりに、==の意味を再定義するだけです
-evilcandybag

4
=ちょっと待ってください、F#の等値演算子ではありませんか?==デフォルトでは定義されていません。
ジョスティ14年

50

C

int main() { float x = 1e10; printf("%d\n", x == x + 2); }

注:次の場合は機能しない可能性がありFLT_EVAL_METHOD != 0ます(以下のコメントを参照)。


24
実際のアプリケーションでは+1。浮動小数点数学を理解していない人が多すぎます。
ティムS.

1
@ mbomb007:それらは異なると思います-あなたがリンクする答えはに依存していますがINF + 2 == INF、私の答えは、2が1 ULPより小さいほど十分に大きい単精度浮動小数点を使用しています。
ポールR

2
@ mbomb007:私も彼らは非常に異なっていると思います- ∞ + 2 = ∞誰もが理解できるものであり、コンピュータ固有のものには依存しませんが、具体的な数値に2を追加しても効果はありませんコンピュータ、およびより興味深い私見
-GoatInTheMachine

1
これはFLT_EVAL_METHOD == 1、数学がとして行われるときに、すぐに失敗しdoubleます。より大きなFP値をお勧めします。次のように、long double精度も必ず超えるようにしてください1.0e37f
chux

1
@chux:確認してくれてありがとう-私のコードの多くがクロスプラットフォームになるので、それは間違いなく将来的に注意する必要があるかもしれません。
ポールR

36

C#

class T {
  static int _x;
  static int X { get { return _x -= 2; } }

  static void Main() { Console.WriteLine(X == X + 2); }
}

ショーティーではありませんが、ややエレガントです。

http://ideone.com/x56Ul


4
この投稿の「いい答え」バッジを取得しました。真剣に、悪魔のバッジを手に入れましたか?!自宅でこれをしないでください
fjdumont

...それは悪だが、それはとても美しいです
ケビン・

32

Scala: { val x = Set(2); (x == x + 2) }


Haskell: eansでℤ/2ℤをBool定義:

instance Num Bool where
    (+) = (/=)
    (-) = (+)
    (*) = (&&)
    negate = id
    abs    = id
    signum = id
    fromInteger = odd

その後、x :: Bool私たちは持っているでしょうx == x + 2

更新:コメントのアイデアをありがとう、それに応じてインスタンスを更新しました。


3
あなたは簡素化することができます:fromInteger = odd
Rotsor

1
私が信じている(+)ように定義することもできます(/=)
MatrixFrog

2
より短い解決策は、のインスタンスを作成することです()
トーマスエディング

31

Python

class X(int):__add__=lambda*y:0
x=X()

# Then (x == x+2) == True

いいね 演算子のオーバーロードをサポートするすべての言語は同様のソリューションを使用できますが、Cはそれらの1つではありません。
ウゴレン

オーバーロード__cmp__としても機能しますclass X(int):__cmp__=lambda*x:0(または__eq__少し長いですがclass X(int):__eq__=lambda*x:True
ジンボブ博士12

intから拡張しない場合は数文字短くなります。class X:__add__=lambda s,o:s
Doboy

その掛け算が何をするのか尋ねてもいいですか?
seequ 14年

2
@TheRareそれは実際には乗算ではありません。__add__通常は複数の引数(lambda x,y:)が与えられるため、*を使用してすべての引数をタプル(lambda *y:)にパックすることにより、いくつかの文字を保存します。詳細については、ドキュメントを参照してください。
GRC

31

GNU Cは、メンバーがなくサイズ0の構造をサポートします。

struct {} *x = 0;

2
非常に素晴らしい!ラップアラウンドにつながる非常に大きなデータを使用したポインター演算について考えましたが、逆のことは考えませんでした。
ウゴレン

26

PHP:

$x = true;
var_dump($x == $x+2);

または:

var_dump(!($x==$x+2));

出力:

bool(true)


1
私は実際、この非常に単純なPHPの答えを考え出そうとしていましたが、あなたはそれに私を打ち負かしました。
プリーズスタンド

25

Cでは、空白は問題にならないというのはよくある誤解です。GNU Cで誰かがこれを思いついていないとは想像できません:

#include <stdio.h>
#define CAT_IMPL(c, d) (c ## d)
#define CAT(c, d) CAT_IMPL(c, d)
#define x CAT(a, __LINE__)

int main()
{
    int a9 = 2, a10 = 0;
    printf("%d\n", x ==
        x + 2);
    return 0;
}

印刷し1ます。


ニースですが、おそらく技術的には有効ではありません(x == x+2まだ間違っています)。しかし、一度アイデアを持ち出せば、#define x -2*__LINE__もっとエレガントになると思います。
ウゴレン

3
@ugorenありがとう!これをすべて1行にしたい場合は、LINEではなくCOUNTERを使用します-ただし、GCC 4.3以降が必要です。
H2CO3

1
_CAT予約済みの識別子です。下線で始まり、そして大文字はCで予約されている何か
コンラッドボロウスキ

UBを削除するように更新された@xfix
H2CO3 14

20

C

マクロを使用せず、無限を乱用することなく、より興味深いです。

/////////////////////////////////////
// At the beginning                 /
// We assume truth!                 /

int truth = 1;
int x = 42;

/////////////////////////////////////
// Can the truth really be changed??/
truth = (x == x + 2);

/////////////////////////////////////
// The truth cannot be changed!     /
printf("%d",truth);

信じられないなら試してみてください!


1
0。いいえ、まだ信じられません。
–MSalters

@MSalters:どのコンパイラを使用していますか?トライグラフが無効になっている場合があります。
-vsz

VS2010。トライグラフはデフォルトで無効になっている可能性があります。それまたは行連結のいずれかで動作しません??\
-MSalters

MSalters:トライグラフ??\ は単一\ に変換されるため、ありません??\ 。ただし、一部の最新のコンパイラは、有効になっている場合でも、デフォルトで3文字表記と行連結の両方に警告を出します。
-vsz

18

Mathematica:

x /: x + 2 := x
x == x + 2

このソリューションはMathematicaの Up Values 概念を使用しているため、斬新だと思います。

編集:

Mathematicaで Up Valuesの意味を説明するために、答えを広げています。

最初の行は、シンボルの追加を本質的に再定義しますx+シンボルに関連付けられているグローバル関数にそのような定義を直接保存することもできますが、そのような再定義はMathematicaの組み込みアルゴリズムを介して予期せず伝播する可能性があるため危険です。

代わりに、タグを使用してx/:、定義をシンボルに関連付けましたxMathematicaはシンボルを見るたびに、シンボルが他のシンボルの可能なヌルシーケンスを意味する形式のパターンでx加算演算子によって操作されているかどうかをチェックします。+x + 2 + ______

この再定義は非常に具体的であり、Mathematicaの広範なパターンマッチング機能を利用しています。たとえば、式x+y+2はを返しますx+yが、式x+3x+3;を返します。前者の場合、パターンは一致する可能性がありますが、後者の場合、追加の簡略化なしではパターンを一致させることができないためです。


1
私はあなたがそれが何をするのか説明すべきだと思います。ほとんどの人はMathematica(またはUp Valuesとは何か)を知りません。
ウゴレン

1
@ugorenに感謝します。私はほとんどの時間をMathematica Stack Exchange Webサイトに費やしているので、例が意味のあるものである理由を説明するのを忘れました。コンセプトをできる限り簡潔に説明する編集を行いました。
カールモリス

17

Javascript:

var x = 99999999999999999;
alert(x == x+2);​

テストフィドル


2
Infinityまたはを使用-Infinityできますx = 1/0。このため、のショートカットを使用できます。
zzzzBov

6
@zzzzBov:それは間違いなく優れたコードゴルフです。私が選んだ(99999999999999999 == 99999999999999999+2)、私はそれがよりも少し面白いと思うので、(Infinity == Infinity+2)OPは:)「それは主観的だ」、と言うようものの、
Briguy37

これは、正当な理由(プログラミングの謎以外)でこのようなチェックを見た唯一の実世界のケースです:(フロートベースの)教員機能は、カウントダウンして-1再帰するには大きすぎるために入力をチェックしていました。言語自体はPythonでしたが、この場合はそれほど問題ではありません。
アルフェ

5
@NicoBurns not ture :(
ajax333221

2
@NicoBurns、そのコードをコンソールで実行するとfalse、; JSの情報がどこで得られても、それは間違っており、信頼すべきではありません。
zzzzBov

17

スキーム

(define == =)
(define (x a b c d) #t)
(x == x + 2)
;=> #t

いいね Scheme (x == x + 2)はCのように見えますが、まったく異なることを意味します。
ウゴレン

1
今のためにしてください(= x 2)
ジョーZ。13年

(define (x a b c d) #t):)
ランチャー14

@ugorenこれは、このプログラムでこれを行うために定義されています。ここでxは単に関数の名前です。==
ランチャー14


16

ここで利用しないJavaScriptのためのソリューションであるInfinity-Infinity浮動小数点加算のエッジケースは。これは、Internet Explorer 8以下でも、オプトインES5厳格モードでも機能しません。私はwith声明とゲッターを特に「高度な」機能とは呼びません。

with ({ $: 0, get x() {return 2 * this.$--;} }) {
    console.log(x == x+2);
}

:追加するには、編集上のトリックは使用しないでも可能であるwithgetによって示されるように、アンディEJavaScriptでのゴルフのためのヒントともでjncratonこのページ:

var x = { $: 0, valueOf: function(){return 2 * x.$++;} };
console.log(x == x+2);

良いコンセプト- x変数呼び出しのように見えますが、関数呼び出しになります。左から右への評価順序を想定していますが、JSで指定されているため(Cとは異なり)大丈夫です。
ウゴレン

14

以下は標準に準拠したCではありませんが、ほぼすべての64ビットプラットフォームで動作します。

int (*x)[0x2000000000000000];

原則として素晴らしいですが、間違って実装されているようです。xは2 ^ 61のステップでインクリメントされるため、x + 8に等しくなりxます。
ウゴレン

@ ugoren、4バイトのLinuxで動作しますint
ハン

あなたは絶対に正しい。配列でintはなく、配列であるという事実を見逃しましたchar
ウゴレン

10

セージ:

x=Mod(0,2)
x==x+2

Trueを返します

一般に、GF(2 ** n)の場合、任意のxに対してx = x + 2が常に真です

これはバグやオーバーフローや無限大の問題ではなく、実際には正しいです


1
同じトリックがPARI / GPでも機能する
ハーゲンフォンアイゼン

10

Common Lisp

* (defmacro x (&rest r) t)
X
* (x == x+2)
T

x実際の値である必要がない場合は、非常に簡単です。


8

APL(ダイアログ)

X←1e15
X=X+2

APLも、それがフロートの間の違いを伝えるには十分正確ではないだけということですが、無限大を持っていない1.000.000.000.000.0001.000.000.000.000.002。私の知る限り、これがAPLでこれを行う唯一の方法です。


浮動小数点の精度を活用するための最初の答えだからです。
-AndrewKS

1
@AndrewKS:実際、ポールRは少し早かった。
MSalters

8

Perl 6

以前にこの解決策を見なかったことに驚いています。とにかく、解決策がある-どのような場合xである02同時に?my \xこの例ではsigilless変数を宣言しています-この質問はx、Perlスタイルではなく質問$xです。?? !!三項演算子です。

$ perl6 -e 'my \x = 0|2; say x == x + 2 ?? "YES" !! "NO"'
YES

しかし...

$ perl6 -e 'my \x = 0|2; say x == x + 3 ?? "YES" !! "NO"'
NO

x一度に複数の値です。xに等しい02すぐに。x + 2に等しい24すぐに。したがって、論理的には同等です。


8

Python 2.X((キャッシュされた)整数の再定義を使用)

私はすべてのPythonの答えが+演算子を再定義するクラスを定義していることに気付きました。pythonの柔軟性のさらに低レベルのデモンストレーションで答えます。(これはpython2固有のスニペットです)

Pythonでは、整数はCで多かれ少なかれこの方法で保存されます:

typedef struct {            // NOTE: Macros have been expanded
    Py_ssize_t ob_refcnt;
    PyTypeObject *ob_type;
    long ob_ival;
} PyIntObject;

それは、持つ構造体であるsize_tvoid *longその順序で、オブジェクト。
我々が使用するので、整数をキャッシュしたら、私たちは、Pythonの使用できるctypesようにするだけでなく、その整数を再定義するモジュールをx == x+2、しかし、2 == 0

import ctypes
two = 2 # This will help us access the address of "2" so that we may change the value

# Recall that the object value is the third variable in the struct. Therefore,
# to change the value, we must offset the address we use by the "sizeof" a 
# size_t and a void pointer
offset = ctypes.sizeof(ctypes.c_size_t) + ctypes.sizeof(ctypes.c_voidp)

# Now we access the ob_ival by creating a C-int from the address of 
# our "two" variable, offset by our offset value.
# Note that id(variable) returns the address of the variable.
ob_ival = ctypes.c_int.from_address(id(two)+offset)

#Now we change the value at that address by changing the value of our int.
ob_ival.value = 0

# Now for the output
x = 1
print x == x+2
print 2 == 0

プリント

True
True

7

Perl

パッケージ変数に副作用のあるサブルーチンを使用する:

sub x () { $v -= 2 }
print "true!\n" if x == x + 2;

出力: true!


1
sub x{}同様..(少なくとも私の5.10.1で)「作品」が、私は、なぜ..理解できない
mykhal

2
なぜならsub x{}、undefまたは空のリストを返すからです。どちらも数値のゼロです。そして、x + 2はx(+2)として解析されます。perl -MO=Deparse明らかにprint "true\n" if x() == x(2);
ペルレオーネ

@mykhalと@Perleoneです!
メモ

7

Python

浮動小数点の精度を活用すると、これが非常に簡単になります。

>>> x = 100000000000000000.0
>>> (x == x+2)
True

システム固有性を低くするには、追加のインポートが必要です

>>> import sys
>>> x = float(sys.maxint + 1)
>>> (x == x+2)
True

これは他の言語でも機能するはずです。100000000000000000.0と100000000000000002.0の表現がマシン内でまったく同じであるため、これは機能します。これは、マシン内での浮動小数点の表現方法のためです。詳細については、http://en.wikipedia.org/wiki/IEEE_floating_pointを参照してください。

したがって、これは基本的に、整数を浮動小数点数に追加し、その結果を浮動小数点数にすることができる任意の言語で機能します。


6

以下は、演算子のオーバーロードに基づいたC ++のソリューションです。それはからの暗黙的な変換に依存しているenumint

#include <iostream>

enum X {};
bool operator==(X x, int y)
{
    return true;
}

int main()
{
    X x;
    std::cout << std::boolalpha << (x == x+2) << std::endl;
    return 0;
}

std::boolalpha代わりに使用できます?:
ジョンパーディ

5

私はそれがコードの挑戦であることを知っています...しかし、私はそれをゴルフしました。ごめんなさい。

Ruby-13文字-Infinityソリューション

x=1e17;x==x+2

trueを返します

Ruby-41文字-Opオーバーロードソリューション

class Fixnum;def + y;0 end end;x=0;x==x+2

または

class A;def self.+ y;A end end;x=A;x==x+2

5

質問を少し悪用しても問題ない場合は、新しいJavaを追加します。トリックは確かに新しいものではありませんが、おそらくJavaでこれが可能であることは興味深いでしょう。

static void pleaseDoNotDoThis() throws Exception {
    Field field = Boolean.class.getField("FALSE");
    field.setAccessible(true);
    Field modifiersField = Field.class.getDeclaredField("modifiers");
    modifiersField.setAccessible(true);
    modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
    field.set(null, true);
}

public static void main(String args[]) throws Exception {
    pleaseDoNotDoThis();
    doit(1);
    doit("NO");
    doit(null);
    doit(Math.PI);
}

static void doit(long x) {
    System.out.format("(x == x + 2) = (%d == %d) = %s\n", x, x+2, (x == x + 2));
}

static void doit(String x) {
    System.out.format("(x == x + 2) = (%s == %s) = %s\n", x, x+2, (x == x + 2));
}

static void doit(double x) {
    System.out.format("(x == x + 2) = (%f == %f) = %s\n", x, x+2, (x == x + 2));
}

そして結果:

(x == x + 2) = (1 == 3) = true
(x == x + 2) = (NO == NO2) = true
(x == x + 2) = (null == null2) = true
(x == x + 2) = (3,141593 == 5,141593) = true
(x == x + 2) = (Infinity == Infinity) = true

4

このVBScriptソリューションは、私のJavaScriptソリューションと同様に機能します。私はプリプロセッサを使用しませんでしたが、解決策は簡単なようです。

y = 0
Function x
x = y
y = -2
End Function

If x = x + 2 Then
    WScript.Echo "True"
Else
    WScript.Echo "False"
End If

私はあなたと同じソリューションをルビーに投稿するつもりでした。あなたのソリューションを見るまでは、両方の言語で括弧の省略が許可されているため可能です。
ワルドランプ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.