지갑을 채우도록 도와주세요!


9

얼마 전에 저는 8 장의 카드를 넣을 수있는 새로운 지갑을 구입했습니다 (양쪽에 4 개). 그러나 나는 그보다 더 많은 카드를 가지고있는 것 같아서 가지고 다니고 싶은 카드를 선택해야합니다. 다른 카드보다 자주 사용하는 카드도 있지만, 가지고 다니고 싶은 카드가 반드시 가장 많이 사용되는 카드는 아닙니다.

도전

카드 묶음이 주어지면 내 선호도 및 제한 사항이 가능한 한 가장 좋은 방법으로 지갑 레이아웃을 반환하십시오. 레이아웃은 다음과 같아야합니다.

__ __ (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 제한이 적용되지 않는 한 우선 순위가 높은 카드가 우선 순위가 낮은 카드보다 우선합니다.
  • 행 1의 ID / DL은 빈도 규칙을 무시합니다. ID 만 제공하면 행 1에 들어가고 행 4는 비어있게됩니다!
  • 입력 스택의 순서가 유지되는 한 원하는 방식으로 입력 형식을 지정할 수 있습니다. 예 ID,CC,PC,MC,MC,MC,DL를 들어 1ID 1CC 1PC 3MC 1DL 0DC 0GC또는 같이 공급 될 수도있다 ID CC PC MC MC MC DL.
  • 출력 형식에는 몇 가지 제한이 있습니다. 행은 모두 새 줄에서 시작해야하고 열은 어떤 방식 으로든 구분해야합니다. 4x2 레이아웃을 엉망으로 만들지 않는 한 빈 점은 원하는 방식으로 표시 될 수 있습니다.

  • 둘 이상의 솔루션 / 주문이있을 수 있으며 출력으로 제공하는 것은 사용자에게 달려 있습니다.

  • 동일한 유형의 카드는 항상 입력시 그룹화된다고 가정 할 수 있습니다.
  • 상기 외에, 표준 규칙과 허점이 적용됩니다.

보너스

지갑에 넣지 않은 카드도 반환하면 바이트 수의 15 % 를 제거 할 수 있습니다. "맞습니다!" 남은 카드가없는 경우. 이 추가 출력은 returend 레이아웃과 명확하게 분리되어야합니다.

입력:

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

자바 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 PC + N GC + N MC +1 "비용이 꽤 순간 바이트의 많은 ..
그리고이 문제는이 이후는 2.5 년 정도 지났 이후 게시, OP는 어쨌든 다른 지갑을 가지고있을 수 있습니다 ..; p

@Jakob 덕분에 -1 바이트 .

온라인으로 사용해보십시오.

설명:

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하여 1 바이트를 절약 할 수 있습니다 {"CC","DC","PC","GC","MC"}.
Jakob

@Jakob Ah, 그것이 더 짧다는 것을 몰랐습니다. 감사!
Kevin Cruijssen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.