パリティを交換する


22

仕事

正の整数が与えられた場合n、出力n+1if nは奇数、出力n-1if nは偶数です。

入力

正の整数。整数は言語の処理能力の範囲内であると想定できます。

出力

上記で指定された正の整数。

テストケース

input output
    1      2
    2      1
    3      4
    4      3
    5      6
    6      5
    7      8
    8      7
  313    314
  314    313

得点

これはであるため、バイト単位の最短回答が優先されます。

標準の抜け穴が適用されます。

参照資料


入力を単項として受け取ることはできますか?
Kritixiリソス

2
これは、驚くべきことに、一部の言語で逆になればはるかに簡単になります
-MildlyMilquetoast

3
@MistahFigginsこれは十分に知られているので、OPは意図的にこのようにしたと確信しています。
Ørjanヨハンセン

回答:


24

C、20バイト

f(x){return-(-x^1);}

オンラインでお試しください


7
@LeakyNun私はreturnステートメントのない関数を書いていません。
-feersum

18
@EriktheOutgolferいいえ。うん いいえ
-feersum

10
@Sisyphusしかし、これはcode-golfであり、TIOリンクで機能するため、有効です。
エリックアウトゴルファー

7
@EriktheOutgolfer私が言っているのは、あなたの声明(「最初の引数への代入はreturn文と同等」)が事実上間違っているということです。そのようなコードが特定の状況で有効な回答を生成するかどうかは別の質問です(最初のコメントで、そのようなコードを投稿しないことを表明することで対処しました)。
-feersum

8
@EriktheOutgolfer回答が実装固有の動作に依存している場合、実装を指定する必要があります。この答えはそうではないので、そのコードは無効になります。
シーシュポス

17

スタック猫、3 + 3(-n)= 6バイト

-*-

オンラインでお試しください!

-n数値の入力および出力で機能するフラグが必要です。

説明

Stack Catsは通常、コマンドセットが限られているため(すべてインジェクションであり、ほとんどがインボリューションです)、すべてのプログラムがミラー対称性を備えている必要があるため、競争力はありません。ただし、インボリューションの1つは、数値の最下位ビットを切り替えることです。また、存在する単項否定で値をオフセットできます。幸いなことに、これにより対称的なプログラムが提供されるため、他のことを心配する必要はありません。

-   Multiply the input by -1.
*   Toggle the least significant bit of the value (i.e. take it XOR 1).
-   Multiply the result by -1.

入力の取得と出力の生成は可逆操作ではないため、入力と出力はプログラムの最初と最後で暗黙的に行われるため、コマンドにすることはできません。


1
フラグは常に追加のスペースでカウントされますか?(Perlのような)フラグを使用して他の答えを見たことはないと思いますか?編集:OK nvm、関連するメタ投稿を見つけました。「これらを使用しない最短の同等の呼び出しに対する文字カウントの違いとしてそれらをカウントします。「...」perl -nle 'stuff'は、2文字よりも多いためperl -e 'stuff'、さらに2文字をカウントします。」だから、(space)-n3バイト以上のフラグがない場合よりもです。
ケビンCruijssen

@KevinCruijssenこれは、通常の呼び出しに実際に追加する必要があるバイト数によって異なります。Perlおよび他の多くの実稼働言語では、でコードを呼び出して-e "code"から、eなどの前に追加のフラグを挿入でき-pe "code"ます。その場合、-pフラグは1バイトのみです。ただし、Stack Catsにはそのような-e引数がないため、常に<sp>-nコマンドにフルを追加する必要があるため、3バイトになります。
マーティンエンダー

12

x86アセンブリ、9バイト(競合するエントリ用)

高級言語でこの課題を試みている人は誰でも、生のビットを操作する本当の楽しみを逃しています。これを行う方法には非常に多くの微妙なバリエーションがありますが、それは非常識であり、考えるのはとても楽しいです。32ビットx86アセンブリ言語で考案したいくつかのソリューションを以下に示します。

これが典型的なコードゴルフの答えではないことを事前に謝罪します。繰り返し最適化(サイズ)の思考プロセスについて多くのことを取り上げます。それがより多くの聴衆にとって興味深く、教育的であることを願っていますが、もしあなたがTL; DRタイプなら、最後までスキップしても気にしないでしょう。

明白で効率的な解決策は、値が奇数か偶数かをテストし(最下位ビットを調べることで効率的に実行できます)、それに応じてn + 1またはn-1を選択することです。入力がECXレジスタのパラメータとして渡され、結果がEAXレジスタに返されると仮定すると、次の関数が得られます。

F6 C1 01  |  test  cl, 1                      ; test last bit to see if odd or even
8D 41 01  |  lea   eax, DWORD PTR [ecx + 1]   ; set EAX to n+1 (without clobbering flags)
8D 49 FF  |  lea   ecx, DWORD PTR [ecx - 1]   ; set ECX to n-1 (without clobbering flags)
0F 44 C1  |  cmovz eax, ecx                   ; move in different result if input was even
C3        |  ret

(13バイト)

しかし、コードゴルフの目的では、LEAエンコードに3バイトかかるため、これらの命令は素晴らしいものではありません。の単純なDECコメントはECXはるかに短くなります(1バイトのみ)が、これはフラグに影響するため、コードの配置方法について少し賢くする必要があります。私たちは、デクリメントを行うことができますまず、奇数/偶数のテスト第二が、その後我々は、奇数/偶数のテストの結果を反転しなければなりません。

また、条件付き移動命令をブランチに変更することができます。これにより、コードの実行が遅くなる場合があります(ブランチの予測可能性に応じて-入力が奇数と偶数の間で一貫しない場合、ブランチが遅くなります。パターン、それはより高速になります)、それは私たちに別のバイトを節約します。

実際、このリビジョンでは、1つのレジスタのみを使用して、操作全体をインプレースで実行できます。このコードをどこかにインライン化する場合、これは素晴らしいことです(そして、非常に短いので、可能性があります)。

    48     |  dec  eax          ; decrement first
    A8 01  |  test al, 1        ; test last bit to see if odd or even
    75 02  |  jnz  InputWasEven ; (decrement means test result is inverted)
    40     |  inc  eax          ; undo the decrement...
    40     |  inc  eax          ; ...and add 1
  InputWasEven:                 ; (two 1-byte INCs are shorter than one 3-byte ADD with 2)

(インライン:7バイト、関数として:10バイト)

しかし、それを機能にしたい場合はどうでしょうか?標準の呼び出し規則では、戻り値の場合と同じレジスタを使用してパラメーターを渡すことはないためMOV、関数の先頭または末尾にレジスタ間命令を追加する必要があります。これは実質的に速度を犠牲にしませんが、2バイトを追加します。(RET命令はバイトも追加し、関数呼び出しを行って返す必要があるため、オーバーヘッドが発生します。これは、インライン化が単なる古典的な速度ではなく、速度サイズの両方の利点をもたらす1つの例であることを意味します-スペースのトレードオフ。)全体として、関数として記述されたこのコードは10バイトに膨れ上がります。

10バイトで他に何ができますか?パフォーマンス(少なくとも、予測可能なパフォーマンス)を重視する場合は、そのブランチを削除することをお勧めします。これは、バイト単位で同じサイズの、分岐のないビット調整ソリューションです。基本的な前提は簡単です。ビット単位のXORを使用して最後のビットを反転し、奇数の値を偶数の値に、またはその逆に変換します。ただし、奇数の入力に対してはn-1が与えられ、偶数の入力に対してはn + 1が与えられます。これは、希望とは正反対です。そのため、それを修正するために、負の値に対して操作を実行し、効果的に符号を反転させます。

8B C1     |  mov eax, ecx   ; copy parameter (ECX) to return register (EAX)
          |
F7 D8     |  neg eax        ; two's-complement negation
83 F0 01  |  xor eax, 1     ; XOR last bit to invert odd/even
F7 D8     |  neg eax        ; two's-complement negation
          |
C3        |  ret            ; return from function

(インライン:7バイト、関数として:10バイト)

かなり滑らかです。それがどのように改善されるかを見るのは難しいです。ただし、2つの2バイトNEG命令が注目されます。率直に言って、2バイトは単純な否定をエンコードするには1バイトが多すぎるように見えますが、それは私たちが処理しなければならない命令セットです。回避策はありますか?もちろん!我々場合はXOR-2によって、我々は、第二置き換えることができるNEGとエーションをINCリーメント:

8B C1     |  mov eax, ecx
          |
F7 D8     |  neg eax
83 F0 FE  |  xor eax, -2
40        |  inc eax
          |
C3        |  ret

(インライン:6バイト、関数として:9バイト)

x86命令セットの奇妙のもう一つは、多目的LEA命令レジスタ・レジスタ移動を行うことができ、レジスタ-レジスタに加え、定数によって相殺し、すべて1つの命令でスケーリング!

8B C1        |  mov eax, ecx
83 E0 01     |  and eax, 1        ; set EAX to 1 if even, or 0 if odd
8D 44 41 FF  |  lea eax, DWORD PTR [ecx + eax*2 - 1]
C3           |  ret

(10バイト)

このAND命令はTEST、ビット単位のANDを実行し、それに応じてフラグを設定するという点で、以前に使用した命令に似ていANDますが、実際には宛先オペランドを更新します。次に、LEA命令はこれを2でスケーリングし、元の入力値を加算し、1をデクリメントします。入力値が奇数の場合、これから1(2×0 − 1 = -1)を引きます。入力値が偶数の場合、これは1(2×1 − 1 = 1)を追加します。

実行の多くはフロントエンドで実行できるため、これはコードを記述するための非常に高速で効率的な方法ですが、複雑なコードをエンコードするのに非常に多くの時間がかかるため、バイトの面ではあまり買いませんLEA命令。また、このバージョンは、元の入力値をLEA命令の入力として保持する必要があるため、インライン化の目的でも機能しません。そのため、この最後の最適化の試みでは、実際には逆戻りしており、停止する時間である可能性が示唆されています。


したがって、最後の競合するエントリには、ECXレジスタの入力値(32ビットx86の準標準のレジスタベースの呼び出し規則)を取得し、結果をEAXレジスタに返す9バイトの関数があります(同様に)すべてのx86呼び出し規約):

           SwapParity PROC
8B C1         mov eax, ecx
F7 D8         neg eax
83 F0 FE      xor eax, -2
40            inc eax
C3            ret
           SwapParity ENDP

MASMで組み立てる準備ができました。Cからの呼び出し:

extern int __fastcall SwapParity(int value);                 // MSVC
extern int __attribute__((fastcall)) SwapParity(int value);  // GNU   

dec eax; xor eax, 1; inc eax動作して1バイト以上節約するのではないでしょうか?
イルマリカロネン


11

python3、20の 18バイト

lambda n:n-1+n%2*2

ものすごく単純。最初にn-1を計算し、それに2を追加するかどうかを決定します。

nが偶数の場合 -> n mod 2は0になるため、n-12 * 0を追加し、結果としてn-1になります。

nが奇数の場合 -> n mod 2は1になるため、n-12 * 1を追加し、n + 1になります。

私はMSペイントとラップトップのタッチパッドで作った説明が好きです... 視覚的説明


10

Python、16バイト

lambda x:-(-x^1)

オンラインでお試しください!


3
ブルートフォーシングでは、の文字​​を使用した短い解決策は見つかりません"x+-012~|&^()*/%"
-xnor

@xnor良いこと、私はそれを得た!
-sagiksp

1
そして、些細な再配置を除いて、他の同じ長さのソリューションはないよう-(1^-x)です。
-xnor

8

MATL、7バイト

Q:HePG)

これにより、算術演算が回避されます。オンラインでお試しください!

説明

4例として入力を検討してください。

Q    % Implicit input. Add 1
     % STACK: 5
:    % Range
     % STACK: [1 2 3 4 5]
He   % Reshape with 2 rows in column-major order. Pads with a zero if needed
     % STACK: [1 3 5;
               2 4 0]
P    % Flip vertically
     % STACK: [2 4 0;
               1 3 5]
G    % Push input again
     % STACK: [2 4 0;
               1 3 5], 4
)    % Index, 1-based, in column major order. Implicitly display
     % STACK: 3

1
いいね!いいね !
スティーヴィーグリフィン

6

Braingolf v0.1デベロッパー11の 10バイト

.1>2,%?+:-

オンラインでお試しください!(2番目の引数はBraingolfコード、3番目の引数は入力です)

ニールのおかげでバイトを節約

初めての競合ブレインゴルフ回答:D

説明:

.            Duplicate the top of the stack
 1>          Push 1 to the bottom of the stack
   2         Push 2 to stack
    ,%       Pop last 2 items, mod them and push result
      ?      If last item > 0
       +     Add the 1 to the input
        :    Else
         -   Subtract the 1 from the input

             No semicolon in code so print last item

Braingolf v0.2、9バイト[非競合]

.2%?1+:1-

オンラインでお試しください!(2番目の引数はBraingolfコード、3番目の引数は入力です)

説明については上記を参照してください。相違点はBraingolf v0.2のみです。diadic演算子のデフォルトの動作と修飾子の機能,は逆になります。つまり、v0.1の回答の2つのコンマは不要になります。

ただし、v0.2はチャレンジ後にリリースされたため、これは競合しません


5
新しい言語おめでとうございます!
リーキー修道女

DOESは、.1<2,%?+:-私はそれが何を思いますか?
ニール

@Neilではなく-、操作を正しい方法で実行するにはコンマが必要です。その場合、それはまだ私の答えと同じ長さです
Skidsdev

@Mayube私は、入力<1下をすでに回転させることを期待していたので、すでに正しい場所にあります。
ニール

入力は、それが到達した時点で、偶数であれば@Neil -このようなスタックになります[n,1]が実行なるので、braingolfオペレータが反転さを1 - nもたらすであろう、-(n-1)所望の結果が単にwheras、n-1
Skidsdev

5

Cubix10 9バイト

cO1)I(//@

オンラインで試す

説明

ネットバージョン

    c O
    1 )
I ( / / @ . . .
. . . . . . . .
    . .
    . .

実行されたキャラクターは

I(1c)O@
I          Input
 (         Decrement
  1c       XOR with 1
    )      Increment
     O@    Output and exit

4

Python、68バイト

lambda x:[m.floor(x-m.cos(m.pi*x)) for m in [__import__('math')]][0]

ユニークなアプローチの精神。次のグラフは、関数を示しています(最初の10個のケースを表す紫色の点で)。理論的には、ほとんどの(すべて?)周期関数(たとえば、sin、tan、sec)に基づいてこの質問の解を構築することが可能です。実際、コード内のsecをcosにそのまま置き換えることで機能します。

機能を示すグラフ


3

PHP、15バイト

<?=-(-$argn^1);

2
これを実行するにはどうすればよいですか?;が必要かどうかをテストしようとしてい.phpます。また、ファイルを使用して、PHP(php7 cli。)に直接エコーしようとしました$argn
アンドラキス

2
@Andrakis Fフラグとパイプライン:echo 42 | php -F script.php
user63956

3

Javascript、17 12バイト

x=>x-(-1)**x

f=x=>x-(-1)**x;
<input id=i oninput=o.innerText=f(this.value) type=number><pre id=o>

別のアプローチ、C回答から盗まれた 10バイト(sssshhh)

x=>-(-x^1)

f=x=>-(-x^1)
<input id=i oninput=o.innerText=f(this.value) type=number><pre id=o>


1.セミコロンを含める必要はありません。2.x=>x-(-1)**x
リーキーヌン

なぜ|0?どちらのソリューションも、文字列を自動的に数値に変換するように見えます。(最初の解決策では、小数部を避けたい場合は、を使用します<input type=number>。)
Neil

@Neil通知してくれてありがとう!
マシュー盧

3

JavaScript(ES6)、14 13 12 10バイト

n=>-(-n^1)
  • Lukeのおかげで1バイト節約されました。
  • feersumのCソリューションを移植することで2バイト節約されました。(それが眉をひそめているなら、私に知らせてください、そして、私は下の私の前の解決にロールバックします)

それを試してみてください

f=
n=>-(-n^1)
i.addEventListener("input",_=>o.innerText=f(+i.value))
<input id=i type=number><pre id=o>


オリジナル、12バイト

n=>n-1+n%2*2

2

Python、20バイト

lambda n:n+(n%2or-1)

n%2or-1奇数の場合は1を返しますが、偶数の場合n%2は「false」(0)なので、代わりに-1を返します。次に、それを単にに追加しnます。

以前のソリューション、23バイト

lambda n:[n-1,n+1][n%2]

n%2n2で割ったときの剰余を計算します。偶数の場合、これは0を返し、このリストの要素0はn-1です。奇数の場合、これは1を返し、このリストの要素1はn+1です。


1
:ラムダ使用lambda n:[n-1,n+1][n%2]
漏れ修道女

ああ、それでこの場合は短くなりました。完了、ありがとう!
-numbermaniac

2

網膜、21バイト

.+
$*
^11(?=(11)*$)


オンラインでお試しください!私の最初のRetinaは、2つの末尾の改行で答えます!説明:最初の2行は、10進数から単項に変換します。3行目と4行目は、偶数から2を引きます。最後の行は10進数に変換されますが、1行も追加されます。



2

Cubix、11バイト

u%2!I(/+@O<

オンラインでお試しください!

説明

ネットバージョン:

    u %
    2 !
I ( / + @ O < .
. . . . . . . .
    . .
    . .

文字は次の順序で実行されます。

I(2%!+O@
I        # Take a number as input
 (       # Decrement it
  2%     # Take the parity of the decremented number
         # (0 if the input is odd, 1 if it's even)
    !    # If that number is zero:
     +   #   Add 2
      O  # Output the number
       @ # Terminate the program

2

Brain-Flak、36バイト

(({})(())){({}[()]<([{}])>)}{}({}{})

オンラインでお試しください!

私はこの答えに個人的に本当に満足しています。なぜなら、この答えは、この問題を解決する従来の方法と考えるよりもずっと短いからです。

説明

コードの最初のビット

(({})(()))

スタックをただnからに変換します

n + 1
  1
  n

次に、スタックの一番上がゼロでない間、それをデクリメントし、その下の数字の符号を反転します

{({}[()]<([{}])>)}

ゼロを削除し、残りの2つの数値を追加します

{}({}{})

2

Mathematica、22 19バイト

Greg Martinのおかげで3バイト節約できました!

#-1[-1][[#~Mod~2]]&

前の回答、22バイト

#+{-1,1}[[#~Mod~2+1]]&

説明(以前の回答用)

Mathematicaには、算術演算などの操作がリストを自動的にスレッド化するという優れた機能があります。

この場合、Mod[#,2]どちらが0または1を返すかを取得しますが、Mathematicaリストは1インデックスであるため1を追加する必要があります。偶数場合、これは1になり、#-1返されます。奇数の場合、これは2になり、#+1返されます。


2
あなたは、Mathematicaの悪用により3つのバイトを保存することができます[[0]]機能を:#-1[-1][[#~Mod~2]]&
グレッグマーティン

それは非常識です、決してそれを考えなかったでしょう。完了、ありがとう!
numbermaniac

2

Wise、8バイト

-::^~-^-

オンラインでお試しください!

説明

これが逆の場合(奇数の場合は減少、偶数の場合は増加)、これは非常に簡単です。

最後のビットを反転するだけです。

::^~-^

ここでの修正は、負の値の間に最後のビットを反転することです。負の数値は、数値の否定から1離れている~ため、問題を解決するオフセットが作成されます。

だから私たちはプログラムを取り出してそれをラップするだけ-です。

-::^~-^-

1

Javaの8、16の 10バイト

n->-(-n^1)

Java 7、34 28バイト

int c(int n){return-(-n^1);}

@feersumのすばらしいC回答の退屈な移植
ここで試してみてください。


古い答え:

Java 8、16バイト

n->n%2<1?n-1:n+1

Java 7、34バイト

int c(int n){return--n%2>0?n:n+2;}

説明(古いJava 7の回答):

ここで試してみてください。

上記の答えint c(int n){return n%2<1?n-1:n+1;}は、スペースを取り除くことによる短い変形です。

int c(int n){     // Method with integer parameter and integer return-type
  return--n%2>0?  //  If n-1 mod-2 is 1:
    n             //   Return n-1
   :              //  Else:
    n+2;          //   Return n+1
}                 // End of method



1

Befunge 93、18バイト

&:2%#v_1+.@
@.-1 <

私はまだこれをゴルフしていません(願っています)。


ゴルフのヒント:Befunge 98には、の代わりにkv(またはjv厳密に1または0の場合)を使用する機能があります#v_。また、Try it onlineを使用している場合(お勧めします)、別のプログラムでプログラムを終了することができます&(60秒かかります)@以下にBefunge-98のコマンドの完全なリストを示しますが&、EOFを逆にするのではなくプログラムを終了するなど、すべてがTIOに正しく実装されているわけではありません。
MildlyMilquetoast

また、コマンドが少ない98ではなく、befunge 93を使用しているようです。リンク名が実際には98ではなく93である場合、リンク名を修正することをお勧めします
MildlyMilquetoast

@MistahFiggins、ああ、あなたは正しいです。私は93を使用していました。-
ダニエル


1

R、17バイト

(n=scan())-(-1)^n

ここでn=scan()数字の値を取ります。


偶数である場合に戻る必要-(-1)^nがある+(-1)^nためではなく、あなたが必要だと思うn-1n
ジュゼッペ

@ジュゼッペああ、はい、もちろん、愚かな間違い
-Nutle

1

カシオベーシック、27バイト

piecewise(mod(n,2),1,-1)+n

関数の場合は26バイトn、パラメーターボックスに入力する場合は+1 。




0

バッチ、20バイト

@cmd/cset/a"-(1^-%1)

独立して@feersumのアルゴリズムを再発見しました、正直です!

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.