Sản phẩm chữ số


10

Đối với một số nguyên dương N đã cho, hãy viết một chương trình hoàn chỉnh để tìm M tự nhiên tối thiểu sao cho tích của các chữ số của M bằng N. N nhỏ hơn 1.000.000.000. Nếu không có M tồn tại, in -1. Mã của bạn không nên mất hơn 10 giây cho bất kỳ trường hợp nào.

Sample Inputs
1
3
15
10 
123456789
32
432
1296

Sample Outputs
1
3
35
25
-1
48
689
2899

4
1cho 1là một trường hợp thử nghiệm quan trọng.
Peter Taylor

1
Bạn nên thêm các trường hợp phức tạp hơn, như ba trường hợp tôi đã sử dụng dưới đây: 32, 432, 1296. Trừ khi bạn để nó như một bài tập cho lập trình viên.
mellamokb

@ s-mark 26, eh. Số lượng nhỏ nhất.
fR0DDY

Tôi tin rằng chúng ta cũng nên kiểm tra 387420361 rõ ràng (9 ^ 9) và 1000000000 cho vui.
asoundmove

2
Vì đây là một câu hỏi cũ và OP không hoạt động, đây chỉ là một lưu ý cho các bài đăng trong tương lai: "10 giây" không rõ ràng theo tiêu chuẩn hiện tại (trên máy nào?)
user202729

Câu trả lời:


4

Golfscript, 45 43 40 ký tự

~9{{1$1$%!{\1$/1$}*}12*(}8*>{];-1}*]$1or

Thay thế phiên bản không nhóm các số nguyên tố nhỏ thành sức mạnh và lưu 8 ký tự trong khi thực hiện. Lưu ý: 12 = sàn (9 log 10 / log 5).

Lời cảm ơn: hai nhân vật được lưu bằng cách đặt biệt danh cho một mánh khóe từ @mellamokb; 3 lưu với một gợi ý từ @Nabb.


1
Gì! Bạn có thể viết Golfscript mà không cần kiểm tra nó? +1, Có vẻ ổn, ngoại trừ 123456789, phải mất hơn 1 phút trên máy của tôi và tôi đã giết quá trình. 12345cho tôi -1, vì vậy có lẽ nó cũng sẽ hoạt động 123456789nếu tôi có thể chờ đợi đủ lâu.
BẠN

@ S.Mark, cảm ơn. Có vẻ như tôi không thể thoát khỏi thuật toán nhân tố ngây thơ.
Peter Taylor

@Peter: Đưa ra câu trả lời sai cho các trường hợp phức tạp hơn. 32 -> 22222, nên là 48. 432 -> 2222333, nên là 689. 1296 -> 22223333, nên là 2899. v.v.
mellamokb

@mellamokb, điểm tốt. Tôi nghĩ rằng tôi sẽ phải viết lại và kiểm tra.
Peter Taylor

Wow, ít hơn 17 ký tự. Tôi cần một thuật toán tốt hơn, lol!
mellamokb

6

Javascript ( 84 78 76 74 72 70 68)

n=prompt(m="");for(i=9;i-1;)n%i?i--:(m=i+m,n/=i);alert(n-1?-1:m?m:1)

http://jsfiddle.net/D3WgU/7/

Chỉnh sửa: Ý tưởng đầu vào / đầu ra mượn từ giải pháp khác và logic đầu ra ngắn hơn.

Chỉnh sửa 2: Đã lưu 2 ký tự bằng cách loại bỏ các dấu ngoặc không cần thiết trong forvòng lặp.

Chỉnh sửa 3: Đã lưu 2 ký tự bằng cách viết lại whilevòng lặp dưới dạng ifcâu lệnh với i++.

Chỉnh sửa 4: Đã lưu 2 ký tự bằng cách di chuyển xung quanh và giảm các thao tác trên i.

Chỉnh sửa 5: Chuyển đổi nếu câu lệnh thành định dạng ternary tiết kiệm thêm 2 ký tự.

Chỉnh sửa 6: Lưu 2 ký tự bằng cách di chuyển i--vào phần thực của ternary, xóa ++i.


Bạn đã đếm các ký tự cho chỉ chức năng. Đây có phải là một chương trình hoàn chỉnh? Bạn có thể thực hiện nó ở đây ideone.com
fR0DDY

1
có vẻ như có đầu vào tương tự cho javascript với spidermonkey ở ideone mà anh ấy đã liên kết - ideone.com/samples#sample_lang_112
YOU

@ fR0DDY: OK, giờ đây là một chương trình hoàn chỉnh :)
mellamokb

Cuối cùng tôi đã giảm xuống còn 69 ký tự, nhưng bây giờ bạn cũng có thể làm điều đó với cùng một loại ý tưởng và promptđiều.
Ry-

m?m:1=>m||1
l4m2

4

JavaScript, 88 72 78 74 69 68

for (s = '', i = 2, m = n = prompt (); i <m; i ++) while (! (n% i)) {if (i> 9) {alert (-1); E ( )} n / = i; s + = i} cảnh báo
4 ký tự dài hơn, nhưng thực sự là một tập lệnh thực thi (trái ngược với chức năng).

Chỉnh sửa: Sử dụng ý tưởng từ JavaScript khác, tôi có thể giảm ý tưởng này:

for(s='',i=9,n=prompt();i>1;i--)for(;!(n%i);n/=i)s=i+s;alert(n-1?-1:s?s:1)

Cuối cùng! Một giải pháp 69 ký tự, chỉ sử dụng 1 cho vòng lặp;)

for(s='',i=9,n=prompt();i>1;n%i?i--:[n/=i,s=i+s]);alert(n-1?-1:s?s:1)

Được rồi, cạo đi một dấu phẩy.

for(i=9,n=prompt(s='');i>1;n%i?i--:[n/=i,s=i+s]);alert(n-1?-1:s?s:1)

Vấn đề tương tự như giải pháp GolfScript. Thất bại ở đầu vào 32, 432 và 1296. Có một lý do tại sao tôi bắt đầu từ 9 và đi lùi và nối từ bên phải thay vì bên trái.
mellamokb

Cũng không thành công cho đầu vào 1. Phải tạo một trường hợp đặc biệt để xử lý 1.
mellamokb

Tôi đã bỏ lỡ phần "tối thiểu", đã thay đổi.
Ry-

@minitech: Vẫn không hoạt động cho đầu vào '1'. lol, câu trả lời của chúng tôi sắp được đưa ra gần như giống hệt nhau :-)
mellamokb

Ah, quản lý để làm cho nó ngắn hơn 2 ký tự của bạn! : D
Ry-

4

awk ( 63 61 59 58 57)

{for(i=9;i>1;$1%i?i--:($1/=i)<o=i o);print 1<$1?-1:o?o:1}

Chúng tôi đang gọi chương trình cho một đầu vào duy nhất. Nhiều đầu vào được đưa ra chỉ để kiểm tra tính chính xác.
fR0DDY

3

Perl (75) (72)

$ d = shift; map {$ m = $ _. $ m, $ d / = $ _ cho đến khi $ d% $ _} đảo ngược 2..9; in $ d-1? -1: $ m || 1

lấy cảm hứng từ mã javascript của mellamokb; có nghĩa là được chạy với một tham số


Nó sẽ không ngắn hơn nếu bạn sử dụng stdin thay vì một tham số?
asoundmove

3

GolfScript ( 60 57)

~[{9,{)}%{\.@%!},)\;.@@/.9>2$1>&}do])[.])@@{1>},+\9>[-1]@if$

~{9,{)}%{\.@%!},)\;.@@/.9>2$1>&}do])[.])@@{1>},+$\9>-1@if

Biên tập

Ok, tôi nghĩ phiên bản này cung cấp đầu ra chính xác cho mọi trường hợp ngay bây giờ :-)

Chỉnh sửa 2

Cạo sạch 3 ký tự cho mỗi đề xuất của @ Peter.


Lý do tôi nhận xét ở trên rằng 1việc đưa ra 1là một trường hợp thử nghiệm quan trọng là vì đó là trường hợp đặc biệt khó chịu - con số duy nhất mà chữ số 1xuất hiện trong đầu ra. Và nó phá vỡ mã của bạn, tôi sợ.
Peter Taylor

Nó cũng phá vỡ các số chia hết cho các số nguyên tố lớn hơn 9.
Peter Taylor

@Peter: OK, thử lại. Tôi nghĩ rằng phiên bản này hoạt động cho tất cả các trường hợp thử nghiệm bây giờ.
mellamokb

Có vẻ như, vâng. Bạn có thể lưu ngay một ký tự bằng cách xóa ký tự đó trước [- nếu bạn không có ký tự [trên ngăn xếp khi bạn đánh giá một ký tự ]sẽ lấy mọi thứ trên ngăn xếp. Và bạn có thể có thể lưu hai ký tự gần cuối bằng cách không gói -1trong một mảng và di chuyển cuối cùng $.
Peter Taylor

@Peter: Cảm ơn, đã lưu thêm 3 ký tự!
mellamokb

3

Haskell

f n=head([m|m<-[1..10^9],product(map(read.return)$show m)==n]++[-1])

Cạo sạch một char bằng cách thay đổi (show m)thành $show m.
FUZxxl

1
không nên m<-[1..9^9].... nếu không nó là một danh sách vô hạn ... vì vậy -1sẽ không bao giờ xảy ra .... sửa tôi nếu tôi sai.
st0le

Tôi không nghĩ rằng nó có thể hoạt động trong vòng
10 giây

2

Windows PowerShell, 87

if(($n="$args")-le1){$n;exit}(-1,-join(9..2|%{for(;!($n%$_)){$_;$n/=$_}}|sort))[$n-eq1]

2

Perl (68)

$x=pop;map{$_-=11;$x/=$_,$@=-$_.$@until$x%$_}1..9;print!$x?-1:$@||1

vẻ như thủ thuật tuyệt vời mà @mellamokb sử dụng trong javascript để tránh vòng lặp lồng nhau sẽ dịch tốt sang perl nhưng nó xuất hiện dài dòng hơn nhiều vì bạn không thể sử dụng foreachvòng lặp kiểu nữa. Thật đáng tiếc khi perl không nghĩ rằng mapmột vòng lặp khác redosẽ có ích.


2

Scala 106 ký tự:

def p(n:Int,l:Int=9):List[Int]=if(n<=9)List(n)else
if(l<2)List(-1)else
if(n%l==0)l::p(n/l,l)else
p(n,l-1)

Kiểm tra & Gọi:

scala> val big=9*9*9*8*8*8*7*7*7*5*3 
big: Int = 1920360960

scala> p(big)                        
res1: List[Int] = List(9, 9, 9, 8, 8, 8, 7, 7, 7, 5, 3)

Thời gian đáp ứng: ngay lập tức, <1s trên CPU 2Ghz.


2

Thạch , 18 13 10 byte

×⁵RDP$€io-

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

Giải pháp 13 byte:

×⁵RDP$€iµ’¹¬?

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

Giải thích với đầu vào N:

׳R              create a range from 1 to N * 100 (replace ³ with ⁵ for a faster execution time)
   DP$           define a function ($) to get the product of the digits of a number,
      €          apply that function to each element in the list,
       iµ        get the index of the input N in the list (or 0 if it's not there), and yeild it as the input to the next link,
         ’¹¬?    conditional: if the answer is 0, then subtract one to make it -1, otherwise, yeild the answer

Giải pháp 18 byte:

D×/
×⁵RÇ€i
Ç⁾-1¹¬?

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

D×/        product of digits function, takes input M
D          split M into digits,
 ×/        reduce by multiplication (return product of digits)

×⁵RÇ€i     range / index function
×⁵R        make a range from 1 to N*10,
   ǀ      run the above function on each of the range elements,
     i     get the index of N in the result, or 0 if it's not there

Ç⁾-1¹¬?    main function:
Ç    ¬?    run the line above and check if the answer is null (0)
 ⁾-1       if it is, return "-1",
    ¹      otherwise, return the answer (identity function).

Liên kết cuối cùng chỉ để thay thế 0 (giá trị falsey mặc định của Jelly, vì tất cả các danh sách đều được lập chỉ mục một) bằng -1. Nếu bạn coi 0 là một giá trị falsey OK, chương trình là 8 byte .


1
Một số lưu ý: (1) bạn chỉ sử dụng mỗi liên kết phụ trợ một lần, vì vậy không có lý do gì để tạo liên kết phụ trợ. Chỉ cần sử dụng $ƊƲµ. (2) Vì chuỗi -1và số -1giống hệt nhau khi đầu ra, sử dụng số này sẽ tiết kiệm được 2 byte. (3) Plà tốc ký cho ×/. (4) Thất bại cho đầu vào 3125.
dùng202729

@ user202729 Cảm ơn bạn rất nhiều! Tôi đã thực hiện (1), (2) và (3) và họ đã lưu 6 byte! Nếu tôi thay đổi thành ³, nó hoạt động ở đầu vào 3125 nhưng chỉ sau một độ trễ đáng kể. Bạn có biết nếu có một cách tốt hơn (và ngắn hơn), hoặc là cách tiếp cận của tôi (mà tôi biết chắc chắn không phải là nhanh nhất về độ phức tạp thời gian) tốt như nó sẽ có được?
Harry

1
Tôi nghĩ _¬$nên làm việc hơn’¹¬?
dylnan

1
o-thậm chí còn ngắn hơn
dùng202729

@dylnan Cảm ơn bạn - Tôi nhận thấy rằng vì µtôi chỉ có thể sử dụng mà không cần $lưu 2 byte! Nhưng sau đó tôi nhận ra rằng o-tôi chỉ có thể bỏ qua µtoàn bộ và tiết kiệm 3 byte!
Harry

1

Hồng ngọc (100)

n=gets.to_i;(d=1..9).map{|l|[*d].repeated_combination(l){|a|a.reduce(:*)==n&&(puts a*'';exit)}};p -1

0

Python 2 , 89 byte

f=lambda n,a=0,u=1,i=9:n<2and(a or 1)or-(i<2)or n%i<1and f(n/i,a+i*u,u*10)or f(n,a,u,i-1)

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

Chỉ vì chưa có câu trả lời của Python. Thật sự đau đớn khi thiếu chuyển đổi kiểu ngầm giữa chuỗi và int.

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.