ดำเนินการน้อยที่สุดถึง 100


15

ภาพรวม

ระบุรายการตัวเลขให้ค้นหาการดำเนินการที่น้อยที่สุดเพื่อสร้าง 100

อินพุต

สตริงตัวเลขซึ่งอาจหรืออาจจะไม่เรียงตามลำดับตัวเลข ไม่สามารถเปลี่ยนลำดับของตัวเลขได้อย่างไรก็ตามอาจมีการเพิ่มตัวดำเนินการบวก (+) หรือลบ (-) ระหว่างกันเพื่อให้ผลรวมทั้งหมดเท่ากับ 100

เอาท์พุต

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

ตัวอย่าง

ถูกต้อง

อินพุต: 123456789
เอาต์พุต:3 123–45–67+89


อินพุตไม่ถูกต้อง : 123456789
เอาต์พุต:
6 1+2+34-5+67-8+9
(มีวิธีการแก้ปัญหานี้โดยใช้การดำเนินการน้อยลง)



เราต้องใช้ตัวเลขทั้งหมดหรือไม่? เราสามารถใช้+และ-? เราสามารถสันนิษฐานได้ว่าเราสามารถทำ100จากสิ่งที่นำเข้ามาได้เสมอ?
TheLethalCoder

6
บางกรณีทดสอบเพิ่มเติมจะยินดีมาก
Arnauld

2
คุณสามารถยืนยันได้หรือไม่ว่าสัญญาณนั้นไม่สามารถนำมารวมกับตัวเลขแรกได้ นั่นคือการป้อนข้อมูลที่กำหนด299399จะ-299+399ถูกต้อง?
Luis Mendo

1
ตัวเลขคือ '0' หรือไม่ เช่น '10808' อินพุตที่ถูกต้องคืออะไร? '1 108-08' เป็นคำตอบที่ถูกต้องหรือไม่
Chas Brown

คำตอบ:


10

JavaScript (ES6), 153 176 ไบต์

แก้ไข: ในโหมดที่ไม่เข้มงวด JS ตีความนิพจน์ตัวเลข 0 นำหน้าเป็นฐานแปด (เช่น017แยกเป็น 15 ในทศนิยม) นี่เป็นรุ่นที่แก้ไขแล้วที่รองรับศูนย์นำหน้า

let f =

s=>[...Array(3**(l=s.length,l-1))].map((_,n)=>m=eval((x=s.replace(/./g,(c,i)=>c+['','+','-'][o=(n/3**i|0)%3,j-=!o,o],j=l)).replace(/\b0+/g,' '))-100|j>m?m:(S=x,j),m=l)&&m+' '+S

console.log(f("123456789"))
console.log(f("20172117"))


ดีแล้วมีข้อมูลเกี่ยวกับ 20172117 เป็นอินพุตหรือไม่
mdahmoune

@LuisMendo 2-017-2+117อันที่จริงผมคิดว่าคำตอบที่คาดไว้คือ แต่017เป็นสัญกรณ์ฐานแปดใน JS ซึ่งให้ 15 ในทศนิยม 2-0-17-2+117ดังนั้นรหัสปัจจุบันของฉันเท่านั้นพบ ฉันจะพยายามแก้ไขปัญหานั้นในวันนี้
Arnauld

@ Arnauld อ่าฉันไม่เห็นวิธีแก้ปัญหาอื่น กำลังลบความคิดเห็นของฉัน
Luis Mendo

@mdahmoune ขอบคุณที่นำสิ่งนี้ขึ้นมา แก้ไขแล้ว
Arnauld

3**(l=s.length,l-1)=>3**~-(l=s.length)
l4m2

5

MATL , 37 36 ไบต์

n'+-'OhZ^!t2\s&SZ)"G@!vXzU100=?@z3M.

กรณีทดสอบใช้เวลาประมาณ 6 วินาทีใน TIO

ลองออนไลน์!

มันทำงานอย่างไร

n        % Implicitly input a string. Number of elements, say k
'+-'     % Push this string
Oh       % Append char 0. This is treated like ' ' (space)
Z^       % Cartesian power of the three-char string '+- ' raised to k.
         % Gives a matrix where each row is a Cartesian k-tuple
!        % Transpose
t        % Duplicate
2\       % Modulo 2. This turns '+' and '-' into 1, and ' ' into 0
s        % Sum of each column: number of '+' and '-' symbols
&S       % Sort and push the indices of the sorting
Z)       % Apply as column indices. This sorts the columns (k-tuples)
         % by the number of '+' and '-' they contain
"        % For each column, i.e. each k-tuple formed by '+', '-' and ' '
  G      %   Push input string again
  @!     %   Push k-tuple as row vector (string)
  v      %   Concatenate vertically into a 2×k char array
  Xz     %   Remove space (and char 0). Gives a string as result. In this
         %   process, the 2×k array is linearized in column major order 
         %   (down, then across). So the '+' and '-' signs are between 
         %   digits of the input, or at the end
  U      %   Convert to number. This performs the operation determined by
         %   by the '+' and '-' signs and returns the result. A trailing
         %   '+' or '-' sign makes the input invalid, which causes an
         %   empty result
  100=   %   Is it equal to 100?
  ?      %   If so
    @    %     Push current k-tuple
    z    %     Number of nonzeros, i.e. of '+' and '-' signs
    3M   %     Push linearized string without spaces again
    .    %     Break for loop
         %   Implicit end
         % Implicit end
         % Implicitly dispplay stack

เยี่ยมมากแล้ว 299399 เป็นอินพุตได้อย่างไร
mdahmoune

1
@mdahmoune 299399ไม่มีวิธีแก้ปัญหาและดังนั้นจึงไม่ใช่อินพุตที่ถูกต้อง (ตัวดำเนินการถูกระบุว่าให้ไป "ระหว่าง" ตัวเลขนั้นอินพุตนั้นจำเป็นต้องใช้-299+399โดยที่-ไม่ใช่ระหว่างตัวเลข)
Jonathan Allan

@mdahmoune หากเครื่องหมายสามารถแทรกระหว่างตัวเลข (ตามที่ข้อความการท้าทายกล่าว) ฉันคิดว่าไม่มีวิธีแก้ปัญหา หากพวกเขายังสามารถใช้ได้กับหลักแรกแก้ปัญหาคือ-299+399และในกรณีที่ฉันต้องมีการเปลี่ยนแปลงเล็ก ๆ ในรหัสของฉัน ฉันขอ OP เพื่อความกระจ่าง
Luis Mendo

นอกจากนี้ที่น่าสังเกตว่าถ้ามันมีความหมายที่เป็นได้ทั้งก่อนและระหว่างนั้นตัวอย่างเช่น123456789ควรจะมีการนับจำนวนผู้ประกอบการไม่ได้4 3
Jonathan Allan

@mdahmoune OP ยืนยันว่าสัญญาณสามารถอยู่ระหว่างตัวเลขได้เท่านั้น ดังนั้นรหัสของฉันถูกต้องและ299399เป็นอินพุตที่ไม่ถูกต้องเพราะเมื่อ OP ได้ชี้แจงทุกอินพุตควรมีทางออกอย่างน้อยหนึ่งวิธี
Luis Mendo

3

[Python 2], 164 158 bytes

from itertools import*
f=lambda N:min((len(s)-len(N),s)for s in(''.join(sum(zip(N,p+('',)),()))for p in product(('+','-',''),repeat=len(N)-1))if eval(s)==100)

ลองออนไลน์!

รับ N เป็นสตริงตัวเลข ส่งคืน tuple (numOps, expressionString)

โดยพื้นฐานแล้ววิธีการเดียวกับคนอื่น ๆ ; ใช้ itertools.product เพื่อสร้าง "case" ของแต่ละบุคคลเช่นสำหรับ N == '1322', "case" จะเป็น('-','','+')และจะประเมิน '1-32 + 2'

โยน ValueError ถ้าอินพุตไม่ถูกต้อง (แต่ฉันคิดว่า OP รับประกันว่าไม่มีอินพุตที่ไม่ถูกต้อง)


3

PHP, 166 171 ไบต์

for(;$n<3**$e=strlen($x=$argn);eval("return $s;")-100?:$r[]=sprintf("%2d $s",strlen($s)-$e))for($i=0,$s="",$k=$n++;a&$c=$x[$i];$k/=3)$s.="+-"[$i++?$k%3:2].$c;echo min($r);

เรียกใช้เป็นท่อด้วย -nRหรือทดสอบทางออนไลน์ทดสอบออนไลน์

ใช้ตัวเลขที่จัดรูปแบบเพื่อจัดเรียงผลลัพธ์ ->
อาจพิมพ์ช่องว่างนำหน้า (และอาจล้มเหลวในการป้อนข้อมูลที่มีมากกว่า 99 หลักเพิ่มหมายเลขที่%2dจะแก้ไข)

ไม่เกิน 10 หลัก 161 ไบต์

for(;$n<3**$e=strlen($x=$argn);eval("return $s;")-100?:$r[]=(strlen($s)-$e)." $s")for($i=0,$s="",$k=$n++;a&$c=$x[$i];$k/=3)$s.="+-"[$i++?$k%3:2].$c;echo min($r);

ชำรุด

for(;$n<3**$e=strlen($x=$argn); # loop $n up
    eval("return $s;")-100?:        # 2. evaluate term, if 100 then
                                    # prepend number of operations, add to results
        $r[]=sprintf("%2d $s",strlen($s)-$e)
)
                                # 1. create term
    for($i=0,$s="",$k=$n++;         # init variables, increment $n
        a&$c=$x[$i];$k/=3)          # loop through digits/operator index
        $s.="+-"[$i++?$k%3:2].$c;   # prepend operator for base-3 digit (nothing for 2)
echo min($r);                   # print lowest result

3

เยลลี่ 32 ไบต์

L’⁾+_ṗż@€
ŒṖÇ€ẎµFV=ȷ2µÐfLÞḢFṄḟ³L

โปรแกรมเต็มรูปแบบที่แสดงโดยใช้ตัวดำเนินการ Jelly ( _แทน- )

หมายเหตุ:หากต้องการแสดง-ในเอาต์พุตแทน_(ไม่ใช่ข้อกำหนด) ให้เพิ่ม⁾_-yระหว่างFและ( ⁾_-เป็นตัวอักษรคู่ของตัวอักษร['_','-']และyเป็นอะตอม "แปล" แบบ dyadic

อย่างไร?

L’⁾+_ṗż@€ - Link 1, form all sums from a partition: list of lists of characters
                                     e.g. ["12","345","67"]
L         - length                        3
 ’        - decremented                   2
  ⁾+_     - literal ['+','_']
     ṗ    - Cartesian power               ["++","+_","_+","__"]
      ż@€ - zip for €ach (swap @rguments) ["12+345+67","12+345_67","12_345+67","12_345_67"]

ŒṖÇ€ẎµFV=ȷ2µÐfLÞḢFṄḟ³L - Main link: list of characters
ŒṖ                     - all partitions
  Ç€                   - call the last link (1) as a monad for €ach
    Ẏ                  - tighten (flatten by 1 level)
     µ     µÐf         - filter keep if:
      F                -   flatten
       V               -   evaluate as Jelly code (perform the sum)
         ȷ2            -   literal 100
        =              -   equal?
               Þ       - sort by:
              L        -  length
                Ḣ      - head
                 F     - flatten
                  Ṅ    - print that and a newline
                   ḟ³  - filter out the characters from the input
                     L - length (number of operators)
                       - implicit print

ลองออนไลน์!


2

Mathematica, 136 146 149 156 165 166 ไบต์

#&@@Sort[{StringLength@#-e+9!(ToExpression@#-100)^2,#}&/@StringJoin/@(Riffle[b,#]&)/@Tuples[{"","+","-"},(e=Length[b=Characters@#])-1]]&

ผลตอบแทน{3, 123-45-67+89}เช่น

กรณีทดสอบใช้เวลาประมาณ 0.09 วินาทีจึงจะเสร็จสมบูรณ์


2

Python 2 , 256 230 208 205 172 171 170 165 ไบต์วิธีการวนซ้ำ

  • 33ขอบคุณ Chas Brown
  • หนึ่งไบต์ที่บันทึกเมื่อแทนที่len(a)ด้วยw
  • หนึ่งไบต์ที่บันทึกเมื่อแทนที่z-=1;d=zด้วยd=z=z-1
q=[];a=input()
w=len(a);z=n=3**w
while z-n/3:
 d=z=z-1;j=0;b=''
 while d:r=d%3;d/=3;b+=a[j]+chr(r+43)*(d>0!=r-1);j+=1
 if eval(b)==100:q+=[(len(b)-w,b)]
print min(q)

ลองออนไลน์!

คำอธิบายเล็กน้อย โดยใช้การเป็นตัวแทนในฐาน 3 รหัสจะแทรกตัวเลขด้วยตัวดำเนินการ {'+', '-', การต่อข้อมูล} ตามการผสมที่เป็นไปได้ทั้งหมด

Python 2 , 167 ไบต์, วิธีเรียกซ้ำ

def f(s):
 if len(s)==1:return[s]
 b=s[0];q=[]
 for z in f(s[1:]):q+=[b+'+'+z,b+'-'+z,b+z]
 return q
a=input()
print min((len(x)-len(a),x)for x in f(a)if eval(x)==100)

ลองออนไลน์!

เอาท์พุทบางอย่าง

"399299"    --> (1, '399-299')
"987654321" --> (4, '98-76+54+3+21')
"1111111"   --> (3, '1+111-1-11')

1
ฉันชอบการใช้ divmod! กอล์ฟเล็ก ๆ น้อย ๆ ที่ฉันเห็น: แทนที่list(input())ด้วย just input()เนื่องจากสตริงนั้นสามารถบันทึกได้ 6 ไบต์แล้ว แทนที่b.count('+')+b.count('-')ด้วยlen(b)-len(a)เพื่อบันทึก 12 ไบต์ และแทนที่chr(r+43)ด้วยchr(r+43)*(d>0!=r-1)และจากนั้นคุณสามารถลบบรรทัดb=b[:-1].replace(',','')เพื่อบันทึกสุทธิ 15 ไบต์ ( (d>0!=r-1)เทียบเท่า(d>0 and 0!=r-1))
Chas Brown

2

Brachylogขนาด 36 ไบต์

~cịᵐ{|ṅ}ᵐ{+100&{ℕṫ,"+"↻|ṫ}ᵐcbE&kl;E}

ลองออนไลน์!

มากกว่าครึ่งนี้จะได้รูปแบบผลลัพธ์ที่ถูกต้อง ตรรกะหลักที่แท้จริงคือ:

15 ไบต์

~cịᵐ{|ṅ}ᵐ.+100∧

ลองออนไลน์!

ส่งคืนรายการเช่น [123, –45, –67,89] นิพจน์คือผลรวมขององค์ประกอบและจำนวนตัวดำเนินการคือ 1 น้อยกว่าความยาวของรายการ

~cLhℕ∧100~+Lเกือบใช้งานได้ 12 ไบต์ ( ลองออนไลน์! ) - แต่มันช้าเกินกว่าที่จะจัดการกับอินพุต 9 หลักเต็มรูปแบบบน TIO และที่สำคัญกว่านั้นมันล้มเหลวในการป้อนข้อมูลเช่น10808- Brachylog ฉลาดเกินกว่าที่จะแยกตัวเลขให้เป็นศูนย์นำ ไม่เห็นพาร์ติชัน [108, -08]


1

Haskell , 180 178 ไบต์

m#[a]=[[a]]
m#(b:r)|s<-m#r=m(b:)=<<[s,m('+':)s,m('-':)s]
o '-'=(-)
o _=(+)
(p:r)?a|[(b,s)]<-lex r=s?o p a(read b)
_?a=a
g s=minimum[(sum[1|c<-t,c<'0'],t)|t<-map#s,('+':t)?0==100]

ลองออนไลน์! การใช้งาน: อัตราผลตอบแทนg "123456789"(3,"123-45-67+89")

#สร้างรายการคำศัพท์ที่เป็นไปได้ทั้งหมด?ประเมินคำศัพท์และgกรองเงื่อนไขเหล่านั้นซึ่งประเมินเป็น 100 และส่งคืนคำที่มีตัวถูกดำเนินการน้อยที่สุด


0

เยลลี่ , 27 ไบต์

L’““+“_”ṗ⁸żF¥ⱮV⁼ȷ2ƊƇLÞḢṄḟ⁸L

ลองออนไลน์!

ไม่สามารถพูดได้ว่าฉันไม่ได้รับคำแนะนำเล็กน้อยจากคำตอบเก่า ๆ ของ Jonathan Allan ;-)

เปรียบเทียบกับคำตอบของเขาอันนี้สั้นกว่าเพียงสองไบต์ (30) ไม่ใช่ห้าถ้าเราทำการเปรียบเทียบที่ยุติธรรมเนื่องจากการอัพเดทภาษา:

L’““+“_”ṗ⁸żF¥Ð€V⁼ȷ2$$ÐfLÞḢṄḟ⁸L

หากเราเปรียบเทียบวิธีอื่น (เวอร์ชั่นใหม่กว่าเก่ากว่า) ความแตกต่างจะเหมือนกัน (เขาจะกลายเป็น 29 ไบต์ดังที่เห็นด้านล่าง):

ŒṖżⱮL’⁾+_ṗƲ$€ẎFV=ȷ2ƲƇLÞḢFṄḟ³L
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.