Допоможи мені заповнити мій гаманець!


9

Нещодавно я придбав новий гаманець, який може вмістити 8 карт (4 з обох боків). Однак у мене, мабуть, є більше карт, ніж це, і мені потрібно зробити вибір, які з них я хочу взяти з собою. Деякі картки я використовую частіше, ніж інші, але картки, які я вважаю за краще брати з собою, не обов'язково є тими, якими я користуюся найбільше.

Змагання

Давши стопку карт, поверніть макет мого гаманця найкращим чином, щоб змінити мої налаштування та обмеження. Макет повинен бути таким:

__ __ (row 1)
__ __ (row 2)
__ __ (row 3)
__ __ (row 4)

На даний момент я маю такі картки - стеки завжди будуть складатися з вибору з них:

  • 1 посвідчення особи ( ID )
  • 1 водійське посвідчення ( DL )
  • 2 кредитні картки ( CC )
  • 5 дебетових карт ( DC )
  • 1 картка громадського транспорту ( ПК )
  • 1 карта доступу до спортзалу ( GC )
  • 9 членських карток від випадкових магазинів і складів ( MC )

У мене є деякі переваги та обмеження:

  • Карти, відсортовані за пріоритетом: ID, DL, CC, DC, PC, GC, MC
  • Карти, відсортовані за частотою використання: CC, DC, PC, GC, MC, ID, DL
  • З міркувань безпеки загальна кількість дебетових карток та кредитних карток у моєму гаманці може бути щонайменше на 1 більше, ніж сума всіх інших карток, які надійдуть у мій гаманець ( N DC + N CCN ID + N DL + N PC + N GC + N MC +1).
  • Якщо вона присутня, моє посвідчення особи та посвідчення водія завжди мають бути в рядку 1. Це не означає, що інші картки можуть не займати місця в рядку 1.
  • Карти, що найчастіше використовуються зі стека, завжди повинні знаходитись у рядку 4.

Правила

  • Жодна карта не може займати одне і те ж місце.
  • Карти з вищим пріоритетом завжди віддаються перевагу перед картками з нижчим пріоритетом, якщо тільки не введено обмеження DC / CC
  • ID / DL в рядку 1 перекриває правило частоти: якщо надається лише ідентифікатор, він буде переходити в рядок 1, а рядок 4 буде порожнім!
  • Форматування вводу можна виконати будь-яким зручним для вас способом, доки зберігається порядок вхідного стека. наприклад, ID,CC,PC,MC,MC,MC,DLможе також поставлятися як, наприклад, 1ID 1CC 1PC 3MC 1DL 0DC 0GCабо ID CC PC MC MC MC DL.
  • Форматування виводу має кілька обмежень: рядки повинні починатися з нового рядка, стовпці повинні бути певним чином розмежовані. Порожні плями можуть бути представлені будь-яким зручним для вас способом, доки це не зіпсує макет 4x2.

  • Рішення / замовлення може бути більше, залежно від того, яке ви надасте як вихід.

  • Ви можете припустити, що картки одного типу завжди будуть згруповані при вході.
  • Крім вищезазначеного, стандарт застосовуються правила та лазівки.

Бонус

Вам дозволяється видалити 15% вашого рахунку, якщо ви також повернете будь-які картки, які не потрапили в гаманець. Друк "Це підходить!" у разі відсутності інших карт. Цей додатковий вихід повинен бути чітко відокремлений від макета повернення.

Приклади

Вхід:

ID, DL, CC, GC, MC

2 можливі виходи:

ID DL      DL ID
__ __  or  __ MC
MC __      __ __
CC GC      GC CC

optional: It fits!

Вхід:

ID, CC, DC, PC, GC, MC, MC, MC, MC, MC

2 можливі виходи:

ID MC      GC ID
MC MC  or  MC PC
PC GC      MC MC
CC DC      DC CC

optional: e.g. (MC, MC)  or  (2MC)

Вхід:

DC, DC, CC, CC, GC, DL

2 можливі виходи:

DL __      GC DL
__ __  or  DC __
GC DC      __ __
CC CC      CC CC

optional: e.g. (DC)  or  (1DC)

Вхід:

CC, DC, DC, DC

2 можливі виходи:

__ __      __ __
__ __  or  __ __
__ __      __ __
CC __      __ CC

optional: e.g. (DC, DC, DC)  or  (3DC)

Вхід:

CC, CC, MC, MC, MC, MC, MC, MC, PC, DC, DC, DC, DC, DC, GC

2 можливі виходи:

MC MC      MC DC
PC GC  or  DC GC
DC DC      PC MC
CC CC      CC CC

optional: e.g. (DC, DC, DC, MC, MC, MC, MC)  or  (3DC, 4MC)

Вхід:

MC, MC, MC, MC, MC, MC, MC

2 можливі виходи:

__ MC      MC MC
MC MC  or  MC MC
MC MC      MC __
MC MC      MC MC

optional: It fits!

Вхід:

ID, CC

2 можливі виходи:

ID __      __ ID
__ __  or  __ __
__ __      __ __
CC __      CC __

optional: It fits!

Це є , тому найкоротший код (у байтах) виграє.


Відповіді:


3

Java 10, 385 384 382 байт

C->{String[]R=new String[8],F={"CC","DC","PC","GC","MC"};int c=C.size(),i=1,s=0;c=c>8?8:c;for(var q:C)if("DCC".contains(q))s++;for(;s>c- --s;c=(c=C.size())>8?8:c)i=C.remove(F[i])?i:0;for(c=0,i=8;i>0&c<5;c++)for(;i>0&C.remove(F[c]);)R[--i]=F[c];if(C.remove("ID"))R[c=0]="ID";if(C.remove("DL"))R[c<1?1:0]="DL";for(i=0;i<8;)System.out.print((R[i]!=null?R[i]:"__")+(i++%2>0?"\n":" "));}

Хоча це було не надто складно, я можу зрозуміти, чому це було без відповіді. Тим більше, що правило, що стосується " N DC + N CC ≤ N ID + N DL + N PC + N GC + N MC +1 " на даний момент коштує досить багато байтів.
І оскільки минуло вже 2,5 року з моменту цього виклику Опубліковано, ОП у будь-якому разі могла отримати ще один гаманець ..; стор

-1 байт завдяки @Jakob .

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

Пояснення:

C->{                       // Method with String-List parameter and String return-type
  String[]R=new String[8], //  String-array of size 8
          F={"CC","DC","PC","GC","MC"};
                           //  Frequency-order String-array
  int c=C.size(),          //  Size of the input-List
      i=1,                 //  Index integer, starting at 1
      s=0;                 //  Count-integer, starting at 0
  c=c>8?8:c;               //  If the size is larger than 8, set it to 8
  for(var q:C)             //  Loop over the cards of the input-List
    if("DCC".contains(q))  //   If the card is a DC or CC:
      s++;                 //    Increase the counter by 1
  for(;s>                  //  Loop as long as the amount of DC/CC is larger 
         c- --s;           //  than the other amount of cards + 1
      c=(c=C.size())>8?8:c)//    Recalculate the size after every iteration
    i=C.remove(F[i])?i:0;  //   If the List still contains a DC, remove it
                           //   Else: remove a CC instead
  for(c=0,                 //  Reset `c` to 0
      i=8;i>0              //  Loop as long as there is still room in the wallet,
      &c<5;                //  and we still have cards left
      c++)                 //    Go to the next card-type after every iteration
    for(;i>0               //   Inner loop as long as there is still room in the wallet,
        &C.remove(F[c]);)  //   and we still have a card of the current type left
      R[i--]=F[c];         //    Put a card of the current type in the wallet
  if(C.remove("ID"))R[c=0]="ID";
                           //  Add the 'ID' card to the first row if present
  if(C.remove("DL"))R[c<1?1:0]="DL";
                           //  Add the 'DL' card to the first row if present
  for(i=0;i<8;)            //  Loop over the wallet
    System.out.print(      //   Print:
      (R[i]!=null?         //    If the current slot contains a card:
        R[i]               //     Append this card
       :                   //    Else:
        "__")              //     Append an empty slot ("__")
      +(i++%2>0?"\n":" "));//    Append the correct delimiter (space or new-line)
  return r;}               //  And finally return the result

Java 10, 390,15 (459 байт - 15% бонус)

C->{String r="",R[]=new String[8],F[]={"CC","DC","PC","GC","MC"},t=r;int c=C.size(),i=1,s=0;for(var q:C)if("DCC".contains(q))s++;for(;s>(c>8?8:c)- --s;c=C.size())if(C.remove(F[i]))t+=F[i]+",";else i=0;for(c=0,i=8;i>0&c<5;c++)for(;i>0&&C.remove(F[c]);)R[--i]=F[c];if(C.remove("ID")){t+=R[0]+",";R[c=0]="ID";};if(C.remove("DL")){t+=R[c=c<1?1:0]+",";R[c]="DL";}for(i=0;i<8;)r+=(R[i]!=null?R[i]:"__")+(i++%2>0?"\n":" ");return r+"\n"+(C.size()>0?t+C:"It fits!");}

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


1
Ви можете зберегти один байт, ініціалізуючи Fз {"CC","DC","PC","GC","MC"}.
Якоб

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