ค้นหาจำนวนของคนที่จะได้รับหมายเลขโดยใช้ + และ *


28

บทนำ

เป้าหมายของคุณคือการหาจำนวนน้อยที่สุดของคนที่คุณจะต้องเพิ่มหรือคูณกันเพื่อให้ได้ค่าการป้อนข้อมูลนี้เป็นA005245

อินพุต

หนึ่งจำนวนเต็มบวกN

เอาท์พุต

จำนวนที่น้อยที่สุดของคนที่จะต้องเพิ่ม / คูณจะได้รับN

ตัวอย่างอินพุต

7

ตัวอย่างผลลัพธ์

6

คำอธิบาย

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

เพราะสิ่งนี้ต้องการ6สิ่งที่ต้องการผลลัพธ์คือ6

กรณีทดสอบ

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

นี่เป็นความท้าทายของนักมีจำนวนไบต์น้อยที่สุด



9
ยินดีต้อนรับสู่การเขียนโปรแกรมปริศนาและรหัสกอล์ฟ! เป็นความท้าทายครั้งแรกที่ตกลง แต่ในครั้งต่อไปโปรดใช้Sandboxก่อนโพสต์ความท้าทายเพื่อให้คุณสามารถรับข้อเสนอแนะ!
betseg

4
ฉันขอแนะนำให้แก้ไขนี้เพื่อระบุอย่างชัดเจนว่าคุณกำลังค้นหาจำนวนขั้นต่ำที่ต้องการ มิฉะนั้นเพียงแค่ส่งออกหมายเลขเดิมและอ้างว่ามันเป็นจำนวนที่คุณต้องการรวมเข้าด้วยกันจะเป็นทางออกที่ถูกต้อง
Shaggy

2
มีตัวอย่างที่f(x) != x.primeFactorisation().sum()ยกเว้น 1 หรือไม่?
jrtapsell

1
@jrtapsell: ใช่ ตัวอย่างที่กำหนดของ $ f (7) = 6 $ เป็นหนึ่ง สำหรับไพรม์ใด ๆ (ใหญ่พอ) $ p $ คุณสามารถแยก $ p-1 $ และเพิ่มได้ คุณอาจทำได้ดีกว่านี้
Ross Millikan

คำตอบ:


17

Python 2 , 74 70 ไบต์

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

ลองออนไลน์!

รุ่นสำรอง 59 ไบต์ (ไม่ได้ตรวจสอบ)

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

ผลงานอย่างน้อยถึงนี้n = 1,000,000แต่ผมยังไม่ได้พิสูจน์ว่าการทำงานสำหรับทุกบวกn

ลองออนไลน์!


ขออภัยถ้าฉันทำอะไรง่าย ๆ หายไป แต่ก็ไม่ชัดเจนว่านี่จะลองทรีนิพจน์ที่ทำงานได้ทุกต้น โดยเฉพาะอย่างยิ่งเรามีชั้นนอกn=a*j+bด้วยb<jแต่เราต้องการb>=jไหม
xnor

หืมมมมันจะล้มเหลวหากทั้งสองและb>=j b>=aแต่คุณพูดถูกมันไม่ชัดเจนว่าจะไม่เกิดขึ้น
เดนนิส

ที่น่าสนใจว่าไม่มีตัวอย่างโต้แย้งสูงถึง 1,000,000 ฉันสงสัยว่ามันใช้งานได้จริงหรือไม่ ความคิดที่ดีที่สุดของฉันสำหรับตัวอย่างตัวอย่างจะเป็นสิ่งที่a*b+c*dมีรูปแบบพร้อมกับa,b,c,dการแสดงผลรวมทั้งหมดและมีประสิทธิภาพมาก
xnor

10

เยลลี่ , 16 14 ไบต์

ขอบคุณเดนนิสที่ช่วยประหยัด 2 ไบต์!

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

ลองออนไลน์!


คำอธิบายตรรกะ

รับตัวเลขn :

  • ถ้าเป็นคำตอบคือ1 1มิฉะนั้น:

การเป็นตัวแทนเป็นอย่างใดอย่างหนึ่งa + bหรือa × bที่ไหนaและbมีการแสดงออก

พิจารณาคุณค่าที่เป็นไปได้ทั้งหมดaและb:

  • หากตัวแทนเป็นa + bแล้วaและอยู่ในช่วงb[1 .. n-1]
  • หากตัวแทนคือa × b, aและbเป็นตัวหารที่เหมาะสมของขนาดใหญ่กว่าn1

ในทั้งสองกรณีรายการ[[<proper divisors of n larger than 1>], [1, 2, ..., n-1]]จะคำนวณ ( ÆḌḊ,Ṗ) แมปลิงค์ปัจจุบันเหนือแต่ละหมายเลข߀€เพิ่มคู่ที่ถูกต้องเข้าด้วยกัน ( +U$) และรับค่าต่ำสุด ( FṂo)

คำอธิบายรหัส

ÆḌḊ,Ṗ߀€+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 ไบต์

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

ไม่มีประสิทธิภาพมาก Array(n>>1)เพิ่มความเร็วขึ้นเล็กน้อยในราคาไบต์ คำอธิบาย: n%++iไม่ใช่ศูนย์หากiไม่ใช่ปัจจัยดังนั้นจึงn%++i/0เป็นInfinity(และดังนั้นความจริงและไม่น้อยที่สุด) ถ้าiไม่ใช่ปัจจัย แต่NaN(และดังนั้นจึงเป็นเท็จ) หากiเป็นปัจจัย แก้ไข: บันทึก 12 ไบต์ด้วยแรงบันดาลใจจาก @ edc65


ฉันลองเรียกใช้งานในพื้นหลังเพื่อดูว่าจริง ๆ แล้วสามารถคำนวณได้หรือf(50)ไม่ แต่น่าเสียดายที่ Windows Update รีบูตเครื่องพีซีของฉันก่อนที่จะสามารถเสร็จสิ้นได้
Neil

คุณลองเดินแถวเดียวหรือไม่?
edc65

@ edc65 ขออภัย แต่ฉันไม่ชัดเจนว่าคุณกำลังแนะนำอะไรและเพราะอะไร
Neil

ฉันเห็น 2 แผนที่แต่ละคนสแกนaอาร์เรย์ คุณไม่สามารถรวมการประเมินในแลมบ์ดา 2 และใช้เวลาขั้นต่ำได้หรือไม่
edc65

@ edc65 อ่าใช่ด้วยเหตุผลบางอย่างที่ฉันคิดว่าการทำรังขั้นต่ำจะไม่ถูกกว่า แต่ฉันต้องแทนที่(i+=2)ด้วยอันอื่น++iดังนั้นฉันจึงประหยัดได้ทั้งหมด 12 ไบต์ขอบคุณ!
Neil

5

Pari / GP , 66 ไบต์

พอร์ตของคำตอบ Python ของ Dennis :

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

ลองออนไลน์!


Pari / GP , 72 ไบต์

อีกต่อไป แต่มีประสิทธิภาพมากขึ้น:

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

ลองออนไลน์!


1
เดนนิสดีขึ้นวิธีการของเขาและการใช้ที่สามารถช่วยให้คุณประหยัด 11 f(n)=vecmin(concat(n,[f(j)+f(n\j)+f(n%j)|j<-[2..n-1]]))ไบต์:
Jonathan Allan

4

Pari / GP , 213 ไบต์

แก้ไข:ฉันได้รับการตีอย่างรุนแรง

f(n)={d;n<6&return(n);if(n<=#a,a[n]&return(a[n]),a=vector(n));for(i=1,n-1,a[i]||a[i]=f(i));a[n]=min(vecmin(vector(n\2,k,a[k]+a[n-k])),if(isprime(n),n,vecmin(vector((-1+#d=divisors(n))\2,i,a[d[i+1]]+a[d[#d-i]]))))}

ลองออนไลน์!


3

Python 2 , 181 ไบต์

def F(N,n,s="",r=""):
 try:
	if n<1:return(eval(s)==N)*0**(`11`in s or"**"in s)*s
	for c in"()+*1":r=F(N,~-n,s+c)or r
 except:r
 return r
f=lambda N,n=1:F(N,n).count(`1`)or f(N,-~n)

ลองออนไลน์!


@ pizzapants184 ฟังก์ชั่นหลักfจะต้องไม่ระบุชื่อเนื่องจากจะเรียกตัวเองซ้ำ ๆ
Jonathan Frech

ขอโทษด้วยที่ฉันไม่เห็น
pizzapants184

2

ภาษา Wolfram (Mathematica) , 59 ไบต์

บันทึก 3 ไบต์ด้วย Martin Ender ใช้การเข้ารหัส CP-1252 โดยที่±หนึ่งไบต์

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

ลองออนไลน์!


2
การใช้±แทนการfบันทึก 3 ไบต์โดยสมมติว่าซอร์สถูกเข้ารหัสใน CP 1252: tio.run/##y00syUjNTSzJTE78///QRkNbQ@tDG/PirWx9M/ …
Martin Ender

1
ทำงานไม่ถูกต้องสำหรับอินพุต 353942783
Misha Lavrov

1

Perl 5 , -p 78 ไบต์

79 ไบต์ในการนับแบบเก่า ( +1สำหรับ-p)

ความจริงที่ว่า Perl จะต้องใช้สิ่งพิเศษ$สำหรับการเข้าถึงสเกลาร์ทุกครั้งทำให้ความยาวของกอล์ฟเพิ่มขึ้นอย่างมาก ...

วิธีนี้ส่วนใหญ่เหมือนกับวิธีอื่น ๆ ที่โพสต์ไปแล้ว (ลองคูณและสร้างหมายเลขเป้าหมายให้ถูกที่สุด) อย่างไรก็ตามมันไม่ได้ลดการจ่ายซ้ำ ๆ ซ้ำ ๆ ดังนั้นจึงสามารถใช้สำหรับอินพุตที่ค่อนข้างใหญ่ได้

นอกจากนี้ยังไม่พยายามลดค่าใช้จ่ายในการสร้างหมายเลขด้วยการเพิ่มหรือทวีคูณเนื่องจากค่า Perl 5 ไม่มีการminเรียงตัวในตัวและการเรียงลำดับตัวเลขเป็น looooooong (เท่าที่เห็นจากการเรียงลำดับในรหัส) ฉันแค่สมมุติว่าตัวเลขนั้นเป็นปัจจัยของเป้าหมายที่ฉันจะใช้ในการคูณ มีความปลอดภัยเนื่องจากถ้าเช่น3เป็นปัจจัยของ12(ดังนั้นจึงสรุปค่าใช้จ่ายของ3และ12/3) ในภายหลังในลูปจะพิจารณา9=12-3ซึ่งจะไม่เป็นปัจจัยดังนั้น9+3ด้วยค่าใช้จ่ายเช่นเดียวกับที่3+9จะได้รับการพยายามต่อไป อย่างไรก็ตามอาจล้มเหลวสำหรับเป้าหมาย<= 4(ทำเพื่อ1และ2เท่านั้น) การเพิ่ม$_ลงในรายการเพื่อลดการแก้ไขให้น้อยที่สุด ซึ่งน่าเสียดายเพราะฉันไม่ต้องการใช้เคสพื้นฐานเพราะฉันเริ่มต้นแล้ว@; ด้วยค่าเริ่มต้นที่เหมาะสมดังนั้นจึงมีราคา 3 ไบต์

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

ลองออนไลน์!

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