¡Ayúdame a llenar mi billetera!

9

Hace un tiempo compré una nueva billetera que puede contener 8 tarjetas (4 en ambos lados). Sin embargo, parece que tengo muchas más tarjetas que eso y necesito elegir cuáles quiero llevar conmigo. Algunas tarjetas las uso con más frecuencia que otras, pero las tarjetas que prefiero llevar conmigo no son necesariamente las que más uso.

El reto

Dada una pila de tarjetas, devuelva el diseño de mi billetera de la mejor manera posible con mis preferencias y restricciones. El diseño debe ser el siguiente:

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

Actualmente poseo las siguientes cartas: las pilas siempre consistirán en una selección de estas:

  • 1 documento de identidad ( ID )
  • 1 licencia de conducir ( DL )
  • 2 tarjetas de crédito ( CC )
  • 5 tarjetas de débito ( DC )
  • 1 tarjeta de transporte público ( PC )
  • 1 tarjeta de acceso al gimnasio ( GC )
  • 9 tarjetas de membresía de tiendas y almacenes aleatorios ( MC )

Tengo algunas preferencias y restricciones:

  • Tarjetas ordenadas por prioridad: ID, DL, CC, DC, PC, GC, MC
  • Tarjetas clasificadas por frecuencia de uso: CC, DC, PC, GC, MC, ID, DL
  • Por razones de seguridad, el número total de tarjetas de débito y crédito en mi billetera puede ser como máximo 1 más que la suma de todas las otras tarjetas que irán en mi billetera ( N DC + N CCN ID + N DL + N PC + N GC + N MC +1).
  • Si está presente, mi tarjeta de identidad y mi licencia de conducir siempre deben ir en la fila 1. Esto no significa que otras tarjetas no puedan ocupar lugares en la fila 1.
  • Las cartas de la pila que se usan con más frecuencia siempre deben ir en la fila 4.

Reglas

  • No hay 2 cartas que puedan ocupar el mismo lugar.
  • Las tarjetas de mayor prioridad siempre se prefieren a las de menor prioridad, a menos que la restricción DC / CC se active.
  • ID / DL en la fila 1 anula la regla de frecuencia: si solo se proporciona ID, irá en la fila 1 y la fila 4 estará vacía.
  • El formateo de entrada se puede hacer de la forma que desee, siempre que se mantenga el orden de la pila de entrada. p. ej. ID,CC,PC,MC,MC,MC,DLtambién se puede suministrar como p . ej . 1ID 1CC 1PC 3MC 1DL 0DC 0GCo ID CC PC MC MC MC DL.
  • El formato de salida tiene algunas restricciones: todas las filas deben comenzar en una nueva línea, las columnas deben estar delimitadas de alguna manera. Los espacios vacíos se pueden presentar de la forma que desee, siempre que no estropee el diseño 4x2.

  • Puede haber más de una solución / pedido, depende de usted cuál proporcione como salida.

  • Puede suponer que las tarjetas del mismo tipo siempre se agruparán en la entrada.
  • Además de lo anterior, se aplican las reglas estándar de y las lagunas.

Prima

Puedes eliminar el 15% de su cuenta de byte si también devuelve las tarjetas que no entraron en la billetera. Imprimir "¡Encaja!" en caso de que no queden tarjetas. Esta salida adicional debe estar claramente separada del diseño del returend.

Ejemplos

Entrada:

ID, DL, CC, GC, MC

2 salidas posibles:

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 salidas posibles:

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 salidas posibles:

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

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

Entrada:

CC, DC, DC, DC

2 salidas posibles:

__ __      __ __
__ __  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 salidas posibles:

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 salidas posibles:

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

optional: It fits!

Entrada:

ID, CC

2 salidas posibles:

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

optional: It fits!

Este es el , por lo que gana el código más corto (en bytes).

slvrbld
fuente

Respuestas:

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

Aunque no fue demasiado difícil, puedo ver por qué no recibió respuesta. Especialmente esa regla con respecto a " N DC + N CC ≤ N ID + N DL + N PC + N GC + N MC +1 " cuesta una gran cantidad de bytes en este momento ...
Y como han pasado 2.5 años desde que este desafío publicado, OP podría tener otra billetera por ahora de todos modos ...

-1 byte gracias a @Jakob .

Pruébalo en línea.

Explicación:

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 - 15% de bonificación)

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

Pruébalo en línea.

Kevin Cruijssen
fuente
1
Puede guardar un byte inicializando Fcon {"CC","DC","PC","GC","MC"}.
Jakob
@Jakob Ah, no me di cuenta de que era más corto. ¡Gracias!
Kevin Cruijssen