Jumlah yang disimpulkan sendiri

12

Ubah angka menjadi jumlah digit

Bukan jumlah berapa pun: kami membutuhkan jumlah terpendek
Bukan angka apa pun: Anda hanya dapat menggunakan angka itu

Contoh
Anda akan diberikan sebagai input integern>0

Katakan saja n=27. Anda harus mengekspresikan 27sebagai jumlah , hanya menggunakan digit[2,7] , sesingkat mungkin. Anda tidak harus menggunakan semua digit dari angka yang diberikan!

Jadi 27=2+2+2+7+7+7. Kami kemudian mengambil digit tersebut dan menghitungnya : [2,2,2,7,7,7].
Jawaban akhir untuk n=27is6

Satu contoh lagi untuk n=195mendapatkan jumlah terpendek kita harus menggunakan digit berikut:
[5,5,5,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9,9]dan jawabannya adalah23

Tantangan

Diberikan bilangan bulat n>0, output jumlah minimum digit (terkandung dalam nomor) yang meringkas hingga nomor ini

Uji Kasus

Input->Output

1->1  
2->1  
10->10  
58->8  
874->110  
1259->142  
12347->1765  
123456->20576  
3456789->384088  

Ini adalah Jawaban terpendek dalam byte menang!


sumber
Apakah ada angka yang tidak bisa dijumlahkan untuk diri mereka sendiri / akan mereka masukan?
Stephen
1
@Stephen Mereka semua bisa!
7
@Stephen Karena setiap angka dapat dinyatakan sebagai d_0 + 10 * d_1 + 100 * d_2, dll ...
geokavel
Bisakah kita mengambil input sebagai string, char-array atau integer-array?
Kevin Cruijssen
1
@KevinCruijssen String tidak apa-apa. array-array atau integer-array tidak.

Jawaban:

4

Sekam , 12 byte

Lḟo=⁰ΣṁΠḣ∞d⁰

Menangani angka dua digit dengan cukup cepat. Cobalah online!

Penjelasan

Lḟo=⁰ΣṁΠḣ∞d⁰  Input is n, say n = 13.
          d⁰  Digits of n: [1,3]
         ∞    Repeat infinitely: [[1,3],[1,3],[1,3],[1,3]...
        ḣ     Prefixes: [[],[[1,3]],[[1,3],[1,3]],[[1,3],[1,3],[1,3]],...
      ṁ       Map and concatenate
       Π      Cartesian product: [[],[1],[3],[1,1],[3,1],[1,3],[3,3],[1,1,1],[3,1,1],...
 ḟo           Find the first element
     Σ        whose sum
   =⁰         equals n: [3,3,3,3,1]
L             Return its length: 5
Zgarb
sumber
2

Pyth , 12 byte

lef!-TsM`Q./

Cobalah online!

Sayangnya kesalahan memori pada input sebesar 58.

Penjelasan

lef!-TsM`Q./
          ./    All lists of integers that sum to [the input]
  f             Filter for:
    -TsM`Q           Remove all occurrences of the digits in the input
   !                 Check if falsey (i.e. an empty list)
le              Length of the last occurrence, which is the shortest because all the
                filtered partitions share the same digit pool
notjagan
sumber
maukah Anda menambahkan penjelasan?
Jonah
@Jonah Explanation ditambahkan.
notjagan
1
Terima kasih. Menarik bahwa Pyth memiliki primitif yang pada dasarnya menyelesaikan masalah dalam./
Jonah
Alternatif 12-byte: lef<.{TjQ;./(filter - subset yang tepat - dari digit input)
Tn. Xcoder
2

Mathematica, 78 byte

(t=1;While[(s=IntegerPartitions[x=#,t,IntegerDigits@x])=={},t++];Tr[1^#&@@s])&  

menemukan test case terakhir dalam 5 detik

J42161217
sumber
Sedikit lebih pendek:Length@IntegerPartitions[#, All, Sort@DeleteCases[0]@IntegerDigits@#, 1][[1]] &
Kuba
2

R , 78 byte

function(n){while(all(F-n)){F=outer(F,n%/%10^(0:nchar(n))%%10,"+")
T=T+1}
T-1}

Cobalah online! (versi golf)

Algoritma brute force murni, jadi itu tidak benar-benar menyelesaikan semua kasus uji, dan saya pikir itu mencoba mengalokasikan 40.000 GB untuk kasus uji terakhir ...

Tdi R default untuk 1jadi kami mendapatkan kesalahan off-by-one yang kami perbaiki pada langkah kembali, tetapi kami juga mendapatkan Fdefault 0mana yang terbayar.

Penjelasan tanpa ombak:

function(n){
 d <- n%/%10^(0:nchar(n))%%10   # digit list with a 0 appended at end
 d <- unique(d[d>0])            # filter zeros (not technically necessary)
                                # and get unique digits
 x <- 0                         # storage for sums
 i <- 0                         # counter for number of sums done
 while(!any(x==n)){             # until we find a combination
  x <- outer(x,d,"+")           # take all sums of x and d, store as x
  i <- i + 1}                   # increment counter
i}                              # return counter

Cobalah online! (versi kurang golf)

Giuseppe
sumber
2

Python 2, 168 155 144 byte

Ini bukan terpendek itu bisa, tapi sebaiknya-pertama dan tidak nyata buruk, runtime bijaksana.

n=input()
g=sorted(set(n)-{0})[::-1]
def h(k):
 if k<0:return
 if`k`in g:return 1
 for d in g:
  f=h(k-int(d))
  if f:return 1+f
print h(int(n)) 

The filter(None...adalah untuk menghapus 0 sebagai digit, yang saya pelajari saya bisa melakukan sementara membuat ini.

Masalah terbesar adalah bingkai python stack, yang secara realistis tidak memungkinkan saya untuk menjalankan ini pada input terbesar. Jadi, ini bukan solusi yang valid, sungguh, saya bermain-main dengan meningkatkan batas rekursi yang hanya menyebabkan seg-kesalahan. Ini harus dilakukan dengan loop dan stack atau dengan kecerdasan lebih banyak untuk bekerja dengan python.

sunting: Terima kasih kepada caird dan Chas Brown selama 13 byte!

Backerupper
sumber
Anda dapat menggunakan inputdan meminta input untuk dikelilingi dengan tanda kutip.
caird coinheringaahing
2
Sangat bisa diterima untuk gagal karena keterbatasan fisik, asalkan berhasil dalam teori, dan ini berhasil.
Jonathan Allan
Simpan 9 byte dengan mengganti filter(None,sorted(map(int,set(n)))[::-1])dengan sorted(set(map(int,n))-{0})[::-1](meskipun Nonehal ini cukup bagus untuk diketahui).
Chas Brown
@ ChasBrown Dalam kebanyakan kasus, Anda dapat menggunakan filter(len,...)daftar dan string dan filter(abs,...)untuk integer dan float.
Ovs
0

Sekam , 13 byte

Cukup tidak efisien

VVo=⁰ΣMṖNṘ⁰d⁰

Cobalah online!

H.Piz
sumber
0

JavaScript (ES6), 82 byte

f=(n,l=0,a=n,[c,...b]=a)=>n?1/c?Math.min(!+c|+c>n?1/0:f(n-c,l+1,a),f(n,l,b)):1/0:l
<input type=number oninput=o.textContent=f(this.value)><pre id=o>

Mengambil input sebagai string.

Neil
sumber
Bisakah Anda jelaskan mengapa Anda menggunakan 1/0?
Zacharý
1
@ Zacharý Saya ingin jumlah terpendek, yaitu jumlah minimum digit. Upaya yang mengarah ke solusi yang tidak valid tidak boleh dihitung, jadi untuk mengecualikannya, skor mereka Infinity, yang tidak memengaruhi minimum.
Neil
Oh, tidak sadar itu rekursif.
Zacharý
@ Zacharý Pada f=awalnya adalah petunjuk besar, karena Anda tidak membutuhkannya untuk lambda non-rekursif .
Neil
0

Ruby , 70 byte

->n{w,s=n.digits,0;s+=1while !w.product(*[w]*s).find{|x|x.sum==n};s+1}

Sangat lambat, coba semua kombinasi yang mungkin, tambah ukurannya hingga kita menemukan solusi.

Terima kasih Dennis untuk Ruby 2.4 di TIO.

Cobalah online!

GB
sumber
0

Jelly , 23 byte

D;0ṗµḟ€0
ÇS€=µT
Çị1ĿL€Ṃ

Cobalah online!

Ini sangat tidak efisien, sehingga tidak berjalan untuk kasus uji setelah yang ketiga di TIO karena batas waktu> _ <

Segala kiat bermain golf dipersilakan!

Zacharý
sumber
0

Python 2 , 183 176 172 166 161 byte

def f(n,D=0,p=0,b=0):
	D=D or set(map(int,`n`))-{0}
	d=min(D);c=0;D=D-{d}
	q=[p+n/d,b][n%d>0]
	while c<min(D or{0}):q=b=f(n-c*d,D,p+c,b);c+=1
	return[q,b][q>b>0]

Cobalah online!

Lebih lama dari jawaban Python yang lain, tetapi melakukan semua test case digabung plus 987654321di bawah satu detik pada TIO.

Mengambil keuntungan dari kenyataan bahwa jika d1<d2angka, maka perlu paling banyak d2-1 d1jumlahnya (karena d2contoh d1dapat diganti dengan d1contoh d2untuk jumlah yang lebih pendek). Jadi, mengurutkan digit dalam urutan menaik, ada "hanya" 9! = 362880jumlah yang paling mungkin untuk dipertimbangkan; dan kedalaman rekursi maksimum 9(terlepas dari nilai n).

Chas Brown
sumber
0

Haskell , 91 byte

f n=[read[c]|c<-show n,c>'0']#n!!0
s#n|n>0,x:m<-(s#).(n-)=<<s=[1+minimum(x:m)]|1<3=[0|n==0]

Cobalah online! Contoh penggunaan: f 58hasil 8. Cepat untuk angka dua digit, sangat lambat untuk input yang lebih besar.

Fungsi fmengubah nomor input nmenjadi daftar digit saat memfilter angka nol. Kemudian daftar ini dan ndirinya sendiri diserahkan ke (#)fungsi, yang mengembalikan daftar tunggal. !!0mengembalikan elemen daftar tunggal ini.

(#)menggunakan daftar tunggal dan kosong sebagai jenis opsi. Diberikan masukan dari n=58dan s=[5,8], idenya adalah untuk mengurangi semua digit sdari n, kemudian menerapkan secara rekursif (#)dan memeriksa digit mana yang menghasilkan jumlah langkah minimum dan mengembalikan satu ditambah hasil minimum ini sebagai hasilnya. Bagian pertama dihitung dengan (s#).(n-)=<<s, yang sama dengan concat(map(s#)(map(n-)s)). Jadi, dalam contoh kita pertama [58-5,58-8]dihitung, diikuti oleh [[5,8]#53,[5,8]#50]yang menghasilkan [[7],[7]]atau [7,7]setelah concat. Hasilnya dicocokkan pada pola x:muntuk memastikan daftar memiliki setidaknya satu elemen ( minimumgagal jika tidak), maka daftar singleton 1 ditambah minimum hasil dikembalikan. Jikanlebih kecil nol atau panggilan rekursif mengembalikan daftar kosong, kami berada di cabang pencarian yang gagal dan daftar kosong dikembalikan. Jika n==0cabang berhasil dan [0]dikembalikan.


Haskell , 101 byte

f n=[d|d<-[9,8..1],show d!!0`elem`show n]#n!!0
s@(d:r)#n|n>=d,[x]<-s#(n-d)=[x+1]|1<3=r#n
s#n=[0|n==0]

Cobalah online! Pendekatan yang jauh lebih efisien, memeriksa semua kasus uji dalam waktu kurang dari satu detik.

Kali ini, daftar digit input dihitung dalam urutan menurun, yang memungkinkan (#)untuk mencoba menggunakan digit terbesar sesering mungkin, lalu terbesar kedua, dan seterusnya hingga solusi ditemukan. Solusi pertama yang ditemukan dengan cara ini juga dijamin sebagai yang terkecil.

Laikoni
sumber