5
\$\begingroup\$

Given an input string, output at random the unique combinations with repetition of the characters in the input string, from length 1 up to the length of the input string, with an equal chance of each one occurring.

Example: given the input abcd (or any combination thereof of the four characters a,b,c,d) , there is an equal chance of outputting:

a b c d aa ab ac ad ba bb bc bd ca cb cc cd da db dc dd aaa aab aac aad aba abb abc abd aca acb acc acd ada adb adc add baa bab bac bad bba bbb bbc bbd bca bcb bcc bcd bda bdb bdc bdd caa cab cac cad cba cbb cbc cbd cca ccb ccc ccd cda cdb cdc cdd daa dab dac dad dba dbb dbc dbd dca dcb dcc dcd dda ddb ddc ddd aaaa aaab aaac aaad aaba aabb aabc aabd aaca aacb aacc aacd aada aadb aadc aadd abaa abab abac abad abba abbb abbc abbd abca abcb abcc abcd abda abdb abdc abdd acaa acab acac acad acba acbb acbc acbd acca accb accc accd acda acdb acdc acdd adaa adab adac adad adba adbb adbc adbd adca adcb adcc adcd adda addb addc addd baaa baab baac baad baba babb babc babd baca bacb bacc bacd bada badb badc badd bbaa bbab bbac bbad bbba bbbb bbbc bbbd bbca bbcb bbcc bbcd bbda bbdb bbdc bbdd bcaa bcab bcac bcad bcba bcbb bcbc bcbd bcca bccb bccc bccd bcda bcdb bcdc bcdd bdaa bdab bdac bdad bdba bdbb bdbc bdbd bdca bdcb bdcc bdcd bdda bddb bddc bddd caaa caab caac caad caba cabb cabc cabd caca cacb cacc cacd cada cadb cadc cadd cbaa cbab cbac cbad cbba cbbb cbbc cbbd cbca cbcb cbcc cbcd cbda cbdb cbdc cbdd ccaa ccab ccac ccad ccba ccbb ccbc ccbd ccca cccb cccc cccd ccda ccdb ccdc ccdd cdaa cdab cdac cdad cdba cdbb cdbc cdbd cdca cdcb cdcc cdcd cdda cddb cddc cddd daaa daab daac daad daba dabb dabc dabd daca dacb dacc dacd dada dadb dadc dadd dbaa dbab dbac dbad dbba dbbb dbbc dbbd dbca dbcb dbcc dbcd dbda dbdb dbdc dbdd dcaa dcab dcac dcad dcba dcbb dcbc dcbd dcca dccb dccc dccd dcda dcdb dcdc dcdd ddaa ddab ddac ddad ddba ddbb ddbc ddbd ddca ddcb ddcc ddcd ddda dddb dddc dddd

Example: given the input efgh (or any combination thereof of the four characters e,f,g,h), there is an equal chance of outputting:

e f g h ee ef eg eh fe ff fg fh ge gf gg gh he hf hg hh eee eef eeg eeh efe eff efg efh ege egf egg egh ehe ehf ehg ehh fee fef feg feh ffe fff ffg ffh fge fgf fgg fgh fhe fhf fhg fhh gee gef geg geh gfe gff gfg gfh gge ggf ggg ggh ghe ghf ghg ghh hee hef heg heh hfe hff hfg hfh hge hgf hgg hgh hhe hhf hhg hhh eeee eeef eeeg eeeh eefe eeff eefg eefh eege eegf eegg eegh eehe eehf eehg eehh efee efef efeg efeh effe efff effg effh efge efgf efgg efgh efhe efhf efhg efhh egee egef egeg egeh egfe egff egfg egfh egge eggf eggg eggh eghe eghf eghg eghh ehee ehef eheg eheh ehfe ehff ehfg ehfh ehge ehgf ehgg ehgh ehhe ehhf ehhg ehhh feee feef feeg feeh fefe feff fefg fefh fege fegf fegg fegh fehe fehf fehg fehh ffee ffef ffeg ffeh fffe ffff fffg fffh ffge ffgf ffgg ffgh ffhe ffhf ffhg ffhh fgee fgef fgeg fgeh fgfe fgff fgfg fgfh fgge fggf fggg fggh fghe fghf fghg fghh fhee fhef fheg fheh fhfe fhff fhfg fhfh fhge fhgf fhgg fhgh fhhe fhhf fhhg fhhh geee geef geeg geeh gefe geff gefg gefh gege gegf gegg gegh gehe gehf gehg gehh gfee gfef gfeg gfeh gffe gfff gffg gffh gfge gfgf gfgg gfgh gfhe gfhf gfhg gfhh ggee ggef ggeg ggeh ggfe ggff ggfg ggfh ggge gggf gggg gggh gghe gghf gghg gghh ghee ghef gheg gheh ghfe ghff ghfg ghfh ghge ghgf ghgg ghgh ghhe ghhf ghhg ghhh heee heef heeg heeh hefe heff hefg hefh hege hegf hegg hegh hehe hehf hehg hehh hfee hfef hfeg hfeh hffe hfff hffg hffh hfge hfgf hfgg hfgh hfhe hfhf hfhg hfhh hgee hgef hgeg hgeh hgfe hgff hgfg hgfh hgge hggf hggg hggh hghe hghf hghg hghh hhee hhef hheg hheh hhfe hhff hhfg hhfh hhge hhgf hhgg hhgh hhhe hhhf hhhg hhhh

Example: given the input ijkl (or any combination thereof of the four characters i,j,k,l), there is an equal chance of outputting:

i j k l ii ij ik il ji jj jk jl ki kj kk kl li lj lk ll iii iij iik iil iji ijj ijk ijl iki ikj ikk ikl ili ilj ilk ill jii jij jik jil jji jjj jjk jjl jki jkj jkk jkl jli jlj jlk jll kii kij kik kil kji kjj kjk kjl kki kkj kkk kkl kli klj klk kll lii lij lik lil lji ljj ljk ljl lki lkj lkk lkl lli llj llk lll iiii iiij iiik iiil iiji iijj iijk iijl iiki iikj iikk iikl iili iilj iilk iill ijii ijij ijik ijil ijji ijjj ijjk ijjl ijki ijkj ijkk ijkl ijli ijlj ijlk ijll ikii ikij ikik ikil ikji ikjj ikjk ikjl ikki ikkj ikkk ikkl ikli iklj iklk ikll ilii ilij ilik ilil ilji iljj iljk iljl ilki ilkj ilkk ilkl illi illj illk illl jiii jiij jiik jiil jiji jijj jijk jijl jiki jikj jikk jikl jili jilj jilk jill jjii jjij jjik jjil jjji jjjj jjjk jjjl jjki jjkj jjkk jjkl jjli jjlj jjlk jjll jkii jkij jkik jkil jkji jkjj jkjk jkjl jkki jkkj jkkk jkkl jkli jklj jklk jkll jlii jlij jlik jlil jlji jljj jljk jljl jlki jlkj jlkk jlkl jlli jllj jllk jlll kiii kiij kiik kiil kiji kijj kijk kijl kiki kikj kikk kikl kili kilj kilk kill kjii kjij kjik kjil kjji kjjj kjjk kjjl kjki kjkj kjkk kjkl kjli kjlj kjlk kjll kkii kkij kkik kkil kkji kkjj kkjk kkjl kkki kkkj kkkk kkkl kkli kklj kklk kkll klii klij klik klil klji kljj kljk kljl klki klkj klkk klkl klli kllj kllk klll liii liij liik liil liji lijj lijk lijl liki likj likk likl lili lilj lilk lill ljii ljij ljik ljil ljji ljjj ljjk ljjl ljki ljkj ljkk ljkl ljli ljlj ljlk ljll lkii lkij lkik lkil lkji lkjj lkjk lkjl lkki lkkj lkkk lkkl lkli lklj lklk lkll llii llij llik llil llji lljj lljk lljl llki llkj llkk llkl llli lllj lllk llll

This by definition also means that every indiviual character within the string too has equal probability. All characters in the input are distinct.

\$\endgroup\$
  • 1
    \$\begingroup\$ @Flog Edoc: (2) There is a real difference between 'will contain at least two distinct characters' and 'all characters will be distinct'. Which do you intend? \$\endgroup\$ – Chas Brown Apr 6 at 5:35
  • 5
    \$\begingroup\$ This challenge seems to have been significantly changed from what was initially posted, making it a completely different challenge and invalidating the existing solutions. That's an automatic -1 from me and the reason I've VTCed as unclear. \$\endgroup\$ – Shaggy Apr 7 at 11:14
  • 1
    \$\begingroup\$ The whole part about each character in the string having equal probability of occurring is redundant. Since each combo has equal probability each character has equal probability. \$\endgroup\$ – Wheat Wizard Apr 7 at 15:59
  • 2
    \$\begingroup\$ @Shaggy As it stands now, many edge cases have in fact been resolved, so it is far from unclear as compared to where it started. Right now, I think it's pretty understandable what the requirements are. Other than exact formulaic assumptions (which may affect existing answers and may as well be a different question entirely), I'm not sure what you're looking to do. \$\endgroup\$ – Flog Edoc Apr 8 at 16:33
  • 1
    \$\begingroup\$ Your three examples are all essentially the same. I suggest showing the expected output for: the empty string (if applicable — I suggest you rule it out), input x, input xy, input xxy, input zzz. \$\endgroup\$ – Lynn Apr 10 at 0:51

18 Answers 18

6
\$\begingroup\$

Jelly,  10  5 bytes

ṗJẎQX

A monadic Link accepting a list of characters which yields a list of characters.

Try it online!

How?

ṗJẎQX - Link list of characters    e.g.  aabc
 J    - range of length                  [1,2,3,4]
ṗ     - Cartesian power (vectorises)     [[a,a,b,c],[aa,aa,ab,ac,aa,aa,ab,ac,ba,ba,bb,bc,ca,ca,cb,cc],[aaa,aaa,aab,aac,aaa,aaa,aab,aac,aba,aba,abb,abc,aca,aca,acb,acc,aaa,aaa,aab,aac,aaa,aaa,aab,aac,aba,aba,abb,abc,aca,aca,acb,acc,baa,baa,bab,bac,baa,baa,bab,bac,bba,bba,bbb,bbc,bca,bca,bcb,bcc,caa,caa,cab,cac,caa,caa,cab,cac,cba,cba,cbb,cbc,cca,cca,ccb,ccc],[aaaa,aaaa,aaab,aaac,aaaa,aaaa,aaab,aaac,aaba,aaba,aabb,aabc,aaca,aaca,aacb,aacc,aaaa,aaaa,aaab,aaac,aaaa,aaaa,aaab,aaac,aaba,aaba,aabb,aabc,aaca,aaca,aacb,aacc,abaa,abaa,abab,abac,abaa,abaa,abab,abac,abba,abba,abbb,abbc,abca,abca,abcb,abcc,acaa,acaa,acab,acac,acaa,acaa,acab,acac,acba,acba,acbb,acbc,acca,acca,accb,accc,aaaa,aaaa,aaab,aaac,aaaa,aaaa,aaab,aaac,aaba,aaba,aabb,aabc,aaca,aaca,aacb,aacc,aaaa,aaaa,aaab,aaac,aaaa,aaaa,aaab,aaac,aaba,aaba,aabb,aabc,aaca,aaca,aacb,aacc,abaa,abaa,abab,abac,abaa,abaa,abab,abac,abba,abba,abbb,abbc,abca,abca,abcb,abcc,acaa,acaa,acab,acac,acaa,acaa,acab,acac,acba,acba,acbb,acbc,acca,acca,accb,accc,baaa,baaa,baab,baac,baaa,baaa,baab,baac,baba,baba,babb,babc,baca,baca,bacb,bacc,baaa,baaa,baab,baac,baaa,baaa,baab,baac,baba,baba,babb,babc,baca,baca,bacb,bacc,bbaa,bbaa,bbab,bbac,bbaa,bbaa,bbab,bbac,bbba,bbba,bbbb,bbbc,bbca,bbca,bbcb,bbcc,bcaa,bcaa,bcab,bcac,bcaa,bcaa,bcab,bcac,bcba,bcba,bcbb,bcbc,bcca,bcca,bccb,bccc,caaa,caaa,caab,caac,caaa,caaa,caab,caac,caba,caba,cabb,cabc,caca,caca,cacb,cacc,caaa,caaa,caab,caac,caaa,caaa,caab,caac,caba,caba,cabb,cabc,caca,caca,cacb,cacc,cbaa,cbaa,cbab,cbac,cbaa,cbaa,cbab,cbac,cbba,cbba,cbbb,cbbc,cbca,cbca,cbcb,cbcc,ccaa,ccaa,ccab,ccac,ccaa,ccaa,ccab,ccac,ccba,ccba,ccbb,ccbc,ccca,ccca,cccb,cccc]
  Ẏ   - tighten                          [a,a,b,c,aa,aa,ab,ac,aa,aa,ab,ac,ba,ba,bb,bc,ca,ca,cb,cc,aaa,aaa,aab,aac,aaa,aaa,aab,aac,aba,aba,abb,abc,aca,aca,acb,acc,aaa,aaa,aab,aac,aaa,aaa,aab,aac,aba,aba,abb,abc,aca,aca,acb,acc,baa,baa,bab,bac,baa,baa,bab,bac,bba,bba,bbb,bbc,bca,bca,bcb,bcc,caa,caa,cab,cac,caa,caa,cab,cac,cba,cba,cbb,cbc,cca,cca,ccb,ccc,aaaa,aaaa,aaab,aaac,aaaa,aaaa,aaab,aaac,aaba,aaba,aabb,aabc,aaca,aaca,aacb,aacc,aaaa,aaaa,aaab,aaac,aaaa,aaaa,aaab,aaac,aaba,aaba,aabb,aabc,aaca,aaca,aacb,aacc,abaa,abaa,abab,abac,abaa,abaa,abab,abac,abba,abba,abbb,abbc,abca,abca,abcb,abcc,acaa,acaa,acab,acac,acaa,acaa,acab,acac,acba,acba,acbb,acbc,acca,acca,accb,accc,aaaa,aaaa,aaab,aaac,aaaa,aaaa,aaab,aaac,aaba,aaba,aabb,aabc,aaca,aaca,aacb,aacc,aaaa,aaaa,aaab,aaac,aaaa,aaaa,aaab,aaac,aaba,aaba,aabb,aabc,aaca,aaca,aacb,aacc,abaa,abaa,abab,abac,abaa,abaa,abab,abac,abba,abba,abbb,abbc,abca,abca,abcb,abcc,acaa,acaa,acab,acac,acaa,acaa,acab,acac,acba,acba,acbb,acbc,acca,acca,accb,accc,baaa,baaa,baab,baac,baaa,baaa,baab,baac,baba,baba,babb,babc,baca,baca,bacb,bacc,baaa,baaa,baab,baac,baaa,baaa,baab,baac,baba,baba,babb,babc,baca,baca,bacb,bacc,bbaa,bbaa,bbab,bbac,bbaa,bbaa,bbab,bbac,bbba,bbba,bbbb,bbbc,bbca,bbca,bbcb,bbcc,bcaa,bcaa,bcab,bcac,bcaa,bcaa,bcab,bcac,bcba,bcba,bcbb,bcbc,bcca,bcca,bccb,bccc,caaa,caaa,caab,caac,caaa,caaa,caab,caac,caba,caba,cabb,cabc,caca,caca,cacb,cacc,caaa,caaa,caab,caac,caaa,caaa,caab,caac,caba,caba,cabb,cabc,caca,caca,cacb,cacc,cbaa,cbaa,cbab,cbac,cbaa,cbaa,cbab,cbac,cbba,cbba,cbbb,cbbc,cbca,cbca,cbcb,cbcc,ccaa,ccaa,ccab,ccac,ccaa,ccaa,ccab,ccac,ccba,ccba,ccbb,ccbc,ccca,ccca,cccb,cccc]
   Q  - de-duplicate                     [a,b,c,aa,ab,ac,ba,bb,bc,ca,cb,cc,aaa,aab,aac,aba,abb,abc,aca,acb,acc,baa,bab,bac,bba,bbb,bbc,bca,bcb,bcc,caa,cab,cac,cba,cbb,cbc,cca,ccb,ccc,aaaa,aaab,aaac,aaba,aabb,aabc,aaca,aacb,aacc,abaa,abab,abac,abba,abbb,abbc,abca,abcb,abcc,acaa,acab,acac,acba,acbb,acbc,acca,accb,accc,baaa,baab,baac,baba,babb,babc,baca,bacb,bacc,bbaa,bbab,bbac,bbba,bbbb,bbbc,bbca,bbcb,bbcc,bcaa,bcab,bcac,bcba,bcbb,bcbc,bcca,bccb,bccc,caaa,caab,caac,caba,cabb,cabc,caca,cacb,cacc,cbaa,cbab,cbac,cbba,cbbb,cbbc,cbca,cbcb,cbcc,ccaa,ccab,ccac,ccba,ccbb,ccbc,ccca,cccb,cccc]
    X - uniform random choice
\$\endgroup\$
6
\$\begingroup\$

05AB1E, 6 bytes

ā€ã˜ÙΩ

Try it online!

Explanation

ā       # push [1 ... len(input)]
 ۋ     # apply repeated cartesian product on each and input
   ˜    # flatten
    Ù   # remove duplicates
     Ω  # pick random string
\$\endgroup\$
4
\$\begingroup\$

Perl 6, 35 33 28 bytes

-2 bytes thanks to nwellnhof

{[~] roll .rand+1,$_}o*.comb

Try it online!

This challenge keeps changing a lot.

Explanation:

{                   }o*.comb  # Anonymous code block turning input into chars
                  $_          # From the input
          .rand+1,              # Take a random number from 1 to length of list
     roll                       # Of characters
 [~]                          # And join them into a string
\$\endgroup\$
3
\$\begingroup\$

Brachylog, 8 bytes

⊇ᶠbṛ;?ṛw

Try it online!

Prints output directly instead of constraining the output variable, because for some reason this actually fails without the w at the end. Originally this used and the ∈& backtracking hack I used to implement bogosort, but I realized that it would be far saner to just use b instead.

       w    Print
      ṛ     a random one of
     ?      the input
    ;       or
   ṛ        a random element of
 ᶠ          every
⊇           sublist of
            the input
  b         except the first one (which would be the input).
\$\endgroup\$
2
\$\begingroup\$

Python 2, 111 121 bytes

lambda s:choice(g(list(set(s)),len(s)))
from random import *
g=lambda s,n:s+(n>1and[c+k for k in g(s,n-1)for c in s]or[])

Try it online!

Takes any iterable (list, set, string, etc.) of either distinct characters or non-distinct characters as input. Outputs a non-empty string with the required distribution.

g is a recursive function to generate a list of compliant strings.

\$\endgroup\$
2
\$\begingroup\$

R, 72 64 bytes

-8 bytes thanks to Giuseppe.

S=sample;S(t<-unique(s<-scan(,"")),S(n<-seq(s),p=length(t)^n),T)

Try it online!

Input and output are vectors of characters. All possible outputs have equal probability.

Explanation (ungolfed version):

s<-scan(,"")                         # takes input as vector of characters
n<-length(s)
t<-unique(s)
sample(t,                           # sample uniformly at random from the list of unique characters
       sample(n,p=length(t)^(1:n)), # with length k in 1..n chosen randomly such that P[k] is proportional to length(t)^k
       T)                           # the sampling is with replacement
\$\endgroup\$
  • 1
    \$\begingroup\$ 64 bytes \$\endgroup\$ – Giuseppe Apr 10 at 1:36
  • \$\begingroup\$ @Giuseppe Thanks! \$\endgroup\$ – Robin Ryder Apr 10 at 5:52
1
\$\begingroup\$

Wolfram Language (Mathematica), 41 bytes

""<>#&@*RandomChoice@*Subsets@*Characters

Try it online!

\$\endgroup\$
  • \$\begingroup\$ Wha is this part? ""<>#&@ \$\endgroup\$ – Jonah Apr 6 at 21:30
  • 1
    \$\begingroup\$ @Jonah <> is StringJoin; ""<>#& is an anonymous function that joins "" with its argument (and is much shorter than StringJoin). @* composes functions. \$\endgroup\$ – attinat Apr 7 at 18:19
1
\$\begingroup\$

Java 131 bytes

void k(String a){a.chars().forEach(v->{int z=(int)(Math.random()*(a.length()+1));if(z<a.length())System.out.print(a.charAt(z));});}
\$\endgroup\$
  • \$\begingroup\$ Nice approach! Since you're using a Java 8+ stream, why not change void k(String a){a.chars()..;} to a->a.chars().. as well? Also, int z=(int)(Math.random()*(a.length()+1));if(z<a.length()) can be int l=a.length(),z=l+1;z*=Math.random();if(z<l) to save some more bytes. In total it then becomes 104 bytes \$\endgroup\$ – Kevin Cruijssen Apr 10 at 10:03
1
\$\begingroup\$

Pyth - 7 bytes

Os^LQSl

O                         Random choice
 s                        Collapse list
  ^L                      Map cartesian power
   Q                      Input
   S                      1-indexed range
    l                     Length
     (Q implicit)         Input

Try it online.

Try it online without random pick to see all possible options.

\$\endgroup\$
1
\$\begingroup\$

Haskell, 143 126 bytes

-7 bytes thanks to @Laiconi, additional improvement (which I need to fully understand first) in the comments

import Control.Monad
import System.Random
f a|c<-concat[replicateM x a|x<-[1..length a]]=randomRIO(0,length c-1)>>=print.(c!!)

Try it online!


Original

\$\endgroup\$
  • 1
    \$\begingroup\$ Instead of where you can use a binding in a guard. The do can be desugared, and there was a bit of extraneous whitespace: Try it online! \$\endgroup\$ – Laikoni Apr 13 at 14:02
  • 1
    \$\begingroup\$ The list comprehension can be rewritten as concatMap(`replicateM`a)[1..length a] and then shortened to (`replicateM`a)=<<[1..length a]. \$\endgroup\$ – Laikoni Apr 13 at 14:06
  • 1
    \$\begingroup\$ Though a shorter way to get all strings is mapM(\_->a)=<<scanr(:)[]a, as it does not need the import. This list includes the empty string at the end, so we need to subtract 2 in randomRIO(0,length c-2) to avoid it: Try it online! \$\endgroup\$ – Laikoni Apr 13 at 14:10
  • \$\begingroup\$ Thanks for the feedback, I'm relatively new to haskell (and totally new to golfing), so it's always nice to get some tips from more experiences users :) \$\endgroup\$ – bugs Apr 13 at 14:52
  • \$\begingroup\$ seems like it'd be easier generating all possible lists (of every length) and nub-ing to filter out duplicates \$\endgroup\$ – ASCII-only Apr 14 at 2:50
0
\$\begingroup\$

C (gcc), 68 65 bytes

f(s,i)char*s;{for(;i<strlen(s);i++)rand()&1?putc(s[i],stdout):0;}

Try it online!

\$\endgroup\$
  • \$\begingroup\$ I don't think this is correct anymore \$\endgroup\$ – Jo King Apr 6 at 3:02
  • 1
    \$\begingroup\$ If the op changed the rules that's a pity. \$\endgroup\$ – Natural Number Guy Apr 6 at 11:45
0
\$\begingroup\$

Charcoal, 34 bytes

≔Φθ⁼κ⌕θιη≔⊕‽ΣEθXLη⊕κζW櫧ηζ≔÷⊖ζLηζ

Try it online! Link is to verbose version of code. Explanation:

≔Φθ⁼κ⌕θιη

Extract the unique characters of the input. Let's call the number of unique characters n.

≔⊕‽ΣEθXLη⊕κζ

Calculate the number of combinations for each possible length and take the sum. Then, pick a random number between 1 and this number (inclusive). This ensures that all combinations are equally likely (within the accuracy of the random number generator).

W櫧ηζ≔÷⊖ζLηζ

Convert the number into bijective base n, using the unique characters as the digits.

\$\endgroup\$
0
\$\begingroup\$

MATLAB / Octave, 110 bytes

Choose a random permutation of a subset of the input letters (with repetitions), whose random length is based on the probability of generating a word with that length.

@(a)a(randi(numel(a),[find(cumsum(numel(a).^[1:numel(a)])>=randi(sum(numel(a).^[1:numel(a)])),1,'first'),1]));

Try it online!

\$\endgroup\$
0
\$\begingroup\$

T-SQL, 222 bytes

This creates all combinations of each unique character with recursive sql, then picks a random row from the distinct combinations.

DECLARE @ varchar(max)='T-SQL';

WITH C as(SELECT DISTINCT substring(@,number+1,1)x
FROM spt_values
WHERE'P'=type and len(@)>number),D
as(SELECT x y
FROM c UNION ALL
SELECT y+x
FROM C JOIN D
ON len(y)<len(@))SELECT top 1*FROM D
GROUP BY y
ORDER BY newid()

Note the online version will always give the same result unlike MS-SQL Studio Management. This is because newid() always returns the same value in the online testing. This should work in Studio Management.

Try it online ungolfed version

\$\endgroup\$
0
\$\begingroup\$

Python 2, 124 bytes

lambda s:g(list(set(s)),len(s))
from random import*
g=lambda s,n:choice(s)+(random()*~-len(s)**(n)>~-len(s)and g(s,n-1)or'')

Try it online!

A different approach: instead of first constructing a list of all compliant strings and choosing one at random, this approach randomly decides to continue extending the string or stopping.

This again has to deal with the exacting input requirements, at a cost of 31 bytes; but the function of interest g takes a list s of characters to be used, and an integer n which is the maximum length of the returned string.

As an example, consider the set of characters ['a','b'] and suppose we want to generate random strings of length 1, 2, or 3.

Then if we randomly choose 'a' as the starting character, the possible strings which could be returned are:

a
 aa
  aaa
  aab
 ab
  aba
  abb

shown above in 'tree' form, which is a total of 1 + 2 + 2*2 = 2^0 + 2^1 + 2^2 = 7 strings. So if we generate a string a; then 1/7 of the time we should stop and return 'a', and 6/7 of the time we should add further to the string - then the distribution will be uniform in the way desired.

More generally, if n is maximum length of the string and x is the number of characters in the set, then the number of strings starting with some given character is going to be:

$$h(n)=\sum_{i=0}^{n-1} x^i$$ $$h(n)=1+x+x^2+x^3...+x^{n-1}$$

For x>1 (guaranteed by OP's rule 'at least two distinct...'), we have:

$$h(n)(x-1)=(1+x+x^2+x^3...+x^{n-1})(x-1)=x^n-1$$ $$h(n)=\frac{x^n-1}{x-1}$$

So to decide whether we should continue extending our string, let p be a random number in [0,1); then we should recurse only if any of these equivalent statements are true:

$$p>\frac{1}{h(n)}$$ $$p>\frac{x-1}{x^n-1}$$ $$p(x^n-1)>x-1$$

of which g is the golfed implementation.

\$\endgroup\$
0
\$\begingroup\$

C# (Visual C# Interactive Compiler), 126 bytes

a=>{var s=new Random();int d=a.Length;return Enumerable.Range(1,s.Next(1,d)).Select(x=>a.Distinct().ToList()[s.Next(0,d-1)]);}

Try it online!

\$\endgroup\$
0
\$\begingroup\$

Forth (gforth), 68 bytes

include random.fs
: f dup random 1+ 0 do 2dup random + 1 type loop ;

Try it online!

Explanation

  • Get a random number between 1 and string-length
  • Loop that many times
  • For each iteration
    • Get a random number between 0 and string length - 1
    • Add that to string starting address and output the character at that address

Code Explanation

include random.fs          \ include the library file needed to generate random numbers
: f                        \ start a new word definition
  dup                      \ duplicate the string-length
  random 1+                \ get the length of the new string, make sure it starts from 1
  0 do                     \ start a loop of that length
    2dup                   \ duplicate the starting address and string length
    random +               \ get a number from 0 to string-length and add it to the address
    1 type                 \ output the character at that address
  loop                     \ end the loop
;                          \ end the word definition
\$\endgroup\$
0
\$\begingroup\$

J, 27 bytes

[:(?@#{])@;[:,@{&.>#\<@#"{<

Try it online!

standard formatting

[: (?@# { ])@; [: ,@{&.> #\ <@#"1 _ <

explanation

Eg, for the string 'abc' we first use #\<@#"{< to create:

┌─────┬─────────┬─────────────┐
│┌───┐│┌───┬───┐│┌───┬───┬───┐│
││abc│││abc│abc│││abc│abc│abc││
│└───┘│└───┴───┘│└───┴───┴───┘│
└─────┴─────────┴─────────────┘

We then take the cartesian product of each of these {, flatten the results, and finally remove the outer boxing ;.

(?@#{])@ takes a random result from that list.

\$\endgroup\$
  • \$\begingroup\$ TIO will return the same result every time, but in a normal J REPL it will be random. sounds like a bug to report, random works for Python 3 TIO... \$\endgroup\$ – Artemis Fowl Apr 9 at 0:16
  • \$\begingroup\$ J will start each session with the same seed for its RNG. If you keep running the same verb in a single session, you'll get different answers. But if you start your session over, the same sequence will occur. TIO is like a fresh J session. So it's not exactly a bug -- at least I wouldn't call it one. \$\endgroup\$ – Jonah Apr 9 at 0:57
  • \$\begingroup\$ Bug, maybe not. Improvable feature, quite possibly. As someone who's never used J, I'll leave it up to you to report the bug if you wish to. \$\endgroup\$ – Artemis Fowl Apr 9 at 1:03
  • \$\begingroup\$ @ArtemisFowl I figured out how to fix it. The TIO now works, returning a fresh result each time. \$\endgroup\$ – Jonah Apr 10 at 0:06
  • \$\begingroup\$ The program now seems to output a list of values... \$\endgroup\$ – Artemis Fowl Apr 10 at 10:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.