Operasi paling sedikit hingga 100

15

Gambaran

Diberi daftar angka, temukan operasi paling sedikit untuk menghasilkan 100

Memasukkan

String angka, yang mungkin atau tidak dalam urutan numerik. Urutan digit tidak dapat diubah, namun ditambah (+) atau minus (-) operator dapat ditambahkan antara masing-masing sehingga jumlah total sama dengan 100.

Keluaran

Jumlah operator ditambahkan, diikuti oleh urutan penuh digit dan operator. Keduanya dapat dipisahkan oleh spasi, tab, atau urutan baris baru.

Contohnya

sah

Input: 123456789
Keluaran:3 123–45–67+89


Input Tidak Valid : 123456789
Output:
6 1+2+34-5+67-8+9
(Ada beberapa cara untuk menyelesaikan ini dengan operasi yang lebih sedikit)

CyberJacob
sumber
Terkait
Adám
Apakah kita harus menggunakan semua digit? Bisakah kita menggunakan +dan -? Bisakah kita berasumsi bahwa kita akan selalu dapat membuat 100dari input?
TheLethalCoder
6
Beberapa kasus uji lagi akan disambut baik.
Arnauld
2
Bisakah Anda mengonfirmasi bahwa tanda tidak dapat ditambahkan ke digit pertama? Artinya, diberi masukan 299399, apakah -299+399akan valid?
Luis Mendo
1
Apakah '0' digit? Misalnya, apakah '10808' adalah input yang valid? Apakah '1 108-08' merupakan respons yang valid?
Chas Brown

Jawaban:

10

JavaScript (ES6), 153 176 byte

EDIT: Dalam mode non-ketat, JS menginterpretasikan ekspresi numerik 0-awalan sebagai oktal (misalnya 017diuraikan sebagai 15 dalam desimal). Ini adalah versi tetap yang mendukung angka nol di depan.

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

Arnauld
sumber
Bagus, bagaimana dengan 20172117 sebagai input?
mdahmoune
@LuisMendo Sebenarnya, saya pikir jawaban yang diharapkan adalah 2-017-2+117. Tetapi 017adalah notasi oktal di JS, yang memberikan 15 dalam desimal. Jadi kode saya saat ini hanya ditemukan 2-0-17-2+117. Saya akan mencoba mengatasi masalah itu hari ini.
Arnauld
@Arnauld Ah, saya belum melihat solusi lain itu. Menghapus komentar saya
Luis Mendo
@mdahmoune Terima kasih telah membicarakan ini. Sekarang sudah diperbaiki.
Arnauld
3**(l=s.length,l-1)=>3**~-(l=s.length)
l4m2
5

MATL , 37 36 byte

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

Kasing uji membutuhkan waktu sekitar 6 detik dalam TIO.

Cobalah online!

Bagaimana itu bekerja

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
Luis Mendo
sumber
Hebat, bagaimana dengan 299399 sebagai input?
mdahmoune
1
@ mdahmoune 299399tidak memiliki solusi dan karenanya bukan input yang valid (operator ditentukan untuk "di antara" digit, input yang akan membutuhkan di -299+399mana -tidak di antara digit).
Jonathan Allan
@mdahmoune Jika tanda-tanda hanya dapat disisipkan di antara digit (seperti kata teks tantangan), saya pikir tidak ada solusi. Jika mereka juga dapat ditambahkan ke digit pertama, solusinya adalah -299+399, dan dalam hal ini saya perlu sedikit perubahan dalam kode saya . Saya sudah meminta OP untuk klarifikasi
Luis Mendo
Juga patut dicatat bahwa jika itu dimaksudkan untuk menjadi sebelum dan di antara maka contoh 123456789harus memiliki hitungan operator 4tidak 3.
Jonathan Allan
@mdahmoune OP telah mengkonfirmasi bahwa tanda-tanda hanya dapat di antara angka. Jadi kode saya benar dan 299399merupakan input yang tidak valid karena, seperti OP juga telah mengklarifikasi, setiap input harus memiliki setidaknya satu solusi
Luis Mendo
3

[Python 2], 164 158 byte

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)

Cobalah online!

Ambil N sebagai string angka; mengembalikan tuple (numOps, expressionString).

Pada dasarnya pendekatan yang sama dengan yang lain; menggunakan itertools.product untuk membangun "kasus" individu misalnya untuk N == '1322', sebuah "kasus" akan ('-','','+'), dan akan mengevaluasi '1-32 + 2'.

Melempar ValueError jika input tidak valid (tapi saya pikir OP tidak menjamin input tidak valid).

Chas Brown
sumber
3

PHP, 166 171 byte

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

Jalankan sebagai pipa dengan -nRatau uji secara online .

menggunakan angka yang diformat untuk mengurutkan hasil ->
dapat mencetak blanko terkemuka (dan mungkin gagal untuk input dengan lebih dari 99 digit; menambah angka pada %2duntuk memperbaiki).

tidak lebih dari 10 digit, 161 byte

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

kerusakan

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
Titus
sumber
3

Jelly , 32 byte

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

Program lengkap yang ditampilkan menggunakan operator Jelly (_ bukan -).

Catatan: Untuk tampil -dalam output alih-alih _(bukan keharusan) tambahkan ⁾_-yantara Fdan ( ⁾_-adalah pasangan karakter literal ['_','-']dany merupakan atom "translate" diad).

Bagaimana?

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

Cobalah online!

Jonathan Allan
sumber
2

Mathematica, 136 146 149 156 165 166 byte

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

Pengembalian {3, 123-45-67+89}misalnya.

Kasing tes membutuhkan waktu sekitar 0,09 detik untuk diselesaikan.

Keyu Gan
sumber
2

Python 2 , 256 230 208 205 172 171 170 165 byte, metode berulang

  • 33 berkat Chas Brown
  • Satu byte yang disimpan saat diganti len(a)olehw
  • Satu byte yang disimpan saat diganti z-=1;d=zolehd=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)

Cobalah online!

Penjelasan kecil Menggunakan representasi dalam basis 3, kode interleave digit dengan operator {'+', '-', concatenation} sesuai dengan semua kemungkinan kombinasi.

Python 2 , 167 byte, metode rekursif

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)

Cobalah online!

Beberapa output

"399299"    --> (1, '399-299')
"987654321" --> (4, '98-76+54+3+21')
"1111111"   --> (3, '1+111-1-11')
mdahmoune
sumber
1
Saya suka menggunakan divmod! Beberapa golf yang bisa saya lihat: ganti list(input())dengan just input(), karena sebuah string sudah dapat menyimpan 6 byte; ganti b.count('+')+b.count('-')dengan len(b)-len(a)untuk menyimpan 12 byte; dan ganti chr(r+43)dengan chr(r+43)*(d>0!=r-1)dan kemudian Anda dapat menghapus baris b=b[:-1].replace(',','')untuk menghemat net 15 byte ( (d>0!=r-1)setara dengan (d>0 and 0!=r-1)).
Chas Brown
2

Brachylog , 36 byte

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

Cobalah online!

Lebih dari setengahnya adalah untuk mendapatkan format output yang benar. Logika inti yang sebenarnya hanya:

15 byte

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

Cobalah online!

Ini mengembalikan daftar seperti [123, –45, –67,89]. Ekspresi adalah jumlah dari elemen, dan jumlah operator adalah 1 kurang dari panjang daftar.

~cLhℕ∧100~+Lhampir berfungsi untuk 12 byte ( Coba online! ) - tetapi terlalu lambat untuk menangani input 9 digit penuh pada TIO, dan yang lebih penting, gagal untuk input seperti 10808- Brachylog terlalu pintar untuk membagi angka untuk memimpin nol, jadi tidak t melihat partisi [108, -08].

sundar - Pasang kembali Monica
sumber
1

Haskell , 180 178 byte

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]

Cobalah online! Penggunaan: g "123456789"hasil (3,"123-45-67+89").

#membuat daftar semua istilah yang mungkin, ?mengevaluasi suatu istilah dan gmenyaring istilah-istilah yang mengevaluasi ke 100 dan mengembalikan yang dengan jumlah minimum operan.

Laikoni
sumber
0

Jelly , 27 byte

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

Cobalah online!

Tidak bisa mengatakan saya tidak mengambil beberapa petunjuk dari jawaban Jonathan Allan yang lebih tua. ;-)

Dibandingkan dengan jawabannya, yang ini hanya dua byte lebih pendek (30), bukan lima, jika kita membuat perbandingan yang adil karena pembaruan bahasa:

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

Jika kita membandingkan cara lain (versi yang lebih baru dan bukan yang lebih lama), perbedaannya sama (menjadi 29 byte, terlihat di bawah):

ŒṖżⱮL’⁾+_ṗƲ$€ẎFV=ȷ2ƲƇLÞḢFṄḟ³L
Erik the Outgolfer
sumber