Teaser 2612: Star signs
From The Sunday Times, 14th October 2012 [link] [link]
Five friends, Abel, Bob, Jedd, Tim and Will, were investigating birthdays. Abel commented that there was just one letter of the alphabet that occurred in both his star sign and in his month of birth.
After further investigation he found that for any pair of his star sign, his month of birth, his name, and the day of the week on which he was born, just one letter of the alphabet occurred in both. Remarkably, the same turned out to be true for each of the friends.
Their names are listed alphabetically. What, respectively, are their star signs?
[teaser2612]








Jim Randell 5:29 pm on 30 April 2024 Permalink |
This is a “grouping” style problem (for which there is a solver in enigma.py), but in this case the non-primary values (i.e. signs, month, day) can be re-used, and the signs and months are not independent (i.e. a particular sign spans two consecutive months).
This Python program runs in 67ms. (Internal runtime is 4.4ms).
from enigma import grouping # names names = "Abel Bob Jedd Tim Will".split() # map months -> month number months = "January February March April May June July August September October November December".split() months = dict((x, i) for (i, x) in enumerate(months, start=1)) # map signs -> valid month numbers signs = { "Aries": {3, 4}, "Taurus": {4, 5}, "Gemini": {5, 6}, "Cancer": {6, 7}, "Leo": {7, 8}, "Virgo": {8, 9}, "Libra": {9, 10}, "Scorpio": {10, 11}, "Sagittarius": {11, 12}, "Capricorn": {12, 1}, "Aquarius": {1, 2}, "Pisces": {2, 3}, } # days days = "Monday Tuesday Wednesday Thursday Friday Saturday Sunday".split() # check a (<name>, <sign>, <month>, <day>) group def check(n, s, m, d, fn=grouping.share_letters(1)): # sign/month should match, as well as the shared letters return (months[m] in signs[s]) and fn(n, s, m, d) # find candidate groups (allowing repeated values) grouping.solve([names, signs.keys(), months.keys(), days], check, distinct=0)Solution: The star signs are: Pisces, Virgo, Leo, Virgo, Leo.
The full solution is:
LikeLike
Ruud 4:14 am on 2 May 2024 Permalink |
Here’s my solution:
import itertools def day_month_to_zodiac(day, month): signs = [ ("capricorn", 19), ("aquarius", 18), ("pisces", 20), ("aries", 19), ("taurus", 20), ("gemini", 20), ("cancer", 22), ("leo", 22), ("virgo", 22), ("libra", 22), ("scorpio", 21), ("sagittarius", 21), ("capricorn",), ] return signs[month - (day <= signs[month - 1][1])][0] month_names = "x january febuary march april may june july august september october november december".split() weekday_names = "monday tuesday wednesday thursday friday saturday sunday".split() for first_name in "abel bob jedd tim will".split(): for month, weekday_name in itertools.product(range(1, 13), weekday_names): month_name = month_names[month] for zodiac_name in (day_month_to_zodiac(1, month), day_month_to_zodiac(31, month)): if all(len(set(c0) & set(c1)) == 1 for c0, c1 in itertools.combinations((first_name, month_name, zodiac_name, weekday_name), 2)): print(first_name, zodiac_name, month_name, weekday_name)LikeLike
Frits 11:24 am on 2 May 2024 Permalink |
first_names = "abel bob jedd tim will".split() zodiac_names = "capricorn aquarius pisces aries taurus gemini cancer " \ "leo virgo libra scorpio sagittarius".split() month_names = "january febuary march april may june july august " \ "september october november december".split() weekday_names = "monday tuesday wednesday thursday " \ "friday saturday sunday".split() # does sequence <x> share exactly one item with all sequences in <g> share1 = lambda x, g: all(len(set(x).intersection(z)) == 1 for z in g) sols = [] for m, mo in enumerate(month_names, start=1): for zo in (zodiac_names[m - 1], zodiac_names[m % 12]): if not share1(zo, [mo]): continue for wd in weekday_names: if not share1(wd, [mo, zo]): continue for nm in first_names: if not share1(nm, [mo, zo, wd]): continue sols.append((nm, zo)) print(', '.join(x[1] for x in sorted(sols)))LikeLike