10進数の「XOR」演算子


15

多くのプログラミング言語は、整数の2進数(2進数)を操作する演算子を提供します。これらの演算子を他のベースに一般化する1つの方法を次に示します。

ましょう、X及びYは塩基で一桁の数字であるB。単項演算子の定義~とバイナリ演算子&|および^、そのようなことを:

  • 〜x =(B-1)-x
  • x&y = min(x、y)
  • x | y = max(x、y)
  • x ^ y =(x&〜y)| (y&〜x)

B = 2の場合、おなじみのビット単位のNOT、AND、OR、XOR演算子が得られることに注意してください。

B = 10の場合、「10進数XOR」テーブルを取得します。

^ │ 0 1 2 3 4 5 6 7 8 9
──┼────────────────────
0 │ 0 1 2 3 4 5 6 7 8 9
1 │ 1 1 2 3 4 5 6 7 8 8
2 │ 2 2 2 3 4 5 6 7 7 7
3 │ 3 3 3 3 4 5 6 6 6 6
4 │ 4 4 4 4 4 5 5 5 5 5
5 │ 5 5 5 5 5 4 4 4 4 4
6 │ 6 6 6 6 5 4 3 3 3 3
7 │ 7 7 7 6 5 4 3 2 2 2
8 │ 8 8 7 6 5 4 3 2 1 1
9 │ 9 8 7 6 5 4 3 2 1 0

複数桁の番号の場合、1桁の演算子を1桁ずつ適用します。たとえば、12345 ^ 24680 = 24655です。理由は次のとおりです。

  • 1 ^ 2 = 2
  • 2 ^ 4 = 4
  • 3 ^ 6 = 6
  • 4 ^ 8 = 5
  • 5 ^ 0 = 5

オペランドの長さが異なる場合は、短い方に先行ゼロを埋め込みます。

チャレンジ

入力として2つの整数(0〜999 999 999を含むと想定される可能性があります)を取り、上記で定義した2つの数値の「10進数XOR」を出力するプログラムまたは関数をできる限り少ないバイトで書き込みます。

テストケース

  • 12345、24680→24655
  • 12345、6789→16654
  • 2019、5779→5770
  • 0、999999999→999999999
  • 0、0→0

入力または出力を文字列またはchar配列として使用できますか?
無知の

6
数字配列はどうですか?それは受け入れられますか?
無知の

1
09入力に対して許容可能な結果はあります90, 99か?
ニール

1
維持された一般化があったことを願っていますA^B^B=A
-trichoplax

2
@trichoplax、あなたは両方を持つことができないa^b=b^aa^b^b=a奇素数除数と塩基について
MIK

回答:


3

ゼリー、14バイト

DUz0«9_ṚƊṀƊ€UḌ

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

すべての1桁ペアのグリッド

2つの整数のリストを引数として受け取り、整数を返すモナドリンク。

説明

D               | Decimal digits
 U              | Reverse order of each set of digits
  z0            | Transpose with 0 as filler
          Ɗ€    | For each pair of digits, do the following as a monad:
    «   Ɗ       | - Minimum of the two digits and the following as a monad (vectorises):
     9_         |   - 9 minus the digits
       Ṛ        |   - Reverse the order
         Ṁ      | - Maximum
            U   | Reverse the order of the answer to restore the orignal order of digits
             Ḍ  | Convert back from decimal digits to integer

数字行列が受け入れ可能な入出力の場合:

ゼリー、12バイト

Uz0«9_ṚƊṀƊ€U

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


2

Pyth、31バイト

LhS,hb-9ebjkmeS,ydy_d_.t_MjRTQ0

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

LhS,hb-9eb             # Helper function, computes the (x & ~y) part
L                      # y = lambda b:
  S                    #               sorted(                )  
   ,                   #                       [    ,        ]
    hb                 #                        b[0]
      -9eb             #                              9-b[-1]
 h                     #                                       [0] # sorted(...)[0] = minimum

jkmeS,ydy_d_.t_MjRTQ0  # Main program (example input Q: [123, 45])
                jRTQ   # convert each input to a list of digits -> [[1,2,3],[4,5]]
              _M       # reverse each -> [[3,2,1],[5,4]]
            .t      0  # transpose, padding right with 0 -> [[3,5],[2,4],[1,0]]
           _           # reverse -> [[1,0],[2,4],[3,5]]
  m                    # map that over lambda d:
    S,                 #   sorted([    ,           ])
      yd               #           y(d)
        y_d            #                 y(d[::-1])         # reversed
   e                   #                             [-1]   # sorted(...)[-1] = maximum
jk                     # ''.join( ^^^ )


1

Forth(gforth)、111バイト

: m 10 /mod rot ;
: t 9 swap - min ;
: f 2dup + 0> if m m recurse 10 * -rot 2dup swap t -rot t max + 1 then * ;

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

コードの説明

: m          \ start a new word definition
  10 /mod    \ get quotient and remainder of dividing by 10
  rot        \ move item in 3rd stack position to top of stack
;            \ end word definition

\ word implementing "not" followed by "and"
: t          \ start a new word definition
  9 swap -   \ subtract top stack element from 9
  min        \ get the minimum of the top two stack elements
;            \ end word definition

: f          \ start a new word definition
  2dup +     \ duplicate top two stack elements and add them together
  0> if      \ if greater than 0
    m m      \ divide both by 10, move remainders behind quotients
    recurse  \ call self recursively
    10 *     \ multiply result by 10 (decimal left shift of 1)
    -rot     \ get remainders from original division
    2dup     \ duplicate both remainders 
    swap t   \ swap order and call t (b & !a)
    -rot t   \ move result back and call t on other pair (a & !b)
    max + 1  \ get the max of the two results and add to total. put 1 on top of stack
  then       \ end if block
  *          \ multiply top two stack results (cheaper way of getting rid of extra 0)
;            \ end word definition

1

C#(Visual C#Interactive Compiler)、75バイト

a=>b=>a.Select((x,y)=>Math.Max(9-x<(y=y<b.Count?b[y]:0)?9-x:y,9-y<x?9-y:x))

@someoneのおかげで6バイト節約

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


76バイト。この質問は、Zipを使用するユニークな機会になると思います。
私の代名詞はmonicareinstate

1
@誰かありがとう!Zipそれが自動的に短い方の長さに長くコレクションを切り捨てて、あなたがそれを使用することはできません、
無知の実施の形態

0

PHP111 109バイト

for(;''<($a=$argv[1][-++$i]).$b=$argv[2][-$i];)$s=min($a<5?9-$a:$a,max($a<5?$a:9-$a,$a<5?$b:9-$b)).$s;echo$s;

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

テスト:オンラインで試してみてください!

XORしたい数字を呼び出す$a$b、が見つかりました:

  • ときは$a、5未満でありますXOR = min(9-$a, max($a, $b))
  • 場合$a、以上で5XOR = min($a, max(9-$a, 9-$b))

そこで、このロジックに加えて、長さの異なる数字を処理するためのハックを実装しました。私は、各桁の形に(のような負のインデックスの両方入力番号の端を取るinput[-1]input[-2]...)とXORを計算し、最後に印刷される文字列に逆の順序で結果を置きます。数字の末尾から数字を取得するため、XORの結果は逆の順序でまとめる必要があります。入力の1つが他の入力より長い場合、短い入力の負のインデックスは0に等しい空の文字列になります。


0

網膜85 59バイト

^'0P`.+
N$`.
$.%`
¶

/../_(`^
$"
T`d`Rd`.¶.
%N`.
^N`..
L`^.

オンラインでお試しください!入力を個別の行として受け取りますが、リンクは、コンマ区切りの入力を再フォーマットするテストスイートです。説明:

^'0P`.+

両方の行を同じ長さにゼロで左詰めします。

N$`.
$.%`
¶

各桁を列インデックスで並べ替えてから、改行を削除します。これには、転置とほぼ同じ方法で数字をペアリングする効果があります。

/../_(`

数字の各ペアに個別に適用し、結果を結合します。

^
$"

ペアを複製します。

T`d`Rd`.¶.

最初のペアの2番目の数字と2番目の最初の数字を逆にします。これで、x ~y1行ともう1行になり~x yます。

%N`.

最初の数字は今ように、順番に各ラインの数字を並べ替えるx & ~yか、~x & y必要に応じて。

^N`..

行を逆ソートします。

L`^.

そして、希望する結果である最初の数字を抽出します。

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