# Implement the Conjunction of a Three-Valued Logic

Your task, should you choose to accept it, is to take two input values $$\a\$$ and $$\b\$$, where $$\a\$$ and $$\b\$$ are in the set $$\\{T, U, F\}\$$, and compute and output their logical conjunction in a three-valued logic system.

A three valued logical conjunction is this transformation:

a b output
U U U
U F F
F U F
U T U
T U U
F F F
F T F
T F F
T T T

## I/O Rules

You have to take as an input two characters $$\a\$$ and $$\b\$$, where $$\a\$$ and $$\b\$$ are T, U, or F.

You have to output one of F, T, or U, with an optional trailing newline.

These very restrictive I/O rules help prevent trivial solutions.

### Example Program (in Nim)

proc f(s: string): char =
if s=='F' or s=='F':return 'F'
if s=='U' or s=='U':return 'U'
if s=='T' and s=='T':return 'T'


Attempt This Online!

• is taking input as a list of two characters, instead of a single string of two characters, also acceptable? May 5 at 23:36
• Sure; I will specify. May 5 at 23:40
• What about taking the two characters as separate arguments?
– m90
May 6 at 13:40
• Yes, that works as well. I am going to rewrite the input section to clarify. May 6 at 14:53

# Python, 22 bytes

lambda s:s["T"<s<"UT"]


Try it online!

# Python 2, 24 bytes

lambda s:s[s in'TUF TF']


Try it online!

Alternative Solution

lambda s:s[hash(s)/22%2]


# Jelly, 6 bytes

O%4µÞṪ


Try It Online!

O%4µÞṪ  Main Link
Þ   Sort by
O       ord (codepoint)
%4     modulo 4
Ṫ  Take the last character


-1 byte thanks to emanresu A by not closing the string
-3 bytes thanks to Kevin Cruijssen by sorting the original characters instead of indexing back into "FUT"

This at its core works the same as the original "map by O%4 → take max → index back into FUT" but instead of actually indexing it just sorts by the O%4 key which puts the max (the answer) at the end which is extracted with Ṫ.

• Wow, quick answer! Nice solution, very clever with the modulo by 4! May 5 at 21:47
• FYI closing the string is unnecessary. May 5 at 23:38
• @emanresuA oh yeah duh, thanks May 5 at 23:54
• 6 bytes by sorting instead of indexing: O%4µÞṪ May 6 at 7:48
• @KevinCruijssen oh that's clever, thanks May 6 at 14:12

# x86 32-bit machine code, 9 bytes

37 38 D1 37 91 0F 42 C2 C3


Try it online!

Uses the fastcall calling convention, this takes two characters in CL and DL and returns a character in AL.

In assembly:

f:  aaa
cmp cl, dl
aaa
xchg ecx, eax
cmovc eax, edx
ret


The character codes of F, U, T are 0x46, 0x55, 0x54 respectively. Notice that the low nybbles are in descending order.

cmp cl, dl sets flags based on the subtraction of the two given characters. In particular, the auxiliary carry flag (AF) is set based on carries across the centre of the byte, and it exactly indicates which character should be the result.

The difficulty lies in getting that information out of AF. Unlike the rest of the status flags, AF cannot be used as the condition for a jump, move, or SETcc. It is used mainly by several instructions intended for handling binary-coded decimal.

aaa is one of those instructions. (Its mnemonic stands for ASCII Adjust after Addition.) Helpfully, its opcode is only one byte. Its effect is: If AF=1 or the low nybble of AL is at least 10, add 0x106 to AL. Also, set both AF and CF based on the same condition. Afterwards, zero the high nybble of AL.

The first aaa makes sure that the low nybble of AL is less than 10, so that after the cmp cl, dl, the second aaa sets CF to equal AF. Finally, the value of CF can be used to select the correct result.

• Brilliant! I imagine it is not common for the aaa instruction to be useful in golfing. May 7 at 16:11

# Pyth, 5 bytes

hox1C


Try it online!

      Q   implicit input
o        sort by key lambda N:
N      implicit element
C       character code point
x1        bitwise XOR with 1
h         first element


# JavaScript (ES6), 18 bytes

s=>s[s>"T"^s>"UF"]


Try it online!

# 05AB1E (legacy), 7 bytes

'FDl‡àu


Try it online! Explanation:

'F      Push literal character F
D     Duplicate
l    Lowercase the duplicate
‡   Transliterate F to f in the input
à  Take the maximum
u Uppercase

• 7 bytes alternative: …FUTIÃн. Although a port of the Pyth answer is 1 byte shorter: ΣÇ1^}н May 6 at 7:39
• @KevinCruijssen Thanks, but I was stretching the limits of my 05AB1E knowledge as it is just to get it down to 7 bytes. (In case you hadn't noticed this is actually a port of my alternative Charcoal answer.)
– Neil
May 6 at 8:45
• @KevinCruijssen I found another 7-byter: 'U†'F†н. There would be another 7-byter if I had a way of checking the top of stack and replacing it with a character if it was empty.
– Neil
May 7 at 8:34

# Vyxal, 6 bytes

≬C4%Þ↑


Try it Online!

## How?

≬C4%Þ↑
≬      # Three element lambda:
C     # Convert to character code
4%   # Modulo 4
# Lambda implicitly ends here
Þ↑ # Maximum of the (implicit) input by this function


Also 6 bytes:

µC4%;t


Try it Online!

## How?

µC4%;t
µ   ;   # Sorting lambda
C      # Character code
4%    # modulo four
t  # Last item


# MathGolf, 6 bytes

áÉ$4%╞  Port of hyper-neutrino♦'s Jelly answer, after I golfed it a bit more. Try it online. Explanation: á # Sort the (implicit) input-string by, É # using the following 3 character as inner code-block:$     #  Convert the character to a codepoint-integer
4%   #  Modulo-4 ("F"→70→2; "T"→84→0; "U"→85→1)
╞  # Remove the first character of the sorted string
# (after which the entire stack is output implicitly as result)


# C (gcc), 22 bytes

f(a,b){a=a%4<b%4?b:a;}


Try it online!

Inputs two characters.
Returns their logical conjunction.

# AWK, 22 bytes

$0=/F/?"F":/U/?"U":"T"  Try it online! As short as Python! #TeamAWK Sets the input $0 to the result of that ugly conditional. Because the assigned value is not false (i.e., not null/empty nor zero), AWK considers it a true pattern, and prints $0. $0=             Assigns to \$0 the result of:
/F/?         Is there an F in the input?
"F"      If so, it's now F.
:         Otherwise...
/U/?     Is there an U in the input?
"U"  If so, it's now U.
:     Otherwise...
"T"  It's T, then.


# Vyxal, 7 bytes

\F:ɽĿGɾ


Ported from Neil's 05AB1E answer; make sure to upvote that answer as well!

Explanation:

\F      Push literal character F
:     Duplicate
ɽ    Lowercase the duplicate
Ŀ   Transliterate F to f
G  Take the maximum
ɾ Change to uppercase


Try it online!

# Ruby, 24 bytes

->n{"FFTU"[n.sum/13-10]}


Input is taken as a single string. n.sum Adds together the ASCII codes of the input. This sum is modified by arithmetic, then used to index the string.

Try it online!

# Retina 0.8.2, 15 13 bytes

1T

O.
1!.


Try it online! Link includes test cases. Explanation:

1T



Delete the first T, if any.

O.
1!.


Take the minimum.

# Charcoal, 8 7 bytes

⌊∨⁻θT¦T


Try it online! Link is to verbose version of code. Explanation: If the string only contains Ts then output T otherwise output the minimum of the other character(s).

   θ    Input string
⁻     Remove any occurrences of
T   Literal string T
∨      Logical Or
T Literal string T
⌊       Take the minimum
Implicitly print


# brainfuck, 97 bytes

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


Takes in inputs as you would expect, and outputs as you would expect.

Copy the input characters to do math on them while preserving the original.

The math is just subtracting 70 ('F'), returning 'F' if either is 0 now, then subtracting 15 ('U' - 'F' == 15), returning 'U' if either is 0 now, otherwise return 'T'.

It's 3:30 a.m. as I'm writing this, so I may comment the code when I wake up.

Try it online!

A slightly different approach with 98 bytes

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


Since this function's output is always one of the inputs, it can be executed using a pure regex. This is done by picking an F if one exists, or otherwise picking a U if one exists, or otherwise picking a T.

# Regex (Perl / PCRE / Boost), 13 11 bytes

.?\KF|T?\K.


-2 bytes thanks to m90!

Returns the result in the match.

Try it online! - Perl
Try it on regex101 - PCRE
Try it online! - Boost

The \K feature is used to discard the first character of the input if .? or T? needed to be used to skip it.

# Regex (Java / Python / Ruby / .NET / ECMAScript 2018), 18 15 bytes

(.?(?=F)|T?)(.)


-3 bytes thanks to m90's idea

Returns the result in capture group 2.

Try it online! – Try It Online") - Java
Try it online! - Python
Try it online! - Ruby
Try it online! - .NET
Try it on regex101 - ECMAScript 2018

This is based on the PCRE regex, using lookahead and group capture to replace the inavailability of \K.

## Regex (.NET), 15 bytes

.?(F)|T?(?<1>.)


Returns the result in capture group 1.

Try it online!

It was only possible to make a shorter .NET version thanks to m90's suggestion. This is done using the .NET-specific feature of aliasing a capture group. It could be done in PCRE using a Branch Reset Group, (?|.?(F)|T?(.)), but that's 15 bytes, longer than the existing 11 byte solution.

This is now merely tying with the above solution.

• The first one can be improved to .?\KF|T?\K..
– m90
May 7 at 15:32

# SNOBOL4 (CSNOBOL4), 67 bytes

 i =input
i 'F' . x :s(o)
i 'U' . x :s(o)
x ='T'
o output =x
end


Try it online!

# C, 25 bytes

f(x,y){return y-x&8?x:y;}


Try it online!

This uses the same observation as my previous answer: the character codes of F, U, T are 0x46, 0x55, 0x54 respectively, and their low nybbles are in descending order.

The low nybble of the result of the subtraction is -2, -1, 0, 1, or 2 (modulo 16), and its high bit (the 8s bit) indicates whether it is one of the negative possibilities.

• Taxking a tip from Noodle9's 22 byte answer, you can use x= instead of return. f(x,y){x=y-x&8?x:y;} May 8 at 13:06

# brainfuck, 75 69 bytes

6 bytes saved by improving U -> F conversion from subtract 1x15 to subtract 3x5.

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


Try it online!

Developed at https://minond.xyz/brainfuck/ (additional > characters are needed at the beginning and end of the program there due to lack of support of negative memory indices and to avoid auto re-run.)

Subtracts one input from the other.

• If they are the same, output one of the inputs
• If they differ by 1 (UT or TU) output U
• Otherwise output F

Commented

,>,               Input into cells 0 and 1
[<<+>->-]         Decrement cell 1 while copying its contents into cell minus 1; Simultaneously decrement cell 0
<                 Leave the pointer at cell 0 which contains the difference between the inputs
[                 If difference is nonzero
>-[--->+<]          Subtract 1 from cell 1 giving 255 then loop until cell 1 is 0 and cell 2 is 255/3 = 85 ASCII U
<-[>]>[>+<<]        Subtract 1 from cell 0; If nonzero take step to right; now take a further step right
If cell 0 was nonzero we are now at cell 2 containing 85; add 1 to cell 3 then step back left
<++[>]>[>+<<]       Add 2 to cell 0; if nonzero use the same procedure as above to increment cell 3
>>                  Move to cell 3; If cell 2 remained nonzero through all steps above cell 3 is now 2 otherwise 1
-[++[<----->-]]     Subtract 1 from cell 3; If nonzero boost it to 3 then subtract 3x5=15 from cell 2
]                     changing it to 70 ASCII F
<.                Take 1 step left from current position and output result


# Python, 37 bytes

lambda s:s=="TT"and"T"or"UF"["F"in s]

Or alternatively for the same byte count

lambda s:["UF"["F"in s],"T"][s=="TT"]


Attempt This Online!

# C (GCC), 3833 29 bytes

f(char*s){*s=s[*s%4<s%4];}

Attempt This Online!

Returns the desired output in *s.

• Don't think this works for UF returns U not F as it should.. May 6 at 17:50
• Fixed, it wrote %3 instead of %4. May 7 at 18:09

# Nim, 55 bytes

proc f(a,b:char):char=(if int(a)%%4<int(b)%%4:b else:a)

Attempt This Online!