| Bytes | Lang | Time | Link |
|---|---|---|---|
| nan | Rust | 240831T124135Z | 138 Aspe |
| 052 | JavaScript Node.js | 240827T011728Z | l4m2 |
| 594 | Oracle SQL 11.2 | 240828T151244Z | Jeto |
| 127 | Clojure | 240903T135900Z | NikoNyrh |
| 109 | C gcc | 240831T014044Z | Consindi |
| 114 | C clang | 240828T135743Z | jdt |
| 117 | Scala 3 | 240831T021730Z | 138 Aspe |
| 011 | Brachylog | 240829T094440Z | Fatalize |
| 066 | R | 240827T191400Z | David Jo |
| 009 | Japt | 240827T064722Z | Shaggy |
| 049 | Ruby | 240827T170409Z | Jordan |
| 064 | Python 3 | 240827T175843Z | Jonathan |
| 071 | Python | 240826T215815Z | shape wa |
| 006 | 05AB1E | 240827T071746Z | Kevin Cr |
| 026 | Retina | 240827T104206Z | Neil |
| 1087 | Jelly | 240827T001136Z | Jonathan |
| 154 | Google Sheets | 240826T231658Z | doubleun |
| 069 | JavaScript ES6 | 240826T210254Z | Arnauld |
| 009 | Vyxal | 240826T212519Z | emanresu |
| 018 | Charcoal | 240826T210607Z | Neil |
| 023 | Jelly | 240826T191846Z | hyperneu |
Rust, 316 312 294 286 278 bytes
Saved 4+18+8+8=38 bytes thanks to @ceilingcat
Golfed version. Attempt This Online!
fn f<T:Clone>(x:&[T])->Vec<T>{let r:Vec<T>=(0..).zip(x).flat_map(|(i,b)|{x.iter().take(i).map(move|a|(a.clone(),b.clone()))}).into_iter().flat_map(|(a,b)|vec![a.clone(),a,b.clone(),b]).collect();let z=r.len()-1;let mut y=vec![r[z].clone()];y.extend(r.iter().take(z).cloned());y}
Ungolfed version. Attempt This Online!
fn two_element_combinations<T: Clone>(list: &[T]) -> Vec<(T, T)> {
list.iter()
.enumerate()
.flat_map(|(i, b)| {
list.iter()
.take(i)
.map(move |a| (a.clone(), b.clone()))
})
.collect()
}
fn f<T: Clone>(list: &[T]) -> Vec<T> {
let result: Vec<T> = two_element_combinations(list)
.into_iter()
.flat_map(|(a, b)| vec![a.clone(), a, b.clone(), b])
.collect();
let mut rotated = Vec::with_capacity(result.len());
rotated.push(result[result.len() - 1].clone());
rotated.extend(result.iter().take(result.len() - 1).cloned());
rotated
}
fn main() {
let result = f(&['a', 'b', 'c', 'd']);
println!("{:?}", result);
}
JavaScript (Node.js), 52 bytes
or 56 bytes if not flatten
f=([a,...x])=>x.flatMap(t=>[a,t,...f(x),t,...x=[a]])
JavaScript (Node.js), 71 bytes
f=([a,b,...x],y)=>b?[[a,b],...y||f([b,...x]),[b,a],...f([a,...x],[])]:x
- A->B
- f(ALL-A)
- B->A
- A->C->A, A->D->A, ...
Oracle SQL 11.2, 594 bytes
WITH v(s,i,j,r)AS(SELECT :1,1,LENGTH(:1),''FROM DUAL UNION ALL SELECT s,i+DECODE(j,i+1,1,0),DECODE(j,i+1,LENGTH(s),j-1),SUBSTR(s,i,1)||SUBSTR(s,j,1)FROM v WHERE j>i),l AS(SELECT i,j,r,1 p FROM v UNION ALL SELECT i,j,REVERSE(r),2 p FROM v),m AS(SELECT l.*,DECODE(p,1,0,DECODE(LAG(i,2,i)OVER(ORDER BY i,j DESC,p),i,0,j-i))o FROM l)SELECT LISTAGG(r)WITHIN GROUP(ORDER BY o,i,j DESC,p)FROM m;
Un-golfed
WITH v(s,i,j,r) AS --> Generate the pairs
(
SELECT :1 s
, 1 i
, LENGTH(:1) j
, '' r
FROM DUAL
UNION ALL
SELECT s
, i+DECODE(j,i+1,1,0)
, DECODE(j,i+1,LENGTH(s),j-1)
, SUBSTR(s,i,1)||SUBSTR(s,j,1)
FROM v
WHERE j>i
)
, l AS --> Add the reverse pairs
(
SELECT i,j,r,1 p
FROM v
UNION ALL
SELECT i,j,REVERSE(r),2 p FROM v
)
, m AS --> Add a new variable to order the pairs based on when the first item in the pair change
(
SELECT l.*
, DECODE(p,1,0,DECODE(LAG(i,2,i)OVER(ORDER BY i,j DESC,p),i,0,j-i))o
FROM l
WHERE r IS NOT NULL
)
SELECT LISTAGG(r)WITHIN GROUP(ORDER BY o,i,j DESC,p)
FROM m
;
Clojure, 127 bytes
#(first(filter(fn[i](=(set(map(fn[[x a][b y]](= a b))i(rest i)))#{true}))(iterate shuffle(for[a % b % :when(not= a b)][a b]))))
This turned out to be a bit... exotic. The list of greetings is shuffled until it satisfies the condition! So the runtime will be poor on larger groups of people. Is this O(n!) ?
Ungolfed with thread-last macro:
(def perm #(->> (for [a %
b %
:when (not= a b)]
[a b])
(iterate shuffle)
(filter (fn [i] (->> (map = (map second i)
(map first (rest i)))
set
(= #{true}))))
first))
TIO.
C (gcc), 109 bytes
n;main(c,s)char**s;{for(n=c;s[n]||(++s)[n=1];n++)printf("%s %s %s %s ",*s,s[n],s[n],s[!s[n+1]*(n-1?1:3-c)]);}
C (clang), 115 114 bytes
f(**s,n,*o){for(int*w,j=n-1,i=*o=0;i<n;i-=i-j&&!strstr(o,w)?j=i-!strcat(o,w):-1)asprintf(&w,"%s %s\n",s[j],s[i]);}
Ungolfed:
void func(char **s, int n, char *out) {
int i = 0;
int j = n - 1;
char pair[80];
*out = 0;
for (; i < n; i++) {
if (i != j) {
sprintf(pair, "%s %s\n", s[j], s[i]);
if (!strstr(out, pair)) {
strcat(out, pair);
j = i;
i = -1;
}
}
}
}
Scala 3, 117 bytes
Golfed version. Attempt This Online!
L=>{val r=L.zipWithIndex.flatMap{case(b,i)=>L.take(i).map(a=>(a,b))}.flatMap{case(a,b)=>Seq(a,a,b,b)};r.last+:r.init}
Ungolfed version. Attempt This Online!
object Main {
def twoElementCombinations[T](L: List[T]): Seq[(T, T)] = {
L.zipWithIndex.flatMap { case (b, i) =>
L.take(i).map(a => (a, b))
}
}
def f[T](L: List[T]): Seq[T] = {
val result = twoElementCombinations(L).flatMap { case (a, b) => Seq(a, a, b, b) }
val rotated = result.last +: result.init
rotated
}
def main(args: Array[String]): Unit = {
println(f(List('a', 'b', 'c', 'd')))
}
}
Brachylog, 11 bytes
{⊇Ċ}ᶠcgj↺ᵗz
Explanation
Same algorithm as most approaches.
{⊇Ċ}ᶠ Find all pairs
cgj Flatten and duplicate
↺ᵗ Shift duplicate cyclically to the left
z Zip
A more declarative approach, 18 bytes
{⊇Ċp}ᶠp.¬{s₂tʰhᵗ≠}
Explanation
Longer and less efficient, but easily readable.
{⊇Ċp}ᶠ Find all pairs, both permutations
p. The final output is a permutation of this list of all pairs
¬{ } Such that it is impossible…
s₂ To find two consecutive pairs…
tʰ Where the last element of the first pair…
hᵗ≠ Is different from the first element of the second pair
R, 66 bytes
This accepts a character vector of names x that needs to be specified beforehand:
for(i in 1:ncol(combn(x,2)))print(combinat::permn(combn(x,2)[,i]))
Japt, 11 9 bytes
à2 c
íUéJ
à2 c\níUéJ :Implicit input of array U
à2 :Combinations of length 2
c :Flatten
\n :Reassign to U
í :Interleave with
Ué : U rotated right
J : -1 times (i.e., rotated left)
Ruby, 49 bytes
Port of Jonathan Allan's Jelly answer; give him an upvote.
->a{(b=[*a.combination(2)].flatten).zip b.rotate}
Python 3, 64 bytes
I started by looking at shape warrior t's excellent Python 3 answer (go upvote!), but got to a slightly different solution in terms of both function and form, so went with a new post.
f=lambda h,*r:r and sum(((h,h,n,n)for n in r),r[-1:])[:-1]+f(*r)
A recursive function that accepts the names as arguments and returns a flat tuple of the names.
How?
f=lambda : # f is a function
, # that accepts:
h # h, the head name
*r # r, the rest of the names
r and # return r if empty, else...
sum( , ) # concatenate:
r[-1:] # the tail name
( for n in r) # and for each n(ame) in r:
(h,h,n,n) # (head, head, n, n)
[:-1] # and remove the very last n
+ # and concatenate
f( ) # a recursive call to f
*r # with just the rest
# (i.e. h will be the
# first of the rest)
Python, 88 74 71 bytes
lambda L:sum([[a,a,b,b]for b in L for a in L[:L.index(b)]],L[-1:])[:-1]
-14 bytes thanks to att, replacing a call to itertools.combinations. -3 bytes thanks to Jonathan Allan with a better way to get the iteration index. Outputs as a flattened list.
Ungolfed algorithm:
from collections import deque
def two_element_combinations(L):
for i, b in enumerate(L):
# In the golfed code: i == L.index(b) as names are unique
for a in L[:i]:
yield a, b
def f(L):
result = deque(x for a, b in two_element_combinations(L) for x in [a, a, b, b])
result.rotate() # a b c d -> d a b c
return result
Explanation
If we imagine a directed graph where vertices represent friends and edges represent introductions, this challenge algorithmically boils down to finding an Eulerian path in a complete digraph.
It turns out that (using example vertices A, B, C, D, E, F) the loop with the sequence of vertices
ABACBCADBDCDAEBECEDEAFBFCFDFEF is a valid Eulerian path. Grouping the vertices (which gives the edges that appear at even-numbered positions under 0-indexing), we have
AB AC BC AD BD CD AE BE CE DE AF BF CF DF EF, the two-element combinations of ABCDEF where the first element comes before the second. Rotating left by one yields
BACBCADBDCDAEBECEDEAFBFCFDFEFA, and regrouping (which gives the edges that appear at odd-numbered positions under 0-indexing) gives us
BA CB CA DB DC DA EB EC ED EA FB FC FD FE FA, the two-element combinations of ABCDEF where the first element comes after the second (in a slightly weird order -- combinations that end in A are moved to the end of their respective groups). Between these two groupings, every edge is accounted for exactly once in the entire path.
The output format in this challenge requires a sequence of edges, not vertices. The loop with vertices A B C D has the edges AB BC CD DA, or equivalently DA AB BC CD. The flattened form DAABBCCD can be produced from ABCD by doubling each vertex and rotating right by one.
In the actual code, we take the first list of two-element combinations, double both vertices in each combination, and then flatten and rotate the entire thing. For vertices A, B, C, D, the golfed code calculates rotate_right(flatten([AABB, AACC, ..., CCDD])) as
all_but_last(D + AABB + AACC + ... + CCDD).
05AB1E, 7 6 bytes
.ƘDÀø
Port of @JonathanAllan's Jelly answer, so make sure to upvote that answer as well!
-1 byte thanks to @JonathanAllan
Try it online or verify all test cases.
Explanation:
# e.g. input = [1,2,3]
.Æ # Create all possible pairs of the (implicit) input-list
# STACK: [[1,2],[1,3],[2,3]]
˜ # Flatten it
# STACK: [1,2,1,3,2,3]
D # Duplicate this list
# STACK: [1,2,1,3,2,3],[1,2,1,3,2,3]
À # Rotate the items in the copy once towards the left
# STACK: [1,2,1,3,2,3],[2,1,3,2,3,1]
ø # Zip to create pairs using both lists
# STACK: [[1,2],[2,1],[1,3],[3,2],[2,3],[3,1]]
# (after which the result is output implicitly)
Retina, 26 bytes
w`(.).*(.)
$1$1$2$2
V`.+\B
Try it online! Link includes test cases. Explanation:
w`(.).*(.)
$1$1$2$2
List all pairs of characters without replacement, but doubled.
V`.+\B
Mirror all but the last character of the string.
33 bytes to output using the order from A097285:
rw`(.).*(.)
$1$1$2$2
(.)(.+)
$2$1
Jelly, 10 8 7 bytes
ŒcẎṙ-żƊ
A monadic Link that accepts a list of names (lists of characters) and yields a list of pairs of names.
How?
ŒcẎṙ-żƊ - Link: Names
Œc - ordered pairs {Names} -> [[a,b],[a,c],...,[a,Z],[b,c],...[Y,Z]]
Ẏ - tighten -> [a,b,a,c,...,a,Z,b,c,...,X,Y,Z]
Ɗ - last three links as a monad - f(X=that):
- - -1
ṙ - rotate {X} left by -1 (rotate right by 1)
-> [Z,a,b,a,c,...,a,Z,b,c,...,X,Y]
ż - zip with {X} -> [[Z,a],[a,b],[b,a],[a,c],...,[a,Z],[Z,b],[b,c],...,[X,Y]]
Google Sheets, 154 bytes
=let(s," ",f,lambda(f,a,let(n,counta(a)-1,h,+a,t,choosecols(a,sequence(n,1,2)),if(n,join(s,sort(h&s&h&s&t&s&t),f(f,t)),))),mid(f(f,1:1),2+len(A1),9^9)&A1)
Put the names in row 1 and the formula in cell A2.
The formula takes the first name and pairs it with every name that follows it, repeating each name twice every time. Does the same recursively with remaining names, pairing each name with every name that follows it (but without pairing with preceding ones.) Finally, tidies up the head and tail with string manipulation.

Ungolfed:
=let(
s, " ",
f, lambda(f, a, let(
n, counta(a) - 1,
head, single(a),
tail, choosecols(a, sequence(n, 1, 2)),
if(n,
join(s,
sort(head & s & head & s & tail & s & tail),
f(f, tail)
),
""
)
)),
mid(f(f, { A1:1 }), 2 + len(A1), 9^9) & A1
)
Uses sort() as array enabler only.
Pretty much the same in JavaScript (non-competing):
f = a =>
a.slice(1)
.map(n => ([a[0], a[0], n, n]).join())
.join()
+ (a.length > 1 ? ',' + f(a.slice(1)) : '')
g = A => f(A).slice(A[0].length + 1) + A[0]
console.log(g(["Alice","Bob","Cole","Dave"])) // "Alice,Bob,Bob,Alice,Alice,Cole,Cole,Alice,Alice,Dave,Dave,Bob,Bob,Cole,Cole,Bob,Bob,Dave,Dave,Cole,Cole,Dave,Dave,Alice"
JavaScript (ES6), 69 bytes
Expects an array of strings and returns a flat list as a comma-separated string.
f=([v,...a],b=v)=>a.map((p,i)=>[v,p,p,a[i+1]?v:i?[a[0],f(a,b)]:b])+""
Method
Given \$n\$ elements, we do \$n-1\$ iterations from \$j=0\$ to \$j=n-2\$.
At each iteration, we generate:
- all the pairs of the form \$\color{blue}{(j,k)},\:j<k<n\$
- interleaved with the pairs of the form \$\color{green}{(k,j)},\:j<k<n-1\$
- followed by the pair \$\color{purple}{(n-1,j+1)}\$ if \$j<n-2\$ or \$\color{red}{(n-1,0)}\$ otherwise
With five elements, this gives:
$$\begin{aligned}&j=0:\color{blue}{(0,1)}\color{green}{(1,0)}\color{blue}{(0,2)}\color{green}{(2,0)}\color{blue}{(0,3)}\color{green}{(3,0)}\color{blue}{(0,4)}\color{purple}{(4,1)}\\ &j=1:\color{blue}{(1,2)}\color{green}{(2,1)}\color{blue}{(1,3)}\color{green}{(3,1)}\color{blue}{(1,4)}\color{purple}{(4,2)}\\ &j=2:\color{blue}{(2,3)}\color{green}{(3,2)}\color{blue}{(2,4)}\color{purple}{(4,3)}\\ &j=3:\color{blue}{(3,4)}\color{red}{(4,0)}\end{aligned}$$
Note that the actual JS implementation directly manipulates the entries of the original array rather than their indices.
Commented
f = ( // f is a recursive function taking:
[ v, // v = next element
...a ], // a[] = remaining elements
b = v // b = copy of the first element
) => //
a.map((p, i) => // for each element p at index i in a[]:
[ //
v, p, // insert the pair (v, p)
p, // insert the pair (p, X), where ...
a[i + 1] ? // if this is not the last element:
v // X = v
: // else:
i ? // if i > 0:
[ a[0], // X = a[0] followed by the result
f(a, b) // of a recursive call
] //
: // else (last iteration):
b // X = b
] //
) // end of map()
+ "" // coerce to a string
Vyxal, 9 bytes
KƛZṫwẊ;fǓ
Try it Online! Port of Neil's Charcoal answer.
Kƛ ; # Over every prefix
Z # Double each value
wẊ # Append the last value to
ṫ # The rest
fǓ # Flatten and move the first character to the end.
Vyxal, 14 bytes
₌ẊZFṖvf'zy∩≈;h
Brute force answer. 12 bytes by removing the ;h if we can output all solutions.
Ṗ # Permutations
Ẋ # Of all pairs in the input
₌ ZF # Aside from doubles of one item
vf # Flatten each
' ;h # Find one where
zy # Every other overlapping pair
∩≈ # Has all elements equal?
Charcoal, 18 bytes
Φ⭆θ⭆…θκ⁺ײλײικ§θ⁰
Try it online! Link is to verbose version of code. Explanation: A097285 is almost the sequence of indices, with each element doubled, except that there is only one of the first element at the start, the second coming at the end.
θ Input list
⭆ Map over letters and join
θ Input list
… Truncated to length
κ Current index
⭆ Map over letters and join
λ Inner letter
ײ Doubled
⁺ Concatenated with
ι Outer letter
ײ Doubled
Φ κ§θ⁰ Remove the first element and append it to the end
Jelly, 23 bytes
2œṖ$ÐƤṖUp/€żUẎṖƲ€Ẏ;Uṡ2Ɗ
pretty horribly long but it is fairly efficient and i kinda like the idea of it which is basically this: starting from the first person counting forwards, we introduce them to everyone starting from the last person counting backwards and do this back and forth until the next person, then we do not introduce them back, and we repeat this until we've done all of the introductions except each person to the one before them which we do at the end to close the loop
Explanation
2œṖ$ÐƤṖUp/€żUẎṖƲ€Ẏ;Uṡ2Ɗ main link
ÐƤ for each suffix of the list
2œṖ$ - partition at index 2, so split the first element off
Ṗ remove the last element (the single list)
U reverse (vectorizing) to flip the targets around
€ for each of these pairs
p/ - take their cartesian product to get each intro pair
Ʋ€ for each of these lists of intros
żU - interleave with the reverse
Ẏ - flatten by one level
Ṗ - remove the last element (the last back-intro)
Ẏ flatten by one level
; Ɗ append
Uṡ2 - each pair of [the original list reversed]