Hilf mir, meine Brieftasche zu füllen!

9

Vor einiger Zeit habe ich eine neue Brieftasche gekauft, die 8 Karten aufnehmen kann (4 auf beiden Seiten). Ich habe jedoch anscheinend viel mehr Karten als diese und ich muss entscheiden, welche ich mitnehmen möchte. Einige Karten benutze ich häufiger als andere, aber die Karten, die ich lieber bei mir habe, sind nicht unbedingt die, die ich am häufigsten benutze.

Die Herausforderung

Geben Sie bei einem Kartenstapel das Layout meiner Brieftasche gemäß meinen Vorlieben und Einschränkungen bestmöglich zurück. Das Layout sollte wie folgt aussehen:

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

Derzeit besitze ich folgende Karten - Stapel bestehen immer aus einer Auswahl aus diesen:

  • 1 Personalausweis ( ID )
  • 1 Führerschein ( DL )
  • 2 Kreditkarten ( CC )
  • 5 Debitkarten ( DC )
  • 1 Karte für öffentliche Verkehrsmittel ( PC )
  • 1 Zugangskarte für das Fitnessstudio ( GC )
  • 9 Mitgliedskarten aus zufälligen Geschäften und Lagern ( MC )

Ich habe einige Vorlieben und Einschränkungen:

  • Karten nach Priorität sortiert: ID, DL, CC, DC, PC, GC, MC
  • Karten sortiert nach Nutzungshäufigkeit: CC, DC, PC, GC, MC, ID, DL
  • Aus Sicherheitsgründen kann die Gesamtzahl der Debit- und Kreditkarten in meiner Brieftasche höchstens 1 mehr betragen als die Summe aller anderen Karten in meiner Brieftasche ( N DC + N CCN ID + N DL + N PC) + N GC + N MC +1).
  • Falls vorhanden, sollten mein Personalausweis und mein Führerschein immer in Zeile 1 stehen. Dies bedeutet nicht, dass andere Karten möglicherweise keine Plätze in Zeile 1 belegen.
  • Die am häufigsten verwendeten Karten aus dem Stapel sollten immer in Zeile 4 stehen.

Regeln

  • Keine 2 Karten können den gleichen Platz einnehmen.
  • Karten mit höherer Priorität werden immer Karten mit niedrigerer Priorität vorgezogen, es sei denn, die DC / CC-Beschränkung setzt ein.
  • ID / DL in Zeile 1 setzt die Frequenzregel außer Kraft: Wenn nur ID angegeben wird, wird sie in Zeile 1 angezeigt und Zeile 4 ist leer!
  • Die Eingabeformatierung kann beliebig erfolgen, solange die Reihenfolge des Eingabestapels beibehalten wird. zB ID,CC,PC,MC,MC,MC,DLkann auch als zB 1ID 1CC 1PC 3MC 1DL 0DC 0GCoder geliefert werden ID CC PC MC MC MC DL.
  • Die Ausgabeformatierung unterliegt einigen Einschränkungen: Zeilen müssen alle an einer neuen Zeile beginnen, Spalten müssen auf irgendeine Weise begrenzt werden. Leere Stellen können beliebig dargestellt werden, solange das 4x2-Layout nicht durcheinander gebracht wird.

  • Es kann mehr als eine Lösung / Bestellung geben. Es liegt an Ihnen, welche Sie als Ausgabe bereitstellen.

  • Sie können davon ausgehen, dass Karten des gleichen Typs bei der Eingabe immer gruppiert werden.
  • Abgesehen von den oben genannten Regeln gelten die Standard- Regeln und Lücken.

Bonus

Sie dürfen 15% entfernen Ihres Bytecounts wenn Sie auch Karten zurückgeben, die nicht in der Brieftasche waren. Drucken "Es passt!" falls keine Karten übrig bleiben. Diese zusätzliche Ausgabe sollte klar vom Returend-Layout getrennt sein.

Beispiele

Eingang:

ID, DL, CC, GC, MC

2 mögliche Ausgänge:

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

optional: It fits!

Eingang:

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

2 mögliche Ausgänge:

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

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

Eingang:

DC, DC, CC, CC, GC, DL

2 mögliche Ausgänge:

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

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

Eingang:

CC, DC, DC, DC

2 mögliche Ausgänge:

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

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

Eingang:

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

2 mögliche Ausgänge:

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)

Eingang:

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

2 mögliche Ausgänge:

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

optional: It fits!

Eingang:

ID, CC

2 mögliche Ausgänge:

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

optional: It fits!

Dies ist , also gewinnt der kürzeste Code (in Bytes).

slvrbld
quelle

Antworten:

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

Obwohl es nicht allzu schwierig war, kann ich sehen, warum es unbeantwortet blieb. Insbesondere diese Regel in Bezug auf " N DC + N CC ≤ N ID + N DL + N PC + N GC + N MC + 1 " kostet im Moment ziemlich viele Bytes.
Und seit dieser Herausforderung sind ungefähr 2,5 Jahre vergangen wurde gepostet, OP könnte inzwischen sowieso eine andere Brieftasche haben ..; p

-1 Byte dank @Jakob .

Probieren Sie es online aus.

Erläuterung:

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% Bonus)

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

Probieren Sie es online aus.

Kevin Cruijssen
quelle
1
Sie können durch Initialisierung eines Bytes speichern Fmit {"CC","DC","PC","GC","MC"}.
Jakob
@ Jakob Ah, wusste nicht, dass das kürzer war. Vielen Dank!
Kevin Cruijssen