Tìm số lượng người nhận được số bằng + và *


28

Giới thiệu

Mục tiêu của bạn là tìm ra số lượng ít nhất những cái bạn cần thêm hoặc nhân với nhau để có được giá trị đầu vào, đây là A005245 .

Đầu vào

Một số nguyên dương N .

Đầu ra

Số nhỏ nhất của những người mà phải được bổ sung / nhân để có được N .

Đầu vào mẫu

7

Đầu ra mẫu

6

Giải trình

( 1+ 1+ 1) * ( 1+ 1) + 1= 7

Bởi vì điều này đòi hỏi 6những cái, đầu ra là6

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

 1  1
 2  2
 3  3
 5  5
10  7
20  9
50 12

Vì đây là một thử thách , số byte thấp nhất sẽ thắng.



9
Chào mừng bạn đến với Câu đố lập trình và Code Golf! Thử thách đầu tiên là ổn, nhưng lần sau hãy sử dụng Sandbox trước khi đăng các thử thách để bạn có thể nhận phản hồi!
betseg

4
Tôi khuyên bạn nên sửa đổi điều này để nói rõ rằng bạn đang tìm kiếm số lượng tối thiểu cần thiết. Mặt khác, chỉ cần xuất ra số ban đầu và tuyên bố rằng đó là số lượng bạn cần cộng lại sẽ là một giải pháp hợp lệ.
Xù xì

2
Có ví dụ nào f(x) != x.primeFactorisation().sum()ngoại trừ 1?
jrtapsell

1
@jrtapsell: có. Ví dụ đã cho của $ f (7) = 6 $ là một. Đối với bất kỳ số nguyên tố (đủ lớn) $ p $, bạn có thể tính $ p-1 $ và thêm một số nguyên tố. Bạn có thể làm tốt hơn
Ross Millikan

Câu trả lời:


17

Python 2 , 74 70 byte

f=lambda n:min([n]+[f(j)+min(n%j*n+f(n/j),f(n-j))for j in range(2,n)])

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

Phiên bản thay thế, 59 byte (chưa được xác minh)

f=lambda n:min([n]+[f(j)+f(n/j)+f(n%j)for j in range(2,n)])

Điều này hoạt động ít nhất lên tới n = 1.000.000 , nhưng tôi chưa chứng minh rằng nó hoạt động cho tất cả n tích cực .

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


Xin lỗi nếu tôi thiếu một cái gì đó đơn giản, nhưng không rõ ràng là nó sẽ thử mọi cây biểu hiện khả thi. Cụ thể, chúng ta có lớp ngoài n=a*j+bcùng b<j, nhưng chúng ta có thể cần b>=jkhông?
xnor

Hừm, nó sẽ chỉ thất bại nếu cả hai b>=jb>=a. Nhưng bạn nói đúng, không rõ ràng rằng điều này sẽ không xảy ra.
Dennis

Điều thú vị là không có mẫu nào lên tới 1.000.000, tôi tự hỏi liệu nó có thực sự luôn hoạt động không. Suy nghĩ tốt nhất của tôi cho một ví dụ mẫu sẽ là một cái gì đó có hình thức a*b+c*dvới a,b,c,dtất cả các biểu thức tổng hợp và rất hiệu quả.
xnor

10

Thạch , 16 14 byte

Cảm ơn Dennis vì đã tiết kiệm 2 byte!

ÆḌḊ,Ṗ߀€+U$FṂo

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


Giải thích logic

Cho một số n :

  • Nếu đó là 1, câu trả lời là 1. Nếu không thì:

Các đại diện là a + bhoặc a × b, ở đâu ablà biểu thức.

Xem xét tất cả các giá trị có thể của ab:

  • Nếu đại diện là a + b, sau đó ablà trong phạm vi [1 .. n-1].
  • Nếu đại diện là a × b, ablà ước số thích hợp của nlớn hơn 1.

Trong cả hai trường hợp, danh sách [[<proper divisors of n larger than 1>], [1, 2, ..., n-1]]được tính ( ÆḌḊ,Ṗ), ánh xạ liên kết hiện tại qua từng số ߀€, cộng các cặp chính xác với nhau ( +U$) và nhận giá trị tối thiểu ( FṂo).

Giải thích mã

ÆḌḊ,Ṗ߀€+U$FṂo   Main link. Assume n = 10.
ÆḌ       Proper divisors. [1,2,5]equeue, remove the first element. [2,5]
   ,Ṗ    Pair with op. Auto convert n = 10 to range 
         [1,2,3,4,5,6,7,8,9,10] and remove the last element
         10, get [1,2,3,4,5,6,7,8,9].

߀€      Apply this link over each element.
   +U$   Add with the Upend of itself.

FṂ       Flatten and get the inimum element.
  o      Logical or with n.
         If the list is empty, minimum returns 0 (falsy), so logical or
         convert it to n.

5

JavaScript (ES6), 108 96 byte

f=n=>n<6?n:Math.min(...[...Array(n-2)].map((_,i)=>Math.min(f(++i)+f(n-i),n%++i/0||f(i)+f(n/i))))

Rất kém hiệu quả; Array(n>>1)tăng tốc nó lên một chút với chi phí của một byte. Giải thích: n%++ikhông phải là zero nếu ikhông phải là một yếu tố, do đó n%++i/0Infinity(và do đó truthy, và cũng chắc chắn không phải tối thiểu) nếu ikhông phải là một yếu tố, nhưng NaN(và do đó falsy) nếu ilà một yếu tố. Chỉnh sửa: Đã lưu 12 byte với cảm hứng từ @ edc65.


Tôi đã thử chạy cái này trong nền để xem liệu nó có thực sự có khả năng tính toán hay f(50)không, nhưng thật không may, Windows Update đã khởi động lại PC của tôi trước khi nó có thể kết thúc.
Neil

Bạn đã thử đi bộ trên một mảng?
edc65

@ edc65 Xin lỗi, nhưng tôi không rõ những gì bạn đang đề xuất và tại sao.
Neil

Tôi thấy 2 bản đồ, mỗi bản quét một amảng. Bạn không thể hợp nhất các đánh giá trong 2 lambdas và mất tối thiểu?
edc65

@ edc65 À đúng rồi, vì một số lý do tôi nghĩ rằng việc lồng min sẽ không rẻ hơn nhưng tôi phải thay thế (i+=2)bằng ++icái khác để tôi tiết kiệm tổng cộng 12 byte, cảm ơn!
Neil

5

Pari / GP , 66 byte

Một cổng trả lời Python của Dennis :

f(n)=vecmin(concat(n,[f(j)+min(n%j*j+f(n\j),f(n-j))|j<-[2..n-1]]))

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


Pari / GP , 72 byte

Lâu hơn, nhưng hiệu quả hơn:

f(n)=if(n<6,n,vecmin([if(d>1,f(d)+f(n/d),1+f(n-1))|d<-divisors(n),d<n]))

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


1
Dennis đã cải thiện phương pháp của mình và sử dụng nó có thể giúp bạn tiết kiệm 11 byte : f(n)=vecmin(concat(n,[f(j)+f(n\j)+f(n%j)|j<-[2..n-1]])).
Jonathan Allan



2

Ngôn ngữ Wolfram (Mathicala) , 59 byte

Đã lưu 3 byte nhờ Martin Ender. Sử dụng mã hóa CP-1252, trong đó ±là một byte.

±1=1;±n_:=Min[1+±(n-1),±#+±(n/#)&/@Divisors[n][[2;;-2]]]

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


2
Sử dụng ±thay vì ftiết kiệm 3 byte giả sử nguồn được mã hóa trong CP 1252: tio.run/##y00syUjNTSzJTE78///QRkNbQ@tDG/PirWx9M/ tựa
Martin Ender

1
Không hoạt động chính xác cho đầu vào 353942783.
Misha Lavrov

1

Perl 5 , -p 78 byte

79 byte trong kiểu đếm cũ ( +1for -p)

Việc perl phải sử dụng thêm $cho tất cả các truy cập vô hướng thực sự làm tổn thương chiều dài của các sân golf làm nhiều số học ...

Phương pháp này chủ yếu giống như các phương pháp khác đã được đăng (thử nhân và cộng để xây dựng số mục tiêu, lấy giá rẻ nhất). Tuy nhiên, nó không lặp đi lặp lại nhiều lần nên có thể được sử dụng cho các đầu vào tương đối lớn.

Nó cũng không cố gắng giảm thiểu chi phí xây dựng một số bằng cách thêm hoặc nhân [phần mềm vì perl 5 không có nội dung dựng sẵn minvà sắp xếp số là looooooong (như được thấy từ loại vẫn còn trong mã). Thay vào đó tôi chỉ giả sử nếu một số là một yếu tố của mục tiêu mà tôi sẽ sử dụng phép nhân. Điều đó là an toàn vì nếu ví dụ 3là một yếu tố của 12(vì vậy nó tính tổng chi phí 312/3) sau này trong vòng lặp, nó sẽ xem xét 9=12-3đó sẽ không phải là một yếu tố, do đó, 9+3với cùng một chi phí 3+9sẽ được dùng thử. Tuy nhiên, điều đó có thể thất bại cho các mục tiêu <= 4(nó chỉ làm cho 12). Thêm $_vào danh sách để giảm thiểu sửa lỗi đó. Thật không may vì tôi thực sự không cần điều đó cho các trường hợp cơ bản vì tôi đã khởi tạo@; với các giá trị bắt đầu thích hợp để nó có giá 3 byte.

#!/usr/bin/perl -p
($_)=sort{$a-$b}$_,map{$;[$_]+$;[$'%$_?$'-$_:$'/$_]}//..$_ for@;=0..$_;$_=pop@

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

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.