Cuộc thi thả trứng


8

Thử thách của bạn:

Bạn đang ở tầng 0 của một tòa nhà cao vô hạn. Ở bất kỳ tầng nào, bạn có thể đi bộ đến cửa sổ và thả một quả trứng. Mục tiêu của bạn là tìm ra tầng cao nhất mà trứng có thể chịu được mà không bị vỡ. Tuy nhiên, bạn có tối đa 3 quả trứng để sử dụng để tìm ra điều này, nhưng bạn cần giảm thiểu số lần thử.

Về mặt chính thức:

  1. Bạn được cung cấp một hàm f(n)trả về bool(n <= X)cho một ẩn số X, trong đó0 <= X
  2. Bạn phải trả về giá trị của X(không truy cập trực tiếp)
  3. f(n)chỉ phải trả lại Falsetối đa số 3lần (trong một trường hợp thử nghiệm). Nếu nó trả về Falsenhiều hơn thế, thì câu trả lời của bạn bị loại.

Những hạn chế

Điểm của bạn là tổng số cuộc gọi bạn thực hiện f(n)(trong các trường hợp thử nghiệm bên dưới)

Nếu bạn muốn, bạn có thể từ bỏ chức năng và chỉ cần "mô phỏng" tình huống trên. Tuy nhiên , thuật toán giải của bạn phải không biết gì X.

Thuật toán của bạn không nên mã cứng các trường hợp thử nghiệm, hoặc tối đa X. Nếu tôi tạo lại các số hoặc thêm nhiều hơn, chương trình của bạn sẽ có thể xử lý chúng (với số điểm tương tự).

Nếu ngôn ngữ của bạn không hỗ trợ các số nguyên chính xác tùy ý, thì bạn có thể sử dụng longkiểu dữ liệu. Nếu ngôn ngữ của bạn không hỗ trợ, thì bạn đã hết may mắn.

Trường hợp thử nghiệm thứ n được tạo bằng cách sử dụng như sau:

g(n) = max(g(n-1)*random(1,1.5), n+1), g(0) = 0hoặc khoảng 1.25^n

Các trường hợp thử nghiệm:

0,1,2,3,4,6,7,8,10,14,15,18,20,27,29,40,57,61,91,104,133,194,233,308,425,530,735,1057,1308,1874,2576,3162,3769,3804,4872,6309,7731,11167,11476,15223,15603,16034,22761,29204,35268,42481,56238,68723,83062,95681,113965,152145,202644,287964,335302,376279,466202,475558,666030,743517,782403,903170,1078242,1435682,1856036,2373214,3283373,4545125,6215594,7309899,7848365,8096538,10409246,15103057,20271921,22186329,23602446,32341327,33354300,46852754,65157555,93637992,107681394,152487773,181996529,225801707,324194358,435824227,579337939,600264328,827690923,1129093889,1260597310,1473972478,1952345052,1977336057,2512749509,3278750235,3747691805,5146052509

Đây là một , và người có điểm thấp nhất sẽ thắng!


2
Liên quan (xem thêm câu hỏi liên kết trong nhận xét của tôi về câu hỏi đó).
Peter Taylor

1
Câu hỏi liên quan về Puzzling SE (nhưng cũng có số sàn tối đa).
Martin Ender

8
Nếu tôi thả một quả trứng từ cửa sổ tầng zeroth của bất kỳ tòa nhà nào, tôi chắc chắn nó sẽ vỡ. Vấn đề được giải quyết
Chấn thương kỹ thuật số

5
@NathanMerrill Point là, điều này về cơ bản là vô dụng vì chúng ta không thể biết bất cứ điều gì về khả năng mỗi kích thước của x là như thế nào khi bạn từ chối chỉ định những gì chúng ta có thể giả định về n . Không thể viết câu trả lời được tối ưu hóa nếu chúng tôi không biết tất cả các thông số về cách bạn chạy tính điểm. Nếu bạn cho chúng tôi biết, mã của bạn được chạy trên 100 trường hợp thử nghiệm từ n = 0 đến 99, thì đó sẽ là một sự đảm bảo hữu ích. Hoặc nếu bạn thực hiện g độc lập với n .
FUZxxl

11
Bỏ phiếu để đóng: Không có phân phối xác suất để sao chép một cách công bằng quá trình cho điểm, tiêu chí chiến thắng là không khách quan.
FUZxxl

Câu trả lời:


8

Javascript, 438859 442857 74825 cuộc gọi

function findFloor(f){
    var max = 1;
  var min = 0;

  //First egg.
  var n = 1;
  while (f(max)) {
    min = max;
    n += 1;
    max = tetrahedral(n);
  }

  if (max <= min + 1){
    return min;
  }

  //Second egg.
  do {
    var range = max - min;
    var floor = min + reverseTriangle(range);
    var smashed = !f(floor);
    if (smashed) {
        max = floor;
    } else {
        min = floor;
    }
  } while (!smashed && max > min + 1);

  if (max <= min + 1){
    return min;
  }

  //Third egg.
  while (max > min + 1){
    var floor = min + 1;
    var smashed = !f(floor);
    if (smashed) {
        max = floor;
    } else {
        min = floor;
    }
    if (smashed) {
        break;
    }
  }

  return min;

}

function reverseTriangle(x) {
    return Math.ceil((-1 + Math.sqrt(1 + 8 * x)) / 2);
}

function tetrahedral(n) {
    return n * (n + 1) * (n + 2) / 6;
}

Kiểm tra tại đây

Điểm cho từng trường hợp kiểm tra riêng lẻ:

0: 1, 1: 4, 2: 4, 3: 3, 4: 5, 6: 6, 7: 6, 8: 6, 10: 6, 14: 7, 15: 8, 18: 8, 20: 7, 27: 10, 29: 9, 40: 12, 57: 10, 61: 14, 91: 16, 104: 16, 133: 16, 194: 17, 233: 16, 308: 24, 425: 26, 530: 28, 735: 31, 1057: 33, 1308: 38, 1874: 32, 2576: 47, 3162: 45, 3769: 43, 3804: 55, 4872: 52, 6309: 63, 7731: 69, 11167: 69, 11476: 80, 15223: 90, 15603: 75, 16034: 82, 22761: 69, 29204: 110, 35268: 101, 42481: 105, 56238: 126, 68723: 113, 83062: 113, 95681: 160, 113965: 149, 152145: 148, 202644: 187, 287964: 238, 335302: 175, 376279: 258, 466202: 250, 475558: 247, 666030: 256, 743517: 237, 782403: 245, 903170: 278, 1078242: 256, 1435682: 408, 1856036: 304, 2373214: 401, 3283373: 286, 4545125: 328, 6215594: 510, 7309899: 616, 7848365: 458, 8096538: 683, 10409246: 754, 15103057: 787, 20271921: 653, 22186329: 957, 23602446: 754, 32341327: 1141, 33354300: 1033, 46852754: 984, 65157555: 839, 93637992: 1539, 107681394: 1130, 152487773: 1605, 181996529: 1845, 225801707: 1760, 324194358: 2346, 435824227: 2244, 579337939: 2670, 600264328: 2620, 827690923: 3047, 1129093889: 3334, 1260597310: 3813, 1473972478: 4076, 1952345052: 3946, 1977336057: 3599, 2512749509: 4414, 3278750235: 3600, 3747691805: 5580, 5146052509: 4751

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

1 quả trứng:

Khi có một quả trứng, chiến lược tốt nhất là lên 1 tầng một lần và trả lại tầng ngay dưới sàn nơi nó vỡ trước.

2 quả trứng:

Khi chúng ta có hai quả trứng, số tầng tối đa chúng ta phải kiểm tra sẽ là n nhỏ nhất mà T n lớn hơn phạm vi tầng chúng ta phải kiểm tra. T n là số tam giác thứ n. Lần ném đầu tiên sẽ được thực hiện trên tầng thứ n. Lần ném thứ hai sẽ được thực hiện các n - 1tầng trên lần ném đầu tiên. Ném thứ m sẽ được thực hiện n - m + 1trên sàn m - 1ném thứ. Sau khi đập trứng, nó sẽ mấtn - m ném để xác định sàn bằng phương pháp đầu tiên.

3 quả trứng:

Với quả trứng đầu tiên, chúng ta nên xác định giới hạn trên cho tầng cao nhất. Ban đầu, tôi đã làm điều này bằng cách nhân đôi số sàn mỗi lần. Sau khi phân tích thuật toán cho 2 quả trứng, tôi nghĩ rằng có lẽ sẽ tốt hơn nếu mỗi lần chúng ta ném quả trứng, số lần ném tối đa để tìm đúng sàn với 2 quả trứng sẽ tăng thêm 1. Điều này có thể được thỏa mãn bằng cách sử dụng số tứ diện. Sau khi đập trứng đầu tiên, chúng ta có thể sử dụng các phương pháp trên cho những quả trứng còn lại.

Các giọt trứng tối đa nó yêu cầu để xác định sàn nên tối ưu. Tuy nhiên, một thuật toán tốt hơn có thể được tìm thấy ở nơi những giọt trứng trung bình tốt hơn.


4

Java, 68985 cuộc gọi

public static long solve(Predicate<Long> eggSurvives) {
  long bestFloor = 0, e1 = 1, e2;

  for(long callsDone = 2; eggSurvives.test(e1); bestFloor = e1, e1 += callsDone * callsDone++);

  for(e2 = bestFloor;; bestFloor = e2) {
    e2 += Math.max((long)Math.sqrt(e1 - e2), 1);

    if(e2 >= e1 || !eggSurvives.test(e2)) {
      break;
    }
  }

  for(long e3 = bestFloor + 1; e3 < e2 && eggSurvives.test(e3); e3++) {
    bestFloor = e3;
  }

  return bestFloor;
}

Kết quả kiểm tra:

0: 1 1: 4 2: 4 3: 4 4: 4 6: 6 7: 6 8: 6 10: 7 14: 6 15: 7 18: 7 20: 8 27: 10 29: 10 40: 10 57: 10 61: 9 91: 9 104: 11 133: 18 194: 20 233: 18 308: 18 425: 17 530: 17 735: 28 1057: 31 1308: 30 1874: 30 2576: 39 3162: 47 3769: 60 3804: 34 4872: 65 6309: 37 7731: 48 11167: 79 11476: 39 15223: 56 15603: 82 16034: 93 22761: 88 29204: 111 35268: 110 42481: 127 56238: 126 68723: 135 83062: 117 95681: 115 113965: 137 152145: 138 202644: 115 287964: 234 335302: 223 376279: 244 466202: 220 475558: 193 666030: 214 743517: 225 782403: 230 903170: 338 1078242: 223 1435682: 303 1856036: 384 2373214: 453 3283373: 542 4545125: 459 6215594: 525 7309899: 600 7848365: 388 8096538: 446 10409246: 466 15103057: 650 20271921: 822 22186329: 899 23602446: 698 32341327: 804 33354300: 1065 46852754: 1016 65157555: 1408 93637992: 1390 107681394: 1638 152487773: 1283 181996529: 1877 225801707: 2067 324194358: 1842 435824227: 3110 579337939: 2983 600264328: 1817 827690923: 2450 1129093889: 2981 1260597310: 3562 1473972478: 4237 1952345052: 2244 1977336057: 3585 2512749509: 2893 3278750235: 3101 3747691805: 5182 5146052509: 4107

Chương trình kiểm tra:

import java.util.function.Predicate;

public class Eggs {
  private static long totalCalls;
  private static long calls;

  public static void main(String[] args) {
    for(long maxFloor : new long[] {0,1,2,3,4,6,7,8,10,14,15,18,20,27,29,40,57,61,91,104,133,194,233,308,425,530,735,1057,1308,1874,2576,3162,3769,3804,4872,6309,7731,11167,11476,15223,15603,16034,22761,29204,35268,42481,56238,68723,83062,95681,113965,152145,202644,287964,335302,376279,466202,475558,666030,743517,782403,903170,1078242,1435682,1856036,2373214,3283373,4545125,6215594,7309899,7848365,8096538,10409246,15103057,20271921,22186329,23602446,32341327,33354300,46852754,65157555,93637992,107681394,152487773,181996529,225801707,324194358,435824227,579337939,600264328,827690923,1129093889,1260597310,1473972478,1952345052,1977336057,2512749509L,3278750235L,3747691805L,5146052509L}) {
      long resultingFloor = solve(f -> {
        calls++;
        return f <= maxFloor;
      });

      if(resultingFloor != maxFloor) {
        throw new RuntimeException("Disqualified");
      }

      System.out.print(maxFloor + ": " + calls + " ");
      totalCalls += calls;
      calls = 0;
    }

    System.out.println("\nCalls = " + totalCalls);
  }

  public static long solve(Predicate<Long> eggSurvives) {
    long bestFloor = 0, e1 = 1, e2;

    for(long callsDone = 2; eggSurvives.test(e1); bestFloor = e1, e1 += callsDone * callsDone++);

    for(e2 = bestFloor;; bestFloor = e2) {
      e2 += Math.max((long)Math.sqrt(e1 - e2), 1);

      if(e2 >= e1 || !eggSurvives.test(e2)) {
        break;
      }
    }

    for(long e3 = bestFloor + 1; e3 < e2 && eggSurvives.test(e3); e3++) {
      bestFloor = e3;
    }

    return bestFloor;
  }
}

Trong khi tối ưu hóa, tôi đã cố gắng thực hiện số lần thử với mỗi quả trứng gần bằng nhau.

  • Quả trứng đầu tiên tăng số tầng dựa trên số lần thử cho đến nay.
  • Quả trứng thứ hai bỏ qua các tầng dựa trên căn bậc hai của số lần thử tối đa có thể còn lại (dựa trên giới hạn dưới và giới hạn được thiết lập bởi quả trứng thứ nhất) để trung bình số lần thử cho quả trứng thứ 3 và cuối cùng giống như những nỗ lực cho quả trứng thứ 2.

2

Ruby, 67466 66026 cuộc gọi

$calls = 0

def drop n 
    $calls += 1
    n <= $x
end

def test
    min = 0
    test = 8
    i = 8
    while drop(test)
        min = test
        test += i*i
        i+=1
    end
    max = test
    test = min+((max-min)**0.4).to_i
    while drop(test)
        min = test
        test = min+((max-min)**0.5).to_i
    end
    return min if min+1 == test
    min += 1 while drop(min+1)
    min
end

Mã kiểm tra:

tests = [0,1,2,3,4,6,7,8,10,14,15,18,20,27,29,40,57,61,91,104,133,194,233,308,425,530,735,1057,1308,1874,2576,3162,3769,3804,4872,6309,7731,11167,11476,15223,15603,16034,22761,29204,35268,42481,56238,68723,83062,95681,113965,152145,202644,287964,335302,376279,466202,475558,666030,743517,782403,903170,1078242,1435682,1856036,2373214,3283373,4545125,6215594,7309899,7848365,8096538,10409246,15103057,20271921,22186329,23602446,32341327,33354300,46852754,65157555,93637992,107681394,152487773,181996529,225801707,324194358,435824227,579337939,600264328,827690923,1129093889,1260597310,1473972478,1952345052,1977336057,2512749509,3278750235,3747691805,5146052509]
tests.each{|n|$x = n;test;$calls}
puts $calls

Các kết quả:

0: 3, 1: 4, 2: 4, 3: 5, 4: 5, 6: 5, 7: 6, 8: 4, 10: 6, 14: 6, 15: 7, 18: 10, 20: 6, 27: 7, 29: 9, 40: 10, 57: 13, 61: 15, 91: 13, 104: 13, 133: 15, 194: 12, 233: 18, 308: 16, 425: 15, 530: 15, 735: 16, 1057: 32, 1308: 30, 1874: 35, 2576: 35, 3162: 54, 3769: 32, 3804: 29, 4872: 45, 6309: 42, 7731: 55, 11167: 72, 11476: 60, 15223: 55, 15603: 71, 16034: 94, 22761: 82, 29204: 119, 35268: 106, 42481: 123, 56238: 127, 68723: 110, 83062: 95, 95681: 139, 113965: 149, 152145: 149, 202644: 144, 287964: 219, 335302: 189, 376279: 183, 466202: 234, 475558: 174, 666030: 235, 743517: 195, 782403: 235, 903170: 346, 1078242: 215, 1435682: 245, 1856036: 422, 2373214: 448, 3283373: 512, 4545125: 378, 6215594: 502, 7309899: 486, 7848365: 440, 8096538: 496, 10409246: 566, 15103057: 667, 20271921: 949, 22186329: 829, 23602446: 746, 32341327: 799, 33354300: 964, 46852754: 1125, 65157555: 1317, 93637992: 1000, 107681394: 1361, 152487773: 1215, 181996529: 2004, 225801707: 1752, 324194358: 1868, 435824227: 3084, 579337939: 2592, 600264328: 1726, 827690923: 2577, 1129093889: 3022, 1260597310: 2582, 1473972478: 3748, 1952345052: 2035, 1977336057: 3712, 2512749509: 2859, 3278750235: 2888, 3747691805: 5309, 5146052509: 4234

Thuật toán này hoạt động giống như thuật toán cũ của tôi, nhưng có một vài điểm khác biệt:

  1. Lần thả trứng đầu tiên là ở tầng 8

  2. Gia số đầu tiên là 8 * 8 = 64

Những con số này là kết quả của việc tinh chỉnh ngẫu nhiên bằng tay.

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.