18
\$\begingroup\$

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-empty string \$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, so ABCA 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, CBC
AB, 3 -> ABA, BAB
ABCD, 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, DCD
OKAY, 2 -> OK, OA, OY, KO, KA, KY, AO, AK, AY, YO, YK, YA
CODEGLF, 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, FLF
NFKD, 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, DKDK
JOHN, 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
asked Feb 19, 2024 at 14:00
\$\endgroup\$
8
  • 2
    \$\begingroup\$ Is A, 2 a valid input that should return an empty list? \$\endgroup\$ Commented Feb 19, 2024 at 14:55
  • \$\begingroup\$ Can the input be list? \$\endgroup\$ Commented Feb 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\$ Commented Feb 19, 2024 at 15:27
  • \$\begingroup\$ @Fmbalbuena Yes, it can be a list of characters or a list of strings of length 1. \$\endgroup\$ Commented Feb 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\$ Commented Feb 20, 2024 at 15:56

25 Answers 25

12
\$\begingroup\$

Husk, 4 bytes

fΛ≠π

Try it online!

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 different
answered Feb 20, 2024 at 0:10
\$\endgroup\$
8
\$\begingroup\$

Google 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 column A:A, the target length \$n\$ in cell B1, and the formula in cell D1.

no adjacent letters.png

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, and letters is a horizontal array. The sort() function is array enabled, which means that the inner comparison and concatenation produce acc ×ばつ letters results each round. tocol() then flattens the result, weeding out blanks generated by the if().

Hat tip to JvdV for the left(acc) = letters pattern.

answered Feb 19, 2024 at 16:29
\$\endgroup\$
5
  • 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\$ Commented Feb 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 than and(iserr(find())) because it doesn't require map() in filter(). \$\endgroup\$ Commented Feb 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\$ Commented Feb 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\$ Commented Feb 21, 2024 at 16:00
  • 1
    \$\begingroup\$ @JvdV thanks! Using that pattern now. if() and = save one more byte. \$\endgroup\$ Commented Feb 21, 2024 at 18:18
7
\$\begingroup\$

Ruby, 42 bytes

->l,n{(?A*n..?Z*n).grep_v /[^#{l}]|(.)1円/}

Attempt This Online!

Input in uppercase. Start with a list of all \$n\$-letter strings, then remove those containing letters not in \$L\$ or double letters.

answered Feb 19, 2024 at 21:32
\$\endgroup\$
7
\$\begingroup\$

Haskell, (削除) 49 (削除ここまで) 47 bytes

l#1=pure<$>l
l#n=[c:a:r|a:r<-l#(n-1),c<-l,a/=c]

Try it online!

Edit: Thanks to @xnor for taking off two bytes! I didn't know you could remove the parentheses in that context

answered Feb 19, 2024 at 14:39
\$\endgroup\$
1
  • 1
    \$\begingroup\$ The (a:r)<- works without parens \$\endgroup\$ Commented Feb 20, 2024 at 3:37
5
\$\begingroup\$

JavaScript (ES10), 54 bytes

Expects (a)(n), where a 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):[]):o

Try it online!

Commented

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 undefined
n-- ? // 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 output
answered Feb 19, 2024 at 14:09
\$\endgroup\$
5
\$\begingroup\$

Vyxal, 5 bytes

↔'ÞǓ=

Try it Online!

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.

answered Feb 19, 2024 at 18:12
\$\endgroup\$
5
\$\begingroup\$

C (gcc), (削除) 168 (削除ここまで) (削除) 160 (削除ここまで) (削除) 119 (削除ここまで) 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);}

Try it online!

Prints the newline separated output to STDOUT.

answered Feb 19, 2024 at 18:25
\$\endgroup\$
2
  • 1
    \$\begingroup\$ If you print the output newline-separated, you can replace printf("%s ",c) with puts(c). \$\endgroup\$ Commented Feb 19, 2024 at 20:08
  • 1
    \$\begingroup\$ 119 bytes \$\endgroup\$ Commented Feb 22, 2024 at 11:59
5
\$\begingroup\$

K (ngn/k), (削除) 22 21 (削除ここまで) 18 bytes:

-1 byte due to @ovs. -3 bytes thanks to @ngn.

{(|/'=':')_+!y#,x}

Try it online

answered Feb 20, 2024 at 8:51
\$\endgroup\$
2
  • 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 does x@'!#'x. Doing !y#,x will avoid indexing back into x at the end. \$\endgroup\$ Commented Feb 20, 2024 at 11:50
  • 1
    \$\begingroup\$ replacing list@&mask with "filter" can help shorten this - func#list or its negation func_list (note that func is applied to the entire list, not to its individual items) \$\endgroup\$ Commented Feb 23, 2024 at 13:42
4
\$\begingroup\$

MATL, 9 bytes

Z^t!dXAY)

Try it online!

Explanation

Z^ % Implicit inputs. Cartesian product. Gives a character matrix where 
 % each row is a Cartesian tuple (*)
t! % Duplicate, transpose
d % Consecutive differences, computed along vertical dimension
XA % Vertical-all: gives true for columns that only contain nonzeros
Y) % Use as logical index into the rows of (*). Implicit display
answered Feb 19, 2024 at 18:08
\$\endgroup\$
4
\$\begingroup\$

R, 70 bytes

\(L,n,x=combn(rep(L,n+1),n))unique(x[,apply(x,2,\(a)all(diff(a)))],,2)

Attempt This Online!

Uses a rather loose definition of string - a vector of character codes. Outputs a matrix with unique words in columns.

answered Feb 20, 2024 at 6:51
\$\endgroup\$
4
\$\begingroup\$

Python 3, (削除) 74 (削除ここまで) (削除) 67 (削除ここまで) 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]}]

Try it online!

answered Feb 19, 2024 at 17:03
\$\endgroup\$
6
  • 1
    \$\begingroup\$ [...]if n else[''] can be n and[...]or[''] \$\endgroup\$ Commented Feb 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\$ Commented Feb 20, 2024 at 4:46
  • 1
    \$\begingroup\$ @kg583 won't work for testcase A, 2 \$\endgroup\$ Commented Feb 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\$ Commented Feb 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\$ Commented Feb 20, 2024 at 14:18
4
\$\begingroup\$

Perl 5 -nl, 30 bytes

map!/(.)1円/&&say,glob"{$_}"x<>

Try it online!

answered Feb 20, 2024 at 15:28
\$\endgroup\$
2
  • \$\begingroup\$ Nice! I did wonder about changing the input format for my older version, but I didn't pick up on the map usage! Smart! \$\endgroup\$ Commented Feb 20, 2024 at 17:30
  • \$\begingroup\$ Looks like you can remove ! if you change && to || for 29 Try it online! \$\endgroup\$ Commented Feb 25, 2024 at 5:24
3
\$\begingroup\$

APL+WIN, 42 bytes

Prompts for string followed by n:

n←m←⎕⋄⍎∊(⎕-1)⍴⊂'n←n∘.,m⋄'⋄(0=+/ ̈2=/ ̈,n)/,n

Try it online! Thanks to Dyalog Classic

answered Feb 19, 2024 at 14:59
\$\endgroup\$
3
\$\begingroup\$

Uiua SBCS , (削除) 23 (削除ここまで) (削除) 21 (削除ここまで) 20 bytes

▽≡(×ばつ≡/≠◫2).⊏☇1⇡▽:⧻,

Try it!

▽≡(×ばつ≡/≠◫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
answered Feb 19, 2024 at 16:03
\$\endgroup\$
1
  • \$\begingroup\$ huh, /(☇1⊞⊂)↯ does the exact same thing as ⊏☇1⇡▽:⧻, completely differently \$\endgroup\$ Commented Feb 21, 2024 at 17:07
3
\$\begingroup\$

Jelly, 6 bytes

ṗ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.

Try it online!

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).

answered Feb 19, 2024 at 21:41
\$\endgroup\$
3
\$\begingroup\$

Excel ms365, (削除) 85 (削除ここまで) 84 bytes

  • -1 thanks to doubleunary's tip to apply LEFT() instead of RIGHT().

Assuming:

  • \$L\$ - Given input in the first row 1:1 starting from A1 onwards;
  • \$n\$ - Given integer in A2.

Formula, thus output, in A4 spilled down:

=LET(L,TOROW(1:1,1),REDUCE("",TAKE(L,,A2),LAMBDA(x,n,TOCOL(IFS(LEFT(x)<>L,L&x),3))))

enter image description here

answered Feb 19, 2024 at 16:28
\$\endgroup\$
1
  • 1
    \$\begingroup\$ Save one more byte: ifs(L<>left(x),L&x). \$\endgroup\$ Commented Feb 23, 2024 at 8:57
2
\$\begingroup\$

Charcoal, 20 bytes

⊞υωFN≔ΣEηEΦυ⌕μκ+κμυυ

Attempt This Online! Link is to verbose version of code. Explanation:

⊞υω

Start with the empty string.

FN

Loop n times.

≔ΣEηEΦυ⌕μκ+κμυ

For each letter of L, prefix it to each string so far that does not begin with that letter, then concatenate all of the results together. (Prefixing each letter of L that the string does not begin with fails when there are no strings in the list.)

υ

Output the final list.

answered Feb 19, 2024 at 18:01
\$\endgroup\$
2
\$\begingroup\$

05AB1E, 5 bytes

ãʒüÊP

Inputs in the order \$n,L\$.

Try it online or verify all test cases.

Or alternatively:

ãʒDÔQ

Try it online or verify 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 same
answered Feb 20, 2024 at 7:52
\$\endgroup\$
2
\$\begingroup\$

Retina, 41 bytes

"$&"+%Lw$`,.*(.)
$`1ドル$&$'
\d|,.+
A`(.)1円

Try it online! Link includes test cases. Takes comma-separated input. Explanation:

"$&"+`

Repeat n times...

%Lw$`,.*(.)
$`1ドル$&$'

Replicate each line for each letter of L but inserting a copy of the letter before the comma.

\d|,.+

Remove the copies of n and L.

A`(.)1円

Remove all lines with duplicate adjacent letters.

answered Feb 20, 2024 at 0:41
\$\endgroup\$
2
  • 1
    \$\begingroup\$ Nice one! You can have a test suite if you use the current string rather than the original input from the history (0ドル instead of $+) Try it online! \$\endgroup\$ Commented Feb 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\$ Commented Feb 20, 2024 at 9:05
2
\$\begingroup\$

Perl 5 + -lF -M5.10.0, 40 bytes

!/[^@F]|(.)1円/&&say for A x($;=<>)..Z x$

Try it online!

answered Feb 20, 2024 at 13:17
\$\endgroup\$
2
\$\begingroup\$

Brachylog, (削除) 13 (削除ここまで) 10 bytes

-3 bytes inspired by a suggestion from Fatalize

ghj)∋m.ẹ~ḅ

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.

ghj)∋m.ẹ~ḅ
 Input: list containing string and number
gh Wrap the first element in a singleton list
 j) Concatenate that list with itself (second element) times
 ∋m 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 output

To 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, then unapplies to that result, then requires that 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.
answered Feb 19, 2024 at 23:18
\$\endgroup\$
2
  • 1
    \$\begingroup\$ ḅl1m is 1 less byte than s2f≠m to check that no two consecutive elements are equal. \$\endgroup\$ Commented Feb 20, 2024 at 12:37
  • 1
    \$\begingroup\$ Thanks! I was able to save a couple more bytes with a variation on that idea. \$\endgroup\$ Commented Feb 20, 2024 at 17:41
2
\$\begingroup\$

Nekomata, 4 bytes

ŧĉmz

Attempt This Online!

ŧĉmz Take input L and n
ŧ Find an n-tuple of elements of L
 ĉ Split into runs of equal elements
 m For each run:
 z Check that it contains exactly one element, and take that element
answered Feb 21, 2024 at 3:14
\$\endgroup\$
2
\$\begingroup\$

R, (削除) 65 (削除ここまで) 64 bytes

\(L,n,A=expand.grid(rep(list(L),n)))A[!rowSums(A[,-n]==A[,-1]),]

Assuming L is a vector of characters.

-1 byte thanks to @pajonk!

Try it online here!

answered Mar 13, 2024 at 14:28
\$\endgroup\$
2
  • \$\begingroup\$ This needs column selector in [ to work (for me): ato.pxeger.com/… BTW, I also changed ==0 to !, so overall -1 byte :) Also, a link in the post to an online repl (like the one linked above) would be nice. \$\endgroup\$ Commented Mar 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\$ Commented Mar 17, 2024 at 22:43
1
\$\begingroup\$

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
 }
 }
answered Feb 20, 2024 at 9:46
\$\endgroup\$
1
  • \$\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\$ Commented Feb 20, 2024 at 14:39
1
\$\begingroup\$

jq, 67 bytes

def f($n):combinations($n)|join("")|select(test("(.)\1円";"x")|not);

Try it online!

Defines a function f which takes \$L\$ as input and \$n\$ as an argument.

answered Feb 20, 2024 at 22:32
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.