트롤 통행료를 계산하여 안전하게 통과하십시오.


12

/puzzling//q/626에서 영감을 얻었습니다.


당신의 모험에서 당신은 교차 해야하는 일련의 7 다리에 도착합니다. 각 다리 아래에는 트롤이 있습니다. 다리를 건너려면 먼저 트롤에게 가지고있는 케이크 수의 백분율로 많은 케이크를 줘야합니다. 이것들은 친절한 트롤이기 때문에, 당신에게 일정한 수의 케이크를 돌려 줄 것입니다.

매일 매일, 현지 트롤 킹은 각 여행자가 지불해야하는 케이크 세율과 트롤 케이크 환불-각 트롤이 여행자에게 돌려 주어야하는 케이크의 수를 설정합니다.

당신의 임무는 그날 주어진 조건에 대해 7 개의 트롤 교량을 통과하는 데 필요한 최소 케이크 수를 계산하는 것입니다.

취하다:

  1. 두 가지 입력 매개 변수 : 케이크 세율 (0에서 100 사이의 정수) 및 트롤 케이크 환불.
  2. 트롤조차도 아무도 다른 트롤이 부분적으로 먹는 케이크를 원하지 않습니다. 케이크 한 조각이 남아 있으면 트롤이 가져옵니다.
  3. 트롤이 케이크 세를 받아들이지 만 모든 케이크를 돌려 주어야한다면 (전과 같거나 적은 케이크를 남겨둔 채), 화를 내고 당신과 당신의 케이크를 먹습니다.
  4. 모든 트롤은 하나 이상의 완전한 케이크를 유지해야합니다.
  5. 케이크는 최대 100 개까지만 운반 할 수 있습니다.
  6. 현재 위치한 교량 또는 7 개 교량의 반대편에 하루를 끝내야합니다.

도전:

오늘 하루 동안 여행 할 수있는 최소 케이크 수를 출력하거나 오늘 안전하게 여행 할 수없는 경우에는 0을 출력하는 완전한 프로그램을 작성하십시오. 내일 숫자가 무엇인지 기다릴 것입니다.

입력은 stdin, 명령 행 인수 또는 파일 입력으로 전달되어야합니다.

가장 짧은 코드 (바이트 수)가 이깁니다.

예:

케이크 세 25 %, 트롤 케이크 환불 2 회.


트롤 1 전에 19 개의 케이크로 시작하십시오 : (19 * 0.75) =
트롤 1:14 후 14.25 : (14 + 2) = 16

트롤 2 전 : (16 * 0.75) =
트롤 2 후 : (12 + 2) = 14

기타

19 개 케이크-> 16-> 14-> 12-> 11-> 10-> 9-> 8
18 개 케이크-> 15-> 13-> 11-> 10-> 9-> 8-> 8 (규칙 3)

18 개의 케이크의 경우, 마지막 트롤은 케이크를 보관할 수 없습니다. 따라서 25 % / 2 일의 최소 케이크 수는 19입니다.

input: 25 2
output: 19

예 2 :

케이크 세 90 %, 트롤 케이크 1 회 환불

케이크 100 개-> 11-> 2-> 1 (규칙 4)

세 번째 트롤은 케이크를 보관하지 못했습니다. 따라서 최대 케이크 수부터 시작하여 90 % / 1 일 여행 할 수 없습니다.

input: 90 1
output: 0

데이터

입력 및 출력 값의 빠른 그래프를 구성하십시오. 나는 이것이 "부드럽 지 않다"는 것에 놀랐습니다. 눈에 띄는 섬이 몇 군데 있습니다.

데이터 차트

관심있는 사람들을위한 데이터. 열은 5 % 간격으로 나뉘고, 행은 1 케이크 환불 간격의 단위입니다 (이미지 회전). 당신은 28 케이크보다 높은 환불이 불가능하다는 것을 알 수 있습니다.

27, 17, 13, 14, 15, 18, 20, 24, 53, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
47, 27, 20, 19, 19, 19, 24, 39, 48, 68, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0
67, 37, 28, 24, 23, 28, 27, 29, 50, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
87, 47, 33, 29, 27, 28, 31, 44, 37, 72, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 57, 40, 34, 31, 29, 34, 34, 62, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 67, 48, 39, 35, 38, 37, 49, 57, 76, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 77, 53, 44, 39, 38, 47, 39, 59, 78, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 87, 60, 49, 43, 39, 40, 54, 46, 80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 97, 68, 54, 47, 48, 44, 44, 71, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 73, 59, 51, 48, 47, 59, 73, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 80, 64, 55, 49, 51, 49, 68, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 88, 69, 59, 58, 54, 64, 70, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 93, 74, 63, 58, 57, 54, 57, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 100, 79, 67, 59, 67, 69, 82, 92, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 84, 71, 68, 60, 59, 77, 94, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 89, 75, 68, 64, 74, 79, 96, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 94, 79, 69, 67, 64, 66, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 99, 83, 78, 71, 79, 91, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 87, 78, 74, 69, 93, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 91, 79, 77, 84, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 95, 88, 87, 74, 90, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 99, 88, 80, 89, 77, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 89, 84, 79, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 98, 87, 94, 97, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 98, 91, 84, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 99, 94, 99, 86, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 97, 89, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0

좋은 지적. 단순성을 위해 완벽한 프로그램으로 만드십시오. 입력을 지정할 수는 있지만 하드 코딩되지 않은 경우 (업데이트 된 챌린지) 적합한 것으로 보입니다.

CJam의 무차별 대입 퍼즐입니다. 내일

bah, 이것이 C #이 좋은 것을 가질 수없는 이유입니다

규칙 2는 트롤이 케이크의 일부만받을 가능성을 배제하는 것으로 보이며, 이는 가정 4를 중복으로 만들어야합니다. 그러나 예 2에서 세 번째 트롤은 0.8 개의 케이크 만 얻을 것이라고 말합니다.
Dennis

사양에 충돌이 있습니다. 에서 25 211 케이크의 경우, 당신은 트롤에게 2.75 케이크를주고 2를 다시 얻을 트롤은 0.75 유지하므로 (+를. 25) 당신은 살아 남기. 에서 90 12 케이크의 경우, 당신은 트롤 1.8을 제공하고 트롤은 0.8 유지 그래서 다시 일을 얻을 (+합니다. 2)하지만 당신은 죽는다.
TwiNight

답변:


6

CJam, 46 43 41 39 38 36 33 바이트

100:H,{)_7{ea:i~H@m2$*H/+@;}*>}#)

ARGV를 통한 입력.

온라인 인터프리터가 있지만 불행히도 명령 줄 인수를 지원하지 않습니다. 테스트를 위해 STDIN에서 다음 버전으로 흉내낼 수 있습니다.

rr]:A;
100:H,{)_7{A:i~H@m2$*H/+@;}*>}#)

ARGV 기반 버전에 대한 설명 :

100:H                                  "Push a 100 and save it in H.";
     ,                                 "Create a range (as an array) from 0 to 99.";
      {                       }#       "Find the first index in [0,1,2,...,99] for which the
                                        block produces a truthy (non-zero) value.";
       )_                              "Increment and duplicate the current array element.";
         7{                }*          "Execute the block seven times.";
           ea:i                        "Push the command-line arguments as an array of strings
                                        and convert each element to an integer";
               ~                       "Unwrap the array.";
                H@                     "Push a 100 and rotate the stack to pull up
                                        the first command line argument.";
                  m                    "Subtract (from 100).";
                   2$                  "Copy the last iterations result.";
                     *H/               "Multiply and divide by 100, deducting tax.";
                        +              "Add the refund.";
                         @;            "Rotate top three stack elements, and discard the one that 
                                        has been pulled to the top. This always leaves the last 
                                        two results on the stack.";

                             >         "Make sure that the last result was less than the second 
                                        to last. Yields 0 or 1.";
                                )      "After the # search completes, we'll get -1 if no such 
                                        index exists, or one less than the desired number if it 
                                        does, so we can just increment.";

스택의 내용은 프로그램 끝에서 자동으로 인쇄됩니다.


코드가 55 2( 0대신 100) 및 56 5( 98대신 )에 대해 잘못된 결과를 생성합니다 94. 이는입니다 100_0.55*-i25_0.56*-i가을 피해자 부동 소수점 부정확합니다. 내가 알 수있는 한 쌍 31 24, 31 25, 33 21, 33 22, 33 23, 35 10, 35 12, 35 15, 35 16, 35 27, 56 1, 57 4은 잘못된 결과를 제공합니다.
Dennis

1
@Dennis 고정, 감사합니다!
Martin Ender

@Dennis 실제로 바이트를 저장했습니다. CJam이 폐쇄되기를 바란다면 처음에는 세금 공제를 수행하는 블록을 정의하고 두 변수를 사용하는 대신 사용할 수 있습니다. 아마도 STDIN 대신 ARGV를 사용하여 무언가를 저장할 수 있습니다.
Martin Ender

5

CJam, 44 40 38 37 35 바이트

l~U100:M),{{_M5$-*M/3$+_@<*}7*}=]W=

또는 명령 줄 인수와 {}#트릭을 사용할 때 33 바이트 :

100:M,{){_ea:i~M@-@*M/+_@<*}7*}#)

이것을 {}#접근 방식 으로 내 주체로 두지 않는 것은 Martin의 대답에서 영감을 얻었습니다.

예제 실행 :

입력:

25 2

산출:

19

다른:

입력:

15 14

산출:

100

작동 원리

l~                       "Read the two numbers, swap and convert tax to double";
  U100:M),               "Push 0 and [0, 1, ... 100] to stack, storing 100 in M";
          {  ...  }=     "Run this code for each element until top stack element is 1";
           {...}7*       "Run this code block 7 times";
_                        "Copy the array element";
  M5$                    "Push 100 and a copy tax % to stack";
     -*                  "Number = (100 - tax %) * Number";
       M/                "Integer divide the number by 100";          
         3$+             "Add refund";
            _@<*         "Convert to 0 if refunded number > before tax one";
                    ]W=  "Take the last element of the stack";

여기에서 온라인으로 사용해보십시오


그리고 이제 남은 것은 데니스가 와서 우리 둘을 이길 때까지 기다리는 것입니다. ;)
Martin Ender

CJam에 없음;) (희망적으로)
Optimizer

나는 ]W=트릭을 정말로 좋아 하지만, 지금까지 그것을 사용하려고 할 때마다 같은 문자 수로 끝납니다.
Martin Ender

@ MartinBüttner-그래, 나도.
Optimizer

1
@Dennis-코드가 2 바이트 더 짧아 진 지금 작동해야합니다. D
Optimizer

4

APL (39)

T R←⎕⋄⊃Z/⍨{⍵(⊢×>)R+⌊⍵×1-T÷M}⍣7¨Z←⍳M←100

설명:

  • T R←⎕: 키보드에서 두 숫자를 읽고 T(세금)과 R(반품)에 저장하십시오.
  • Z←⍳M←100: 번호 저장 100에서 M, 그리고 모든 숫자 1100의를 Z.
  • {... }⍣7¨:의 각 요소에 Z대해 다음 기능을 7 번 실행하십시오.
    • R+⌊1-T÷M: 얼마나 많은 케이크를 지불해야하는지 계산하십시오.
    • ⍵(⊢×>): 트롤이 시작한 것보다 더 많은 케이크로 끝나면 그 양에 1을 곱하고 그렇지 않으면 0을 곱하십시오.
  • ⊃Z/⍨:의 각 요소에 Z대해 해당 함수가 제공 한 번호로 복제합니다. (따라서 함수가 반환 된 모든 숫자가 0사라집니다.) 그런 다음 해당 목록에서 첫 번째 항목을 선택하십시오. 목록이 비어 있으면이 결과가 나타납니다 0.

3

C, 83 바이트

int cake(int perc_taken, int given_back)
{
    int startcake = floor(100.f/perc_taken*given_back+1);
    for(int i = 0; i < 6; i++)
    {
        startcake = ceil((startcake-given_back) * 100.f/(100 - perc_taken));
    }
    return startcake;
}

작동하면 1에서 100까지가 아니라 가능한 모든 시작 케이크에서 작동합니다.

편집 : 작동합니다. 골프 :

n(int p,int g) {int s=100./p*g+1,i=0;for(;i++<6;){s=ceil((s-g)*100./(100-p));}return s;}

'최대 100 케이크'한도 :

n(int p,int g) {int s=100./p*g+1,i=0;for(;i++<6;){s=ceil((s-g)*100./(100-p));}return s>100?0:s;}

91 바이트


처음에 100 개 이상의 케이크가 필요한 경우 솔루션이 0을 반환하는 것이 사양의 중요한 부분이라고 생각합니다.
Martin Ender


1

C ++-202 자

평소와 같이 C ++은 최악의 작업을 수행했습니다.

#include<iostream>
int main(){double p,g,c=1,i,r,t;std::cin>>p>>g;for(;c<101;c++){r=c;for(i=0;i<7;i++){t=(int)(r*(1-(p/100))+g);if(t>=r){r=-1;break;}r=t;}if(r!=-1)break;}r!=-1?std::cout<<c:std::cout<<0;}

1

APL, 36

x y←⎕⋄101|1⍳⍨y<x×{y+⍵-⌈⍵×x}⍣6⍳x÷←100

설명

"케이크 임계 값"이 있습니다. 세율 x및 환불의 경우 다음 교량을 통과하기 위해서는 케이크 y이상이 필요합니다 y÷x.

x y←⎕입력하고 x(세금)과 y(반환) 을 100으로
⍳x÷←100나누고 x1에서 100까지의 배열을 할당하십시오.

{y+⍵-⌈⍵×x}⍣6"패스 브릿지"기능을 6 번 호출하십시오.
⌈⍵×x보유한 케이크 수, 세율, 반올림 (지불 금액)
⍵-보유한 케이크 수에서 빼기
y+환불 추가

그런 다음 1 ~ 100 개의 케이크로 시작하면 6 개의 다리를 건넌 후 남은 케이크 수를 보여주는 100 요소 배열을 얻게됩니다. 마지막 브리지를 통과 할 수 있는지 확인하려면 임계 값 이상인지 확인하십시오 y÷x. 또는 다음 보다 큰 경우 확인
하여 배열에 곱하십시오 .x
y<y

마지막으로, (true)
1⍳⍨의 첫 번째 발생 색인을 찾으십시오. 찾을 수 없는 경우 1리턴 101합니다.
101|mod 101


1

C 128

다른 C 솔루션과 매우 유사하지만 필연적이라고 생각합니다. 주요 트릭은 완료 여부에 따라 다른 값으로 내부 루프를 차단하는 것입니다. 이렇게하면?를 사용할 수 있습니다. break를 사용하면 불가능합니다.

t,r,j,k,l,p;main(i){for(scanf("%d%d",&t,&r),i=101;k=--i;){for(j=8;--j>0;)(p=r+k*(100-t)/100)<k?k=p:j=0;j?0:l=i;}printf("%d",l);} 

언 골프

int t,r,j,k,l,p;
main(int i)
{
    for(scanf("%d%d",&t,&r),i=101;k=--i;)
    {
        for(j=8;--j>0;)
        {
            if((p=r+k*(100-t)/100)<k)
                k=p;
            else
                j=0;
        }
        j?0:l=i;
    }
    printf("%d",l);
}

어떤 컴파일러를 사용하고 있습니까?
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.