Brain-Teaser 900: World Cup goal scorers
From The Sunday Times, 5th November 1978 [link]
The Soccotia World Cup soccer squad consists of two goalkeepers and sufficient outfield players to ensure that each of these latter play in exactly two games, of the three scheduled. Each player is also allocated a consecutive number starting with one, including the goalkeepers. Each outfield player is equally capable of playing in defence and attack, but will not change from one role to another during the same game.
The manager selects the teams for each match such that the sum of the numbers of the outfield players remains constant for each game, and such that the sum of the numbers of the four defenders equals one half of the sum of the six attackers.
In each game Soccotia scored one goal, each of which was scored by an attacking player, three different players scoring one goal each.
In the first game, the goal resulted from a five man move involving four passes. The move was started by a defender, who was the only defender in the move. Each pass was made to a player whose number was a fixed integer multiple of the passer.
In the second game, the same four players were chosen to play in defence as in the first game, and the same defender started the five man/four pass move which led to the goal scored in this game. This time however the number of each player receiving the ball exceeded the number of the passer by a fixed integer.
In the third game the five man/four pass move leading to the goal followed the same pattern as that scored in the second game.
What were the numbers of the goalscorers in match order?
News
There are now 900 Teaser puzzles available on the site, so I thought it appropriate to post Teaser 900.
[teaser900]
Jim Randell 10:32 am on 6 July 2023 Permalink |
In each match the team consists of 11 players (1 goalkeeper, 4 defenders, 6 attackers).
In the 3 games with 30 slots for outfield (= non-goalkeeper) players, each member of the squad fills 2 slots, so there are 15 outfield members, and 17 members of the squad in total. So they are numbered from 1-17.
This Python program starts by forming possible geometric and arithmetic sequences from the available numbers, and then selects attackers and defenders for each match based on the specified requirements. Once we have 3 matches we check there are 2 unused numbers for the goalkeepers, and then determine the scorers in each match.
The program runs in 296ms.
from enigma import (irange, subsets, repeat, div, multiset, printf) # numbers 1 .. 17 ns = set(irange(1, 17)) # form possible geometric and arithmetic sequences gseqs = list() aseqs = list() # consider the first 2 terms for (a, b) in subsets(sorted(ns), size=2): # geometric? n = div(b, a) if n: ss = tuple(repeat((lambda x: x * n), a, 4)) if ns.issuperset(ss): gseqs.append(ss) # arithmetic? n = b - a ss = tuple(repeat((lambda x: x + n), a, 4)) if ns.issuperset(ss): aseqs.append(ss) # choose a geometric sequence for the first game for seq1 in gseqs: # the sequence consists of 1d + 4a (d1, a1s) = (seq1[0], seq1[1:]) # choose 2 more attackers to give an even sum (= 2t) for atts1 in subsets(ns.difference(seq1), size=2, fn=set): atts1.update(a1s) t = div(sum(atts1), 2) if t is None: continue # choose 3 defenders to bring their total to t for defs1 in subsets(ns.difference(atts1, {d1}), size=3, fn=set): defs1.add(d1) if sum(defs1) != t: continue # in the second game we have the same 4 defenders defs2 = defs1 h2 = sum(defs2) # find an arithmetic sequence that starts with d1 ... for seq2 in aseqs: if seq2[0] != d1: continue # and ends in an attacker a2 = seq2[-1] if a2 == seq1[-1] or a2 in defs2: continue # any player in the sequence that is not a defender is an attacker a2s = set(seq2).difference(defs2) # find more attackers to give a sum of 2 * t for atts2 in subsets(ns.difference(defs2, a2s), size=6 - len(a2s), fn=set): atts2.update(a2s) if sum(atts2) != 2 * t: continue # find out who has already played twice m = multiset.from_seq(defs1, atts1, defs2, atts2) p2s = set(k for (k, v) in m.items() if v == 2) # find an arithmetic sequence for game 3 that doesn't involve p2s for seq3 in aseqs: if not p2s.isdisjoint(seq3): continue # the sequence starts with a defender and ends with an attacker a3 = seq3[-1] if a3 == seq1[-1] or a3 == seq2[-1]: continue d3 = seq3[0] # choose 3 more defenders to bring the sum to t for defs3 in subsets(ns.difference(p2s, {d3, a3}), size=3, fn=set): defs3.add(d3) if sum(defs3) != t: continue # any player in the sequence that is not a defender is an attacker a3s = set(seq3).difference(defs3) # find more attackers to give a sum of 2 * h3 for atts3 in subsets(ns.difference(p2s, defs3, a3s), size=6 - len(a3s), fn=set): atts3.update(a3s) if sum(atts3) != 2 * t: continue # find the goalkeepers (not involved in any match so far) gs = ns.difference(defs1, atts1, defs2, atts2, defs3, atts3) if len(gs) != 2: continue # find the scorers ss = (seq1[-1], seq2[-1], seq3[-1]) # output solution fmt = sorted printf("1: defs={defs1} atts={atts1} {seq1}", defs1=fmt(defs1), atts1=fmt(atts1)) printf("2: defs={defs2} atts={atts2} {seq2}", defs2=fmt(defs2), atts2=fmt(atts2)) printf("3: defs={defs3} atts={atts3} {seq3}", defs3=fmt(defs3), atts3=fmt(atts3)) printf("goalies = {gs}", gs=fmt(gs)) printf("scorers = {ss}") printf()Solution: The goalscorers were: 16, 9, 8.
The squad for the first match was:
This is the only possible geometric sequence using the allowed numbers.
The numbers of the defenders sum to 28, and the numbers of the attackers sum to 56.
The squad for the second match was:
And the squad for the third match was one of the following:
Each of the outfield player has played in 3 matches, and the remaining members of the squad, 10 and 17, are the goalkeepers.
The goal scorers are the final players in the three sequences: 16, 9, 8.
LikeLike
Frits 8:22 pm on 6 July 2023 Permalink |
from itertools import combinations N = 17 # return all arithmetic sequences in sorted seq, len=5 [x, k + x, ... , 4k + x] def ametric(seq): for x in seq[:-4]: for k in range(1, 5): if 4 * k + x > seq[-1]: break if all(x + i * k in seq for i in range(5)): yield (x, 4 * k + x) # yield first and last # decompose <t> into <n> different numbers, min/max, excluding <xs> elements def decompose(t, n, xs, m=1, M=17, s=[]): if n == 1: if m <= t <= M and t not in xs: yield s + [t] else: # still n - 1 numbers to follow with minimal sum m+1 + m+2 + .. + m+n-1 # or (n - 1)m + n(n-1)/2 for x in range(m, min(M + 1, t - (n - 1) * m + n * (n - 1 ) // 2 + 1)): if x not in xs: yield from decompose(t - x, n - 1, xs, x + 1, M, s + [x]) # round 1: defs = [fd, x, y, z], atts = {k*fd, k**2fd, k**3fd, k**4fd, a, b} # geometric sequences for fd, geo in [(fd, {fd * m**i for i in range(5)}) for fd in range(1, int(N**.25) + 1) for m in range(2, int((N / fd)**.25) + 1)]: s1 = max(geo) # scorer in round 1 # choose 2 remaining attackers in round 1 for a, b in combinations(set(range(1, N + 1)).difference(geo), 2): if (a + b) % 2: continue # a + b is even atts_1 = geo.difference([fd]) | {a, b} sum_atts = sum(atts_1) # can we make defender sum (minus fd) from choosing 3 from leftovers? for d in decompose(sum_atts // 2 - fd, 3, {fd} | atts_1): d = {fd} | set(d) sumd = sum(d) # make an arithmetic sequence [fd, k + fd, ... , 4k + fd] for k in range(1, 5): # different scorer must be an attacker if (s2 := 4 * k + fd) == s1 or s2 in d: continue # already known attackers in round 2 atts_2_1 = set(fd + i * k for i in range(5)).difference(d) # only one attacker played in both round 1 and round 2 # so exactly 10 outfield players remain for round 3 if len(both := atts_1 & atts_2_1) > 1: continue # choose remaining attackers in round 2 for d2 in decompose(sum_atts - sum(atts_2_1), 6 - len(atts_2_1), d | atts_2_1 | (atts_1 if both else set())): atts_2 = atts_2_1 | set(d2) # only one attacker played in both round 1 and round 2 if len(p11 := atts_1 | atts_2) != 11: continue # pick players who played only one game in round 1 and 2 p3 = sorted(p for p in p11 if p not in atts_1 or p not in atts_2) # sum of the numbers of the outfield players remains constant if sum(p3) != 3 * sumd: continue # build list of possible defenders defss = list(decompose(sumd, 4, set(range(1, N + 1)).difference(p3))) # can we make an arithmetic sequence [x, k + x, ... , 4k + x]? for (f, s3) in ametric(p3): # three different players scoring one goal each if s3 in {s1, s2}: continue # the sequence starts with a defender and ends with an attacker if any(s3 not in defs and f in defs for defs in defss): print(f"answer: {s1}, {s2} and {s3}")LikeLike