Generate a 6 character string from a 15 character alphabet

17

2

In one of our projects at work, we recently discovered a particularly large method for generating a 6 character string from a 15 character alphabet. A few of us claimed "I bet we can get that in one line" which started a little internal game of code golf.

Your task is to beat us, which I have no doubt won't take long!

The original algorithm used the alphabet 0-9A-E, but we've experimented with other alphabets. There are therefore three subtasks.

  1. Generate a 6 character string randomly selecting from an arbitrary hardcoded 15 character alphabet like ABC123!@TPOI098. (This is just an example, and should be customizable without affecting the byte count.)
  2. Generate a 6 character string randomly selecting from a 15 character alphabet 0123456789ABCDE.
  3. Generate a 6 character string randomly selecting from a 15 character alphabet of your choice (printable characters only please).

Each character should have equal chance of selection and repetition should be possible.

The best we have been able to manage for each of the subtasks is:

  • "ABC123!@TPOI098" - 24 bytes
  • "0123456789ABCDE" - 21 bytes
  • Custom alphabet - 13 bytes

Your score is the sum of the bytes in each subtask's solution. i.e. our score is currently 58.

We've attempted using among others, CJam and Ruby. The original was in C#. Use any language you like, but we'll be interested to see solutions in these languages particularly

James Webster

Posted 2016-10-15T13:32:20.137

Reputation: 2 809

5Regarding multi-part challenges. Unfortunately, I don't have a good solution in this case, since these three subtasks are way too similar for it to make sense to split them up into multiple challenges. I've also been considering proposing an exception to that policy for multi-part challenges where the subtasks are just minor variations of the same challenge. (Although that still has the problem that sub-solutions can be taken from other answers.) So I won't mod-hammer this, and see what the community thinks. – Martin Ender – 2016-10-15T13:51:20.870

"Your score is the sum of the bytes..." so my first example is unfortunate. I'll amend to another potential example – James Webster – 2016-10-15T14:11:03.277

2

@MartinEnder My 2 cents: I think it's OK and will not VTC. Sure, I generally think a challenge with a single interesting task is better, but since these tasks are very similar, it's a lot better than a "golf-course" that says "do these 8 random unrelated tasks." Even though there is no interaction between tasks, in my eyes this challenge is not very different than say Golf all 16 logic gates.

– James – 2016-10-15T14:41:37.440

Are there any time or memory limits? Do the subtasks have to be independent or are they allowed to share code? – Dennis – 2016-10-15T14:41:55.980

@DJMcMayhem Yes, that is actually the challenge which made me consider the exception I mentioned. I just didn't get around to sorting out my thoughts on the matter yet. – Martin Ender – 2016-10-15T14:43:31.017

Borderline dupe – Peter Taylor – 2016-10-15T14:45:56.370

2Does "generate a string" mean the code has to actually generate a string value with the appropriate characters in it, or is outputting the six characters (not separated by space or newlines) acceptable? – DLosc – 2016-10-15T19:17:19.477

Maybe I’m being dense here, but how can the character alphabet possibly be customisable without affecting the byte count? Wouldn’t changing the character set from 0123456789ABCDE to 0123456789x̃ᾖत्रुँֆ齉 increase the byte count by definition (unless the encoding uses 4 bytes for all characters)? Or is ‘character’ here to be taken to refer to single-byte ASCII characters only? – Janus Bahs Jacquet – 2016-10-16T13:19:49.493

Answers

6

Jelly, 38 bytes

TryItOnline links A, B, and C.

A: ABC123!@£POI098, 22 bytes

“ABC123!@£POI098”Wẋ6X€

(thinking about a compression to lessen this one)

B: 0123456789ABCDE, 8 bytes:

ØHṖWẋ6X€

C:123456789ABCDEF (choice), 8 bytes:

ØHḊWẋ6X€

How?

...Wẋ6X€ - common theme
   W     - wrap (string) in a list
    ẋ6   - repeat six times
      X€ - random choice from €ach

ØH...... - hexadecimal digit yield: "0123456789ABCDEF"

..Ṗ..... - pop: z[:-1] (B)

..Ḋ..... - dequeue: z[1:] (C)

Jonathan Allan

Posted 2016-10-15T13:32:20.137

Reputation: 67 804

8

CJam (23 + 14 + 10 = 47 bytes)

Arbitrary alphabet: 23 bytes (online demo)

{"ABC123!@TPOI098"mR}6*

Hexadecimal alphabet: 14 bytes (online demo)

{FmrAbHb'0+}6*

Custom alphabet: ABCDEFGHIJKLMNO, 10 bytes (online demo)

{Fmr'A+}6*

Dissection

The hexadecimal one is the interesting one:

{      e# Loop...
  Fmr  e#   Select a random number from 0 to 14
  AbHb e#   Convert to base 10 and then to base 17
       e#   (i.e. add 7 if the number is greater than 9)
  '0+  e#   Add character '0' (i.e. add 48 and convert from integer to character)
       e#   Note that 'A' - '0' = 17
}6*    e# ...six times

The six characters are left on the stack and printed automatically.

Peter Taylor

Posted 2016-10-15T13:32:20.137

Reputation: 41 901

2AbHb is brilliant. I thought about that general approach but _9>7*+ was too long. – Martin Ender – 2016-10-15T15:00:18.833

6

Perl, 46 + 26 + 26 = 98 bytes

A lot of the credit goes to @Dom Hastings for saving 13 bytes!

The 3 programs are pretty much identical, except for the alphabet that changes.

  • Hardcoded alphabet (ABC123!@)POI098 in this example) -> 46 bytes:

    say map{substr"ABC123!@)POI098",15*rand,1}1..6

  • Fixed alphabet 0123456789ABCDE -> 26 bytes:

    printf"%X",rand 15for 1..6

  • Custom alphabet 0123456789ABCDE in that case -> 26 bytes:

    printf"%X",rand 15for 1..6

You can put them all in a file to run them :

$ cat 6chr_strings.pl
say map{substr"ABC123!@)POI098",15*rand,1}1..6;
say "";
printf"%X",rand 15for 1..6;
say "";
printf"%X",rand 15for 1..6;
say "";
$ perl -M5.010 6chr_string.pl
CB8!8!
24D582
9ED58C

(the say ""; are just here to improve the output format)

Dada

Posted 2016-10-15T13:32:20.137

Reputation: 8 279

2Good answers! I had pretty much the same for the first and last, but you can save a byte using say: say map{("ABC123!@)POI098"=~/./g)[rand 15]}1..6 and say map{(A..O)[rand 15]}1..6. For the second you can use printf: printf"%X",rand 15for 1..6 to save 11 over all! I'm sure Ton can advise on some arcane magic to save more too! – Dom Hastings – 2016-10-17T14:40:57.383

1Actually with the custom alphabet substr saves another: say map{substr"ABC123!@)POI098",15*rand,1}1..6 – Dom Hastings – 2016-10-17T14:42:55.660

1@DomHastings Hmm indeed, that's nice, well played! Thanks :-) – Dada – 2016-10-17T15:06:08.660

2I like that you removed the note about the code being straightforward :D – Dom Hastings – 2016-10-17T15:32:00.673

@DomHastings with printf"%X", substr..rand and map, it's just a bit less obvious, so I let people enjoy perl magic with no spoilers! :D – Dada – 2016-10-17T15:36:33.870

4

JavaScript (ES6), 167 166 164 163 bytes

Saved 1 byte thanks to Neil
Saved 2 bytes thanks to ETHproductions
Saved 1 byte thanks to premek.v

Hardcoded: "ABC123!@TPOI098" (58 bytes)

f=(n=6)=>n?"ABC123!@TPOI098"[Math.random()*15|0]+f(n-1):''

Fixed: "0123456789ABCDE" (58 57 bytes)

f=(n=6)=>n?f(n-1)+("ABCDE"[n=Math.random()*15|0]||n-5):''

Custom: "()+.1=>?M[afhnt" (51 49 48 bytes)

f=(n=6)=>n?(f+1)[Math.random()*15|0+5]+f(n-1):''

Arnauld

Posted 2016-10-15T13:32:20.137

Reputation: 111 334

1(n=6)=>n?f(n-1)+("ABCDE"[n=Math.random()*15|0]||n-5):'' saves you a byte. – Neil – 2016-10-15T17:58:00.217

1/8+Math is great :) – ETHproductions – 2016-10-16T00:52:03.137

But .1+JSON is better ;) – ETHproductions – 2016-10-16T13:49:08.113

1Or JSON+f ([object JSON](n => " (JNOS[]bcejnot") – ETHproductions – 2016-10-16T13:53:50.720

@ETHproductions Nice one. :) – Arnauld – 2016-10-16T14:05:53.283

4

R, 33+43+59 = 135 bytes

Arbitrary hard-coded alphabet (change the string to change the alphabet):

cat(sample(strsplit("ABC123!@TPOI098","")[[1]],6,1),sep="")

Alphabet of [0-9A-E]:

cat(sample(c(0:9,LETTERS[1:6]),6,1),sep="")

User-defined alphabet from stdin:

cat(sample(scan(,''),6,1),sep="")

All cases print the output word to stdout.

rturnbull

Posted 2016-10-15T13:32:20.137

Reputation: 3 689

3

JavaScript (ES6), 184 bytes

Custom alphabet: 66 bytes

_=>"......".replace(/./g,c=>"ABC123!@TPOI098"[Math.random()*15|0])

0-9A-E: 63 bytes

_=>"......".replace(/./g,c=>"ABCDE"[n=Math.random()*15|0]||n-5)

0-9a-e: 55 bytes

_=>(Math.random()*11390625+1e8|0).toString(15).slice(1)

(Subtract 6 bytes if date-based randomness is permissible.)

Neil

Posted 2016-10-15T13:32:20.137

Reputation: 95 035

You can save a byte on the last one with **: _=>((Math.random()+1)*15**6|0).toString(15).slice(1) – ETHproductions – 2016-10-16T14:21:33.033

@ETHproductions Surely that would make it ES7, rather than ES6? (Also, it looks like a 3-byte saving to me.) – Neil – 2016-10-16T21:21:20.403

Yes, and it does appear to save 3 bytes. I must have included the f= in the byte count – ETHproductions – 2016-10-20T02:39:45.163

3

q, 42 bytes

A

19 bytes

6?"ABC123!@TPOI098"

B

14 bytes

6?15#.Q.n,.Q.A

C

9 bytes

6?15#.Q.a

(uses the first fifteen letters of the alphabet)

skeevey

Posted 2016-10-15T13:32:20.137

Reputation: 4 139

3

Julia (36+26+21 = 83)

join(rand(["ABC123!@TPOI098"...],6))

base(15,rand(15^6:15^7-1))

join(rand('a':'o',6))

Lyndon White

Posted 2016-10-15T13:32:20.137

Reputation: 1 021

2

CJam, 48 bytes

Arbitrary alphabet, 23 bytes:

{"ABC123!@TPOI098"mR}6*

Try it online!

Hex digits, 15 bytes:

{A,'F,65>+mR}6*

Try it online!

Alphabet ABCDEFGHIJKLMNO, 10 bytes:

{Fmr'A+}6*

Try it online!

Martin Ender

Posted 2016-10-15T13:32:20.137

Reputation: 184 808

I had a bad idea. If we consider U+FFFE a character, ~c instead of 'A+ returns something technically printable. – jimmy23013 – 2016-10-16T15:34:59.290

Maybe I'm wrong. I didn't find a definition of printable Unicode characters. – jimmy23013 – 2016-10-16T15:38:29.563

2

Ruby 47 + 37 + 31 = 115

Hardcoded: "ABC123!@TPOI098" (47)

(1..6).map{"5CABC123!@TPOI098".chars.sample}*''

Fixed: "0123456789ABCDE" (37)

(1..6).map{[*0..9,*?A..?E].sample}*''

Custom: "ABCDEFGHIJKLMNO" (31)

(1..6).map{[*?A..?O].sample}*''

Michael Kohl

Posted 2016-10-15T13:32:20.137

Reputation: 483

1

05AB1E, 43 bytes

Arbitratry alphabet (ABC123!@TPOI098), 23 bytes Try it online

"ABC123!@TPOI098"6F.r¬?

Almost hexadecimal alphabet (0123456789ABCDE), 10 bytes Try it online

14Ýh6F.r¬?

Custom alphabet (abcdefghijklmno), 10 bytes Try it online

A15£6F.r¬?

Emigna

Posted 2016-10-15T13:32:20.137

Reputation: 50 798

1

Python 2, 70 + 70 + 64 = 204 bytes

from random import*
s=""
exec"s+=choice('ABC123!@TPOI098');"*6
print s

from random import*
s=""
exec"s+=choice('0123456789ABCDE');"*6
print s

from random import*
s=""
exec"s+=chr(randint(65,80));"*6
print s

Unfortunately, the second example is easier with the first method than something like choice([randint(48,57)),choice(65,69)])

Karl Napf

Posted 2016-10-15T13:32:20.137

Reputation: 4 131

Why do you use from random import*? I think you can use import random and random.choice at least in the first two examples. – Roman Gräf – 2016-10-15T18:27:37.460

import random random.choice is 27 but from random import* choice is 26, also import random as r r.choice is 27 – Karl Napf – 2016-10-15T19:26:28.820

For the hex case, we can do a bit better by using format(randrange(8**8),'X'), I think. – DSM – 2016-10-16T15:37:39.693

@DSM the problem is, there must be no F – Karl Napf – 2016-10-16T20:32:19.473

1

Vitsy, 27 + 24 22 + 13 10 = 64 62 59 bytes

#1:

"ABC123!@TPOI098"6\[eR2+@O]

Try it online!

#2:

aH7+D4+H6\[eR2+@68*+O]

Try it online!

#3:

6\[eR5F-O]

Where the available characters are:

ヨユヤモメムミマホヘフヒハノネ

Try it online!

Addison Crump

Posted 2016-10-15T13:32:20.137

Reputation: 10 763

1

J, 24 + 24 + 18 10 = 58 bytes

8 bytes saved thanks to miles!

'ABC123!@TPOI098'{~?6#15
'0123456789ABCDE'{~?6#15
u:65+?6#15

Yeah, the second string isn't easily compressible in J:

u:47+23#.inv 12670682677028904639x
u:47+;(+i.@])/"1&.>1 10;18 5
('ABCDE',~1":i.10)
(toupper,hfd?6#15)
'0123456789ABCDE'

If a lowercase hex alphabet is fine, then there's ,hfd?6#15 for 9 bytes, as @miles noted.

Anyhow, ?6#15 is 6 random numbers between 0 and 15; {~ is take-from. u: converts numbers to chars. The last example encodes ABCDEFGHIJKLMNOP.

Bonus: general case

{~6?@##

{~6?@## is roughly:

{~6?@##  input: y
      #  length of y
  6  #   six copies of the length
   ?@    random numbers between 0 and the length
{~       taken from y

Conor O'Brien

Posted 2016-10-15T13:32:20.137

Reputation: 36 228

On the second case, there's a builtin named hfd which converts to hex from decimal. You can get a 9 byte solution using ,hfd?6#15. The last case, just to have something easily read, uses the alphabet from 'A' for a 10 byte solution u:65+?6#15, making a total 24 + 9 + 10 = 45. – miles – 2016-10-17T03:51:32.550

@miles I think the second case requires capitalized letters. As for the last case... haha, oops. I completely forgot about vectorized addition. – Conor O'Brien – 2016-10-17T11:08:56.027

1

PHP, 46+36+35=117 bytes

Hardcoded (46 bytes)

for(;$i++<6;)echo"ABC123!@TPOI098"[rand()%15];

(47 bytes)

for(;$i++<6;)echo"ABC123!@TPOI098"[rand(0,14)];

Hexadecimal (lowercase) (36 bytes)

for(;$j++<6;)echo dechex(rand()%15);

For uppercase, 46 bytes with Hardcoded version.

Custom (A-O) (35 bytes)

for(;$k++<6;)echo chr(rand(65,79));

Crypto

Posted 2016-10-15T13:32:20.137

Reputation: 862

I don't think I can accept your 2nd part. a-e isn't the same as A-E – James Webster – 2016-10-17T08:38:05.870

0

Scala, 154 bytes

Hardcoded alphabet (54 bytes):

Seq.fill(6)("ABC123!@TPOI098"((math.random*14).toInt))

Hex alphabet (54 bytes):

Seq.fill(6)("0123456789ABCDE"((math.random*14).toInt))

Custom alphabet ABCDEFGHIJKLMNO (47 bytes):

Seq.fill(6)(('A'to'O')((math.random*14).toInt))

Explanation:

Seq.fill(6)(               //build a sequence of 6 elements, where each element is...
  "ABC123!@TPOI098"(         //from the string
    (math.random*14).toInt   //take a random char
  )
)

'A'to'O' creates a sequence of 15 chars, A to O

corvus_192

Posted 2016-10-15T13:32:20.137

Reputation: 1 889

0

Pip, 42 bytes

Hardcoded alphabet, 22 bytes:

L6ORC"ABC123!@TPOI098"

Hex digits, 11 bytes:

L6ORR15TB16

First 15 lowercase letters, 9 bytes:

L6Oz@RR15

Explanation

All three programs start with L6O: loop 6 times and output the given expression.

  • RC"...": Random Choice of a character from the hard-coded string
  • RR15TB16: RandRange(15), converted To Base 16
  • z@RR15: lowercase alphabet z, indexed with RandRange(15)

Try it online!

DLosc

Posted 2016-10-15T13:32:20.137

Reputation: 21 213

0

Skript/skQuery, 108 bytes

Hardcoded (43 bytes):

random 6 char string from `A@cD%F3h9JK{mN!`

0123456789ABCDE (34 bytes):

random 6 char string from `0-9A-E`

Choice (31 bytes):

random 6 char string from `A-M`

Oliver Ni

Posted 2016-10-15T13:32:20.137

Reputation: 9 650

Can you move the opening ``` to the left? – Addison Crump – 2016-10-16T16:01:16.463

@VTCAKAVSMoACE No, it doesn't let you – Oliver Ni – 2016-10-16T16:38:09.983

0

Jolf, 26 + 14 + 13 = 51 bytes

Μ*S6d rG"ABC123!@TPOI098"E

Custom alphabet, 24 bytes. Try it here!

Μ*S6d r lp^0wά

0-9A-E alphabet, 14 bytes. Try it here! lp^0wά is lp (0-Z) sliced (l) from 0 to 15 ().

Μ*S6d r lp^1ά

1-9A-F alphabet, 13 bytes. Try it here! lp^1ά is the same as above, except from 1 to 16.


General method:

Μ*S6d r
M*S6d      map six newlines over this function:
      r    select random element from array.

Other attempts (using string compression):

Μ*S6d rGμpwΞ $AE

Conor O'Brien

Posted 2016-10-15T13:32:20.137

Reputation: 36 228

0

PowerShell v2+, 45 + 44 + 37 = 126 bytes

Fixed alphabet, 45 bytes

-join(0..5|%{'ABC123!@TPOI098'[(Random)%15]})

Nearly-hexadecimal alphabet, 44 bytes

-join[char[]](0..5|%{Random(48..57+65..69)})

Custom alphabet (A to O), 37 bytes

-join[char[]](0..5|%{Random(65..79)})

All of these follow the same pattern -- loop from 0 to 5, each iteration selecting a Random character or ASCII value, casting that as a char-array if necessary, and -joining it together into a string. That string is left on the pipeline, and output is implicit.


Examples

PS C:\Tools\Scripts\golfing> -join(0..5|%{'ABC123!@TPOI098'[(Random)%15]})
32ATB3

PS C:\Tools\Scripts\golfing> -join(0..5|%{'ABC123!@TPOI098'[(Random)%15]})
III@B2

PS C:\Tools\Scripts\golfing> -join(0..5|%{'ABC123!@TPOI098'[(Random)%15]})
@302O@

PS C:\Tools\Scripts\golfing> -join[char[]](0..5|%{Random(48..57+65..69)})
74E117

PS C:\Tools\Scripts\golfing> -join[char[]](0..5|%{Random(48..57+65..69)})
09D7DD

PS C:\Tools\Scripts\golfing> -join[char[]](0..5|%{Random(65..79)})
COJDFI

PS C:\Tools\Scripts\golfing> -join[char[]](0..5|%{Random(65..79)})
EAKCNJ

AdmBorkBork

Posted 2016-10-15T13:32:20.137

Reputation: 41 581

-1

Pyke, 35 bytes

Arbitary alphabet, 20 bytes

6V"ABC123!@TPOI098"H

Try it here!

Hex alphabet, 8 bytes

6V~J15<H

Try it here!

~J15< - "0123456789abcdefghijklmno..."[:15]

Custom alphabet, 7 bytes

6VG15<H

Try it here!

G15< - alphabet[:15]

Alphabet chosen: abcdefghijklmno

6V     - repeat 6 times:
  ...  -   get alphabet
     H -  choose_random(^)

Blue

Posted 2016-10-15T13:32:20.137

Reputation: 26 661

This seems to output 6 chars separated by newline instead of a 6-char string. – Emigna – 2016-10-17T11:26:45.293

The question doesn't state the output format. – Blue – 2016-10-17T11:29:15.820

I see the words Generate a 6 character string in 4 places in the specification. – Emigna – 2016-10-17T11:30:24.450