Tính toán phí troll để vượt qua an toàn


12

Lấy cảm hứng từ /puzzling//q/626


Trong cuộc phiêu lưu của bạn, bạn đến một loạt 7 cây cầu bạn phải đi qua. Bên dưới mỗi cây cầu sống một con troll. Để qua cầu, trước tiên bạn phải cung cấp cho troll một số bánh theo tỷ lệ phần trăm của số bánh bạn đang mang. Bởi vì đây là những loại troll tốt bụng, họ sẽ trả lại một số lượng bánh nhất định cho bạn.

Vào đầu mỗi ngày, vua troll địa phương thiết lập thuế phần trăm bánh mà mỗi khách du lịch phải trả, và tiền hoàn trả bánh troll - số bánh mà mỗi troll phải trả lại cho khách du lịch.

Công việc của bạn là tính toán số lượng bánh tối thiểu cần thiết để vượt qua tất cả 7 cây cầu troll cho các điều kiện nhất định vào ngày hôm đó.

Giả định:

  1. Hai tham số đầu vào: thuế phần trăm bánh (số nguyên từ 0 đến 100) và hoàn trả bánh troll.
  2. Không ai, thậm chí không troll, muốn một chiếc bánh được ăn bởi một con troll khác. Nếu bạn còn lại một phần bánh, thì troll sẽ lấy nó.
  3. Nếu một con troll chấp nhận thuế bánh, nhưng sau đó phải trả lại cho bạn tất cả các bánh (được để lại cùng hoặc ít bánh hơn trước), nó sẽ trở nên tức giận và ăn thịt bạn và bánh của bạn.
  4. Mỗi troll phải giữ ít nhất một chiếc bánh hoàn chỉnh.
  5. Bạn chỉ có thể mang tối đa 100 bánh.
  6. Bạn cần kết thúc ngày mà bạn hiện đang ở hoặc ở phía bên kia của tất cả 7 cây cầu.

Thử thách:

Viết một chương trình hoàn chỉnh để xuất số lượng bánh tối thiểu để đi trong ngày hiện tại hoặc bằng 0 nếu không thể đi du lịch một cách an toàn ngày hôm nay - bạn sẽ chờ xem ngày mai con số nào.

Đầu vào phải được truyền dưới dạng stdin, đối số dòng lệnh hoặc nhập tệp.

Mã ngắn nhất (đếm byte) thắng.

Thí dụ:

Thuế bánh 25%, hoàn tiền 2 bánh troll.

bắt đầu với 19 bánh
trước khi troll 1: (19 * 0,75) = 14,25
sau khi troll 1: (14 + 2) = 16

trước troll 2: (16 * 0,75) = 12
sau troll 2: (12 + 2) = 14

Vân vân.

19 bánh -> 16 -> 14 -> 12 -> 11 -> 10 -> 9 -> 8
18 bánh -> 15 -> 13 -> 11 -> 10 -> 9 -> 8 -> 8 (quy tắc 3)

Đối với 18 chiếc bánh, troll cuối cùng sẽ không giữ được bất kỳ chiếc bánh nào. Do đó, số lượng bánh tối thiểu trong 25% / 2 ngày là 19.

input: 25 2
output: 19

Ví dụ 2:

Thuế bánh 90%, hoàn tiền 1 troll

100 bánh -> 11 -> 2 -> 1 (quy tắc 4)

Con quỷ thứ ba không được giữ bất kỳ chiếc bánh nào. Do đó, không thể đi du lịch 90% / 1 ngày ngay cả khi bắt đầu với số lượng bánh tối đa.

input: 90 1
output: 0

Dữ liệu

Kết hợp một biểu đồ nhanh của các giá trị đầu vào và đầu ra. Tôi đã ngạc nhiên khi điều này không "trơn tru" (như đường cong hình chuông hoặc tương tự); có một số hòn đảo đáng chú ý.

biểu đồ dữ liệu

Dữ liệu cho những người quan tâm. Các cột được chia thành các khoảng 5%, các hàng là đơn vị của 1 khoảng thời gian hoàn trả bánh (excel xoay hình ảnh). Bạn có thể thấy không thể hoàn tiền cao hơn 28 bánh.

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

Điểm tốt. Làm cho nó một chương trình hoàn chỉnh cho đơn giản. Đầu vào có thể được chỉ định tuy nhiên bạn thấy phù hợp miễn là nó không được mã hóa cứng (thử thách cập nhật).

Đây là một câu đố hay cho lực lượng vũ phu trong CJam. Tôi sẽ làm điều đó vào khoảng ngày mai

bah, đây là lý do tại sao c # không thể có những thứ tốt đẹp

Quy tắc 2 dường như loại trừ khả năng troll chỉ nhận được một phần nhỏ của bánh, điều này sẽ khiến giả định 4 trở nên dư thừa. Tuy nhiên, bạn nói trong ví dụ 2 rằng troll thứ ba sẽ chỉ nhận được 0,8 bánh.
Dennis

Có những xung đột trong thông số kỹ thuật. Trong 25 2trường hợp 11 bánh, bạn cho troll 2,75 bánh và nhận lại 2 để troll giữ 0,75 (+ 25) và bạn sống sót. Trong 90 1trường hợp 2 bánh, bạn cho troll 1.8 và lấy lại 1 để troll giữ .8 (+. 2) nhưng bạn chết.
TwiNight

Câu trả lời:


6

CJam, 46 43 41 39 38 36 33 byte

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

Nhập liệu thông qua ARGV.

Có một trình thông dịch trực tuyến, nhưng thật không may, nó không hỗ trợ các đối số dòng lệnh. Để thử nghiệm, bạn có thể bắt chước nó từ STDIN với phiên bản này:

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

Giải thích về phiên bản dựa trên 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.";

Nội dung của ngăn xếp được tự động in vào cuối chương trình.


Mã của bạn tạo ra kết quả không chính xác cho 55 2( 0thay vì 100) và 56 5( 98thay vì 94). Điều này là do 100_0.55*-i25_0.56*-itrở thành nạn nhân của sự thiếu chính xác điểm nổi. Theo như tôi có thể nói, các cặp cũng 31 24, 31 25, 33 21, 33 22, 33 23, 35 10, 35 12, 35 15, 35 16, 35 27, 56 1, 57 4cho kết quả không chính xác.
Dennis

1
@Dennis đã sửa, cảm ơn!
Martin Ender

@Dennis Điều đó thực sự đã lưu một byte. Tôi ước rằng CJam đã đóng cửa, sau đó tôi chỉ có thể xác định một khối ngay từ đầu thực hiện khấu trừ thuế và sử dụng khối đó, thay vì sử dụng hai biến. Có lẽ tôi có thể lưu thứ gì đó bằng ARGV thay vì STDIN, hãy để tôi xem.
Martin Ender

5

CJam, 44 40 38 37 35 byte

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

Hoặc khi sử dụng đối số và {}#mẹo dòng lệnh , 33 byte :

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

Không đặt điều này làm {}#phương pháp chính của tôi được lấy cảm hứng từ câu trả lời của Martin.

Chạy ví dụ:

Đầu vào:

25 2

Đầu ra:

19

Khác:

Đầu vào:

15 14

Đầu ra:

100

Làm thế nào nó hoạt động

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";

Dùng thử trực tuyến tại đây


Và bây giờ điều còn lại là chờ đợi Dennis đi cùng và đánh bại cả hai chúng tôi. ;)
Martin Ender

Không phải ở CJam;) (hy vọng)
Trình tối ưu hóa

Tôi thực sự thích ]W=mánh khóe, nhưng cho đến nay, mỗi khi tôi cố gắng sử dụng nó, tôi đều có cùng số lượng nhân vật.
Martin Ender

@ MartinBüttner - Vâng, tôi cũng vậy.
Trình tối ưu hóa

1
@Dennis - Nên hoạt động ngay bây giờ, với lợi ích bổ sung là 2 byte mã ngắn hơn: D
Trình tối ưu hóa

4

APL (39)

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

Giải trình:

  • T R←⎕: đọc hai số từ bàn phím và lưu chúng vào T(thuế) và R(trả lại).
  • Z←⍳M←100: lưu số 100 trong M, và tất cả các số từ 1để 100Z.
  • {... }⍣7¨: cho mỗi phần tử trong Z, chạy chức năng sau 7 lần:
    • R+⌊1-T÷M: tính toán số lượng bánh cần phải trả,
    • ⍵(⊢×>): nhân số tiền đó với 1 nếu troll kết thúc với nhiều bánh hơn anh ta bắt đầu, hoặc bằng 0 nếu không.
  • ⊃Z/⍨: cho mỗi phần tử trong Z, sao chép nó bằng số mà hàm đó đã cho. (Vì vậy, tất cả các số mà hàm trả về 0biến mất.) Sau đó chọn mục đầu tiên từ danh sách đó. Nếu danh sách kết thúc trống, điều này mang lại 0.

3

C, 83 byte

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;
}

Nếu nó hoạt động, nó hoạt động cho tất cả các bánh bắt đầu có thể, không chỉ từ 1 đến 100.

EDIT: Nó hoạt động. Chơi gôn

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;}

Với giới hạn 'tối đa 100 bánh':

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 byte.


Tôi nghĩ rằng đó là một phần quan trọng của thông số kỹ thuật rằng giải pháp trả về 0 nếu bạn cần hơn 100 bánh khi bắt đầu.
Martin Ender


1

C ++ - 202 ký tự

Như thường lệ, C ++ của tôi đã làm điều tồi tệ nhất:

#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

Giải trình

Lưu ý rằng có một "ngưỡng bánh". Đối với thuế suất xvà hoàn trả y, bạn sẽ cần nhiều hơn y÷xbánh ngọt để vượt qua cây cầu tiếp theo.

x y←⎕lấy đầu vào và gán cho x(thuế) và y(trả lại)
⍳x÷←100chia xcho 100, sau đó tạo một mảng từ 1 đến 100

{y+⍵-⌈⍵×x}⍣6gọi hàm "cầu vượt" 6 lần:
⌈⍵×xSố lượng bánh bạn có, số lần thuế suất, làm tròn số tiền (số tiền bạn phải trả)
⍵-Trừ vào số lượng bánh bạn có
y+Thêm tiền hoàn trả

Sau đó, bạn nhận được một mảng 100 phần tử hiển thị số lượng bánh bạn còn lại sau khi vượt qua 6 cây cầu nếu bạn bắt đầu với 1 ~ 100 bánh. Để xem bạn có thể băng qua cây cầu cuối cùng hay không, hãy kiểm tra xem bạn có vượt quá ngưỡng không y÷x. Cách khác:
nhân mảng bằng cách x
y<kiểm tra nếu lớn hơny

Cuối cùng,
1⍳⍨tìm chỉ mục xuất hiện đầu tiên của 1(true), trả về 101nếu không tìm thấy
101|mod 101


1

C 128

Khá giống với giải pháp C khác nhưng tôi nghĩ đó là điều không thể tránh khỏi. Thủ thuật chính là thoát ra khỏi vòng lặp bên trong với các giá trị khác nhau tùy thuộc vào việc nó có hoàn thành hay không. Điều này cho phép tôi sử dụng ?: Khi tôi không thể sử dụng 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);} 

Ung dung

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

bạn đang sử dụng trình biên dịch nào?
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.