ผลิตภัณฑ์ของตัวเลข


10

สำหรับจำนวนเต็มบวกที่กำหนด N ให้เขียนโปรแกรมที่สมบูรณ์เพื่อหาค่า M ธรรมชาติน้อยที่สุดซึ่งผลคูณของ M เท่ากับ N N น้อยกว่า 1,000,000,000 หากไม่มี M ให้พิมพ์ -1 รหัสของคุณไม่ควรเกิน 10 วินาทีไม่ว่ากรณีใด ๆ

Sample Inputs
1
3
15
10 
123456789
32
432
1296

Sample Outputs
1
3
35
25
-1
48
689
2899

4
1การให้1เป็นกรณีทดสอบที่สำคัญ
Peter Taylor

1
คุณควรเพิ่มเคสที่ซับซ้อนมากขึ้นเช่นกรณีที่ฉันเคยใช้ด้านล่าง: 32, 432, 1296 เว้นแต่คุณจะปล่อยให้มันเป็นแบบฝึกหัดสำหรับ coder
mellamokb

@ s-mark 26, eh จำนวนที่น้อยที่สุด
fR0DDY

ฉันเชื่อว่าเราควรทดสอบ 387420489 (9 ^ 9) และ 1000000000 เพื่อความสนุก
asoundmove

2
เนื่องจากนี่เป็นคำถามเก่าและ OP ไม่ทำงานนี่เป็นเพียงหมายเหตุสำหรับการโพสต์ในอนาคต: "10 วินาที" ไม่ชัดเจนตามมาตรฐานปัจจุบัน (ที่เครื่องใด?)
user202729

คำตอบ:


4

Golfscript, 45 43 40 ตัวอักษร

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

แทนที่เวอร์ชันที่ไม่ได้จัดกลุ่มช่วงเวลาเล็ก ๆ ให้เป็นพลังและบันทึก 8 ตัวอักษรในขณะที่ทำเช่นนั้น หมายเหตุ: 12 = floor (9 บันทึก 10 / บันทึก 5)

กิตติกรรมประกาศ: บันทึกตัวละครสองตัวโดยการหลอกลวงจาก @mellamokb; 3 บันทึกด้วยคำใบ้จาก @Nabb


1
อะไร! คุณสามารถเขียน Golfscript โดยไม่ต้องทดสอบหรือไม่ +1 ดูดียกเว้น 123456789 มันใช้เวลามากกว่า 1 นาทีบนเครื่องของฉันและฉันฆ่ากระบวนการไปแล้ว 12345ให้ฉัน -1 ดังนั้นอาจใช้งานได้123456789เช่นกันหากฉันรอนานพอ
คุณ

@ S. Mark ขอบคุณ ดูเหมือนว่าฉันจะไม่สามารถหลบหนีได้ด้วยอัลกอริธึมไร้เดียงสาไร้เดียงสา
Peter Taylor

@ Peter: ให้คำตอบที่ผิดสำหรับกรณีที่ซับซ้อนมากขึ้น 32 -> 22222 ควร 48. 432 -> 2222333 ควรเป็น 689 1296 -> 22223333 ควรเป็น 2899 เป็นต้น
mellamokb

@ mellamokb จุดดี ฉันคิดว่าฉันจะต้องเขียนใหม่และทดสอบ
Peter Taylor

ว้าวน้อยกว่า 17 ตัวอักษร ฉันต้องการอัลกอริทึมที่ดีกว่าฮ่า ๆ !
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/

แก้ไข:แนวคิดอินพุต / เอาต์พุตที่ยืมมาจากโซลูชันอื่นและตรรกะเอาต์พุตที่สั้นลง

แก้ไข 2:บันทึก 2 ตัวอักษรโดยลบวงเล็บปีกกาที่ไม่ต้องการในforลูป

แก้ไข 3:บันทึกไว้ 2 ตัวอักษรโดยการเขียนใหม่whileห่วงเป็นคำสั่งที่มีifi++

แก้ไข 4:บันทึกไว้ 2 ตัวอักษรโดยการย้ายไปรอบ ๆ iและลดการดำเนินงาน

แก้ไข 5:แปลงถ้าคำสั่งเป็นรูปแบบที่ประกอบไปด้วยประหยัดอีก 2 ตัวอักษร

แก้ไข 6:บันทึกตัวอักษร 2 โดยการย้ายi--เข้ามาเป็นส่วนหนึ่งที่แท้จริงของ ternary ++iลบ


คุณได้นับจำนวนตัวอักษรสำหรับฟังก์ชั่นเท่านั้น นี่เป็นโปรแกรมที่สมบูรณ์หรือไม่ คุณสามารถดำเนินการได้ที่นี่ideone.com
fR0DDY

1
ดูเหมือนว่าจะมีการป้อนข้อมูลที่คล้ายกันสำหรับจาวาสคริปต์ที่มี spidermonkey ที่ ideone ที่เขาเชื่อมโยง - ideone.com/samples#sample_lang_112
คุณ

@ fR0DDY: ตกลงตอนนี้มันเป็นโปรแกรมที่สมบูรณ์ :)
mellamokb

ในที่สุดฉันก็ลดความสามารถลงเหลือ 69 ตัวละคร แต่คุณสามารถทำได้ด้วยความคิดและpromptสิ่งเดียวกัน
Ry-

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

4

JavaScript, 88 72 78 74 69 68

สำหรับ (s = '', I = 2 m = n = พรอมต์ (); ฉัน <มผม ++) ในขณะที่ {if (i ((n% i)!)> 9) {alert (-1); E ( )} n / = ฉัน; s + = i} การแจ้งเตือน (s)
อีก 4 ตัวอักษร แต่จริง ๆ แล้วเป็นสคริปต์ที่ปฏิบัติการได้ (ตรงข้ามกับฟังก์ชั่น)

แก้ไข: การใช้แนวคิดจาก JavaScript อื่นฉันสามารถลดความคิดลงในสิ่งนี้:

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

ที่สุด! โซลูชัน 69 อักขระใช้ 1 สำหรับลูปเท่านั้น)

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

ตกลงโกนคอมมาหนึ่งอันแล้ว

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

ปัญหาเดียวกับวิธีแก้ไข GolfScript ล้มเหลวในอินพุต 32, 432 และ 1296 มีเหตุผลทำไมฉันเริ่มต้นที่ 9 และย้อนกลับและเชื่อมต่อจากด้านขวาแทนด้านซ้าย
mellamokb

การป้อนข้อมูลล้มเหลวด้วย 1. ต้องสร้างเคสพิเศษเพื่อจัดการ 1.
mellamokb

ฉันพลาดส่วน "น้อยที่สุด" เปลี่ยนไป
Ry-

@minitech: ยังใช้งานไม่ได้กับอินพุต '1' ฮ่า ๆ คำตอบของเราจะออกมาเกือบจะตรงเหมือนกัน :-)
mellamokb

อ่าทำให้ตัวละครสั้นกว่าของคุณ 2 ตัว! : 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}

เรากำลังเรียกโปรแกรมสำหรับอินพุตหนึ่งเท่านั้น อินพุตหลายอินพุตถูกกำหนดเพื่อตรวจสอบความถูกต้อง
fR0DDY

3

Perl (75) (72)

$ d = shift; map {$ m = $ _. $ m, $ d / = $ _ จนกระทั่ง $ d% $ _} ย้อนกลับ 2..9; พิมพ์ $ d-1? -1: $ m || 1

แรงบันดาลใจจากรหัสจาวาสคริปต์ของ mellamokb; ตั้งใจที่จะทำงานกับพารามิเตอร์


จะไม่สั้นลงหรือไม่ถ้าคุณใช้ stdin แทนที่จะเป็นพารามิเตอร์
asoundmove

3

GolfScript ( 60 57)

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

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

แก้ไข

ตกลงฉันคิดว่ารุ่นนี้ให้ผลลัพธ์ที่ถูกต้องสำหรับทุกกรณีทันที :-)

แก้ไข 2

ลบ 3 ตัวอักษรตามคำแนะนำของ @ Peter


เหตุผลที่ฉันแสดงความคิดเห็นข้างต้นว่าการ1ให้1เป็นกรณีทดสอบที่สำคัญคือมันเป็นกรณีพิเศษที่น่ารังเกียจ - หมายเลขเดียวที่ตัวเลข1ปรากฏในผลลัพธ์ และมันก็ทำลายรหัสของคุณฉันกลัว
Peter Taylor

นอกจากนี้ยังแบ่งให้ตัวเลขหารด้วยจำนวนเฉพาะที่มากกว่า 9
Peter Taylor

@Peter: ตกลงลองอีกครั้ง ฉันคิดว่ารุ่นนี้ใช้ได้กับกรณีทดสอบทั้งหมดตอนนี้
mellamokb

ดูเหมือนว่าใช่ คุณสามารถบันทึกอักขระหนึ่งตัวได้ทันทีโดยลบอักขระนั้นออกก่อน[- ถ้าคุณไม่มี a [ในสแต็กเมื่อคุณประเมิน a ]จะใช้ทุกอย่างบนสแต็ก และคุณอาจจะสามารถบันทึกตัวละครทั้งสองใกล้จะจบโดยไม่ตัดในอาร์เรย์และการย้ายครั้งสุดท้าย-1 $
Peter Taylor

@ Peter: ขอบคุณบันทึกอีก 3 ตัวอักษร!
mellamokb

3

Haskell

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

โกนหนึ่งถ่านโดยการเปลี่ยนไป(show m) $show m
FUZxxl

1
ไม่ควรมันจะเป็นm<-[1..9^9].... มิฉะนั้นจะเป็นรายการที่ไม่มีที่สิ้นสุด ... ดังนั้น-1จะไม่เกิดขึ้น .... แก้ไขฉันถ้าฉันผิด
st0le

ฉันไม่คิดว่ามันจะสามารถทำงานได้ภายใน
10 วินาที


2

Perl (68)

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

มันดูเหมือนเช่นเคล็ดลับที่น่ากลัวที่ใช้ @mellamokb ใน JavaScript เพื่อหลีกเลี่ยงวงซ้อนกันจะแปลดีเพื่อ Perl แต่มันออกมามากขึ้นอย่างละเอียดเพราะคุณไม่สามารถใช้foreachห่วงลักษณะใด ๆ อีกต่อไป นอกจากนี้ยังเป็นที่น่าเสียดายที่ perl ไม่คิดว่าmapเป็นวงอื่นredoจะมาสะดวก


2

สกาล่า 106 ตัวอักษร:

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)

ทดสอบและขอร้อง:

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)

เวลาตอบสนอง: ทันที <1 วินาทีบน CPU 2Ghz


2

เยลลี่ , 18 13 10 ไบต์

×⁵RDP$€io-

ลองออนไลน์!

วิธีแก้ปัญหา 13 ไบต์:

×⁵RDP$€iµ’¹¬?

ลองออนไลน์!

คำอธิบายด้วยอินพุต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

โซลูชัน 18 ไบต์:

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

ลองออนไลน์!

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

ลิงก์สุดท้ายใช้เพื่อแทนที่ 0 เท่านั้น (ค่า falsey เริ่มต้นของ Jelly เนื่องจากรายการทั้งหมดเป็นดัชนีเดียว) ด้วย -1 หากคุณพิจารณา 0 ค่า falsey ตกลงโครงการคือ8 ไบต์


1
หมายเหตุบางประการ: (1) คุณใช้ลิงก์เสริมแต่ละลิงก์เพียงครั้งเดียวดังนั้นจึงไม่มีเหตุผลที่จะสร้างลิงค์สำรอง $ƊƲµเพียงแค่ใช้ (2) เนื่องจากสตริง-1และหมายเลข-1เหมือนกันเมื่อเอาท์พุทการใช้หมายเลขจะประหยัด 2 ไบต์ (3) เป็นชวเลขP ×/(4) 3125ล้มเหลวสำหรับการป้อนข้อมูล
user202729

@ user202729 ขอบคุณมาก! ฉันใช้งาน (1), (2) และ (3) และพวกเขาบันทึกได้ 6 ไบต์! ถ้าฉันเปลี่ยน⁵เป็น³มันจะทำงานกับอินพุต 3125 แต่หลังจากล่าช้ามาก คุณรู้หรือไม่ว่ามีวิธีที่ดีกว่า (หรือสั้นกว่า) หรือเป็นแนวทางของฉัน (ซึ่งฉันรู้ว่าไม่ใช่วิธีที่เร็วที่สุดในแง่ของเวลา - ความซับซ้อน) ดีเท่าที่ควรจะเป็น
แฮร์รี่

1
ฉันคิดว่า_¬$ควรจะทำงานได้ดี’¹¬?
dylnan

1
o-สั้นกว่า
user202729

@ dylnan ขอบคุณ - ฉันสังเกตเห็นว่าเพราะµฉันสามารถใช้โดยไม่ต้อง$บันทึก 2 ไบต์! แต่จากนั้นฉันก็ตระหนักได้ว่าo-ฉันสามารถละµทั้งหมดและบันทึก 3 ไบต์!
แฮร์รี่


0

Python 2 , 89 ไบต์

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)

ลองออนไลน์!

เพียงเพราะยังไม่มีคำตอบของ Python มันเจ็บปวดจริงๆที่ขาดการแปลงชนิดโดยนัยระหว่างสตริงและ int

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.