Cọc và đống sỏi


8

Công việc của tôi là xếp đá cuội thành đống hình tam giác. Tôi mới chỉ làm điều này trong một thế kỷ và nó đã khá nhàm chán. Phần tồi tệ nhất là tôi dán nhãn cho mỗi đống. Tôi biết cách phân hủy sỏi thành đống có kích thước tối đa , nhưng tôi muốn giảm thiểu số lượng cọc. Bạn có thể giúp?

Bài tập

Cho một số nguyên, phân tách nó thành số lượng tam giác tối thiểu và xuất ra số tối thiểu đó.

Số tam giác

Số tam giác là một số có thể được biểu thị bằng tổng của các nsố tự nhiên đầu tiên , đối với một số giá trị n. Do đó, một số số tam giác đầu tiên là

1 3 6 10 15 21 28 36 45 55 66 78 91 105

Thí dụ

Ví dụ, giả sử đầu vào là 9. Nó không phải là số tam giác, vì vậy nó không thể được biểu thị dưới dạng tổng của 1số tam giác. Do đó, số lượng tam giác tối thiểu là 2, có thể thu được với [6,3], mang lại đầu ra chính xác của 2.

Một ví dụ khác, giả sử đầu vào là 12. Giải pháp rõ ràng nhất là sử dụng thuật toán tham lam và loại bỏ số tam giác lớn nhất tại một thời điểm, cho năng suất [10,1,1]và đầu ra 3. Tuy nhiên, có một giải pháp tốt hơn : [6,6], mang lại đầu ra chính xác 2.

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

in out
1 1
2 2
3 1
4 2
5 3
6 1
7 2
8 3
9 2
10 1
11 2
12 2
13 2
14 3
15 1
16 2
17 3
18 2
19 3
20 2
100 2
101 2
5050 1

Quy tắc

  • Số nguyên đầu vào nằm trong khoảng từ 1 đến số nguyên tối đa của ngôn ngữ của bạn.
  • Tôi có thể mô phỏng bất kỳ ngôn ngữ nào với các viên sỏi của mình và tôi muốn mã của bạn càng nhỏ càng tốt vì tôi không có gì ngoài viên sỏi để theo dõi nó. Do đó, đây là , vì vậy mã ngắn nhất trong mỗi ngôn ngữ sẽ thắng.

Sandbox đầy sỏi.
fireflame241



Không nên nhầm lẫn với OEIS A057945 (sự khác biệt đầu tiên xảy ra cho n = 12).
Martin Ender

Câu trả lời:


3

Võng mạc , 57 49 byte

.+
$*
(^1|1\1)+$
1
(^1|1\1)+(1(?(2)\2))+$
2
11+
3

Hãy thử trực tuyến! Dựa trên câu trả lời của tôi cho Ba số tam giác . Thay đổi dòng thứ ba ^(^1|1\1)*$để hỗ trợ đầu vào bằng không. Chỉnh sửa: Đã lưu 8 byte (nhưng có lẽ nên nhiều hơn) byte nhờ @MartinEnder.


Bạn không cần nhóm 1trong giai đoạn thứ hai, và cả nhóm 1cũng không phải 3trong giai đoạn thứ ba.
Martin Ender

Và sau đó ((?(2)1\2|1))có thể được rút ngắn (1(?(2)\2)).
Martin Ender

Trên thực tế, đó là một byte ngắn hơn để làm một cái gì đó kỳ lạ như thế này : ^((?<2>)(1\2)+){2}$. Hoặc ^(()(?<2>1\2)+){2}$nếu bạn thích.
Martin Ender

@MartinEnder Phiên bản cuối cùng đó khiến não tôi đau, nhưng tôi đã có thể sử dụng bình luận thứ hai của bạn cho câu trả lời được liên kết của tôi, thật tuyệt.
Neil

Tôi nghĩ rằng cách cuối cùng thực sự đơn giản hơn cả cách tiếp cận tiêu chuẩn bởi vì nó không có tham chiếu chuyển tiếp có điều kiện kỳ ​​lạ.
Martin Ender

1

Toán học, 53 byte

Min[Plus@@@Table[$($+1)/2,{$,#+1}]~FrobeniusSolve~#]&

Mã này rất chậm. Nếu bạn muốn kiểm tra chức năng này, hãy sử dụng phiên bản sau:

Min[Plus@@@Table[$($+1)/2,{$,√#+1}]~FrobeniusSolve~#]&

Dùng thử trên Wolfram Sandbox

Giải trình

Min[Plus@@@Table[$($+1)/2,{$,#+1}]~FrobeniusSolve~#]&  (* input: n *)

           Table[$($+1)/2,{$,#+1}]                     (* Generate the first n triangle numbers *)
                                  ~FrobeniusSolve~#    (* Generate a Frobenius equation from the *)
                                                       (* triangle numbers and find all solutions. *)
    Plus@@@                                            (* Sum each solution set *)
Min                                                    (* Fetch the smallest value *)

1

Jelly ( ngã ba ), 9 byte

æFR+\$S€Ṃ

Điều này phụ thuộc vào một ngã ba nơi tôi thực hiện một nguyên tử giải quyết Frobenius không hiệu quả. Không thể tin rằng đã một năm kể từ lần cuối tôi chạm vào nó.

Giải trình

æFR+\$S€Ṃ  Input: n
æF         Frobenius solve with
     $     Monadic chain
  R          Range, [1, n]
   +\        Cumulative sum, forms the first n triangle numbers
      S€   Sum each
        Ṃ  Minimum

Nguyên tử giải quyết Darn Frobenius đã đánh bại giải pháp Jelly bình thường của tôi bằng 6 byte toàn bộ :(
Erik the Outgolfer

@EriktheOutgolfer Tôi cần hoàn thành nó và thực hiện một cú kéo cho nó.
dặm

1

R , 69 58 byte

function(n)3-n%in%(l=cumsum(1:n))-n%in%outer(c(0,l),l,"+")

Hãy thử trực tuyến!

Giải trình:

function(n){
 T <- cumsum(1:n)             # first n triangular numbers  [1,3,6]
 S <- outer(c(0,T),T,"+")     # sums of the first n triangular numbers,
                              # AND the first n triangular numbers [1,3,6,2,4,7,4,6,9,7,9,12]
 3 - (n %in% S) - (n %in% T)  # if n is in T, it's also in S, so it's 3-2: return 1
                              # if n is in S but not T, it's 3-1: return 2
                              # if n isn't in S, it's not in T, so 3-0: return 3
}


0

JavaScript (ES6), 75 63 61 byte

f=(n,x=y=0)=>y<n+2?x*x+y*y-8*n-2+!y?f(n,x<n+2?x+1:++y):2-!y:3

Làm sao?

Chúng tôi sử dụng các thuộc tính sau:

  • Theo định lý số đa giác Fermat , bất kỳ số nguyên dương nào cũng có thể được biểu diễn dưới dạng tổng của tối đa 3 số tam giác.
  • Một số t là tam giác khi và chỉ khi 8t + 1 là một hình vuông hoàn hảo (điều này có thể dễ dàng được chứng minh bằng cách giải t = n (n + 1) / 2 ).

Cho một số nguyên dương n , nó đủ để kiểm tra xem chúng ta có thể tìm thấy hay không:

  • x> 0 sao cho 8n + 1 = x² ( n chính là tam giác)
  • hoặc x> 0y> 0 sao cho 8n + 2 = x² + y² ( n là tổng của 2 số tam giác)

Nếu cả hai bài kiểm tra đều thất bại, n phải là tổng của 3 số tam giác.

f = (n, x = y = 0) =>                 // given n and starting with x = y = 0
  y < n + 2 ?                         // if y is less than the maximum value:
    x * x + y * y - 8 * n - 2 + !y ?  //   if x² + y² does not equal 8n + 2 - !y:
      f(                              //     do a recursive call with:
        n,                            //       - the original input n
        x < n + 2 ? x + 1 : ++y       //       - either x incremented or
      )                               //         y incremented and x set to y
    :                                 //   else:
      2 - !y                          //     return either 1 or 2
  :                                   // else:
    3                                 //   return 3

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


0

MATL , 15 byte

`G:Ys@Z^!XsG-}@

Hãy thử trực tuyến!

Giải trình

`         % Do...while
  G:      %   Push range [1 2 3 ... n], where n is the input
  Ys      %   Cumulative sum: gives [1 3 6 ... n*(n+1)/2]
  @Z^     %   Cartesian power with exponent k, where k is iteration index
          %   This gives a k-column matrix where each row is a Cartesian tuple
  !Xs     %   Sum of each row. Gives a column vector
  G-      %   Subtract input from each entry of that vector. This is the loop 
          %   condition. It is truthy if it only contains non-zeros
}         % Finally (execute before exiting the loop)  
  @       %   Push iteration index, k. This is the output
          % End (implicit). Proceeds with next iteration if the top of the
          % stack is truthy

0

Kotlin , 176 154 byte

Nộp hồ sơ

{var l=it
var n=0
while(l>0){n++
val r=mutableListOf(1)
var t=3
var i=3
while(t<=l){r.add(t)
t+=i
i++}
l-=r.lastOrNull{l==it|| r.contains(l-it)}?:r[0]}
n}

Làm đẹp

{
    // Make a mutable copy of the input
    var l=it
    // Keep track of the number of items removed
    var n=0
    // While we still need to remove pebbles
    while (l > 0) {
        // Increase removed count
        n++
        // BEGIN: Create a list of triangle numbers
        val r= mutableListOf(1)
        var t = 3
        var i = 3
        while (t<= l) {
            // Add the number to the list and calculate the next one
            r.add(t)
            t+=i
            i++
        }
        // END: Create a list of triangle numbers
        // Get the fitting pebble, or the biggest one if none fit or make a perfect gap
        l -= r.lastOrNull {l==it|| r.contains(l-it)} ?: r[0]
    }
    //Return the number of pebbles
    n
}

Kiểm tra

var r:(Int)->Int =
{var l=it
var n=0
while(l>0){n++
val r=mutableListOf(1)
var t=3
var i=3
while(t<=l){r.add(t)
t+=i
i++}
l-=r.lastOrNull{l==it|| r.contains(l-it)}?:r[0]}
n}

data class TestData(val input:Int, val output:Int)

fun main(args: Array<String>) {
    val tests = listOf(
            TestData(1,1),
            TestData(2,2),
            TestData(3,1),
            TestData(4,2),
            TestData(5,3),
            TestData(6,1),
            TestData(7,2),
            TestData(8,3),
            TestData(9,2),
            TestData(10,1),
            TestData(11,2),
            TestData(12,2),
            TestData(13,2),
            TestData(14,3),
            TestData(15,1),
            TestData(16,2),
            TestData(17,3),
            TestData(18,2),
            TestData(19,3),
            TestData(20,2),
            TestData(100,2),
            TestData(101,2),
            TestData(5050,1)
    )
    tests.map { it to r(it.input) }.filter { it.first.output != it.second }.forEach { println("Failed for ${it.first}, output ${it.second} instead") }
}

Dùng thử

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.