Generate a US License Plate
Python3, 861 821 819 714 678 674 670 662 661 658 596 591 561 555 551 536 bytes.
-8 bytes thanks to @DestructibleLemon (b=a+
... and d=B
...), -15 bytes thanks to @Felipe Nardi Batista (useless lambda and variable)
And thanks to everyone over in chat who helped golf this!
from random import*
C=choice
Z='000'
A='AAA'
B=A+'-0'+Z
a=A+' '+Z
b=A+'0'+Z
c=a[::-1]
d=B[1:]
print(C(''.join(C(['ABCDEFGHJKLMNPRSTUVWXYZ','0123456789',i]['A0'.find(i)])for i in([a]*5+[Z+'0',b,b,b]+[c]*6+['0'+A+Z,d,d+'0',A+' A00','AA 00'+Z,Z+'A,000AA,000AAA,'+A+Z,'0AA0'+Z,a+'0,0AA A00,'+a,Z+'-'+A,'00A-'+A,Z+' 0'+Z,'A00-'+A,Z+'-AAA,AAA-'+Z]+[B]*6+[a+'0',Z+A,B[:-1],Z+'-'+Z,a+','+c,'A00-00A','A00 0AA'])[[*zip('AIMMVAAGWAKKLNOCDCFIIMMMNNNNNNPTVWOOPRSTU','KASPTSZAARSYADRACTLLNDINVHJMYCAXAIHKRICNT')].index(tuple(input()))]).split(',')))
Try it online
Any golfing suggestions are welcome (and wanted). And, please, if you spot any errors, just tell me via the comments!
JavaScript (ES6), 374 368 bytes
s=>(P=n=>parseInt(n,36),R=Math.random,g=F=>F?(' -'+(R()*10|0)+'ABCDEFGHJKLMNPRSTUVWXYZ'[R()*23|0])[F&3]+g(F>>2):'')(P('8cf,4q,8fz,ch6,8hq,xpb,8f3,8jj,xov,6i|ru|356|24f,8fy,xmn|8ji|8cf,ciy,8e2,xm2,ciz,ciy|8e7,xof,xmn,356,8e7,8dm,8cf|ca2,bjf,ca3'.split`,`[P('1k3600d2mha35h7bi00jc000o03000000809l002003n0h3032e0fh4g0h'[P(s)%159%131%70%58])].split`|`.sort(_=>R()-.5)[0]))
Formatted and commented
In the following code, data sections have been truncated. Missing parts are marked with (...)
.
s => ( // given the state s
P = n => parseInt(n, 36), // P = base-36 parsing function
R = Math.random, // R = random generator
g = F => // g = recursive function taking an encoded format F
F ? // if the format has not been yet fully processed:
( // build a string consisting of:
' -' + // 0: space, 1: hyphen
(R() * 10 | 0) + // 2: a random digit
'ABCD(...)YZ'[R() * 23 | 0] // 3: a random uppercase letter (minus I, O, Q)
)[F & 3] + // pick the next character from this string
g(F >> 2) // recursive call, dropping the 2 consumed bits
: // else:
'' // stop recursion
)( // initial call to g():
P( // base-36 decoding of a format picked from
'8cf,4q,(...),ca3'.split`,`[ // a list of binary encoded formats
P( // accessed through a base-36 decoded index
'1k36(...)0h'[ // picked from a lookup-table of 58 entries
P(s) % 159 % 131 % 70 % 58 // based on a hash of the state
] // end of lookup-table access
) // end of lookup-table index decoding
].split`|` // end of list access / split it on '|'
.sort(_ => R() - .5)[0] // randomly pick a format from this list
) // end of format decoding
) // end of call
Demo
let f =
s=>(P=n=>parseInt(n,36),R=Math.random,g=F=>F?(' -'+(R()*10|0)+'ABCDEFGHJKLMNPRSTUVWXYZ'[R()*23|0])[F&3]+g(F>>2):'')(P('8cf,4q,8fz,ch6,8hq,xpb,8f3,8jj,xov,6i|ru|356|24f,8fy,xmn|8ji|8cf,ciy,8e2,xm2,ciz,ciy|8e7,xof,xmn,356,8e7,8dm,8cf|ca2,bjf,ca3'.split`,`[P('1k3600d2mha35h7bi00jc000o03000000809l002003n0h3032e0fh4g0h'[P(s)%159%131%70%58])].split`|`.sort(_=>R()-.5)[0]))
;[
'AK','AR','AS','AZ','CA','CT','DC','FL','GA','IL','IN','IA','KS','KY',
'LA','MD','MI','MN','MS','NV','NH','NJ','NM','NY','NC','ND','MP','OH',
'OK','OR','PA','PR','RI','SC','TN','TX','UT','VT','VA','WA','WI'
]
.forEach(s => console.log(s + ' --> ' + f(s)))
T-SQL, 1104 1100 797 657 bytes
DECLARE @ CHAR(8)SELECT @=STUFF(value,1,2,'')FROM STRING_SPLIT(CAST(DECOMPRESS(CAST('H4sIAAAAAAAEAEWPUQ6DMAiGr2JCwlM9BKnZ7LTV2E7n7n+QlRbYC3yl8PNDCyIOAOACKcVstCudRYkytPSthUZPUrqM6KhxqC+3ZKNbaSWlNCltNuEJuozzdekITXDygu6xshNkx2u3xJhqREmWGUQqTiDWYpBLGEGkrOgij47N21k1eKdLM3trI+mF+h2tMSJK441qM3nDnQzLx/D8V69guM3mblvkiP1Q/SPwTqbs1XD2zVztKwnbL7p3wV77AcxSbMHfAQAA'as XML).value('.','varbinary(max)'))AS varchar(max)),','),t WHERE s=LEFT(value,2)ORDER BY NEWID()WHILE CHARINDEX('&',@)>0SET @=STUFF(@,CHARINDEX('&',@),1,SUBSTRING('ABCDEFGHJKLMNPRSTUVWXYZ',CAST(1+23*RAND()AS INT),1))WHILE CHARINDEX('#',@)>0SET @=STUFF(@,CHARINDEX('#',@),1,CAST(10*RAND()AS INT))PRINT @
EDIT 1: Saved over 300 bytes by changing VALUES()
to STRING_SPLIT()
(only available in SQL 2016 and later)
EDIT 2: Saved another 140 bytes by using GZIP compression as described here. We've already restricted ourselves to SQL 2016 and later, so these functions are available.
Input is via pre-existing table t with the State code in column s, per our IO standards.
After expanding the compressed string, here's the formatted code, with the super long list of states snipped:
DECLARE @ CHAR(8)
SELECT @=STUFF(value,1,2,'')
FROM STRING_SPLIT('AK&&& ###,IA&&& ###,MS&&& ###,...
(long string continues)
...,SC### #&&,TN&##-##&,UT&## #&&',','),t
WHERE s=LEFT(value,2)ORDER BY NEWID()
WHILE CHARINDEX('&',@)>0
SET @=STUFF(@,CHARINDEX('&',@),1,
SUBSTRING('ABCDEFGHJKLMNPRSTUVWXYZ',CAST(1+23*RAND()AS INT),1))
WHILE CHARINDEX('#',@)>0
SET @=STUFF(@,CHARINDEX('#',@),1,
CAST(10*RAND()AS INT))
PRINT @
So I created a huge in-memory table consisting of all the possible pairs of (state, pattern). Note that I'm not combining rows, each state is separate, and states like IN will have 4 rows, one for each pattern.
When I join that in-memory table to the input table, I sort by NEWID()
, which randomizes the order and returns a random matching pattern to the variable @
.
I then just replace each &
with a random letter, and each #
with a random digit and return the result.