Matrículas francesas


41

Caixa de areia

Placas Francesas

As placas francesas vêm em uma ordem seqüencial, seguindo um padrão específico de números e letras:AB-012-CD

Desafio

Escreva um programa ou função que, para um determinado número, emita o número correspondente da placa francesa . Seu programa não deve lidar com nenhum caso especial, conforme especificado na página vinculada. Ele deve ser capaz de gerar todas 26*26*1000*26*26 => 456 976 000as placas possíveis, ou até onde seu idioma puder suportar.

O sistema de numeração é o seguinte:

  • AA-000-AA a AA-999-AA (os números evoluem primeiro);
  • AA-000-AB a AA-999-AZ (então a última letra à direita);
  • AA-000-BA a AA-999-ZZ (então a primeira letra à direita);
  • AB-000-AA a AZ-999-ZZ (então a última letra à esquerda);
  • BA-000-AA a ZZ-999-ZZ (então a primeira letra à esquerda).

Entrada

  • O índice do número da placa como um número inteiro

Saída

  • O número correspondente da placa francesa

Informação adicional

  • As letras devem estar em maiúsculas
  • Você pode usar a indexação com base em 0 e com base em 1 para gerar as placas (o que significa que AA-000-AA pode corresponder 0ou 1, supondo que todos os outros casos de teste usem a mesma indexação.

Este é o código-golfe , a resposta mais curta em todos os idiomas vence!

Casos de teste (indexação baseada em 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
Aqui estão mais alguns requisitos, diretamente da Wikipedia, se você quiser criar uma variação mais difícil: "Esta figura exclui três letras que não são usadas: I, O e U, pois podem ser confundidas com 1, 0 e V, respectivamente. Ele também exclui a combinação da SS porque lembra a organização nazista e a WW no primeiro grupo de letras, pois indica uma placa temporária ".
Eric Duminil 25/09

4
@EricDuminil Eu o excluí propositalmente porque acabou de adicionar restrições desajustadas ao desafio. Mas é verdade que poderia ser interessante, mas mesmo com "pontos de bônus", duvido que valha a pena implementar essas regras
Elcan

Respostas:


17

Pure Bash (sem utilitários externos), 64

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

Experimente online! - leva cerca de 10 segundos para atropelar as 7 caixas de teste.

  • A linha 1 é uma atribuição simples de uma string a uma variável
  • A linha 2 é uma expansão de colchete para criar uma matriz de seqüências de caracteres de formato printf, uma para todas as 456.976 combinações possíveis de letras, com os dígitos ainda não especificados. A evalé necessária para assegurar a expansão variável (de x) ocorre antes da expansão da cinta.
  • A linha 3 indexa a matriz para obter a sequência de formato apropriada e usa a parte dos dígitos como parâmetro.


13

Perl 5 (-ap), 47 bytes

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

Experimente online!


PHP , 74 bytes

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

Experimente online!


2
+1 para PHP, sabia que poderíamos incrementar letras em PHP, mas não sabia que podemos incrementar uma combinação de letras e dígitos. PHP me surpreende todos os dias! E obrigado, eu aprendi algo novo.
Night2 24/09


8

Ruby, 61 59 55 bytes

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

Também 55 bytes:

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

Experimente online!

Isso inicializa um contador para AA-AA000-, incrementa-o nvezes (multiplicando uma sequência do código que faz isso por n e evaling) e, em seguida, move os últimos 4 caracteres após o 3º.


->n{s=('AA-AA000-'..?Z*9).step.take(n)[-1];s[2]+=s.slice!5,4;s}é mais longo, mas me pergunto se é possível reduzi-lo.
Eric Duminil 24/09

Em teoria, ->n{s=[*'AA-AA000-'..?Z*9][n];s[2]+=s.slice!5,4;s}deve funcionar e tem apenas 50 bytes de comprimento, mas gera primeiro todas as placas possíveis. : - /
Eric Duminil 25/09

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

Então isso também deve funcionar: 45 bytes
GB

7

PHP , 96 84 79 bytes

-5 bytes graças aos ótimos comentários de Ismael Miguel .

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

Experimente online!

Aproveito o fato de que você pode incrementar letras em PHP! Assim AAAA++se tornaria AAABe AAAZ++se tornaria AABA. Calculo quantas vezes as letras precisam ser incrementadas, obtendo parte inteira de input/1000. Em seguida, aumente o comprimento dos quatro caracteres várias vezes e os dois primeiros e os dois últimos se tornarão automaticamente o lado esquerdo e direito da placa.

Por exemplo, para a introdução do 675999número de incrementos de letras é (int)(675999 / 1000) = 675, assim AAAAserá AAZZ.

Finalmente, o número do meio é calculado por input%1000e tudo é impresso no formato especificado com a ajuda de printf . %.2simprime os dois primeiros caracteres da string, %03upreenche o número à esquerda com 3 zeros.


2
@ Elcan Desculpe, corrigimos os problemas a um custo de 12 bytes. Eu tenho uma desculpa de estar sendo atacado por três gatos, pela minha bagunça: P
Night2

1
Em vez de %0.2svocê pode escrever %.2s. Isso economiza 1 byte. (Como uma pequena dica: se você deseja gerar um número decimal com um número específico de casas decimais, poderá fazê-lo %.2f(ou qualquer outro modificador), pois funciona da mesma maneira)
Ismael Miguel

1
@IsmaelMiguel Obrigado, não sabia que podíamos largar o 0. Edit: olhando as documentações, parece que eu nem precisava disso em primeiro lugar: P
Night2

1
Ah, sim, você pode largar isso. Além disso, você pode fazer em $x++^$argn/1e3vez de $x++<(0^$argn/1e3)e deve salvar 4 bytes. Isso fará um loop até ($x++^$argn/1e3) === 0, e é 0quando $xe $argn/1e3é o mesmo número inteiro (usando ^o converterá os números em número inteiro). Você pode tentar isso em sandbox.onlinephpfunctions.com/code/…
Ismael Miguel

1
@IsmaelMiguel Obrigado novamente, ideia muito inteligente. Você fez esta resposta mais curta que a JS one e isso é uma conquista: P
Night2

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

Muito simples, ele usa divisão e módulo para extrair os campos, adiciona 'A' para as letras para mapeá-los para caracteres ASCII e formatar printf para os números.

Experimente online!



6

05AB1E , 25 22 20 bytes

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

-2 bytes (e aumentou o desempenho por não gerar a lista inteira) graças ao @Grimy .

Indexação baseada em 0.

Experimente online ou verifique todos os casos de teste .

Explicação:

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)

A última parte ( s₄‰`UèX₄+¦'-.øý) pode ser I₄÷èI₄+3.£.ý'-ýuma alternativa de bytes iguais:
Experimente online ou verifique todos os casos de teste .

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 com Au2ããI₄‰`UèX₄+¦'-.øýou Au2ããI₄÷èI₄+3.£'-.øý.
Grimmy 24/09

1
@ Grimy Thanks! E agora também é muito mais rápido ao não gerar e indexar na lista completa. :)
Kevin Cruijssen 24/09

6

J , 56 49 46 bytes

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

Experimente online!

-3 bytes graças ao FrownyFrog

A coisa toda não passa de sete trens aninhados - se isso não é divertido, o que é?

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

1
Legal! Usar permutação é uma boa maneira de formatar a string resultante.
Galen Ivanov


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

Experimente online!

Apenas faz os cálculos aritméticos necessários. Salvei 5 bytes incluindo no vetor aum valor inútil em a[4], permitindo-me reutilizar o vetor auxiliar b.

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


4

Geléia ,  26  22 bytes

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

Um link monádico que aceita um número inteiro (indexado a 1) que produz uma lista de caracteres ... Louco-devagar, pois constrói todas as placas primeiro!

Experimente online! (não será concluído)
Ou tente uma versão reduzida do alfabeto (apenas "ABC" para as letras).


Para o código que é concluído em tempo hábil, eis um programa completo de 32 bytes (indexado a 0) que cria a placa única em vez disso, usando descompressão modular aritmética e base numérica modular:

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

Tente este!


Parece que faltam os traços, então por enquanto não se encaixa nas regras do desafio: P
Elcan

1
Ah, eu os ignorei completamente como uma espécie de separador! Faz muita diferença para estes métodos :(
Jonathan Allan

Desculpe por isso: c Ainda é muito bom ver isso feito em Jelly, mesmo sem!
Elcan 23/09

Foram adicionados 7 bytes para adicioná-los, com certeza existe um método geral mais curto agora ...
Jonathan Allan

Opa, obrigado @Grimy - posso jogar golfe por 3 enquanto estou aqui: p - Jonathan Allan 1 minuto atrás
Jonathan Allan


3

Carvão , 33 bytes

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

Experimente online! Link é a versão detalhada do código. Explicação:

Nθ

Digite o número.

¹

Imprimir a -.

✂I⁺θφ±³

Adicione 1000 ao número, depois converta o resultado em sequência e imprima os três últimos dígitos.

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

Divida o número por 1000 e adicione 26⁵, para que a conversão para a base personalizada usando o alfabeto maiúsculo resulte em uma sequência de comprimento 6, que é dividida em pares de letras.

¹

Imprimir a -.

⊟η

Imprima o último par de letras.

M⁹←

Mover para o início da chapa de matrícula.

⊟η

Imprima o restante das letras desejadas.



3

Excel, 183 167 155 147 bytes

-16 bytes graças a @Neil. (6 usando E3)

-12 bytes graças a @Keeta. (em TRUNCvez de QUOTIENT)

-8 bytes graças a @ Jonathan Larouche (em INTvez 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))

Não MOD(QUOTIENT(A1,1E3),26)funciona? Além disso, por 1E3que 1000mas não 26E3etc?
Neil

Economize ainda mais removendo o TRUNC completamente e movendo a divisão para dentro do MOD. = CHAR (65 + A1 / 17576E3) & CHAR (65 + MOD (A1 / 676E3,26)) & "-" e TEXTO (MOD (A1,1E3), "000") & "-" & CHAR (65 + MOD (A1 / 26E3,26)) & CHAR (65 + MOD (A1 / 1E3,26)) diminuindo para 127 bytes.
Keeta 25/09

Eu quis dizer remover QUOTIENT. Originalmente, eu estava sugerindo alterar o quociente para truncar com / em vez de vírgula.
Keeta 25/09

@ Keeta, sua solução de 127 bytes falha por alguns valores: por exemplo 456 975 996->[Z-996-ZZ
Wernisch

@ Keeta, Parece que CHAR(65+)silenciosamente trunca decimais até %.9999997614649. Maior do que isso é arredondado para cima. Compare CHAR(65+24.9999997614649)e CHAR(65+24.999999761465).
Wernisch 26/09

2

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

Experimente online!

Define o $ :: Int -> [Char]fornecimento da n-ésima matrícula com zero índice.


2

Japonês , 21 bytes

Obscenamente lento! Sério, nem tente executá-lo!

Ponta do chapéu para Kevin por me fazer perceber onde eu estava errado quando lutava para fazer isso funcionar ontem à noite.

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

Experimente - limita o intervalo 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

Quarto (gforth) , 94 bytes

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

Experimente online!

Indexado a 0. A entrada é obtida do topo da pilha

Explicação do 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

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

Explicações:

A primeira linha define uma função que produzirá um char (de Aa Z), função de 2 entradas. O número do índice xa ser convertido em um número de placa e um número inteiro pque será usado como expoente para 26 (ou seja 26^p). Esta segunda entrada permite ajustar os cálculos do primeiro dígito alfanumérico da placa ( p=3) até o último ( p=0).

Por exemplo, para o segundo dígito, ciclado a cada 1000 * 26 * 26 iterações, a operação: mod(idivide(x,1000*26^2),26)retorna um índice entre 0 e 25, que é então convertido em um ASCII charadicionando 65 (porque o índice é 0baseado)

A segunda linha simplesmente concatena os caracteres. Cada caractere alfanumérico é calculado com o uso da função c(x,p), o caractere numérico é simplesmente calculado com uma modulooperação e convertido em string.

Cada componente da corda que compõe o número da placa é o seguinte:

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 não posso permitir que você experimente o MATLAB online ( edit: na verdade, você pode experimentá-lo online ), permitirei aos usuários do MATLAB a possibilidade de verificar os casos de teste:

% 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

saídas:

     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: observe que a opção de permitir sprintfou fprintfcuidar da conversão de número em caracteres é possível. Permite simplificar a função c, mas no geral resulta em mais alguns bytes nesta implementação (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);}

Experimente online!

-7 bytes de celingcat da solução , com adicional -23 inspirado por ela

-1 byte da solução do roofcat, alterando o char[]para uma conversão wchar_t[]implicitamente paraint[]

Usa indexação baseada em 0.

Explicação / Sem Golfe:

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! Usando essa idéia, removi os parâmetros ae bda macro e desceu para 106 bytes
pizzapants184 28/09



Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.