Pomóż mi wypełnić mój portfel!

9

Jakiś czas temu kupiłem nowy portfel, który może pomieścić 8 kart (4 po obu stronach). Wydaje mi się jednak, że mam o wiele więcej kart i muszę dokonać wyboru, które z nich chcę ze sobą nosić. Niektóre karty używam częściej niż inne, ale karty, które wolę mieć przy sobie, niekoniecznie są tymi, których używam najczęściej.

Wyzwanie

Biorąc pod uwagę stos kart, zwróć układ mojego portfela w najlepszy możliwy sposób, zgodnie z moimi preferencjami i ograniczeniami. Układ powinien wyglądać następująco:

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

Obecnie posiadam następujące karty - stosy zawsze będą się składać z wybranych z nich:

  • 1 dowód osobisty ( ID )
  • 1 prawo jazdy ( DL )
  • 2 karty kredytowe ( CC )
  • 5 kart debetowych ( DC )
  • 1 karta transportu publicznego ( PC )
  • 1 karta dostępu do siłowni ( GC )
  • 9 kart członkowskich z losowych sklepów i magazynów ( MC )

Mam pewne preferencje i ograniczenia:

  • Karty posortowane według priorytetu: ID, DL, CC, DC, PC, GC, MC
  • Karty posortowane według częstotliwości użytkowania: CC, DC, PC, GC, MC, ID, DL
  • Ze względów bezpieczeństwa łączna liczba kart debetowych i kredytowych w moim portfelu może być najwyżej o 1 większa niż suma wszystkich innych kart, które trafią do mojego portfela ( N DC + N CCN ID + N DL + N PC + N GC + N MC +1).
  • Jeśli jest obecny, mój dowód tożsamości i prawo jazdy powinny zawsze znajdować się w rzędzie 1. Nie oznacza to, że inne karty nie mogą zajmować miejsc w rzędzie 1.
  • Najczęściej używane karty ze stosu powinny zawsze znajdować się w rzędzie 4.

Zasady

  • Żadne 2 karty nie mogą zajmować tego samego miejsca.
  • Karty o wyższym priorytecie są zawsze preferowane przed kartami o niższym priorytecie, chyba że włączy się ograniczenie DC / CC.
  • ID / DL w wierszu 1 zastępuje regułę częstotliwości: jeśli podany zostanie tylko identyfikator, przejdzie do wiersza 1, a wiersz 4 będzie pusty!
  • Formatowanie danych wejściowych można wykonać w dowolny sposób, pod warunkiem zachowania kolejności stosu wejściowego. np. ID,CC,PC,MC,MC,MC,DLmoże być również dostarczony jako np . 1ID 1CC 1PC 3MC 1DL 0DC 0GClub ID CC PC MC MC MC DL.
  • Formatowanie wyjściowe ma kilka ograniczeń: wiersze muszą zaczynać się od nowej linii, kolumny muszą być w jakiś sposób rozdzielane. Puste miejsca mogą być prezentowane w dowolny sposób, o ile nie psuje układu 4x2.

  • Może być więcej niż jedno rozwiązanie / zamówienie, od Ciebie zależy, które z nich podasz jako wynik.

  • Możesz założyć, że karty tego samego typu będą zawsze grupowane na wejściu.
  • Oprócz powyższego standard obowiązują zasady i luki.

Premia

Możesz usunąć 15% swojego bytecount, jeśli zwrócisz również karty, które nie trafiły do ​​portfela. Drukuj „Pasuje!” w przypadku braku pozostałych kart. Ten dodatkowy wynik powinien być wyraźnie oddzielony od układu retainnd.

Przykłady

Wejście:

ID, DL, CC, GC, MC

2 możliwe wyjścia:

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

optional: It fits!

Wejście:

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

2 możliwe wyjścia:

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

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

Wejście:

DC, DC, CC, CC, GC, DL

2 możliwe wyjścia:

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

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

Wejście:

CC, DC, DC, DC

2 możliwe wyjścia:

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

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

Wejście:

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

2 możliwe wyjścia:

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)

Wejście:

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

2 możliwe wyjścia:

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

optional: It fits!

Wejście:

ID, CC

2 możliwe wyjścia:

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

optional: It fits!

To jest , więc wygrywa najkrótszy kod (w bajtach).

slvrbld
źródło

Odpowiedzi:

3

Java 10, 385 384 382 bajtów

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

Chociaż nie było to zbyt trudne, rozumiem, dlaczego nie udzielono odpowiedzi. Zwłaszcza ta reguła dotycząca „ N DC + N CC ≤ N ID + N DL + N PC + N GC + N MC +1 ” kosztuje obecnie sporo bajtów ..
A ponieważ minęło około 2,5 roku, odkąd to wyzwanie ma został opublikowany, OP mógł mieć i tak kolejny portfel ...; s

-1 bajt dzięki @Jakob .

Wypróbuj online.

Wyjaśnienie:

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 bajtów - 15% premii)

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

Wypróbuj online.

Kevin Cruijssen
źródło
1
Możesz zapisać jeden bajt, inicjując za Fpomocą {"CC","DC","PC","GC","MC"}.
Jakob
@Jakob Ah, nie zdawałem sobie sprawy, że to było krótsze. Dzięki!
Kevin Cruijssen