Французькі номерні знаки


41

Пісочниця

Французькі номерні знаки

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

Виклик

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

Система нумерації працює наступним чином:

  • Від АА-000-АА до АА-999-АА (числа розвиваються першими);
  • Від AA-000-AB до AA-999-AZ (тоді останній лист праворуч);
  • Від АА-000-БА до АА-999-ЗЗ (тоді перша літера справа);
  • Від 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

2
Ось ще кілька вимог, безпосередньо з Вікіпедії, якщо ви хочете створити більш складний варіант: "Ця цифра виключає три букви, які не використовуються: I, O і U, оскільки їх можна переплутати з 1, 0 і V відповідно. Це також виключає комбінацію СС, оскільки воно нагадує нацистську організацію та ВВ у першій групі листів, оскільки вказує на тимчасову табличку ".
Ерік Думініл

4
@EricDuminil Я цілеспрямовано виключив це, оскільки він просто додав неприємні обмеження у виклику. Але це правда, що це може бути цікаво зробити, але навіть із "бонусними балами", я сумніваюся, варто було б застосувати ці правила
Елкан,

Відповіді:


17

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

  • 2 байти збережено завдяки @NahuelFouilleul
x={A..Z}
eval f=($x$x-%03d-$x$x)
printf ${f[$1/1000]} $[$1%1000]

Спробуйте в Інтернеті! - для пробігання 7 тестів потрібно близько 10 секунд.

  • Рядок №1 - це просте призначення рядка змінній
  • Рядок №2 є розширенням дужок для створення масиву рядків формату printf, один для всіх 456,976 можливих комбінацій літер, з цифрами ще не вказані. evalПотрібно для забезпечення розширення змінної (х) відбувається перед розширенням розпірки.
  • Рядок №3 індексує масив, щоб отримати відповідний рядок формату, і приймає частину цифр як його параметр.


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

Спробуйте в Інтернеті!


2
+1 для PHP, я знав, що ми можемо збільшувати літери в PHP, але не знав, що ми можемо збільшити комбінацію букв і цифр. PHP мене щодня дивує! І завдяки я дізнався щось нове.
Ніч2

8

Пітон 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 Kai

Використання 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прошиває число зліва з 3 нулями.


2
@Elcan Вибачте, виправлені проблеми вартістю 12 байт. У мене є привід потрапити під атаку трьох котів, за те, що я
моторошив

1
Замість %0.2sвас можна писати %.2s. Це зекономить 1 байт. (Як мініатюрна порада: якщо ви хочете вивести десяткове число з певною кількістю десяткових знаків, ви можете зробити це %.2f(або будь-який інший модифікатор), оскільки він працює так само)
Ісмаель Мігель,

1
@IsmaelMiguel Спасибі, не знав, що ми можемо скинути це 0. Редагувати: дивлячись на документації, здається, мені це навіть не потрібно було в першу чергу: P
Ніч2,

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
Ніч2,

7

C, 88 86 байт

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

Досить простий, він використовує поділ і модуль для вилучення полів, додає "A" для літер, щоб відобразити їх в ASCII символи, і форматування printf для чисел.

Спробуйте в Інтернеті!



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
@Grimy Дякую! А тепер це також набагато швидше, не генеруючи та не індексуючи повний список. :)
Кевін Круїссен

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
Класно! Використання перестановки є хорошим способом форматування отриманого рядка.
Гален Іванов


Дякую @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непотрібне значення at 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”-

Спробуйте це!


Пропускає тире, як здається, тому наразі це не відповідає правилам виклику: P
Елкан

1
Ах, я повністю їх ігнорував як якийсь роздільник! Ці методи дуже різняться :(
Джонатан Аллан

Вибачте з цього приводу: c Ще дуже приємно бачити це зроблено в Jelly, навіть без!
Елькан

Додано 7 байдів, щоб додати їх, майже впевнений, що зараз існує коротший загальний метод ...
Джонатан Аллан

На жаль, дякую @Grimy - може також гольф, що до 3, поки я тут: p - Джонатан Аллан 1 хв тому
Джонатан Аллан


3

Вугілля деревне , 33 байти

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

Спробуйте в Інтернеті! Посилання на багатослівну версію коду. Пояснення:

Nθ

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

¹

Друк a -.

✂I⁺θφ±³

Додайте 1000 до числа, після чого наведіть результат на рядок і надрукуйте останні три цифри.

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

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

¹

Друк a -.

⊟η

Роздрукуйте останню пару літер.

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

Хто MOD(QUOTIENT(A1,1E3),26)не працює? Крім того, чому 1E3для, 1000але не 26E3тощо?
Ніл

Збережіть ще більше, видаливши TRUNC взагалі та перемістивши поділ всередину МО. = 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)), зменшивши її до 127 байт.
Keeta

Я мав на увазі видалити КВОТИЦІ. Спочатку я пропонував змінити коефіцієнт для обрізання символом a / замість коми.
Keeta

@Keeta, ваше 127-байтне рішення не відповідає деяким значенням: напр. 456 975 996->[Z-996-ZZ
Wernisch,

@Keeta, Здається, CHAR(65+)мовчки усікає десятичні знаки до %.9999997614649. Більше, ніж це, округлене. Порівняйте CHAR(65+24.9999997614649)і CHAR(65+24.999999761465).
Верніш


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

Четвертий (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

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





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), числовий символ просто обчислюється за допомогою amodulo операцією і перетворюється в рядок.

Кожен компонент рядка, що складає номер пластини, наступний:

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

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 байт з ceilingcat в розчині шляхом зміни char[]до wchar_t[]неявно приведений доint[]

Використовує індексацію на основі 0.

Пояснення / Недоліковані:

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 Дякую! Користуючись цією ідеєю, я видалив параметри aта bпараметри з макросу і перейшов до 106 байт
pizzapants184,



Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.