Targhe francesi


42

sandbox

Targhe francesi

Le targhe francesi arrivano in ordine sequenziale, seguendo uno schema specifico di numeri e lettere:AB-012-CD

Sfida

Scrivi un programma o una funzione che, per un dato numero, genera il corrispondente numero di targa francese . Il tuo programma non dovrebbe gestire alcun caso speciale come specificato nella pagina collegata. Dovrebbe essere in grado di generare tutte 26*26*1000*26*26 => 456 976 000le piastre possibili, o per quanto la tua lingua può supportare.

Il sistema di numerazione è il seguente:

  • AA-000-AA a AA-999-AA (i numeri si evolvono per primi);
  • AA-000-AB a AA-999-AZ (quindi l'ultima lettera a destra);
  • AA-000-BA a AA-999-ZZ (quindi la prima lettera a destra);
  • AB-000-AA a AZ-999-ZZ (quindi l'ultima lettera a sinistra);
  • BA-000-AA a ZZ-999-ZZ (quindi la prima lettera a sinistra).

Ingresso

  • L'indice del numero di targa come numero intero

Produzione

  • Il numero di targa francese corrispondente

Informazioni aggiuntive

  • Le lettere devono essere maiuscole
  • È possibile utilizzare l'indicizzazione sia a base 0 che a base 1 per generare le piastre (il che significa che AA-000-AA può corrispondere 0o 1, supponendo che tutti gli altri casi di test utilizzino la stessa indicizzazione.

Questo è code-golf , la risposta più breve in ogni lingua vince!

Casi di test (indicizzazione basata su 0)

          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

2
Ecco alcuni altri requisiti, direttamente da Wikipedia, se si desidera creare una variazione più difficile: "Questa cifra esclude tre lettere che non vengono utilizzate: I, O e U, poiché possono essere confuse con 1, 0 e V, rispettivamente. Esclude anche la combinazione delle SS perché ricorda l'organizzazione nazista e WW nel primo gruppo di lettere in quanto indica una targa temporanea ".
Eric Duminil,

4
@EricDuminil L'ho escluso di proposito perché ha appena aggiunto vincoli non comuni alla sfida. Ma è vero che potrebbe essere interessante da fare, ma anche con "punti bonus", dubito che varrebbe la pena implementare queste regole
Elcan

Risposte:


17

Pure Bash (senza utility esterne), 64

  • 2 byte salvati grazie a @NahuelFouilleul
x={A..Z}
eval f=($x$x-%03d-$x$x)
printf ${f[$1/1000]} $[$1%1000]

Provalo online! - impiega circa 10 secondi per passare sopra le 7 prove.

  • La riga n. 1 è una semplice assegnazione di una stringa a una variabile
  • La riga n. 2 è un'espansione di parentesi graffe per creare una matrice di stringhe di formato printf, una per tutte le 456.976 possibili combinazioni di lettere, con le cifre non ancora specificate. La evalè necessario per garantire variabile espansione (di x) avviene prima espansione delle graffe.
  • La riga n. 3 indicizza l'array per ottenere la stringa di formato appropriata e accetta la porzione di cifre come parametro.


13

Perl 5 (-ap), 47 byte

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

Provalo online!


PHP , 74 byte

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

Provalo online!


2
+1 per PHP, sapevo che potevamo incrementare le lettere in PHP, ma non sapevo che potremmo incrementare una combinazione di lettere e cifre. PHP mi stupisce ogni giorno! E grazie ho imparato qualcosa di nuovo.
Night2

8

Python 3 , 79 78 77 byte

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

Provalo online!

In qualche modo non mi sono mai reso conto che il f"string"collegamento al formato esiste fino a quando non ho visto la risposta di Black Owl Kai.


78 byte sostituendo tuplecon(*...,)
Black Owl Kai il

L'utilizzo f"string"rende esclusiva la tua risposta Python 3.6+, solo per essere a conoscenza. Bel lavoro però!
connectyourcharger

8

Rubino, 61 59 55 byte

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

Anche 55 byte:

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

Provalo online!

Questo inizializza un contatore a AA-AA000-, lo incrementa i ntempi (moltiplicando una stringa del codice che lo fa per n e evaling), quindi sposta gli ultimi 4 caratteri dopo il 3 °.


->n{s=('AA-AA000-'..?Z*9).step.take(n)[-1];s[2]+=s.slice!5,4;s}è più lungo ma mi chiedo se è possibile accorciarlo.
Eric Duminil,

In teoria, ->n{s=[*'AA-AA000-'..?Z*9][n];s[2]+=s.slice!5,4;s}dovrebbe funzionare ed è lungo solo 50 byte, ma genera prima ogni possibile piastra. : - /
Eric Duminil,

1
"s + = s.slice! 3,2" per 50 byte
GB

Quindi anche questo dovrebbe funzionare: 45 byte
GB

7

PHP , 96 84 79 byte

-5 byte grazie ai grandi commenti di Ismael Miguel .

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

Provalo online!

Approfitto del fatto che puoi incrementare le lettere in PHP! Così AAAA++sarebbe diventato AAABe AAAZ++sarebbe diventato AABA. Calcolo quante volte le lettere devono essere incrementate ottenendo una parte intera di input/1000. Quindi incrementa la lunghezza di quattro caratteri che molte volte ei suoi primi due e ultimi due caratteri diventeranno automaticamente il lato sinistro e destro del piatto.

Ad esempio per l'immissione del 675999numero di incrementi di lettere è (int)(675999 / 1000) = 675, così AAAAdiventerà AAZZ.

Infine, il numero medio viene calcolato da input%1000e tutto viene stampato nel formato specificato con l'aiuto di printf . %.2sstampa i primi due caratteri della stringa, %03uinserisce il numero a sinistra con 3 zeri.


2
@Elcan Siamo spiacenti, risolto il problema con un costo di 12 byte. Ho una scusa per essere stato attaccato da tre gatti, per il mio pasticcio: P
Night2

1
Invece di %0.2ste puoi scrivere %.2s. Questo ti fa risparmiare 1 byte. (Come un piccolo suggerimento: se si desidera emettere un numero decimale con un numero specifico di posizioni decimali, è possibile fare %.2f(o qualsiasi altro modificatore) poiché funziona allo stesso modo)
Ismael Miguel

1
@IsmaelMiguel Grazie, non sapevo che potevamo lasciar perdere 0. Modifica: guardando le documentazioni, sembra che non ne avessi nemmeno bisogno in primo luogo: P
Night2

1
Oh, sì, puoi lasciar perdere. Inoltre, puoi fare $x++^$argn/1e3invece di $x++<(0^$argn/1e3)e dovresti salvare 4 byte. Questo eseguirà il ciclo fino a ($x++^$argn/1e3) === 0, ed è 0quando $xe $argn/1e3sono lo stesso numero intero (usando ^lanci i numeri in numero intero). Puoi provarlo su sandbox.onlinephpfunctions.com/code/…
Ismael Miguel

1
@IsmaelMiguel Grazie ancora, idea molto intelligente. Hai reso questa risposta più breve di quella di JS e questo è un risultato: P
Night2

7

C, 88 86 byte

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

Abbastanza semplice, usa la divisione e il modulo per estrarre i campi, aggiunge 'A' per le lettere per mapparli a caratteri ASCII e stampa la formattazione per i numeri.

Provalo online!



6

05AB1E , 25 22 20 byte

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

-2 byte (e aumentato le prestazioni non generando l'intero elenco) grazie a @Grimy .

Indicizzazione basata su 0.

Provalo online o verifica tutti i casi di test .

Spiegazione:

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)

L'ultima parte ( s₄‰`UèX₄+¦'-.øý) potrebbe essere I₄÷èI₄+3.£.ý'-ýper un'alternativa di byte uguali:
provala online o verifica tutti i casi di test .

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)

1
20 con Au2ããI₄‰`UèX₄+¦'-.øýo Au2ããI₄÷èI₄+3.£'-.øý.
Grimmy,

1
@Grimy Grazie! E ora è anche molto più veloce non generando e indicizzando l'elenco completo. :)
Kevin Cruijssen,

6

J , 56 49 46 byte

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

Provalo online!

-3 byte grazie a FrownyFrog

Il tutto non è altro che 7 treni nidificati - se non è divertente, che cos'è?

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

1
Freddo! L'uso della permutazione è un buon modo per formattare la stringa risultante.
Galen Ivanov,


Thanks @FrownyFrog!
Jonah



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×26×1000=676000 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.


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!


Misses the dashes it seems, so for now it doesn't fit the challenge's rules :P
Elcan

1
Ah, I completely ignored them as some kind of separator! Makes quite a difference for these methods :(
Jonathan Allan

Sorry about that :c Still pretty nice to see it done in Jelly, even without !
Elcan

Added 7 byes to add them in, pretty sure there is a shorter overall method now...
Jonathan Allan

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


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.



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

Does MOD(QUOTIENT(A1,1E3),26) not work? Also, why 1E3 for 1000 but not 26E3 etc?
Neil

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

I meant removing QUOTIENT. Originally I was suggesting to change quotient to trunc with a / instead of comma.
Keeta

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

@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

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.


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) 

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

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

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


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!


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


1
Change 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

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)]')

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

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



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!

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.