Placas francesas


41

Salvadera

Placas francesas

Las placas francesas vienen en orden secuencial, siguiendo un patrón específico de números y letras:AB-012-CD

Reto

Escriba un programa o función que, para un número dado, muestre el número de matrícula francés correspondiente . Su programa no debe manejar ningún caso especial como se especifica en la página vinculada. Debería ser capaz de generar todas 26*26*1000*26*26 => 456 976 000las placas posibles, o en la medida en que su idioma lo permita.

El sistema de numeración es el siguiente:

  • AA-000-AA a AA-999-AA (los números evolucionan primero);
  • AA-000-AB a AA-999-AZ (luego la última letra a la derecha);
  • AA-000-BA a AA-999-ZZ (luego la primera letra a la derecha);
  • AB-000-AA a AZ-999-ZZ (luego la última letra a la izquierda);
  • BA-000-AA a ZZ-999-ZZ (luego la primera letra a la izquierda).

Entrada

  • El índice del número de placa como un entero

Salida

  • El número de matrícula francés correspondiente

Información Adicional

  • Las letras deben ser mayúsculas
  • Puede utilizar la indexación tanto base 0 y basados en 1 para generar las placas (es decir, AA-000-AA puede corresponder a 0o 1, suponiendo que todos los demás casos de prueba utilizan la misma indexación.

Este es el código de golf , ¡la respuesta más corta en todos los idiomas gana!

Casos de prueba (indexación basada en 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
Aquí hay algunos requisitos más, directamente de Wikipedia, si desea crear una variación más difícil: "Esta figura excluye tres letras que no se usan: I, O y U, ya que pueden confundirse con 1, 0 y V, respectivamente. También excluye la combinación SS porque recuerda a la organización nazi y WW en el primer grupo de letras, ya que indica una placa temporal ".
Eric Duminil

44
@EricDuminil Lo excluí a propósito porque solo agregó restricciones no ejecutadas en el desafío. Pero es cierto que podría ser interesante hacerlo, pero incluso con "puntos de bonificación", dudo que valga la pena implementar estas reglas
Elcan

Respuestas:


17

Pure Bash (sin utilidades externas), 64

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

Pruébalo en línea! - tarda unos 10 segundos en pasar por las 7 cajas de prueba.

  • La línea n. ° 1 es una asignación simple de una cadena a una variable
  • La línea # 2 es una expansión de llaves para construir una matriz de cadenas de formato printf, una para las 456,976 combinaciones de letras posibles, con los dígitos aún no especificados. Se evalrequiere para garantizar que se produzca una expansión variable (de x) antes de la expansión de la llave.
  • La línea n. ° 3 indexa la matriz para obtener la cadena de formato adecuada y toma la porción de dígitos como parámetro.


13

Perl 5 (-ap), 47 bytes

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

Pruébalo en línea!


PHP , 74 bytes

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

Pruébalo en línea!


2
+1 para PHP, sabía que podíamos incrementar letras en PHP, pero no sabía que podemos incrementar una combinación de letras y dígitos. PHP me sorprende todos los días! Y gracias, aprendí algo nuevo.
Noche2


8

Ruby, 61 59 55 bytes

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

También 55 bytes:

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

Pruébalo en línea!

Esto inicializa un contador AA-AA000-, lo incrementa npor multiplicado (multiplicando una cadena del código que lo hace por n e evaling), y luego mueve los últimos 4 caracteres después del 3º.


->n{s=('AA-AA000-'..?Z*9).step.take(n)[-1];s[2]+=s.slice!5,4;s}es más largo pero me pregunto si es posible acortarlo.
Eric Duminil

En teoría, ->n{s=[*'AA-AA000-'..?Z*9][n];s[2]+=s.slice!5,4;s}debería funcionar y tiene solo 50 bytes de longitud, pero genera primero todas las placas posibles. : - /
Eric Duminil

1
"s + = s.slice! 3,2" para 50 bytes
GB

Entonces esto también debería funcionar: 45 bytes
GB

7

PHP , 96 84 79 bytes

-5 bytes gracias a los grandes comentarios de Ismael Miguel .

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

Pruébalo en línea!

¡Aprovecho el hecho de que puedes incrementar letras en PHP! Entonces AAAA++se volvería AAABy AAAZ++se volvería AABA. Calculo cuántas veces deben incrementarse las letras obteniendo una parte entera input/1000. Luego incremente la longitud de cuatro caracteres muchas veces y sus primeros dos y últimos dos caracteres se convertirán automáticamente en el lado izquierdo y derecho de la placa.

Por ejemplo, para la entrada del 675999número de incrementos de letras es (int)(675999 / 1000) = 675, así AAAAserá AAZZ.

Finalmente, se calcula el número del medio input%1000y todo se imprime en el formato especificado con la ayuda de printf . %.2simprime los dos primeros caracteres de la cadena, %03urellena el número de la izquierda con 3 ceros.


2
@Elcan Lo sentimos, solucioné los problemas a un costo de 12 bytes. Tengo una excusa de ser atacado por tres gatos, por mi desorden: P
Noche2

1
En lugar de %0.2sti puedes escribir %.2s. Eso te ahorra 1 byte. (Como un pequeño consejo: si desea generar un número decimal con un número específico de lugares decimales, puede hacerlo %.2f(o cualquier otro modificador) ya que funciona de la misma manera)
Ismael Miguel

1
@IsmaelMiguel Gracias, no sabía que podíamos dejar caer el 0. Editar: mirando las documentaciones, parece que ni siquiera lo necesitaba en primer lugar: P
Noche2

1
Oh, sí, puedes dejarlos. Además, puede hacerlo en $x++^$argn/1e3lugar de $x++<(0^$argn/1e3)y debe guardar 4 bytes. Esto se repetirá hasta ($x++^$argn/1e3) === 0, y es 0cuando $xy $argn/1e3son el mismo número entero (el uso ^convertirá los números a entero). Puede probar esto en sandbox.onlinephpfunctions.com/code/…
Ismael Miguel

1
@IsmaelMiguel Gracias de nuevo, idea muy inteligente. Hiciste esta respuesta más corta que JS y ese es un logro: P
Noche2

7

C, 88 86 bytes

#definir 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));}

Bastante simple, utiliza la división y el módulo para extraer los campos, agrega 'A' para las letras para mapearlos con caracteres ASCII e imprime el formato para los números.

Pruébalo en línea!



6

05AB1E , 25 22 20 bytes

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

-2 bytes (y aumentó el rendimiento al no generar la lista completa) gracias a @Grimy .

Indexación basada en 0.

Pruébelo en línea o verifique todos los casos de prueba .

Explicación:

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)

La última parte ( s₄‰`UèX₄+¦'-.øý) podría ser I₄÷èI₄+3.£.ý'-ýpara una alternativa de bytes iguales:
Pruébelo en línea o verifique todos los casos de prueba .

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 Gracias! Y ahora también es mucho más rápido al no generar e indexar en la lista completa. :)
Kevin Cruijssen

6

J , 56 49 46 bytes

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

Pruébalo en línea!

-3 bytes gracias a FrownyFrog

Todo esto no es más que 7 trenes anidados; si eso no es divertido, ¿qué es?

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

1
¡Guay! Usar permutación es una buena manera de formatear la cadena resultante.
Galen Ivanov


Gracias @FrownyFrog!
Jonás



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)

Pruébalo en línea!

Solo hace los cálculos aritméticos necesarios. Ahorré 5 bytes al incluir en el vector aun valor inútil en a[4], lo que me permite reutilizar el vector auxiliar b.

BAB-012-CD26×26×1000=676000nn %/% 676000 %% 26%/%%%


4

Jalea ,  26  22 bytes

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

Un enlace monádico que acepta un número entero (1 indexado) que produce una lista de caracteres ... ¡Loco-lento ya que construye todas las placas primero!

Pruébalo en línea! (no se completará)
O pruebe con una versión reducida del alfabeto (solo "ABC" para las letras).


Para el código que se completa de manera oportuna, aquí hay un programa completo de 32 bytes (indexado 0) que crea la placa única en su lugar usando aritmética modular y descompresión de base numérica:

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

Prueba este!


Parece perder los guiones, así que por ahora no se ajusta a las reglas del desafío: P
Elcan

1
¡Ah, los ignoré por completo como una especie de separador! Hace una gran diferencia para estos métodos :(
Jonathan Allan

Perdón por eso: c ¡Sigue siendo agradable verlo hecho en Jelly, incluso sin él!
Elcan

Se agregaron 7 byes para agregarlos, bastante seguro de que ahora hay un método general más corto ...
Jonathan Allan

Vaya, gracias @Grimy - también podría jugar golf a las 3 mientras estoy aquí: p - Jonathan Allan hace 1 minuto
Jonathan Allan


3

Carbón , 33 bytes

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

Pruébalo en línea! El enlace es a la versión detallada del código. Explicación:

Nθ

Ingrese el número.

¹

Imprimir a -.

✂I⁺θφ±³

Agregue 1000 al número, luego arroje el resultado a una cadena e imprima los últimos tres dígitos.

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

Divida el número entre 1000, luego agregue 26⁵, de modo que la conversión a una base personalizada usando el alfabeto en mayúscula resulte en una cadena de longitud 6, que luego se divide en pares de letras.

¹

Imprimir a -.

⊟η

Imprime el último par de letras.

M⁹←

Avanzar al comienzo de la matrícula.

⊟η

Imprime el resto de las letras deseadas.



3

Excel, 183 167 155 147 bytes

-16 bytes gracias a @Neil. (6 usando E3)

-12 bytes gracias a @Keeta. (en TRUNClugar de QUOTIENT)

-8 bytes gracias a @Jonathan Larouche (en INTlugar de 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))

Concatena 5 partes:

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

No MOD(QUOTIENT(A1,1E3),26)funciona Además, ¿ 1E3por qué, 1000pero no, 26E3etc.?
Neil

Ahorre aún más eliminando TRUNC por completo y moviendo la división al interior del MOD. = CHAR (65 + A1 / 17576E3) y CHAR (65 + MOD (A1 / 676E3,26)) y "-" y TEXT (MOD (A1,1E3), "000") y "-" y CHAR (65 + MOD (A1 / 26E3,26)) y CHAR (65 + MOD (A1 / 1E3,26)) reduciéndolo a 127 bytes.
Keeta

Me refería a eliminar QUOTIENT. Originalmente sugería cambiar el cociente a trunc con una / en lugar de una coma.
Keeta

@ Keeta, su solución de 127 bytes falla para algunos valores: por ejemplo, 456 975 996->[Z-996-ZZ
Wernisch

@Keeta, parece que CHAR(65+)trunca silenciosamente los decimales hasta %.9999997614649. Más grande que eso se redondea. Compara CHAR(65+24.9999997614649)y CHAR(65+24.999999761465).
Wernisch

2

Limpio , 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

Pruébalo en línea!

Define $ :: Int -> [Char]dar la n-ésima placa con índice cero.


2

Japt , 21 bytes

Obscenamente lento! En serio, ¡ni siquiera intentes ejecutarlo!

Punta del sombrero para Kevin por hacerme darme cuenta de dónde me estaba equivocando cuando luché para que esto funcionara anoche.

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

Pruébelo : limita el rango de números a 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

Adelante (gforth) , 94 bytes

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

Pruébalo en línea!

0 indexado. La entrada se toma desde la parte superior de la pila

Explicación del código

\ 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

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)

Pruébalo en línea!

-1 byte gracias a mypetlion


1
Cambie chr(x//26000%26+65)+chr(x//1000%26+65)a '%c%c'%(x//26000%26+65,x//1000%26+65)para guardar 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)]

Explicaciones:

La primera línea define una función que producirá una función char (de Aa Z), de 2 entradas. El número de índice xpara convertir en un número de placa y un número entero pque se utilizará como exponente para 26 (es decir 26^p). Esta segunda entrada permite ajustar los cálculos para el primer dígito alfanumérico de la placa ( p=3) hasta el último ( p=0).

Por ejemplo, para el segundo dígito, ciclado cada 1000 * 26 * 26 iteraciones, la operación: mod(idivide(x,1000*26^2),26)devuelve un índice entre 0 y 25, que luego se convierte en un ASCII charagregando 65 (porque el índice está 0basado)

La segunda línea simplemente concatena caracteres juntos. Cada carácter alfanumérico se calcula con el uso de la función c(x,p), los caracteres numéricos simplemente se calculan con una modulooperación y se convierten en una cadena.

Cada componente de la cadena que compone el número de placa es el siguiente:

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) 

Como no puedo dejar que pruebes MATLAB en línea ( editar: en realidad puedes probarlo en línea ), dejaré a los usuarios de MATLAB la posibilidad de verificar los casos de prueba:

% 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

salidas:

     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

Variante: tenga en cuenta que es posible la opción de permitir sprintfo fprintfcuidar la conversión de números a caracteres. Permite simplificar la función c, pero en general da como resultado unos pocos bytes más en esta implementación (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);}

Pruébalo en línea!

-7 bytes desde celingcat 's solución , con adicional -23 inspirado por ella

-1 byte de la solución de ceilingcat cambiando el char[]a un wchar_t[]molde implícito aint[]

Utiliza indexación basada en 0.

Explicación / 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 Gracias! Usando esa ideaab
eliminé



Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.