Consider an arbitrary set of letters\$L\$. It may either be\$\{A, B, C\}\$,\$\{M, N, O, P\}\$,\$\{N, F, K, D\}\$, or even contain all the 26 letters. Given an instance of\$L\$ and a positive integer\$n\$, how many\$n\$-letter words can we build from\$L\$ such that no adjacent letters are the same (so for example ABBC is not allowed from\$\{A, B, C\}\$)?
This can be solved using combinatorics, but what those words are?
Input
A non-emptystring\$L\$ and a positive integer\$n > 0\$.
You choose to accept only lowercase letters, only uppercase letters, or both, as input for\$L\$.
Also, note that a valid\$L\$ won't contain any duplicate letters, soABCA is an invalid input and should not be handled.
Output
A list of all strings of length\$n\$ that can be formed from\$L\$ such that no adjacent letters are the same.
You can repeat letters, so a valid solution for\$L=\{A, B, C\}\$ and\$n=3\$ is ABA, ABC, ACB, ACA, BAC, BCA, BAB, BCB, CAB, CBA, CAC and CBC.
Also note that\$|L| < n\$ is possible, so a valid solution for\$L=\{A, B\}\$ and\$n=3\$ is only ABA and BAB.
And yes,\$|L| > n\$ is also possible, so a valid solution for\$L=\{A, B, C, D\}\$ and\$n=3\$ is ABA, ABC, ABD, ACA, ACB, ACD, ADA, ADB, ADC, BAB, BAC, BAD, BCA, BCB, BCD, BDA, BDB, BDC, CAB, CAC, CAD, CBA, CBC, CBD, CDA, CDB, CDC, DAB, DAC, DAD, DBA, DBC, DBD, DCA, DCB and DCD.
The output doesn't have to be in a particular order.
Test samples
ABC, 3 -> ABA, ABC, ACA, ACB, BAB, BAC, BCA, BCB, CAB, CAC, CBA, CBCAB, 3 -> ABA, BABABCD, 3 -> ABA, ABC, ABD, ACA, ACB, ACD, ADA, ADB, ADC, BAB, BAC, BAD, BCA, BCB, BCD, BDA, BDB, BDC, CAB, CAC, CAD, CBA, CBC, CBD, CDA, CDB, CDC, DAB, DAC, DAD, DBA, DBC, DBD, DCA, DCB, DCDOKAY, 2 -> OK, OA, OY, KO, KA, KY, AO, AK, AY, YO, YK, YACODEGLF, 3 -> COC, COD, COE, COG, COL, COF, CDC, CDO, CDE, CDG, CDL, CDF, CEC, CEO, CED, CEG, CEL, CEF, CGC, CGO, CGD, CGE, CGL, CGF, CLC, CLO, CLD, CLE, CLG, CLF, CFC, CFO, CFD, CFE, CFG, CFL, OCO, OCD, OCE, OCG, OCL, OCF, ODC, ODO, ODE, ODG, ODL, ODF, OEC, OEO, OED, OEG, OEL, OEF, OGC, OGO, OGD, OGE, OGL, OGF, OLC, OLO, OLD, OLE, OLG, OLF, OFC, OFO, OFD, OFE, OFG, OFL, DCO, DCD, DCE, DCG, DCL, DCF, DOC, DOD, DOE, DOG, DOL, DOF, DEC, DEO, DED, DEG, DEL, DEF, DGC, DGO, DGD, DGE, DGL, DGF, DLC, DLO, DLD, DLE, DLG, DLF, DFC, DFO, DFD, DFE, DFG, DFL, ECO, ECD, ECE, ECG, ECL, ECF, EOC, EOD, EOE, EOG, EOL, EOF, EDC, EDO, EDE, EDG, EDL, EDF, EGC, EGO, EGD, EGE, EGL, EGF, ELC, ELO, ELD, ELE, ELG, ELF, EFC, EFO, EFD, EFE, EFG, EFL, GCO, GCD, GCE, GCG, GCL, GCF, GOC, GOD, GOE, GOG, GOL, GOF, GDC, GDO, GDE, GDG, GDL, GDF, GEC, GEO, GED, GEG, GEL, GEF, GLC, GLO, GLD, GLE, GLG, GLF, GFC, GFO, GFD, GFE, GFG, GFL, LCO, LCD, LCE, LCG, LCL, LCF, LOC, LOD, LOE, LOG, LOL, LOF, LDC, LDO, LDE, LDG, LDL, LDF, LEC, LEO, LED, LEG, LEL, LEF, LGC, LGO, LGD, LGE, LGL, LGF, LFC, LFO, LFD, LFE, LFG, LFL, FCO, FCD, FCE, FCG, FCL, FCF, FOC, FOD, FOE, FOG, FOL, FOF, FDC, FDO, FDE, FDG, FDL, FDF, FEC, FEO, FED, FEG, FEL, FEF, FGC, FGO, FGD, FGE, FGL, FGF, FLC, FLO, FLD, FLE, FLG, FLFNFKD, 4 -> NFNF, NFNK, NFND, NFKN, NFKF, NFKD, NFDN, NFDF, NFDK, NKNF, NKNK, NKND, NKFN, NKFK, NKFD, NKDN, NKDF, NKDK, NDNF, NDNK, NDND, NDFN, NDFK, NDFD, NDKN, NDKF, NDKD, FNFN, FNFK, FNFD, FNKN, FNKF, FNKD, FNDN, FNDF, FNDK, FKNF, FKNK, FKND, FKFN, FKFK, FKFD, FKDN, FKDF, FKDK, FDNF, FDNK, FDND, FDFN, FDFK, FDFD, FDKN, FDKF, FDKD, KNFN, KNFK, KNFD, KNKN, KNKF, KNKD, KNDN, KNDF, KNDK, KFNF, KFNK, KFND, KFKN, KFKF, KFKD, KFDN, KFDF, KFDK, KDNF, KDNK, KDND, KDFN, KDFK, KDFD, KDKN, KDKF, KDKD, DNFN, DNFK, DNFD, DNKN, DNKF, DNKD, DNDN, DNDF, DNDK, DFNF, DFNK, DFND, DFKN, DFKF, DFKD, DFDN, DFDF, DFDK, DKNF, DKNK, DKND, DKFN, DKFK, DKFD, DKDN, DKDF, DKDKJOHN, 5 -> JOJOJ, JOJOH, JOJON, JOJHJ, JOJHO, JOJHN, JOJNJ, JOJNO, JOJNH, JOHJO, JOHJH, JOHJN, JOHOJ, JOHOH, JOHON, JOHNJ, JOHNO, JOHNH, JONJO, JONJH, JONJN, JONOJ, JONOH, JONON, JONHJ, JONHO, JONHN, JHJOJ, JHJOH, JHJON, JHJHJ, JHJHO, JHJHN, JHJNJ, JHJNO, JHJNH, JHOJO, JHOJH, JHOJN, JHOHJ, JHOHO, JHOHN, JHONJ, JHONO, JHONH, JHNJO, JHNJH, JHNJN, JHNOJ, JHNOH, JHNON, JHNHJ, JHNHO, JHNHN, JNJOJ, JNJOH, JNJON, JNJHJ, JNJHO, JNJHN, JNJNJ, JNJNO, JNJNH, JNOJO, JNOJH, JNOJN, JNOHJ, JNOHO, JNOHN, JNONJ, JNONO, JNONH, JNHJO, JNHJH, JNHJN, JNHOJ, JNHOH, JNHON, JNHNJ, JNHNO, JNHNH, OJOJO, OJOJH, OJOJN, OJOHJ, OJOHO, OJOHN, OJONJ, OJONO, OJONH, OJHJO, OJHJH, OJHJN, OJHOJ, OJHOH, OJHON, OJHNJ, OJHNO, OJHNH, OJNJO, OJNJH, OJNJN, OJNOJ, OJNOH, OJNON, OJNHJ, OJNHO, OJNHN, OHJOJ, OHJOH, OHJON, OHJHJ, OHJHO, OHJHN, OHJNJ, OHJNO, OHJNH, OHOJO, OHOJH, OHOJN, OHOHJ, OHOHO, OHOHN, OHONJ, OHONO, OHONH, OHNJO, OHNJH, OHNJN, OHNOJ, OHNOH, OHNON, OHNHJ, OHNHO, OHNHN, ONJOJ, ONJOH, ONJON, ONJHJ, ONJHO, ONJHN, ONJNJ, ONJNO, ONJNH, ONOJO, ONOJH, ONOJN, ONOHJ, ONOHO, ONOHN, ONONJ, ONONO, ONONH, ONHJO, ONHJH, ONHJN, ONHOJ, ONHOH, ONHON, ONHNJ, ONHNO, ONHNH, HJOJO, HJOJH, HJOJN, HJOHJ, HJOHO, HJOHN, HJONJ, HJONO, HJONH, HJHJO, HJHJH, HJHJN, HJHOJ, HJHOH, HJHON, HJHNJ, HJHNO, HJHNH, HJNJO, HJNJH, HJNJN, HJNOJ, HJNOH, HJNON, HJNHJ, HJNHO, HJNHN, HOJOJ, HOJOH, HOJON, HOJHJ, HOJHO, HOJHN, HOJNJ, HOJNO, HOJNH, HOHJO, HOHJH, HOHJN, HOHOJ, HOHOH, HOHON, HOHNJ, HOHNO, HOHNH, HONJO, HONJH, HONJN, HONOJ, HONOH, HONON, HONHJ, HONHO, HONHN, HNJOJ, HNJOH, HNJON, HNJHJ, HNJHO, HNJHN, HNJNJ, HNJNO, HNJNH, HNOJO, HNOJH, HNOJN, HNOHJ, HNOHO, HNOHN, HNONJ, HNONO, HNONH, HNHJO, HNHJH, HNHJN, HNHOJ, HNHOH, HNHON, HNHNJ, HNHNO, HNHNH, NJOJO, NJOJH, NJOJN, NJOHJ, NJOHO, NJOHN, NJONJ, NJONO, NJONH, NJHJO, NJHJH, NJHJN, NJHOJ, NJHOH, NJHON, NJHNJ, NJHNO, NJHNH, NJNJO, NJNJH, NJNJN, NJNOJ, NJNOH, NJNON, NJNHJ, NJNHO, NJNHN, NOJOJ, NOJOH, NOJON, NOJHJ, NOJHO, NOJHN, NOJNJ, NOJNO, NOJNH, NOHJO, NOHJH, NOHJN, NOHOJ, NOHOH, NOHON, NOHNJ, NOHNO, NOHNH, NONJO, NONJH, NONJN, NONOJ, NONOH, NONON, NONHJ, NONHO, NONHN, NHJOJ, NHJOH, NHJON, NHJHJ, NHJHO, NHJHN, NHJNJ, NHJNO, NHJNH, NHOJO, NHOJH, NHOJN, NHOHJ, NHOHO, NHOHN, NHONJ, NHONO, NHONH, NHNJO, NHNJH, NHNJN, NHNOJ, NHNOH, NHNON, NHNHJ, NHNHO, NHNHN- 2\$\begingroup\$Is
A, 2a valid input that should return an empty list?\$\endgroup\$Arnauld– Arnauld2024-02-19 14:55:57 +00:00CommentedFeb 19, 2024 at 14:55 - \$\begingroup\$Can the input be list?\$\endgroup\$Fmbalbuena– Fmbalbuena2024-02-19 15:12:27 +00:00CommentedFeb 19, 2024 at 15:12
- \$\begingroup\$@Arnauld Yes, it's a valid input and it should return an empty list indeed. In fact, every n > 1 should return an empty list for L being a set with a single letter.\$\endgroup\$enzo– enzo2024-02-19 15:27:29 +00:00CommentedFeb 19, 2024 at 15:27
- \$\begingroup\$@Fmbalbuena Yes, it can be a list of characters or a list of strings of length 1.\$\endgroup\$enzo– enzo2024-02-19 15:27:46 +00:00CommentedFeb 19, 2024 at 15:27
- 1\$\begingroup\$@DomHastings I would say yes, so it's easier to distinguish them. A leading space is allowed though, if it helps.\$\endgroup\$enzo– enzo2024-02-20 15:56:44 +00:00CommentedFeb 20, 2024 at 15:56
25 Answers25
Husk, 4 bytes
fΛ≠πShort and straightforward solution, the MVP here isΛ, thanks to its overload that can take a binary function and use it to check pairs of adjacent elements.
Explanation
fΛ≠π π Cartesian power of L and n (generates all possible words)f Filter those Λ for which all adjacent letters ≠ are differentGoogle Sheets, 88 bytes
=let(L,torow(A:A,1),reduce(,sequence(B1),lambda(a,_,sort(tocol(if(left(a)=L,,L&a),1)))))Put letters\$L\$ in columnA:A, the target length\$n\$ in cellB1, and the formula in cellD1.

The formula generates all possible strings of length\$n\$ from the alphabet\$L\$ with repeats, and while building a string, refuses it if its first character is the same as the one currently being prepended.
Ungolfed:
=let( letters, torow(A1:A, 1), n, B1, blank, iferror(ø), reduce(blank, sequence(n), lambda(acc, curr, sort( tocol(if(left(acc) = letters, blank, letters & acc), 1) ) )) )acc is a vertical array, andletters is a horizontal array. Thesort() function is array enabled, which means that the inner comparison and concatenation produceacc ×letters results each round.tocol() then flattens the result, weeding out blanks generated by theif().
Hat tip toJvdV for theleft(acc) = letters pattern.
- 1\$\begingroup\$Porting my answer to GS gives me
=LET(L,TOCOL(A:A,1),SORT(TOCOL(MAP(REDUCE(,SEQUENCE(B1),LAMBDA(r,n,TOROW(r&L))),LAMBDA(s,IFS(AND(ISERR(FIND(L&L,s))),s))),3)))for 126 bytes. A whole wopping 1 byte saved! =)\$\endgroup\$JvdV– JvdV2024-02-19 16:40:11 +00:00CommentedFeb 19, 2024 at 16:40 - 1\$\begingroup\$@JvdV thanks, that made me realize that the array expression and thus also the length test were superfluous. In Sheets,
1-regexmatch()saves more bytes thanand(iserr(find()))because it doesn't requiremap()infilter().\$\endgroup\$doubleunary– doubleunary2024-02-20 07:12:05 +00:00CommentedFeb 20, 2024 at 7:12 - \$\begingroup\$Yes nice. I been looking at this for a bit and for 112 bytes you could use:
=SORT(QUERY(REDUCE(,SEQUENCE(B1),LAMBDA(x,n,TOCOL(x&TOROW(A:A,1)))),"where not Col1 matches'.*(?<c>.)\k<c>.*'")). Though this only saves 1 character when looking at your updated answer.\$\endgroup\$JvdV– JvdV2024-02-21 15:40:34 +00:00CommentedFeb 21, 2024 at 15:40 - \$\begingroup\$Here I got another option for 90 bytes:
=SORT(LET(L,TOROW(A:A,1),REDUCE(,SEQUENCE(B1),LAMBDA(x,n,TOCOL(IFS(RIGHT(x)<>L,x&L),3)))))\$\endgroup\$JvdV– JvdV2024-02-21 16:00:48 +00:00CommentedFeb 21, 2024 at 16:00 - 1\$\begingroup\$@JvdV thanks! Using that pattern now.
if()and=save one more byte.\$\endgroup\$doubleunary– doubleunary2024-02-21 18:18:47 +00:00CommentedFeb 21, 2024 at 18:18
Ruby, 42 bytes
->l,n{(?A*n..?Z*n).grep_v /[^#{l}]|(.)\1/}Input in uppercase. Start with a list of all\$n\$-letter strings, then remove those containing letters not in\$L\$ or double letters.
Haskell,49 47 bytes
l#1=pure<$>ll#n=[c:a:r|a:r<-l#(n-1),c<-l,a/=c]Edit: Thanks to @xnor for taking off two bytes! I didn't know you could remove the parentheses in that context
- 1\$\begingroup\$The
(a:r)<-works without parens\$\endgroup\$xnor– xnor2024-02-20 03:37:33 +00:00CommentedFeb 20, 2024 at 3:37
JavaScript (ES10), 54 bytes
Expects(a)(n), wherea is an array of characters. Returns an array of strings.
a=>g=(n,o,p)=>n--?a.flatMap(c=>p!=c?g(n,[o]+c,c):[]):oCommented
a => // outer function taking a[]g = ( // inner recursive function taking: n, // n = expected length o, // o = output string, initially undefined p // p = previous character in the output,) => // initially undefinedn-- ? // if we don't have enough characters: a.flatMap(c => // for each character c in a[]: p != c ? // if the previous char. is not equal to c: g( // do a recursive call: n, // pass the updated value of n [o] + c, // coerce o to a string and append c to o c // set p = c ) // end of recursive call : // else: [] // abort ) // end of flatMap(): // else: o // return the outputVyxal, 5 bytes
↔'ÞǓ⁼generates all combinations of length n using the characters in the input string, then filters by those which are equal to the string with all adjacent duplicates removed.
C (gcc),168160119 114 bytes
-8 Thanks to @corvus_192 for pointing out newline separation between values was allowed, and a massive -41 thanks to @tsh, a further -5 thanks to @ceilingcat
char*l,*c;f(n,i){n?(c[n-1]=l[i])&&(l[i]-c[n]&&f(n-1,0),f(n,i+1)):puts(c);}g(e,n)char*e;{c=calloc(n,2);l=e;f(n,0);}Prints the newline separated output to STDOUT.
- 1\$\begingroup\$If you print the output newline-separated, you can replace
printf("%s ",c)withputs(c).\$\endgroup\$corvus_192– corvus_1922024-02-19 20:08:40 +00:00CommentedFeb 19, 2024 at 20:08 - 1
K (ngn/k),22 21 18 bytes:
-1 byte due to @ovs.-3 bytes thanks to @ngn.
{(|/'=':')_+!y#,x}- 2\$\begingroup\$There is an barely documented feature of odometer here to save a byte: If
!gets a list of string (or a general nested list?), it doesx@'!#'x. Doing!y#,xwill avoid indexing back intoxat the end.\$\endgroup\$ovs– ovs2024-02-20 11:50:39 +00:00CommentedFeb 20, 2024 at 11:50 - 1\$\begingroup\$replacing
list@&maskwith "filter" can help shorten this -func#listor its negationfunc_list(note thatfuncis applied to the entirelist, not to its individual items)\$\endgroup\$ngn– ngn2024-02-23 13:42:25 +00:00CommentedFeb 23, 2024 at 13:42
MATL, 9 bytes
Z^t!dXAY)Explanation
Z^ % Implicit inputs. Cartesian product. Gives a character matrix where % each row is a Cartesian tuple (*)t! % Duplicate, transposed % Consecutive differences, computed along vertical dimensionXA % Vertical-all: gives true for columns that only contain nonzerosY) % Use as logical index into the rows of (*). Implicit displayPython 3,7467 64 bytes
-7 thanks to @Albert.Lang, -3 thanks to @Mukundan314
f=lambda l,n:[""][n:]or[c+w for w in f(l,n-1)for c in{*l}-{*w[:1]}]- 1\$\begingroup\$
[...]if n else['']can ben and[...]or['']\$\endgroup\$kg583– kg5832024-02-20 00:57:06 +00:00CommentedFeb 20, 2024 at 0:57 - \$\begingroup\$65 bytes:
f=lambda l,n:n-1and[b+a for a in f(l,n-1)for b in{*l}-{a[0]}]or l\$\endgroup\$Mukundan314– Mukundan3142024-02-20 04:46:00 +00:00CommentedFeb 20, 2024 at 4:46 - 1\$\begingroup\$@kg583 won't work for testcase A, 2\$\endgroup\$tsh– tsh2024-02-20 11:44:32 +00:00CommentedFeb 20, 2024 at 11:44
- 1\$\begingroup\$
f=lambda l,n:[""][n:]or[c+w for w in f(l,n-1)for c in{*l}-{*w[:1]}]seems to work.\$\endgroup\$Albert.Lang– Albert.Lang2024-02-20 14:05:48 +00:00CommentedFeb 20, 2024 at 14:05 - 1\$\begingroup\$64 bytes:
f=lambda l,n:l*(n<2)or[b+a for a in f(l,n-1)for b in{*l}-{a[0]}](bug fixed)\$\endgroup\$Mukundan314– Mukundan3142024-02-20 14:18:27 +00:00CommentedFeb 20, 2024 at 14:18
- \$\begingroup\$Nice! I did wonder about changing the input format formy older version, but I didn't pick up on the
mapusage! Smart!\$\endgroup\$Dom Hastings– Dom Hastings2024-02-20 17:30:27 +00:00CommentedFeb 20, 2024 at 17:30 - \$\begingroup\$Looks like you can remove
!if you change&&to||for 29Try it online!\$\endgroup\$noodle person– noodle person2024-02-25 05:24:23 +00:00CommentedFeb 25, 2024 at 5:24
APL+WIN, 42 bytes
Prompts for string followed by n:
n←m←⎕⋄⍎∊(⎕-1)⍴⊂'n←n∘.,m⋄'⋄(0=+/¨2=/¨,n)/,nUiuaSBCS,2321 20 bytes
▽≡(/×≡/≠◫2).⊏☇1⇡▽:⧻,▽≡(/×≡/≠◫2).⊏☇1⇡▽:⧻, ⧻, # length of the set, call it L ⇡▽: # permutations w/ repetition of [0..n) with length L ☇1 # change to rank 2 ⊏ # index into set . # duplicate ≡( ) # map each row ◫2 # windows of length 2 ≡/≠ # reduce each row by inequality /× # product▽ # keep- \$\begingroup\$huh,
/(☇1⊞⊂)↯does the exact same thing as⊏☇1⇡▽:⧻,completely differently\$\endgroup\$Tbw– Tbw2024-02-21 17:07:44 +00:00CommentedFeb 21, 2024 at 17:07
Jelly, 6bytes
ṗnƝẠ$ƇA dyadic Link that accepts the alphabet on the left and the word length on the right and yields a list of valid words.
How?
ṗnƝẠ$Ƈ - Link: Alphabet, WordLengthṗ - {Alphabet} Cartesian power {WordLength} -> all words Ƈ - keep those for which: $ - last two links as a monad - f(Word): Ɲ - for neighbouring pairs: n - not equal? Ạ - all?...if one didn't need to handle an alphabet of length one, then five bytes would do -ṗnƝÐṀ (keep those words which are maximal under neighbourwise not-equal).
Excel ms365,8584 bytes
- -1 thanks todoubleunary's tip to apply
LEFT()instead ofRIGHT().
Assuming:
- \$L\$ - Given input in the first row
1:1starting fromA1onwards; - \$n\$ - Given integer in
A2.
Formula, thus output, inA4 spilled down:
=LET(L,TOROW(1:1,1),REDUCE("",TAKE(L,,A2),LAMBDA(x,n,TOCOL(IFS(LEFT(x)<>L,L&x),3))))- 1\$\begingroup\$Save one more byte:
ifs(L<>left(x),L&x).\$\endgroup\$doubleunary– doubleunary2024-02-23 08:57:13 +00:00CommentedFeb 23, 2024 at 8:57
Charcoal, 20 bytes
⊞υωFN≔ΣEηEΦυ⌕μκ⁺κμυυAttempt This Online! Link is to verbose version of code. Explanation:
⊞υωStart with the empty string.
FNLoopn times.
≔ΣEηEΦυ⌕μκ⁺κμυFor each letter ofL, prefix it to each string so far that does not begin with that letter, then concatenate all of the results together. (Prefixing each letter ofL that the string does not begin with fails when there are no strings in the list.)
υOutput the final list.
05AB1E, 5bytes
ãʒüÊPInputs in the order\$n,L\$.
Try it online orverify all test cases.
Or alternatively:
ãʒDÔQTry it online orverify all test cases.
Explanation:
ã # Cartesian product on both (implicit) inputs to get all n-sized strings using # characters from L ʒ # Filter it by: ü # Map over each overlapping pair: Ê # Check that they're NOT equal P # Check that all of them are truthy # (after which the filtered list is output implicitly) D # Duplicate the current string Ô # Connected uniquify it, collapsing all equal adjacent characters Q # Check if the connected uniquified string is still the sameRetina, 41 bytes
"$&"+%Lw$`,.*(.)$`$1$&$'\d|,.+A`(.)\1Try it online! Link includes test cases. Takes comma-separated input. Explanation:
"$&"+`Repeatn times...
%Lw$`,.*(.)$`$1$&$'Replicate each line for each letter ofL but inserting a copy of the letter before the comma.
\d|,.+Remove the copies ofn andL.
A`(.)\1Remove all lines with duplicate adjacent letters.
- 1\$\begingroup\$Nice one! You can have a test suite if you use the current string rather than the original input from the history (
$0instead of$+)Try it online!\$\endgroup\$Leo– Leo2024-02-20 03:36:22 +00:00CommentedFeb 20, 2024 at 3:36 - \$\begingroup\$@Leo Ah yes, normally I have to delete the input number before the loop, but I was able to get away without that here.\$\endgroup\$Neil– Neil2024-02-20 09:05:31 +00:00CommentedFeb 20, 2024 at 9:05
Brachylog,13 10 bytes
-3 bytes inspired by a suggestion fromFatalize
gʰj₎∋ᵐ.ẹ~ḅGenerator solution. Takes input as a list containing a string and an integer. Returns solutions as lists of single-character strings.Try it online!
Explanation
This feels like it should be shorter. Part of the problem is that Brachylog starts getting verbose when you have to deal with anything past one input and one output.
gʰj₎∋ᵐ.ẹ~ḅ Input: list containing string and numbergʰ Wrap the first element in a singleton list j₎ Concatenate that list with itself (second element) times ∋ᵐ Select one character from each of those strings . This will be the output ẹ Convert each character to a list of its characters (i.e. wrap it in a singleton list) ~ḅ Assert that this is the same as the result of partitioning some list into runs of identical elements ... and that that list is the outputTo help clarify the ending bit: The predicateẹ converts each string in its input into a list of its characters. The predicateḅ finds all runs of consecutive identical values in its input. The.ẹ~ḅ structure appliesẹ to the list, thenunappliesḅ to that result, then requiresthat result to be the same list we started with. This is the same as saying thatẹ andḅ must give the same result when applied to the list. So:
- Given the list
["a","b","b"],ẹoutputs[["a"],["b"],["b"]]andḅoutputs[["a"],["b","b"]]. Those don't match, so the predicate fails. - Given the list
["a","b","a"],ẹoutputs[["a"],["b"],["a"]]andḅoutputs[["a"],["b"],["a"]]. Those do match, so the predicate succeeds.
- 1\$\begingroup\$
ḅl₁ᵐis 1 less byte thans₂ᶠ≠ᵐto check that no two consecutive elements are equal.\$\endgroup\$Fatalize– Fatalize2024-02-20 12:37:15 +00:00CommentedFeb 20, 2024 at 12:37 - 1\$\begingroup\$Thanks! I was able to save a couple more bytes with a variation on that idea.\$\endgroup\$DLosc– DLosc2024-02-20 17:41:13 +00:00CommentedFeb 20, 2024 at 17:41
Nekomata, 4 bytes
ŧĉᵐzŧĉᵐz Take input L and nŧ Find an n-tuple of elements of L ĉ Split into runs of equal elements ᵐ For each run: z Check that it contains exactly one element, and take that elementR,65 64 bytes
\(L,n,A=expand.grid(rep(list(L),n)))A[!rowSums(A[,-n]==A[,-1]),]AssumingL is a vector of characters.
-1 byte thanks to @pajonk!
- \$\begingroup\$This needs column selector in
[to work (for me):ato.pxeger.com/… BTW, I also changed==0to!, so overall -1 byte :) Also, a link in the post to an online repl (like the one linked above) would be nice.\$\endgroup\$pajonk– pajonk2024-03-13 19:45:12 +00:00CommentedMar 13, 2024 at 19:45 - 1\$\begingroup\$@pajonk Thanks! Love the trick with the
!The column selector for some reason works on one machine, but I can't replicate it in general, will edit.\$\endgroup\$runr– runr2024-03-17 22:43:13 +00:00CommentedMar 17, 2024 at 22:43
Scala 3, 128 bytes
A Port of@Arnold Palmer's Python answer in Scala.
Golfed version.Attempt This Online!
type Q=String;def g(l:Q,n:Int,c:Q=""):Seq[Q]={if(n==0)Seq("");else{for{a<-l if a.toString!=c;b<-g(l,n-1,a.toString)}yield a+b}}Ungolfed version.Attempt This Online!
def generateCombinations(l: String, n: Int, c: String = ""): Seq[String] = { if (n == 0) Seq("") else { for { a <- l if a.toString != c b <- generateCombinations(l, n - 1, a.toString) } yield a + b } }- \$\begingroup\$My solution was just golfed quite a bit (-10 bytes). Not sure if it translates to Scala, but wanted to let you know in case you could use that to golf yours.\$\endgroup\$Arnold Palmer– Arnold Palmer2024-02-20 14:39:24 +00:00CommentedFeb 20, 2024 at 14:39
jq, 67 bytes
def f($n):combinations($n)|join("")|select(test("(.)\\1";"x")|not);Defines a functionf which takes\$L\$ as input and\$n\$ as an argument.
Explore related questions
See similar questions with these tags.















