ช่วยฉันเติมกระเป๋าเงินของฉัน!


9

เมื่อไม่นานมานี้ฉันซื้อกระเป๋าเงินใหม่ซึ่งสามารถถือไพ่ได้ 8 ใบ (ทั้งสี่ด้าน) อย่างไรก็ตามดูเหมือนว่าฉันจะมีการ์ดมากกว่านั้นและฉันต้องเลือกสิ่งที่ฉันต้องการพกพาไปด้วย การ์ดบางใบที่ฉันใช้บ่อยกว่าการ์ดอื่น ๆ แต่การ์ดที่ฉันชอบพกติดตัวไม่จำเป็นต้องเป็นการ์ดที่ฉันใช้บ่อยที่สุด

ความท้าทาย

ให้สแต็คการ์ดคืนเลย์เอาท์ของกระเป๋าเงินของฉันด้วยวิธีที่ดีที่สุดที่เป็นไปได้ โครงร่างควรเป็นดังนี้:

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

ขณะนี้ฉันมีการ์ดต่อไปนี้ - สแต็คจะประกอบด้วยตัวเลือกจากสิ่งเหล่านี้เสมอ:

  • 1บัตรประจำตัวประชาชน ( ID )
  • 1ใบขับขี่ ( DL )
  • 2บัตรเครดิต ( CC )
  • 5เดบิตการ์ด ( DC )
  • 1บัตรขนส่งสาธารณะ ( PC )
  • บัตรเข้ายิม1ใบ ( GC )
  • บัตรสมาชิก9ใบจากร้านค้าและคลังสินค้าแบบสุ่ม ( MC )

ฉันมีความต้องการและข้อ จำกัด บางประการ:

  • การ์ดเรียงตามลำดับความสำคัญ: ID, DL, CC, DC, PC, GC, MC
  • การ์ดที่เรียงตามความถี่ในการใช้งาน: CC, DC, PC, GC, MC, ID, DL
  • เพื่อเหตุผลด้านความปลอดภัยจำนวนบัตรเดบิตและบัตรเครดิตทั้งหมดในกระเป๋าของฉันอาจมากกว่า 1 ผลรวมของบัตรอื่น ๆ ทั้งหมดที่จะไปในกระเป๋าของฉัน ( N DC + N CCN ID + N DL + N PC + N GC + N MC +1)
  • ถ้ามีแสดงบัตรประจำตัวประชาชนและใบขับขี่ของฉันควรเข้าแถวที่ 1 เสมอซึ่งไม่ได้หมายความว่าการ์ดอื่น ๆ อาจไม่อยู่ในตำแหน่งที่ 1
  • การ์ดที่ใช้บ่อยที่สุดจากสแต็คควรอยู่ในแถวที่ 4 เสมอ

กฎระเบียบ

  • ไม่มีไพ่ 2 ใบสามารถครอบครองจุดเดียวกัน
  • บัตรที่มีลำดับความสำคัญสูงกว่ามักต้องการบัตรที่มีลำดับความสำคัญต่ำกว่ายกเว้นข้อ จำกัด DC / CC จะเริ่มขึ้น
  • ID / DL ที่แถว 1 ลบล้างกฎความถี่: หากมีเพียง ID ที่ระบุไว้รหัสนั้นจะไปในแถวที่ 1 และแถวที่ 4 จะว่างเปล่า!
  • การจัดรูปแบบอินพุตสามารถทำได้ในแบบที่คุณต้องการตราบใดที่คำสั่งของสแต็กอินพุตยังคงอยู่ เช่นID,CC,PC,MC,MC,MC,DLอาจจะมีการจัดเป็นเช่นหรือ1ID 1CC 1PC 3MC 1DL 0DC 0GCID CC PC MC MC MC DL
  • การจัดรูปแบบผลลัพธ์มีข้อ จำกัด เล็กน้อย: แถวทั้งหมดต้องเริ่มต้นที่บรรทัดใหม่คอลัมน์จะต้องคั่นด้วยวิธีใดวิธีหนึ่ง อาจแสดงจุดที่ว่างเปล่าตามที่คุณต้องการตราบใดที่มันไม่ทำให้รูปแบบ 4x2 ยุ่งเหยิง

  • อาจมีโซลูชัน / คำสั่งซื้อมากกว่าหนึ่งรายการขึ้นอยู่กับว่าคุณให้บริการแบบใด

  • คุณอาจคิดว่าการ์ดประเภทเดียวกันจะถูกจัดกลุ่มที่อินพุต
  • นอกเหนือจากข้างต้นมาตรฐาน ใช้กฎและช่องโหว่

โบนัส

คุณได้รับอนุญาตให้ลบ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!

นี่คือ ดังนั้นรหัสที่สั้นที่สุด (เป็นไบต์) จะชนะ


คำตอบ:


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 พีซี + 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

@Jakob Ah ไม่ทราบว่าสั้นกว่านี้ ขอบคุณ!
Kevin Cruijssen
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.