Французские номерные знаки

42

песочница

Французские номерные знаки

Французские номерные знаки располагаются в последовательном порядке, следуя определенной схеме цифр и букв:AB-012-CD

Вызов

Напишите программу или функцию, которая для данного номера выводит соответствующий французский номерной знак . Ваша программа не должна обрабатывать какие-либо особые случаи, как указано на связанной странице. Он должен быть в состоянии генерировать все 26*26*1000*26*26 => 456 976 000возможные таблички, или насколько ваш язык может поддерживать.

Система нумерации выглядит следующим образом:

  • С AA-000-AA по AA-999-AA (числа развиваются первыми);
  • С AA-000-AB на AA-999-AZ (затем последняя буква справа);
  • AA-000-BA до AA-999-ZZ (затем первая буква справа);
  • AB-000-AA до AZ-999-ZZ (затем последняя буква слева);
  • BA-000-AA до ZZ-999-ZZ (тогда первая буква слева).

вход

  • Индекс номера пластины в виде целого числа

Выход

  • Соответствующий французский номерной знак

Дополнительная информация

  • Письма должны быть в верхнем регистре
  • Вы можете использовать индексирование как на основе 0, так и на основе 1, чтобы сгенерировать пластины (то есть AA-000-AA может соответствовать 0или 1, предполагая, что все другие тестовые примеры используют одинаковое индексирование.

Это код-гольф , самый короткий ответ на любом языке выигрывает!

Контрольные примеры (индексация на основе 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
Elcan
источник
2
Вот еще несколько требований непосредственно из Википедии, если вы хотите создать более сложный вариант: «Этот рисунок исключает три неиспользуемые буквы: I, O и U, поскольку их можно путать с 1, 0 и V соответственно. Это также исключает комбинацию СС, потому что она напоминает нацистскую организацию и WW в первой группе букв, поскольку указывает на временную табличку ".
Эрик Думинил
4
@EricDuminil Я специально исключил это, потому что это только добавило несобранные ограничения на вызов. Но это правда, это может быть интересно сделать, но даже с «бонусными баллами», я сомневаюсь, что стоило бы реализовать эти правила
Elcan

Ответы:

17

Pure Bash (без внешних утилит), 64

  • 2 байта сохранены благодаря @NahuelFouilleul
x={A..Z}
eval f=($x$x-%03d-$x$x)
printf ${f[$1/1000]} $[$1%1000]

Попробуйте онлайн! - требуется около 10 секунд, чтобы пробежать 7 тестов.

  • Строка # 1 - это простое присвоение строки переменной
  • Строка # 2 является расширением фигурной скобки для построения массива строк формата printf, одна для всех 456 976 возможных комбинаций букв, с цифрами, которые еще не указаны. evalТребуется для обеспечения расширения переменной (х) происходит перед расширением распорки.
  • Строка № 3 индексирует массив для получения соответствующей строки формата и принимает часть цифр в качестве параметра.
Цифровая травма
источник
1
-2 байта
Науэль Фуйе
13

Perl 5 (-ap), 47 байт

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

Попробуйте онлайн!


PHP , 74 байта

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

Попробуйте онлайн!

Grimmy
источник
2
+1 для PHP, я знал, что мы можем увеличивать буквы в PHP, но я не знал, что мы можем увеличить комбинацию букв и цифр. PHP поражает меня каждый день! И спасибо, что узнал что-то новое.
Night2
8

Python 3 , 79 78 77 байт

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

Попробуйте онлайн!

Я почему-то никогда не понимал, что f"string"ярлык формата существует, пока не увидел ответ Чёрной Совы Кая.

Мэтью Дженсен
источник
78 байт путем замены tupleна(*...,)
Black Owl Кай
Использование f"string"делает ваш ответ Python 3.6+ эксклюзивным, просто чтобы вы знали. Хорошая работа, хотя!
connectyourcharger
8

Рубин, 61 59 55 байт

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

Также 55 байтов:

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

Попробуйте онлайн!

Это инициализирует счетчик AA-AA000-, увеличивает его в nразы (умножая строку кода, которая делает это на n и evaling), а затем перемещает последние 4 символа после 3-го.

Дверная ручка
источник
->n{s=('AA-AA000-'..?Z*9).step.take(n)[-1];s[2]+=s.slice!5,4;s}длиннее, но мне интересно, можно ли его сократить.
Эрик Думинил
Теоретически, ->n{s=[*'AA-AA000-'..?Z*9][n];s[2]+=s.slice!5,4;s}должно работать и имеет длину всего 50 байтов, но сначала генерирует каждую возможную пластину. : - /
Эрик Думинил
1
"s + = s.slice 3,2!" на 50 байт
GB
Тогда это также должно работать: 45 байтов
GB
7

PHP , 96 84 79 байт

-5 байт благодаря замечательным комментариям Исмаэля Мигеля .

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

Попробуйте онлайн!

Я пользуюсь тем, что вы можете увеличивать буквы в PHP! Так AAAA++бы AAABи AAAZ++стал быAABA . Я рассчитываю, сколько раз буквы должны быть увеличены, получая целую часть input/1000. Затем увеличьте длину четырех символов так, чтобы первые два и два последних символа автоматически стали левой и правой сторонами пластины.

Например для ввода 675999числа приращений буквы есть (int)(675999 / 1000) = 675, значит AAAAстанетAAZZ .

Наконец, вычисляется среднее число, input%1000и все печатается в указанном формате с помощью printf . %.2sпечатает первые два символа строки, %03uдополняет число слева тремя нулями.

night2
источник
2
@Elcan Извините, исправлены ошибки стоимостью 12 байт. У меня есть оправдание, что на меня напали три кошки, потому что я
испортил
1
Вместо %0.2sтебя можно написать %.2s. Это экономит вам 1 байт. (В качестве небольшого совета: если вы хотите вывести десятичное число с определенным количеством десятичных разрядов, вы можете сделать %.2f(или любой другой модификатор), как это работает аналогичным образом)
Исмаэль Мигель
1
@IsmaelMiguel Спасибо, не знал, что мы можем бросить 0. Редактировать: глядя на документацию, кажется, что я даже не нуждался в этом в первую очередь: P
Night2
1
О, да, вы можете бросить их. Кроме того, вы можете сделать $x++^$argn/1e3вместо, $x++<(0^$argn/1e3)и вы должны сохранить 4 байта. Это будет цикл до ($x++^$argn/1e3) === 0, и это , 0когда $xи $argn/1e3того же целого числа (используя ^повергает число в целое число). Вы можете попробовать это на sandbox.onlinephpfunctions.com/code/…
Исмаэль Мигель
1
@IsmaelMiguel Еще раз спасибо, очень умная идея. Вы сделали этот ответ короче JS, и это достижение: P
Night2
7

C 88 86 байтов

#define d (b) a / b / 1000% 26 + 65
е (а) {Е ( "% C% C-% 03d-% C% C", г (17576), D (676), в% 1000 г, (26), D (1));}

Довольно просто, он использует деление и модуль для извлечения полей, добавляет «A» для букв, чтобы сопоставить их с символами ASCII, и форматирование printf для чисел.

Попробуйте онлайн!

Sir_Lagsalot
источник
6

05AB1E , 25 22 20 байт

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

-2 байта (и увеличил производительность, не генерируя весь список) благодаря @Grimy .

Индексирование на основе 0.

Попробуйте онлайн или проверьте все контрольные примеры .

Объяснение:

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)

Последняя часть ( s₄‰`UèX₄+¦'-.øý) может быть I₄÷èI₄+3.£.ý'-ýдля альтернативы равными байтами:
попробуйте онлайн или проверьте все контрольные примеры .

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 с Au2ããI₄‰`UèX₄+¦'-.øýили Au2ããI₄÷èI₄+3.£'-.øý.
Grimmy
1
@ Грими Спасибо! И теперь это также намного быстрее без генерации и индексации в полном списке. :)
Кевин Круйссен
6

J , 56 49 46 байт

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

Попробуйте онлайн!

-3 байта благодаря FrownyFrog

Все это всего лишь 7 вложенных поездов - если это не весело, то что?

  ┌─ 226950                                            
  ├─ A.                                                
  │        ┌─ '--'                                     
──┤        ├─ ,                                        
  │        │      ┌─ 7                                 
  └────────┤      ├─ $                                 
           │      │   ┌─ _3                            
           └──────┤   ├─ |.                            
                  │   │    ┌─ 4                        
                  └───┤    │     ┌─ ,                  
                      │    ├─ @ ─┴─ u:                 
                      └────┤                           
                           │     ┌─ 65 48              
                           │     ├─ / ───── +          
                           └─────┤                     
                                 │       ┌─ '4 3#26 10'
                                 └───────┼─ #:         
                                         └─ ]         
Ион
источник
1
Круто! Использование перестановки - хороший способ отформатировать полученную строку.
Гален Иванов
1
46
FrownyFrog
Спасибо @FrownyFrog!
Иона
5

R 101 байт

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)

Попробуйте онлайн!

Просто делает необходимые арифметические вычисления. Я сэкономил 5 байт, добавив в вектор aбесполезное значение a[4], что позволило мне повторно использовать вспомогательный векторb .

BAB-012-CD26×26×1000знак равно676000nn %/% 676000 %% 26%/%%%

Робин Райдер
источник
4

Желе ,  26  22 байта

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

Монадическая ссылка, принимающая целое число (1-индексированное), которое выдает список символов ... Сумасшедший-медленный, так как сначала строит все листы!

Попробуйте онлайн!(не завершено)
Или попробуйте версию с уменьшенным алфавитом (только «ABC» для букв).


Для кода, который завершается своевременно, вот 32-байтная полная программа (с индексами 0), которая создает единственную пластину вместо использования модульной арифметической и числовой базовой декомпрессии:

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

Попробуй это!

Джонатан Аллан
источник
Кажется, он
пропускает
1
Ах, я полностью игнорировал их как некий разделитель! Имеет большое значение для этих методов :(
Джонатан Аллан
Извините за это: c Еще очень приятно видеть, как это делается в желе, даже без!
Элкан
Добавил 7 байсов, чтобы добавить их, почти наверняка есть более короткий общий метод ...
Джонатан Аллан
Ой, спасибо @Grimy - с таким же успехом можно сыграть в гольф на 3, пока я здесь: p - Джонатан Аллан 1 минуту назад
Джонатан Аллан
3

Древесный уголь , 33 байта

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

Попробуйте онлайн! Ссылка на подробную версию кода. Объяснение:

Nθ

Введите число.

¹

Распечатать а -.

✂I⁺θφ±³

Добавьте 1000 к числу, затем приведите результат к строке и выведите последние три цифры.

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

Разделите число на 1000, затем добавьте 26⁵, чтобы преобразование в пользовательскую базу с использованием прописного алфавита привело к получению строки длиной 6, которая затем делится на пары букв.

¹

Распечатать а -.

⊟η

Напечатайте последнюю пару букв.

M⁹←

Перейти к началу номерного знака.

⊟η

Распечатайте остальные нужные буквы.

Нил
источник
3

Excel, 183 167 155 147 байт

-16 байт благодаря @Neil. (6 с помощью E3)

-12 байт благодаря @Keeta. ( TRUNCвместо QUOTIENT)

-8 байт благодаря @Jonathan Larouche ( INTвместо 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))

Объединяет 5 частей:

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
источник
Не MOD(QUOTIENT(A1,1E3),26)работает? Кроме того , почему 1E3для 1000но не и 26E3т.д.?
Нил
Сэкономьте еще больше, удалив TRUNC и переместив разделение в MOD. = ЗНАК (65 + A1 / 17576E3) & СИМВОЛ (65 + MOD (А1 / 676E3,26)) & "-" & ТЕКСТ (MOD (A1,1E3), "000") и "-" & СИМВОЛ (65 + MOD (А1 / 26E3,26)) & CHAR (65 + MOD (A1 / 1E3,26)), уменьшая его до 127 байт.
Кита
Я имел в виду удаление QUOTIENT. Первоначально я предлагал изменить частное на усечение с / вместо запятой.
Кита
@Keeta, ваше 127-байтовое решение терпит неудачу для некоторых значений: например 456 975 996->[Z-996-ZZ
Wernisch
@Keeta, похоже CHAR(65+)молча усекает десятичные дроби до %.9999997614649. Больше, чем это округляется. Сравните CHAR(65+24.9999997614649)и CHAR(65+24.999999761465).
Верниш
2

Чисто , 107 байт

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

Попробуйте онлайн!

Определяет $ :: Int -> [Char]предоставление n-го номера с нулевым индексом.

Οurous
источник
2

Japt , 21 байт

Непристойно медленный! Серьезно, даже не пытайтесь запустить его!

Совет Кевину, который заставил меня понять, где я ошибался, когда боролся, чтобы заставить это работать прошлой ночью.

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

Попробуйте - ограничивает диапазон номеров 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 байта

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

Попробуйте онлайн!

0 индексированные. Ввод взят с вершины стека

Объяснение кода

\ 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
источник
2

q , 78 байтов

{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 байт

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 2 , 88 байт

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

Попробуйте онлайн!

Час Браун
источник
Сохранение mypetition под моим ответом может быть применено и к Python 2
Black Owl Кай
1

Python 3 , 89 байт

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

Попробуйте онлайн!

-1 байт благодаря mypetlion

Черная сова Кай
источник
1
Изменить, chr(x//26000%26+65)+chr(x//1000%26+65)чтобы '%c%c'%(x//26000%26+65,x//1000%26+65)сохранить 1 байт.
Mypetlion
1

MATLAB , 113 байт

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

Пояснения:

Первая строка определяет функцию, которая будет выдавать символ (от Aдо Z), функцию из 2 входов. Индексный номер xдля преобразования в номерной знак и целое число, pкоторое будет использоваться как показатель степени для 26 (то есть 26^p). Этот второй вход позволяет скорректировать вычисления для первой цифры буквенно-цифровой таблички ( p=3) до последней (p=0 ).

Например, для второй цифры, повторяемой каждые 1000 * 26 * 26 итераций, операция: mod(idivide(x,1000*26^2),26) вернуть индекс в от 0 до 25, который затем преобразуется в ASCII charпутем добавления 65 (потому что индекс 0основан)

Вторая строка просто объединяет символы вместе. Каждый буквенно-цифровой символ рассчитывается с использованием функцииc(x,p) , числовой символ просто вычисляется с помощью moduloоперации и преобразуется в строку.

Каждый компонент строки, составляющий номерной знак, выглядит следующим образом:

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) 

Поскольку я не могу позволить вам попробовать MATLAB онлайн ( отредактируйте: на самом деле вы можете попробовать его онлайн ), я предоставлю пользователям MATLAB возможность проверять контрольные примеры:

% 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

выходы:

     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

Вариант: обратите внимание, что возможен вариант разрешения sprintfили fprintfпреобразования числа в символ. Это позволяет упростить функцию c, но в целом дает в этой реализации еще несколько байт (119 байт):

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
источник
1

C (gcc) , 136 106 105 байтов

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

Попробуйте онлайн!

-7 байт от celingcat 's решение , с дополнительным -23 вдохновлены ею

-1 байт от решения потолка catcat, изменяя char[]к wchar_t[]неявному приведению кint[]

Использует индексирование на основе 0.

Объяснение / 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
источник
@ceilingcat Спасибо! Используя эту идею , я удалил aи bпараметры из макроса и получил до 106 байт
pizzapants184