Помоги мне заполнить мой кошелек!

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, ПК, GC, MC
  • Карты отсортированы по частоте использования: CC, DC, ПК, GC, MC, ID, DL
  • В целях безопасности общее количество дебетовых и кредитных карт в моем кошельке может быть не более чем на 1 больше, чем сумма всех других карт, которые войдут в мой кошелек ( N DC + N CCN ID + N DL + N ПК + N GC + N MC +1).
  • Если они есть, моя идентификационная карта и водительские права должны всегда указываться в строке 1. Это не означает, что другие карты могут не занимать места в строке 1.
  • Наиболее часто используемые карты из стопки всегда должны идти в строке 4.

правила

  • Никакие 2 карты не могут занимать одно и то же место.
  • Карты с более высоким приоритетом всегда предпочтительнее, чем карты с более низким приоритетом, если только не введено ограничение 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.
  • Форматирование вывода имеет несколько ограничений: все строки должны начинаться с новой строки, столбцы должны быть каким-то образом разделены. Пустые места могут быть представлены любым способом, если он не портит макет 4х2.

  • Может быть более одного решения / заказа, вам решать, какое из них вы предоставите в качестве вывода.

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

бонус

Вам разрешается удалить 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!

Это поэтому самый короткий код (в байтах) выигрывает.

slvrbld
источник

Ответы:

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 лет с тех пор, как этот вызов был опубликован, OP, возможно, уже получил другой кошелек в любом случае ..; p

-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 Ах, не понимал, что это было короче. Спасибо!
Кевин Круйссен