# 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[0]=='F' or s[1]=='F':return 'F'
if s[0]=='U' or s[1]=='U':return 'U'
if s[0]=='T' and s[1]=='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? Commented May 5, 2022 at 23:36
• Sure; I will specify. Commented May 5, 2022 at 23:40
• What about taking the two characters as separate arguments?
– m90
Commented May 6, 2022 at 13:40
• Yes, that works as well. I am going to rewrite the input section to clarify. Commented May 6, 2022 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! Commented May 5, 2022 at 21:47
• FYI closing the string is unnecessary. Commented May 5, 2022 at 23:38
• @emanresuA oh yeah duh, thanks Commented May 5, 2022 at 23:54
• 6 bytes by sorting instead of indexing: O%4µÞṪ Commented May 6, 2022 at 7:48
• @KevinCruijssen oh that's clever, thanks Commented May 6, 2022 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. Commented May 7, 2022 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^}н Commented May 6, 2022 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
Commented May 6, 2022 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
Commented May 7, 2022 at 8:34

# 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!

# 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!

# 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
Commented May 7, 2022 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;} Commented May 8, 2022 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[1]%4];}

Attempt This Online!

Returns the desired output in *s.

• Don't think this works for UF returns U not F as it should.. Commented May 6, 2022 at 17:50
• Fixed, it wrote %3 instead of %4. Commented May 7, 2022 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!

# A0A0, 92 bytes

I1L84S2M2V0G0
G-1G-1G-1G-1G-1
I1
G5
I1V0P0
G-1G-1
I1L84S2M2V0G0
G-1G-1G-1G-1G-1
P70

G2

P85


We first read input from stdin and then compare the ascii value of the character against 84 ('T').

I1  L84 S2  M2  V0  G0
G-1 G-1 G-1 G-1 G-1


'F' will be less than this and the operand becomes -1. 'T' is the same, so the opernad becomes 0 and 'U' is higher, so the operand becomes 1. We then jump to three different places depending on this value. The first place is when the character is 'F'.

I1
G5


Since every comparison against F will be an F, we only ask input because we must read two numbers - the input is never stored. We then jump five lines below which prints F.

I1  V0  P0
G-1 G-1


If the first input was T, then the result will simply by the second input. We read the second input and print it.

I1  L84 S2  M2  V0  G0
G-1 G-1 G-1 G-1 G-1


If the input is U, then we need to do a slightly more complex check. We read input and do another comparison against 84, jumping to three different places. Since we now know that the first input is U, each of these places can directly print the appropriate result: 'F' for 'F' and 'U' for both 'T' and 'U'. There are some slight optimizations made by only having a print instruction for each character once and then jumping towards this print from other places. Since the code has few lines, the instructions for jumping will be two bytes, whereas printing will be three bytes due to the double digit ascii value.

# Factor, 25 bytes

[ [ 4 mod ] supremum-by ]


Try it online!

i matched the best awk's 20-bytes with a very different approach

echo 'U\nB\nF'
U
B
F

echo 'U\nB\nF' | mawk -F\[^FU] NF=NF OFS=T | gcat -n

1  U
2  T
3  F