Can this Scottish village have a wedding?
Python 2, 399 393 390 388 385 bytes
def f(s):
V=S(''.join(s))-S(' |+-^');P={v:[]for v in V}
for j,r in E(s):
for i,c in E(r):
if'+'==c:
p,q=a=h(r,i);A=a+P[p][:2]+P[q][:2];V-=S(a);v=j;b='|'
while'z'<b:v+=1;b=s[v][i]
if'^'==b:w,x=h(s[v],i);P[w]=P[x]=A
else:P[b]=A
return 1-all((b>'Z')==(c>'Z')or S(P[b])&S(P[c])for b in V for c in V)
h=lambda r,i:[x.strip('-')[0]for x in r[i-1::-1],r[i+1:]]
E=enumerate;S=set
Try it online!
2 bytes thx to Jitse; 3 bytes thanks to isaacg.
Jeez! I think I could golf this a bit more; but at least I got it under 400 bytes :).
The input s
is a list of strings. The encoding is A-Z
for males, a-z
for females, +
to indicate a marriage, ^
for when a marriage produces 2 children (instead of =
, 'cause I liked the look better :) ). Then -
for horizontal extensions, |
for vertical extensions.
Output is 1
for truthy, 0
for falsey.
V
is the set of all villagers, initially; then as we scan, we will remove from V
those who are already married. So at the end, V
will be the set of un-mated villagers.
P
is a dictionary with keys for all villagers v
. P[v]
will be the list of those parents of v
, followed those grandparents of v
, who are also villagers. Note that then P[v][:2]
are the parents of v
(assuming they are villagers).
h
is a helper function to skip over any horizontal extensions (runs of -
). Useful both for extracting a pair of parent villagers as well as dual children.
Jelly, 155 153 bytes
Ø.UAƭN,Ɗ⁺+Ṫ¥+œị⁾+|yⱮ$ɼ=⁾|=⁼Ø.Ɗɗ¡ƬṪ¥ƒ⁸’1¦⁺œị®⁼”|ƊпṖṪ+2¦œị®⁻1Ɗ¡ƬṪ¥ⱮØ+$“”¹?
o@e¥€€ØẠ“-=“==”;U¤œṣjƭƒ$€ƬṪ©=1ŒṪ+2¦œị®ɗⱮØ+f⁾-+ƊÐḟWÇ€Ẏ$Ƭḣ3ẎƲ€Œcf/ÐḟḢ€€ȧœị¥>”ZIFẸ
Try it online!
Minor modification of my Cyrillic version.
A monadic link that takes a list of Jelly strings and returns 1 for true and 0 for false. I’m sure this could be golfed more. Full explanation to follow.