French license plates

44

7

Sandbox

French License Plates

French license plates come in a sequential order, following a specific pattern of numbers and letters : AB-012-CD

Challenge

Write a program or function that, for a given number, outputs the corresponding french license plate number. Your program should not handle any special case as specified in the linked page. It should be able to generate the full 26*26*1000*26*26 => 456 976 000 possible plates, or as far as your language can support.

The numbering system goes as follows:

  • AA-000-AA to AA-999-AA (numbers evolve first);
  • AA-000-AB to AA-999-AZ (then the last letter on the right);
  • AA-000-BA to AA-999-ZZ (then the first letter on the right);
  • AB-000-AA to AZ-999-ZZ (then the last letter on the left);
  • BA-000-AA to ZZ-999-ZZ (then the first letter on the left).

Input

  • The plate number's index as an integer

Output

  • The corresponding french license plate number

Additional information

  • Letters have to be uppercase
  • You can use both 0-based and 1-based indexing to generate the plates (meaning AA-000-AA can correspond to 0or 1, assuming all the other test cases use the same indexing.

This is code-golf, shortest answer in every language wins!

Test cases (0-based indexing)

          0 -> AA-000-AA
          1 -> AA-001-AA
        999 -> AA-999-AA
       1000 -> AA-000-AB
    675 999 -> AA-999-ZZ
    676 000 -> AB-000-AA
456 975 999 -> ZZ-999-ZZ

Elcan

Posted 2019-09-23T18:46:20.090

Reputation: 913

2Here are some more requirements, directly from Wikipedia, if you want to create a harder variation : "This figure excludes three letters that are not used: I, O and U, as they can be confused with 1, 0 and V, respectively. It also excludes the SS combination because it is reminiscent of the Nazi organisation and WW in the first group of letters as it indicates a temporary plate." – Eric Duminil – 2019-09-25T06:50:53.793

4@EricDuminil I purposefully excluded it because it just added unfun constraints on the challenge. But it's true it could be interesting to do, but even with "bonus points", I doubt it would be worth implementing these rules – Elcan – 2019-09-25T07:33:23.413

Answers

13

Perl 5 (-ap), 47 bytes

$_=AAAA000;$_++while$F[0]--;s/(..)(\d+)/-$2-$1/

Try it online!


PHP, 74 bytes

for($a=AAAA000;$argn--;$a++);echo preg_replace('/(..)(\d+)/','-$2-$1',$a);

Try it online!

Grimmy

Posted 2019-09-23T18:46:20.090

Reputation: 12 521

2+1 for PHP, I knew we could increment letters in PHP, but I didn't know that we can increment a combination of letters and digits. PHP amazes me every day! And thanks I learned something new. – Night2 – 2019-09-24T12:39:19.803

17

Pure Bash (no external utils), 64

  • 2 bytes saved thanks to @NahuelFouilleul
x={A..Z}
eval f=($x$x-%03d-$x$x)
printf ${f[$1/1000]} $[$1%1000]

Try it online! - takes about 10s to run over the 7 testcases.

  • Line #1 is a simple assignment of a string to a variable
  • Line #2 is a brace expansion to build an array of printf format strings, one for all 456,976 possible letter combinations, with the digits not yet specified. The eval is required to ensure variable expansion (of x) occurs before brace expansion.
  • Line #3 indexes the array to get the appropriate format string and takes the digits portion as its parameter.

Digital Trauma

Posted 2019-09-23T18:46:20.090

Reputation: 64 644

1-2bytes – Nahuel Fouilleul – 2019-09-24T15:23:14.297

8

Ruby, 61 59 55 bytes

->n{s='AA-AA000-';eval's.succ!;'*n;s[2]+=s[5,4];s[0,9]}

Also 55 bytes:

->n{s='AA-AA000-';eval's.succ!;'*n;s[2]+=s.slice!5,4;s}

Try it online!

This initializes a counter to AA-AA000-, increments it n times (by multiplying a string of the code that does so by n and evaling), and then moves the last 4 characters after the 3nd.

Doorknob

Posted 2019-09-23T18:46:20.090

Reputation: 68 138

->n{s=('AA-AA000-'..?Z*9).step.take(n)[-1];s[2]+=s.slice!5,4;s} is longer but I wonder if it's possible to shorten it. – Eric Duminil – 2019-09-24T20:10:16.283

In theory, ->n{s=[*'AA-AA000-'..?Z*9][n];s[2]+=s.slice!5,4;s} should work and is only 50 bytes long, but it generates every possible plate first. :-/ – Eric Duminil – 2019-09-25T06:58:53.743

1"s+=s.slice!3,2" for 50 bytes – G B – 2019-09-25T08:47:43.540

Then this should also work: 45 bytes

– G B – 2019-09-25T10:52:22.813

8

Python 3, 79 78 77 bytes

lambda n:f"%c%c-{n%1000:03}-%c%c"%(*(65+n//1000//26**i%26for i in[3,2,1,0]),)

Try it online!

I somehow never realised that the f"string" format shortcut exists until seeing Black Owl Kai's answer.

Matthew Jensen

Posted 2019-09-23T18:46:20.090

Reputation: 713

78 bytes by replacing tuple by (*...,) – Black Owl Kai – 2019-09-23T22:27:04.143

Using f"string" makes your answer Python 3.6+ exclusive, just so you are aware. Nice work though! – connectyourcharger – 2019-09-26T19:31:44.420

7

PHP, 96 84 79 bytes

-5 byte thanks to Ismael Miguel's great comments.

for($s=AAAA;$x++^$argn/1e3;)$s++;printf('%.2s-%03u-'.$s[2].$s[3],$s,$argn%1e3);

Try it online!

I take advantage of the fact that you can increment letters in PHP! So AAAA++ would become AAAB and AAAZ++ would become AABA. I calculate how many times the letters have to be incremented by getting integer part of input/1000. Then increment the four characters length that many times and its first two and last two characters will automatically become the left and right side of the plate.

For example for input of 675999 number of letter increments is (int)(675999 / 1000) = 675, so AAAA will become AAZZ.

Finally, the middle number is calculated by input%1000 and everything is printed in the specified format with help of printf. %.2s prints first two characters of the string, %03u pads the number in the left with 3 zeros.

Night2

Posted 2019-09-23T18:46:20.090

Reputation: 5 484

Looks like it breaks for 456975999, it returns YYAA999ZZ, also you need the dashes inbetween the parts :P – Elcan – 2019-09-23T19:29:25.740

2@Elcan Sorry, fixed the issues at a cost of 12 bytes. I have an excuse of being under attack by three cats, for my messing up :P – Night2 – 2019-09-23T19:53:40.790

All good, now you have a working answer :P – Elcan – 2019-09-23T20:55:24.570

1Instead of %0.2s you can write %.2s. That saves you 1 byte. (As a tiny tip: if you want to output a decimal number with a specific number of decimal places, you can do %.2f (or any other modifier) as it works the same way) – Ismael Miguel – 2019-09-24T09:40:34.510

1@IsmaelMiguel Thanks, didn't know we could drop the 0. Edit: looking at documentations, it seems I didn't even need it at the first place :P – Night2 – 2019-09-24T10:38:40.173

1

Oh, yeah, you can drop those. Also, you can do $x++^$argn/1e3 instead of $x++<(0^$argn/1e3) and you should save 4 bytes. This will loop until ($x++^$argn/1e3) === 0, and it is 0 when $x and $argn/1e3 are the same integer number (using ^ will cast the numbers to integer). You can try this on http://sandbox.onlinephpfunctions.com/code/ab053fc9beff6ba616734e194efb1a0373de91e4

– Ismael Miguel – 2019-09-24T11:16:12.787

1@IsmaelMiguel Thanks again, very clever idea. You made this answer shorter than JS one and that is an achievement :P – Night2 – 2019-09-24T11:28:13.247

1You're welcome. I've been thinking about ways to reduce this answer (using a negative number to save a dash, splitting AAAA at the end, etc.) and nothing so far :/ – Ismael Miguel – 2019-09-24T14:05:44.663

@IsmaelMiguel, Grimy already has a shorter version here: https://codegolf.stackexchange.com/a/193442/81663

– Night2 – 2019-09-24T15:04:36.047

7

C, 88 86 bytes

#define d(b)a/b/1000%26+65
f(a){printf("%c%c-%03d-%c%c",d(17576),d(676),a%1000,d(26),d(1));}

Pretty simple, it uses division and modulus to extract the fields, adds 'A' for the letters to map them to ASCII characters, and printf formatting for the numbers.

Try it online!

Sir_Lagsalot

Posted 2019-09-23T18:46:20.090

Reputation: 4 898

6

Haskell, 85 81 79 77 bytes

([h++'-':n++'-':t|h<-q"AZ",t<-q"AZ",n<-q"099"]!!)
q g=mapM(\_->[g!!0..g!!1])g

Try it online!

nimi

Posted 2019-09-23T18:46:20.090

Reputation: 34 639

6

J, 56 49 46 bytes

226950 A.'--',7$_3|.4,@u:65 48+/(4 3#26 10)#:]

Try it online!

-3 bytes thanks to FrownyFrog

The whole thing is nothing but 7 nested trains -- if that ain't fun, what is?

  ┌─ 226950                                            
  ├─ A.                                                
  │        ┌─ '--'                                     
──┤        ├─ ,                                        
  │        │      ┌─ 7                                 
  └────────┤      ├─ $                                 
           │      │   ┌─ _3                            
           └──────┤   ├─ |.                            
                  │   │    ┌─ 4                        
                  └───┤    │     ┌─ ,                  
                      │    ├─ @ ─┴─ u:                 
                      └────┤                           
                           │     ┌─ 65 48              
                           │     ├─ / ───── +          
                           └─────┤                     
                                 │       ┌─ '4 3#26 10'
                                 └───────┼─ #:         
                                         └─ ]         

Jonah

Posted 2019-09-23T18:46:20.090

Reputation: 8 729

1Cool! Using permutation is a nice way to format the resulting string. – Galen Ivanov – 2019-09-24T06:24:30.107

146 – FrownyFrog – 2019-09-24T09:28:29.887

Thanks @FrownyFrog! – Jonah – 2019-09-24T13:42:46.950

6

05AB1E, 25 22 20 bytes

Au2ããs₄‰`UèX₄+¦'-.øý

-2 bytes (and increased the performance by not generating the entire list) thanks to @Grimy.

0-based indexing.

Try it online or verify all test cases.

Explanation:

Au            # Push the lowercase alphabet, and uppercase it
  2ã          # Create all possible pairs by taking the cartesian product with itself:
              #  ["AA","AB","AC",...,"ZY","ZZ"]
    ã         # Get the cartesian product of this list with itself:
              #  [["AA","AA"],["AA","AB"],...,["ZZ","ZZ"]]
s             # Swap to push the (implicit) input
 ₄‰           # Take the divmod-1000 of it
              #  i.e. 7483045 becomes [7483,45]
    `         # Push these values separated to the stack
     U        # Pop and store the remainder part in variable `X`
      è       # Index the integer part into the list of letter-pairs we created earlier
              #  i.e. 7483 will result in ["AL","BV"]
X             # Push the remainder part from variable `X` again
 ₄+           # Add 1000 to it
   ¦          # And remove the leading 1 (so now the number is padded with leading 0s)
              #  i.e. 45 becomes 1045 and then "045"
    '-.ø     '# Surround this with "-" (i.e. "045" becomes "-045-")
        ý     # Join the two pairs of letters by this
              #  i.e. ["AL","BV"] and "-045-" becomes "AL-045-BV"
              # (after which the top of the stack is output implicitly as result)

The last part (s₄‰`UèX₄+¦'-.øý) could be I₄÷èI₄+3.£.ý'-ý for an equal-bytes alternative:
Try it online or verify all test cases.

I₄÷           # Push the input, integer-divided by 1000
   è          # Use it to index into the letter-pairs we created earlier
              #  i.e. 7483045 becomes 7483 and then ["AL","BV"]
I₄+           # Push the input again, and add 1000
   3.£        # Only leave the last three digits
              #  i.e. 7483045 becomes 7484045 and then "045"
      .ý      # Intersperse the pair with this
              #  i.e. ["AL","BV"] and "045" becomes ["AL","045","BV"]
        '-ý  '# And join this list by "-"
              #  i.e. ["AL","045","BV"] becomes "AL-045-BV"
              # (after which the top of the stack is output implicitly as result)

Kevin Cruijssen

Posted 2019-09-23T18:46:20.090

Reputation: 67 575

120 with Au2ããI₄‰`UèX₄+¦'-.øý or Au2ããI₄÷èI₄+3.£'-.øý. – Grimmy – 2019-09-24T12:05:31.163

1@Grimy Thanks! And now it's also a lot faster by not generating and indexing into the complete list. :) – Kevin Cruijssen – 2019-09-24T12:52:36.017

5

JavaScript (Node.js), 82 bytes

n=>'32-654-10'.replace(/\d/g,x=>Buffer([x&4?n/10**(x-4)%10+48:n/1e3/26**x%26+65]))

Try it online!

Arnauld

Posted 2019-09-23T18:46:20.090

Reputation: 111 334

5

R, 101 bytes

b=0:3;a=scan()%/%c(10^b,1e3*26^b)%%rep(c(10,26),e=4);intToUtf8(c(a[8:7],-20,a[3:1]-17,-20,a[6:5])+65)

Try it online!

Just does the needed arithmetic computations. I saved 5 bytes by including in the vector a a useless value at a[4], allowing me to reuse the helper vector b.

Consider for example the second character (the B in AB-012-CD). That character changes every \$26\times26\times1000=676\,000\$ plates, so the value of that character for input n is the n %/% 676000 %% 26th letter of the alphabet, where %/% is integer division and %% is modulus in R. The other characters are computed similarly.

Robin Ryder

Posted 2019-09-23T18:46:20.090

Reputation: 6 625

5

Ruby, 51 bytes

->n{[*?A*4..?Z*4][n/1e3][/../]+"-%03d-"%(n%1e3)+$'}

Try it online!

G B

Posted 2019-09-23T18:46:20.090

Reputation: 11 099

Impressive. Congrats! – Eric Duminil – 2019-09-24T20:06:40.860

4

Jelly,  26  22 bytes

ØAṗ2,`ØDṗ3¤ṭŒp⁸ị2œ?j”-

A monadic Link accepting an integer (1-indexed) which yields a list of characters... Crazy-slow since it builds all the plates first!

Try it online! (wont complete)
Or try a reduced alphabet version (only "ABC" for the letters).


For code which completes in a timely manner here's a 32 byte full-program (0-indexed) which creates the single plate instead using modular arithmetic and numeric base decompression:

dȷ+“©L§“£ż’µḢṃØAṙ1¤ḊŒHW€jDḊ€$j”-

Try this one!

Jonathan Allan

Posted 2019-09-23T18:46:20.090

Reputation: 67 804

Misses the dashes it seems, so for now it doesn't fit the challenge's rules :P – Elcan – 2019-09-23T20:56:43.023

1Ah, I completely ignored them as some kind of separator! Makes quite a difference for these methods :( – Jonathan Allan – 2019-09-23T21:00:20.407

Sorry about that :c Still pretty nice to see it done in Jelly, even without ! – Elcan – 2019-09-23T21:07:00.810

Added 7 byes to add them in, pretty sure there is a shorter overall method now... – Jonathan Allan – 2019-09-23T21:08:11.680

Oops, thanks @Grimy - may as well golf that by 3 while I'm here :p – Jonathan Allan 1 min ago – Jonathan Allan – 2019-09-23T21:36:58.950

3

APL+WIN, 61 bytes

Prompts for integer:

m←⎕av[4↑66+n←((4⍴26),1E3)⊤⎕]⋄(2↑m),'-',(¯3↑'00',⍕4↓n),'-',2↓m

Try it online! Courtesy of Dyalog Classic

Graham

Posted 2019-09-23T18:46:20.090

Reputation: 3 184

3

Charcoal, 33 bytes

Nθ¹✂I⁺θφ±³≔⪪⍘⁺X²⁶¦⁵÷θφα²η¹⊟ηM⁹←⊟η

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

Nθ

Input the number.

¹

Print a -.

✂I⁺θφ±³

Add 1000 to the number, then cast the result to string, and print the last three digits.

≔⪪⍘⁺X²⁶¦⁵÷θφα²η

Divide the number by 1000, then add 26⁵, so the conversion to custom base using the uppercase alphabet results in a string of length 6, which is then split into pairs of letters.

¹

Print a -.

⊟η

Print the last pair of letters.

M⁹←

Move to the beginning of the number plate.

⊟η

Print the rest of the desired letters.

Neil

Posted 2019-09-23T18:46:20.090

Reputation: 95 035

3

Perl 6, 42 bytes

{S/(..)(\d+)/-$1-$0/}o{('AAAA000'..*)[$_]}

Try it online!

Port of Grimy's Perl 5 solution. Slow for large input values.

nwellnhof

Posted 2019-09-23T18:46:20.090

Reputation: 10 037

3

Excel, 183 167 155 147 bytes

-16 bytes thanks to @Neil. (6 by using E3)

-12 bytes thanks to @Keeta. (TRUNC instead of QUOTIENT)

-8 bytes thanks to @Jonathan Larouche (INT instead of TRUNC)

=CHAR(65+INT(A1/17576E3))&CHAR(65+MOD(INT(A1/676E3),26))&"-"&TEXT(MOD(A1,1E3),"000")&"-"&CHAR(65+MOD(INT(A1/26E3),26))&CHAR(65+MOD(INT(A1/1E3),26))

Concatenates 5 parts:

CHAR(65+INT(A1/17576E3))
CHAR(65+MOD(INT(A1/676E3),26))
TEXT(MOD(A1,1E3),"000")
CHAR(65+MOD(INT(A1/26E3),26))
CHAR(65+MOD(INT(A1/1E3),26))

Wernisch

Posted 2019-09-23T18:46:20.090

Reputation: 2 534

Does MOD(QUOTIENT(A1,1E3),26) not work? Also, why 1E3 for 1000 but not 26E3 etc? – Neil – 2019-09-25T09:23:29.990

Save even more by removing TRUNC altogether and moving the division to inside the MOD. =CHAR(65+A1/17576E3)&CHAR(65+MOD(A1/676E3,26))&"-"&TEXT(MOD(A1,1E3),"000")&"-"&CHAR(65+MOD(A1/26E3,26))&CHAR(65+MOD(A1/1E3,26)) bringing it down to 127 bytes. – Keeta - reinstate Monica – 2019-09-25T13:56:40.423

I meant removing QUOTIENT. Originally I was suggesting to change quotient to trunc with a / instead of comma. – Keeta - reinstate Monica – 2019-09-25T14:10:07.630

@Keeta, your 127 byte solution fails for some values: e.g. 456 975 996 --> [Z-996-ZZ – Wernisch – 2019-09-26T09:09:45.853

@Keeta, Seems like CHAR(65+) silently truncates decimals up to %.9999997614649. Bigger than that is rounded up. Compare CHAR(65+24.9999997614649) and CHAR(65+24.999999761465). – Wernisch – 2019-09-26T09:58:57.040

Stranger still, removing 65+ changes the behaviour. – Wernisch – 2019-09-26T10:01:31.330

Have you tested TRUNC(A1/17576E3) instead of QUOTIENT(A1,17576E3)? – Keeta - reinstate Monica – 2019-09-26T11:22:33.640

Even shorter, INT(A1/17576E3) instead of TRUNC(). 2 bytes times 4 : -8 bytes – Jonathan Larouche – 2019-09-27T20:23:49.057

2

Clean, 107 bytes

import StdEnv
A=['A'..'Z']
N=['0'..'9']
$n=[[a,b,'-',x,y,z,'-',c,d]\\a<-A,b<-A,c<-A,d<-A,x<-N,y<-N,z<-N]!!n

Try it online!

Defines $ :: Int -> [Char] giving the n-th zero-indexed licence plate.

Οurous

Posted 2019-09-23T18:46:20.090

Reputation: 7 916

2

Japt, 21 bytes

Obscenely slow! Seriously, don't even try to run it!

Tip of the hat to Kevin for making me realise where I was going wrong when fighting to get this working last night.

;gBï ï ïq#d0o ùT3 û-5

Try it - limits the number range to 000-005.

;gBï ï ïq#d0o ùT3 û-5     :Implicit input of integer
 g                        :Index into
; B                       :  Uppercase alphabet
   ï                      :  Cartesian product with itself
     ï                    :  Cartesian product of the result with itself
       ï                  :  Cartesian product of that with
         #d0              :    1000
            o             :    Range [0,1000)
              ùT3         :    Left pad each with 0 to length 3
                  û-5     :    Centre pad each with "-" to length 5
        q                 :  Join the first element (the 2 pairs of letters) with the second (the padded digit string) 

Shaggy

Posted 2019-09-23T18:46:20.090

Reputation: 24 623

2

Forth (gforth), 94 bytes

: x /mod 65 + emit ; : f dup 1000 / 17576 x 676 x ." -"swap 0 <# # # # #> type ." -"26 x 1 x ;

Try it online!

0-indexed. Input is taken from top of stack

Code explanation

\ extract out some common logic
: x             \ start a new word definition
  /mod          \ divide first argument by second and get both quotient and remainder
  65 +          \ add 65 (ascii A) to quotient
  emit          \ output
;               \ end word definition

: f             \ start a new word definition
  dup 100 /     \ duplicate input and divide by 1000
  17576 x       \ divide by 26^3 and output ascii char
  676 x         \ divide by 26^2 and output ascii char
  ." -"         \ output "-"
  swap 0        \ grab original number and convert to double-cell number
  <# # # # #>   \ convert last 3 chars of number to a string
  type ." -"    \ output string followed by "-"
  26 x          \ divide result of last mod by 26 and output ascii char
  1 x           \ output ascii char for remaining amount
;               \ end word definition

reffu

Posted 2019-09-23T18:46:20.090

Reputation: 1 361

2

q, 78 bytes

{sv["-","0"^-4$($:[x mod 1000]),"-"]2 2#(|).Q.A mod[x div 1000*26 xexp(!)4]26}

                                                    x div 1000*26 xexp(!)4     / input (floor) divided by 1000*26 ^ 0 1 2 3
                                                mod[                      ]26  / mod 26
                                           .Q.a                                / alphabet uppercase, indexed into by preceeding lines, for x=1000, we'd get "BAAA"
                                    2 2#(|)                                    / reverse and cut into 2x2 matrix ("AA";"AB")
               ($:[x mod 1000]),"-"                                            / string cast x mod 1000 and append "-"
            -4$                                                                / left pad to length 4, "  0-"
    "-","0"^                                                                   / fill nulls (" ") with "0" and prepend "-"
 sv[              x                ]y                                          / join elems of y by x

scrawl

Posted 2019-09-23T18:46:20.090

Reputation: 1 079

2

T-SQL, 135 bytes

select concat(CHAR(65+(@i/17576000)),CHAR(65+(@i/676000)%26),'-',right(1e3+@i%1000,3),'-',CHAR(65+(@i/26000)%26),CHAR(65+(@i/1000)%26))

Jonathan Larouche

Posted 2019-09-23T18:46:20.090

Reputation: 121

1

Python 3, 89 bytes

lambda n:h(n//676)+f"-{n%1000:03}-"+h(n)
h=lambda x:'%c%c'%(x//26000%26+65,x//1000%26+65)

Try it online!

-1 byte thanks to mypetlion

Black Owl Kai

Posted 2019-09-23T18:46:20.090

Reputation: 980

1Change chr(x//26000%26+65)+chr(x//1000%26+65) to '%c%c'%(x//26000%26+65,x//1000%26+65) to save 1 byte. – mypetlion – 2019-09-23T20:40:05.750

1

Python 2, 88 bytes

lambda n:g(n/676000)+'-%03d-'%(n%1000)+g(n/1000)
g=lambda n:chr(65+n/26%26)+chr(65+n%26)

Try it online!

Chas Brown

Posted 2019-09-23T18:46:20.090

Reputation: 8 959

The save by mypetition under my answer can be applied for Python 2, too – Black Owl Kai – 2019-09-23T22:21:46.140

1

C (gcc), 136 106 105 bytes

#define P(i)s[i]=65+x%26;x/=26;
z;s[]=L"  -%03d-  ";f(x){z=x%1000;x/=1e3;P(9)P(8)P(1)P(0)wprintf(s,z);}

Try it online!

-7 bytes from celingcat's solution, with additional -23 inspired by it

-1 byte from ceilingcat's solution by changing the char[] to a wchar_t[] implicitly cast to int[]

Uses 0-based indexing.

Explanation/Ungolfed:

int s[] = L"  -%03d-  "; // Pre-made wide-string with dashes and ending null byte
                         // and wprintf directive for digits
int z;                   // Temporary variable to store the digit part
void f(int x) {
    z = x % 1000;        // The digits represent x % 1000
    x /= 1000;           
    s[9] = 'A' + x % 26; // Place least significant letter
    x /= 26;             // Divide off least significant letter
    s[8] = 'A' + x % 26; // Place second letter
    x /= 26;             // Divide off second letter
    s[1] = 'A' + x % 26; // Place third letter
    x /= 26;             // Divide off third letter
    s[0] = 'A' + x;      // Place fourth letter (Don't need to % 26 because x < 26 now)
    wprintf(s, z); // Print finished string (with x%1000 replacing %03d)
}

pizzapants184

Posted 2019-09-23T18:46:20.090

Reputation: 3 174

@ceilingcat Thanks! Using that idea I removed the a and b parameters from the macro and got down to 106 bytes

– pizzapants184 – 2019-09-28T00:39:30.747

1

Red, 130 127 bytes

func[n][g: func[a b c][t: copy""loop a[insert t b +(n % c)n: n / c]t]a: g 3 #"0"10
s: g 4 #"A"26 rejoin[s/1 s/2"-"a"-"s/3 s/4]]

Try it online!

Galen Ivanov

Posted 2019-09-23T18:46:20.090

Reputation: 13 815

1

MATLAB, 113 bytes

c=@(x,p)char(mod(idivide(x,1000*26^p),26)+65);
s=@(n)[c(n,3),c(n,2),num2str(mod(n,1000),'-%03d-'),c(n,1),c(n,0)]

Explanations:

The first line define a function which will produce a char (from A to Z), function of 2 inputs. The index number x to convert into a plate number, and an integer p which will be used as an exponent for 26 (i.e. 26^p). This second input allow to adjust the calculations for the first alphanumeric plate digit (p=3) down to the last one (p=0).

For example, for the second digit, cycled every 1000*26*26 iterations, the operation: mod(idivide(x,1000*26^2),26) return an index between 0 and 25, which is then converted to an ASCII char by adding 65 (because the index are 0 based)

The second line simply concatenate characters together. Each alphanumeric character is calculated with the use of the function c(x,p), the numeric character are simply calculated with a modulo operation and converted to string.

Each component of the string composing the plate number is as follow:

digit #     |    how often is it cycled             |  code
----------------------------------------------------------------
digit 1     | cycle every 1000*26*26*26=1000*26^3   | c(n,3) 
digit 2     | cycle every 1000*26*26   =1000*26^2   | c(n,2) 
digit 3,4,5 | cycle every iteration                 | num2str(mod(n,1000),'-%03d-')
digit 6     | cycle every 1000*26      =1000*26^1   | c(n,1) 
digit 7     | cycle every 1000         =1000*26^0   | c(n,0) 

Since I can't let you try MATLAB online (edit: actually you can try it online ), I'll let MATLAB users the possibility to verify the test cases:

% chose some test cases
n = uint32([0;1;999;1000;675999;676000;456975999]) ;

% work out their plate numbers
plates = s(n) ;

% display results
fprintf('\n%10s | Plate # \n','Index')
for k=1:numel(n)
    fprintf('%10d : %s\n',n(k),plates(k,:))
end

outputs:

     Index | Plate # 
         0 : AA-000-AA
         1 : AA-001-AA
       999 : AA-999-AA
      1000 : AA-000-AB
    675999 : AA-999-ZZ
    676000 : AB-000-AA
 456975999 : ZZ-999-ZZ

Variant: Note that the option to let sprintf or fprintf take care of the number to character conversion is possible. It allow to simplify the function c, but overall result in a few more bytes in this implementation (119 bytes):

c=@(x,p)mod(idivide(x,1000*26^p),26)+65 ;
s=@(n)sprintf('%c%c-%03d-%c%c\n',[c(n,3),c(n,2),mod(n,1000),c(n,1),c(n,0)]')

Hoki

Posted 2019-09-23T18:46:20.090

Reputation: 271

1

Julia 1.0, 86 bytes

i->(join('A'.+digits(i÷1000,base=26,pad=4))string(i%1000,pad=3)*'-')[[4;3;8;5:8;2;1]]

Try it online!

user3263164

Posted 2019-09-23T18:46:20.090

Reputation: 381

0

Kotlin, 93 bytes

{i:Int->val c={v:Int->'A'+i/v/1000%26}
""+c(17576)+c(676)+"-%03d-".format(i%1000)+c(26)+c(1)}

Try it online!

JohnWells

Posted 2019-09-23T18:46:20.090

Reputation: 611

0

Python 3, 161 bytes

i,t,u,v,a,c,f=int(input()),1000,676,26,ord('A'),chr,lambda x:c(a+x//v)+c(a+x%v)
m,n=i%t,i//t
e,o=n%u,n//u
print('-'.join([f(o),(3-len(str(m)))*'0'+str(m),f(e)]))

Try it online!

Koishore Roy

Posted 2019-09-23T18:46:20.090

Reputation: 1 144