Ajude-me a encher minha carteira!

9

Há um tempo, comprei uma nova carteira capaz de conter 8 cartões (4 em ambos os lados). No entanto, pareço ter muito mais cartões do que isso e preciso fazer escolhas sobre quais quero levar comigo. Alguns cartões que uso com mais frequência do que outros, mas os cartões que prefiro levar comigo não são necessariamente os que mais uso.

O desafio

Dada uma pilha de cartões, devolva o layout da minha carteira da melhor maneira possível, usando minhas preferências e restrições. O layout deve ser o seguinte:

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

Atualmente, possuo as seguintes cartas - as pilhas sempre consistem em uma seleção destas:

  • 1 bilhete de identidade ( ID )
  • 1 carteira de motorista ( DL )
  • 2 cartões de crédito ( CC )
  • 5 cartões de débito ( DC )
  • 1 cartão de transporte público ( PC )
  • 1 cartão de acesso à academia ( GC )
  • 9 cartões de sócio de lojas e armazéns aleatórios ( MC )

Eu tenho algumas preferências e restrições:

  • Cartões classificados por prioridade: ID, DL, CC, CC, PC, GC, MC
  • Cartões classificados por frequência de uso: CC, CC, PC, GC, MC, ID, DL
  • Por razões de segurança, o número total de cartões de débito e cartões de crédito na minha carteira pode ser no máximo 1 a mais do que a soma de todos os outros cartões que estarão na minha carteira ( N DC + N CCN ID + N DL + N PC + N GC + N MC +1).
  • Se presente, meu bilhete de identidade e minha carteira de motorista devem sempre ficar na linha 1. Isso não significa que outros cartões não possam ocupar pontos na linha 1.
  • As cartas mais frequentemente usadas da pilha devem sempre ir na linha 4.

Regras

  • 2 cartas não podem ocupar o mesmo lugar.
  • Os cartões de prioridade mais alta sempre são preferidos aos cartões de prioridade mais baixa, a menos que a restrição DC / CC comece.
  • O ID / DL na linha 1 anula a regra de frequência: se apenas o ID for fornecido, ele entrará na linha 1 e a linha 4 ficará vazia!
  • A formatação de entrada pode ser feita da maneira que você quiser, desde que a ordem da pilha de entrada seja mantida. por exemplo, ID,CC,PC,MC,MC,MC,DLtambém pode ser fornecido como por exemplo 1ID 1CC 1PC 3MC 1DL 0DC 0GCou ID CC PC MC MC MC DL.
  • A formatação de saída tem algumas restrições: todas as linhas devem começar em uma nova linha, as colunas devem ser delimitadas de alguma forma. Pontos vazios podem ser apresentados da maneira que você quiser, desde que não atrapalhe o layout 4x2.

  • Pode haver mais de uma solução / pedido, depende de você qual você fornece como saída.

  • Você pode presumir que cartões do mesmo tipo sempre serão agrupados na entrada.
  • Além do acima, aplicam regras e lacunas de padrão .

Bônus

Você tem permissão para remover 15% do seu número de bytes, se você também devolver todos os cartões que não foram para a carteira. Imprimir "Cabe!" no caso de não haver cartões restantes. Essa saída adicional deve ser claramente separada do layout do retorno.

Exemplos

Entrada:

ID, DL, CC, GC, MC

2 saídas possíveis:

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

optional: It fits!

Entrada:

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

2 saídas possíveis:

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

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

Entrada:

DC, DC, CC, CC, GC, DL

2 saídas possíveis:

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

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

Entrada:

CC, DC, DC, DC

2 saídas possíveis:

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

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

Entrada:

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

2 saídas possíveis:

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)

Entrada:

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

2 saídas possíveis:

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

optional: It fits!

Entrada:

ID, CC

2 saídas possíveis:

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

optional: It fits!

Isso é , então o código mais curto (em bytes) vence.

slvrbld
fonte

Respostas:

3

Java 10, 385 384 382 bytes

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

Embora não tenha sido muito difícil, posso ver por que não houve resposta. Especialmente, essa regra referente a " N DC + N CC ≤ N ID + N DL + N PC + N GC + N MC +1 " custa muitos bytes no momento.
E desde que se passaram cerca de 2,5 anos desde que esse desafio foi publicado, o OP pode ter outra carteira agora de qualquer maneira ..; p

-1 byte graças a @Jakob .

Experimente online.

Explicação:

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 bytes - bônus de 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!");}

Experimente online.

Kevin Cruijssen
fonte
11
Você pode salvar um byte, inicializando Fcom {"CC","DC","PC","GC","MC"}.
Jakob
@ Jakob Ah, não sabia que era mais curto. Obrigado!
Kevin Cruijssen