Should we be friends?
SWI-Prolog, 62 47 41 bytes
X*Y:-X+Y;Y+X;X==Y.
X?Y:-not(X*Y),X*Z,Y*Z.
Prolog isn't too often useful, but when it is it's just beautiful. We'll use a+b
to notate that a
is friends with b
, a*b
that a
knows b
and a?b
that b
should be suggested to a
or not. The first line simply says that X*Y
is true if either X+Y
, Y+X
or X == Y
is true. This implements the symmetry of knowing eachother. Asking if there should be a suggestion is incredibly simple. We just ask if there is a Z
such that X*Y
is false and X*Z
and Y*Z
is true. Exactly as described in the challenge.
If you save this as a file (e.g. friends.pl
) and open SWI-Prolog with this file (prolog -l friends.pl
) you get dropped into a REPL.
You can assert friendships like this:
assert('a' + 'b').
assert('a' + 'c').
assert('b' + 'd').
You can check if people know eachother or suggestion should be made:
'a'*'b'.
'a'?'d'.
PHP, 138 133 129 bytes
PHP beats Mathematica - a rare occurence.
for(;$s=fgets(STDIN);$s>G?print$$a[$b]?$s<L:$s>L&&@array_intersect_key($$a,$$b):$$a[$b]=$$b[$a]=1)[,$a,$b]=explode(" ",trim($s));
prints 1
for truthy, empty string for falsy. Run with -nr
or test it online.
needs PHP 7.1 for the list assignment; user names are case sensitive and should exclude a
, b
, s
.
breakdown
for(;$s=fgets(STDIN); # loop through input
$s>G # 2. evaluate command
?print$$a[$b]
# command KNOW: true if $$a[$b]
?$s<L
# command SUGGEST: true if !$$a[$b] and array_intersect_key returns truthy
:$s>L&&@array_intersect_key($$a,$$b)
# command FRIEND: set keys in $$a and $$b
:$$a[$b]=$$b[$a]=1
)
[,$a,$b]=explode(" ",trim($s)); # 1. parse user names to $a and $b
$s
has to be trimmed because it includes the newline character.array_intersect_key
has to be muted or it would yield warnings for empty$$a
or$$b
.+18+15 bytes for all user names: Replace$$a
with$f[$a]
and$$b
with$f[$b]
.
CMD (Batch), 50 + 20 + 135 = 205 bytes
FRIEND.CMD
@for %%f in (%1.%1 %1.%2 %2.%2 %2.%1)do @set %%f=1
KNOW.CMD
@call echo(%%%1.%2%%
Prints
1
for friends, a blank line for strangers.SUGGEST.CMD
@call set k=0%%%1.%2%% @set k=1&if %k%==0 for /f "tokens=2 delims=.=" %%f in ('set %1.')do @call set k=%%k%%%%%%f.%2%% @echo(%k:~1,1%
Prints
1
or a blank line. I think six consecutive%
s might be a new personal best.