| Bytes | Lang | Time | Link |
|---|---|---|---|
| 075 | Python 3.8 | 241122T043555Z | Jonathan |
| 111 | Haskell | 241120T174135Z | colossus |
| 1420 | Jelly | 241121T012337Z | Jonathan |
| 117 | Python 3 | 241121T055050Z | tsh |
| 022 | 05AB1E | 241120T164730Z | Kevin Cr |
| 118 | JavaScript Node.js | 241121T063237Z | l4m2 |
| 140 | Python | 241121T015123Z | Albert.L |
| 121 | JavaScript V8 | 241120T171419Z | Arnauld |
| 060 | Charcoal | 241121T013552Z | Neil |
| 302 | Python3 | 241120T161119Z | Ajax1234 |
Python 3.8, 87 75 bytes
-12 bytes thanks to Albert.Lang!
def f(C,p=[1]):[p[0]//c and f(C-{c},[c]+p)for c in C]or[0]<p!=print(p[:-1])
A function that accepts a set of children represented as the first \$n\$ positive even integers (girls) and the first \$k\$ negative even integers (boys), where greater absolute values are older, and prints the restricted parades that employ all these children.
Stricter I/O version, 113 97 bytes
-16 using similar methods to Albert.lang's golf of the other one.
def f(n,k,p=[.5,0]):[p[0]//c and f(n,k,[c]+p)for c in{*range(-k,n+1)}-{*p}]or[0]<p!=print(p[:-2])
A function that accepts the number of girls, \$n\$, and the number of boys \$k\$ and prints the restricted parades, where girls are positive integers and boys are negative integers and greater absolute values are older.
Haskell, 120 112 111 bytes
f=filter
[]#_=[[]]
c#p=[o:r|o<-c,odd(o+p)||o>p,r<-f(/=o)c#o]
n!k=f(odd.last)$([2,4..2*n]++[1,3..2*k-1])#(2*k+1)
Uses even numbers for girls and odd numbers for boys.
c#p takes a list of children c, and a previous child p and generates a list of all parades of those children that can follow after p. It iterates over each child o in turn and skips over anyone with the same parity as p unless they're bigger than p was and prepends that child to each parade generated by the recursive call. The recursive call has the same list of children but with o removed and setting p to o.
We initialize p to be an odd number bigger than all the other boys to ensure we choose a girl to lead the parade and then all we have to do is use filter to only get parades that end with an odd value.
EDIT: -8 bytes thanks to @xnor's idea to use odd(o+p) to check if the parities are different.
EDIT: -1 byte thanks to @Wheat Wizard's idea to make an alias for filter.
Jelly, (14?) 20 bytes
14 if we may accept a list of boys and girls in the defined output specification (drop the leading RḤN0¦F).
RḤN0¦FŒ!Ø-j_«×ɗƝṠƲÐṂ
A monadic Link that accepts a pair of positive integers, \$(n, k)\$, and yields a list of lists of parades where the girls are the first \$n\$ positive even* integers and the boys are the first \$k\$ negative even* integers, and amongst each greater means older.
* I only used even numbers to save a byte by moving the Double (Ḥ) atom outside of the filter as Ʋ is the longest monadic chaining quick.
How?
RḤN0¦FŒ!Ø-j_«×ɗƝṠƲÐṂ - Link: positive integers [#Girls, #Boys]
R - range -> [[1..#Girls],[1..#Boys]]
Ḥ - double
N0¦ - negate the boys
F - flatten
Œ! - all permutations
ÐṂ - keep those minimal under:
Ʋ - last four links as a monad - f(Permutation):
Ø- - [-1, 1]
j - join with {Permutation}
Ɲ - for neighbouring pairs:
ɗ - last three links as a dyad - f(L, R):
_ - {L} minus {R} (negative if L < R)
× - {L} times {R} (negative if sign(L) != sign(R))
« - {L-R} minimum {L×R} (negative if either of the above)
Ṡ - signs -> list of -1s and 1s
(A list of only -1s identifies a restricted parade)
Python 3, 117 bytes
def f(y,o,r="",b=0,e="",p=""):
o+e==y[-b:]<y==print(r+y)
for v in y:y=y[1:];f(p,o,r+v,b,y+e);f(o,p+y+e,r+v,~b);p+=v
Python 3, 128 bytes
f=lambda y,o,b=0,e="":o+e==y[1:]and-b*[*y]or[v+t for i,v in enumerate(y)for t in f(y[:i],o,b,y[i+1:]+e)+f(o,y[:i]+y[i+1:]+e,~b)]
05AB1E, 23 22 bytes
L`(«œʒ.γd}€ü‹˜P}ʒÁ2£dJ
Input as a pair \$[g,b]\$. Output as a list of lists, using positive integers in the range \$[1,g]\$ for girls and negative integers in the range \$[-b,-1]\$ for boys.
Try it online or verify all test cases (and their sizes).
Explanation:
L # Convert both values in the (implicit) input to a [1,v]-ranged list
` # Pop and push both lists to the stack
( # Negate the second list (of boys)
« # Merge the two lists together to a single flattened list
œ # Take all permutations of this list
ʒ # Filter it by:
.γ # Adjacent group by:
d # Non-negative (>=0) check
} # Close the adjacent group by
# (the alternating groups each contain the same gender)
€ # Map over each group
ü # Map over each overlapping pair in this group:
‹ # Check that the first value is smaller/younger than the second
˜ # Flatten this list of lists of checks
P # Verify that all checks were truthy by taking the product
}ʒ # After the filter: filter further:
Á # Rotate the valid parade-list once clockwise
2£ # Pop and keep the first two values: [last,first]
d # Non-negative check on both: [last>=0,first>=0]
J # Join the checks together
# (only 1 is truthy in 05AB1E, so this will only be truthy for
# "01", aka `last<0 && first>=0`)
# (after which the filtered list of lists is output implicitly)
JavaScript (Node.js), 118 bytes
g=>q=(b,i=0,e=b,...z)=>g+b?[...1/z[i]?q(b,i+1,...z,e):[],...q(--b,0,b,...z,e)]:z.every(t=>t>0^b>0|b>(b=t))&b<=0?[z]:[]
114 from Arnauld's. Not sure which is actually shorter since different output method
Python, 140 bytes
f=lambda w,m,p=1:[G+R for G in s(w)[1:-1]for R in f(m,sorted({*w}-{*G}),-p)]+p*[w+m]
s=lambda p:p and(X:=s(p[1:]))+[p[:1]+i for i in X]or[p]
History:
Python, 147 bytes
f=lambda w,m,p=1:[G+R for G in s(w)[1:-1]for R in f(m,sorted({*w}-{*G}),-p)]+p*[w+m]
s=lambda p:[p][p>[]:]or sum([[i,i+p[:1]]for i in s(p[1:])],[])
Python, 154 bytes
f=lambda w,m,p=1:[G+R for G,g in s(w)[1:-1]for R in f(m,g,-p)]+p*[w+m]
s=lambda p:[x for i,o in(p and s(p[1:]))for x in[(i,p[:1]+o),(p[:1]+i,o)]]or[(p,p)]
Python, 168 bytes
f=lambda w,m:[G+B+R for G,g in s(w)[1:-1]for B,b in s(m)[1:-1]for R in f(g,b)]+[w+m]
s=lambda p:[x for i,o in(p and s(p[1:]))for x in[(i,p[:1]+o),(p[:1]+i,o)]]or[(p,p)]
This feels terribly clumsy ...
Takes girls and boys as lists of identifiers assuming their order is by age.
How?
Note that every stretch of girls or boys is completely determined once the set of girls or boys as been picked, IOW their order is forced. We therefore are looking for all ordered partitions of girls and boys into the same number of nonempty sets.
This code implements the obvious recursion to enumerate such partitions. At each depth the leftover girls and boys are split into 2 and 2 nonempty sets ("fixed" and "leftover") in all ways possible (function s), the fixed are fixed and the leftover are recursed over.
JavaScript (V8), 121 bytes
Expects (n)(k). In the output, girls are numbered from \$0\$ to \$n-1\$ and boys are numbered from \$n\$ to \$n+k-1\$.
n=>g=(k,a=[...Array(n+k).keys()],...p)=>a.map(v=>(x=v<n,p+p?x/a?0:k<n^x|v>k:x)&&g(v,a.filter(V=>v-V),...p,v))+a||print(p)
Hacked version to print the number of permutations
Commented
n => // outer function taking n = number of girls
g = ( // g = inner recursive function taking:
k, // k = initial call: number of boys
// then: last inserted value in the permutation
a = [ // a[] = array of integers
...Array(n + k) // from 0 to n+k-1
.keys() //
], //
...p // p[] = current permutation, initially empty
) => //
a.map(v => // for each value v in a[]:
( //
x = v < n, // x = flag set if v is a girl
p + p ? // if p[] is not empty:
x / a ? // x / a is truthy if x = 1 and a[] is a singleton
// i.e. v is a girl and the last item to be inserted:
0 // which is invalid
: // otherwise this is valid if:
k < n ^ x // either the neighbors have different genders
| v > k // or the new one is older than the previous one
: // else (first insertion):
x // it must be a girl
) && // if truthy:
g( // do a recursive call:
v, // set n = v
a.filter( // pass a copy of a[] ...
V => v - V // ... where v is removed
), //
...p, v // append v to p[]
) // end of recursive call
) + a // end of map()
|| print(p) // if a[] is empty, print the final permutation
Charcoal, 69 60 bytes
≔⁺…·¹N±…·¹Nθ⊞υ⟦⟧FυF⁻θιF∨›⁰×↨ι⁰κ›↨ι⁰κ⊞υ⁺ι⟦κ⟧EΦυ∧⁼LιLθ‹⁰↨ι⁰⭆¹ι
Try it online! Link is to verbose version of code. Uses negative integers for girls and positive integers for boys where older children have larger absolute value. Explanation:
≔⁺…·¹N±…·¹Nθ
Make a list of all of the boys and girls.
⊞υ⟦⟧Fυ
Start by considering only sequences starting with a girl. This works because an empty polynomial evaluates to zero, which the code sees as a newborn boy, thus only allowing a girl as the first element.
F⁻θι
For each sequence, consider all remaining girls and boys.
F∨›⁰×↨ι⁰κ›↨ι⁰κ
If the next child has the opposite sex, or is younger, then...
⊞υ⁺ι⟦κ⟧
... add the sequence with that child to the sequences under consideration.
EΦυ∧⁼LιLθ‹⁰↨ι⁰⭆¹ι
Output the sequences that ended with a boy.
Python3, 302 bytes
def f(g,b):
u,c=[[],[]],0
while any([t:=len(u[0])<g,T:=len(u[1])<b]):
if t and c%2:u[0]+=[c]
if T and not c%2:u[1]+=[c]
c+=1
q=[({*u[0]+u[1]},[])]
for P,t in q:
if not P:
if not t[0]%2 and t[-1]%2:yield t
continue
for i in P:
if[]==t or t[-1]%2!=i%2 or t[-1]<i:q+=[(P-{i},t+[i])]