# Four distinct 8-bit integers

Submit a well-formed program or function with usual I/O rules which satisfy the input, output, and algorithm conditions below. Shortest submission (in bytes) wins. As always, standard loopholes are forbidden.

In short: Two distinct 8-bit integer inputs must produce two 8-bit integer outputs so that all four numbers are distinct, i.e., not equal.

# Input Conditions

Two distinct 8-bit integers, a and b, both of which are in 8-bit signed (or unsigned at your discretion) format.

# Output Conditions

Two 8-bit integers, c and d, which are in the same format as the input (signed or unsigned), such that a, b, c, and d are distinct, i.e., no two of them are equal to each other.

# Algorithm Conditions

1. The algorithm must halt for all possible valid inputs.
• Valid inputs are those where a and b are distinct. When a and b are equal, the behaviour of the algorithm is unspecified.
2. The algorithm must be deterministic.
• Running the algorithm with the same input must produce the same output.
3. The algorithm must satisfy the output conditions for all valid inputs.

# Verification

There are two ways to verify your algorithm.

1. Brute force: explicitly check the program for all valid input combinations.
2. Prove/show, by analysis, that a clash is impossible (preferred).

# FAQ

1. What if my programming language doesn't provide 8-bit integers?
2. What if my programming language doesn't support fixed-width integers?

• Only the range of the outputs matter; internal computations may be in any precision. If the outputs can be rounded/scaled to the required integral range, then the programming language is good to go.

# Edits

Edit 1: Thank you for the submissions! I am glad to see so many creative solutions! Initially, I planned to restrict the algorithm to one-to-one mapping (i.e., invertible), however, decided against it to make the problem simpler. Looking at the enthusiastic response, I will consider submitting a second code golf with the one-to-one mapping requirement.

• I would suggest explicitly allowing the deterministic output to be unordered, e.g. an input can produce [1,2] or [2,1] or a set that contains 1 and 2.
– Jo King
Mar 23, 2020 at 14:20
• Just to be sure, 0s have to be taken into account right? The input may have one 0?
– RGS
Mar 23, 2020 at 14:28
• @JoKing sorry, without any disrespect, I do not think this is acceptable. The reason being that the original requirements of determinism are for output integers "c" and "d;" combining them into a set is only a convenience, which is allowed per the rules.
– user92857
Mar 23, 2020 at 14:33
• @RGS, yes, input range for 8-bit signed is [-128,127] and for 8-bit unsigned is [0,255].
– user92857
Mar 23, 2020 at 14:34
• Mar 23, 2020 at 15:46

# JavaScript (Node.js), 353127 23 bytes

-4 bytes thanks to Arnauld and Kevin Cruijssen

-4 bytes thanks to xnor

a=>b=>[c=3^a&1^b&2,c^4]


Try it online!

Explanation:

Takes the flipped 1 bit of the first number, and adds the flipped 2 bit of the second number, guaranteeing a number different from both inputs in the 2 least significant bits. Outputs this number, and 4 added to this number

• If you change the + to |, it looks like you can cut out the inner parens. Or better: Try it online!
– xnor
Mar 23, 2020 at 20:00

# Perl 6, 20 bytes

{grep(.none,^4)[^2]}


Try it online!

Outputs the first two numbers from the range 0 to 3 that aren't in the input.

# brainfuck, 69 bytes

,+[->+>+>+<<<],[->>->-<<<]++>>>[[-]<<<->.>>]<+<+>[[-]<<->.>]<+<[->.<]


Try it online!

My solution takes the first input and counts it upwards and prints the first two numbers unless they are the second input. So if the first input is A and the second input is B the output will be:
A+2, A+3 if B = A+1 or
A+1, A+3 if B = A+2 or
A+1, A+2 else

This initializes position 1,2,3 of the band as the first input incremented by 1
,[->>->-<<<]
This substracts the second input from positions 2 and 3.
++
Set position 0 to 2, counting the numbers still to print
The band now reads: (2) a+1 a-b+1 a-b+1
>>>[[-]<<<->.>>]
If position 3 is not 0, print out position 1 and decrement position 0
<+<+>
Increment the band in position 1 and 2
[[-]<<->.>]
If position 2 is not 0, print out position 1 and derement position 0
<+<[->.<]
Increment at position 1, Position 0 is now either 1 or 0. If it is 1 print position 1 one more time. 


# 05AB1E, 9 5 bytes

∞IK2£


I/O as a pair of integers.

Explanation:

∞      # Push an infinite positive list [1,2,3,...]
IK    # Remove the values of the input-pair
2£  # Only leave the first two values
# (after which the result is output implicitly)


a#b=take 2[i|i<-[1..],a/=i,b/=i]


Try it online! We pick the first two positive integers that aren't input numbers.

# JavaScript (ES6),  32 27  26 bytes

Takes input as (x)(y).

x=>y=>[x^=k=y^x^1?1:2,y^k]


Try it online!

# Octave, 28 22 bytes

@(x)setxor(1:4,x)(1:2)


Try it online!

### Explanation

Anonymous function that outputs the first 2 entries from the sorted symmetric difference between [1 2 3 4] and the input.

# Charcoal, 27 10 bytes

Ｉ…⁻Ｅ⁴ιＥ²Ｎ²


Try it online! Link is to verbose version of code. Uses the same set difference algorithm as everyone else. Less boring 27-byte version actually tries to produce interesting outputs for all inputs:

ＮθＮηＩ﹪⁺÷¹²⁸⊕¬﹪⁻θη¹²⁸⟦θη⟧²⁵⁶


Try it online! Link is to verbose version of code. Takes unsigned integers. Explanation: Flips the top bits of the values, unless this would exchange them, in which case adds 64 (modulo 256) instead.

# Wolfram Language (Mathematica), 32 bytes

Complement[Range@4,{##}][[;;2]]&


Try it online!

# Python 3, 27 bytes

lambda s:[*{0,1,2,3}-s][:2]


Try it online! The input is a set s with the integers. We build the set {0, 1, 2, 3, 4, 5, 6, 7, 8} and then perform set subtraction to remove, from that set, any input numbers. We then convert to a list and extract two elements.

Thanks Surculose for saving me 2!

• {0,1,2,3}-s should works Mar 23, 2020 at 14:47

# Japt, 8 bytes

Hõ kU ¯2


Try it

# Python 3.8, 31 29 bytes

Saved 2 bytes thanks to xnor!!!

lambda x,y:(k:=~x&1|~y&2,k+4)


Try it online!

• The parens around the first entry aren't necessary.
– xnor
Mar 23, 2020 at 22:34
• @xnor Interesting - thanks! :-) Mar 23, 2020 at 23:12
• k:=(x|1)^(y|2) seems like a it could save bytes, but I don't a way to get rid of the parens.
– xnor
Mar 25, 2020 at 1:24

# Pyth, 5 bytes

>2-Uy


Try it online!

# Explanation

    y # Repeat the input
U  # Generate a length range: [0 .. 3]
-   # Difference with implicit input
>2    # Slice out the last 2 items of the resulting list

• You probably mean "repeat" the input, not "repeat twice"? Mar 23, 2020 at 18:53
• y is powerset, not repeat the input. Still length 4, which is what counts. Mar 24, 2020 at 4:11

# C (gcc), 36 34 28 bytes

Saved 2 8 bytes thanks to ceilingcat!!!

f(x,y){x=(~y&2|~x&1)*257+4;}


Try it online!

Uses Paul Mutser's formula.
Returns the two 16-bit values in a 32-bit int since there are no tuples &c in C.

# Bash + Core utilities, 29 bytes

seq 4|egrep -v $1\|$2|head -2


Try it online!

Input is passed in two arguments, and the output is printed to stdout.

This prints the first two positive integers that aren't either of the two arguments.

• This seems to give only one number if passed in 1 and 2.
– xnor
Mar 23, 2020 at 20:50
• @xnor Thanks -- that was a dumb mistake. It's fixed now (no scoring change). Mar 24, 2020 at 5:52

# Erlang (escript), 43 bytes

Outputs the first two numbers from the range 0 to 3 that aren't in the input.

f(A)->lists:sublist(lists:seq(0,3)--A,1,2).


Try it online!

# W, 5 bytes

Takes input as a pair of integers.

%G?←√


Uncompressed:

4k     Range from 1 to 4
at   Trim out all items that appear in the input
2< Take the first two items of the output list.


# Io, 46 bytes

method(x,list(1,2,3,4)difference(x)slice(0,2))


Try it online!

# Alchemist, 60 bytes

_->In_x+In_y+2n
n+x+y->Out_z+z+Out_" "
x+0y->z+3y
y+0x->z+3x


Try it online!

As with many answers here, prints the first two non-negative integers not in the input. Input is unsigned, since Alchemist doesn't have signed numbers.

I similarly can't just let a variable "go negative" after it hits zero, so I just let an input value x also exclude x+4, x+8, and so on. This has no effect on anything, provided both variables don't hit zero at the same time. Fortunately, if they ever become the same, both outputs will happen before they hit zero.

# Ruby, 22 bytes

->*a{([*6..9]-a)[0,2]}
`

Try it online!

Same method as almost everybody.