Jumlah digit 1 hingga 7

21

Tantangan

Diberikan bilangan bulat positif Nyaitu 28 atau di atas, mengeluarkan daftar angka yang menjumlahkan Nyang menggunakan setiap digit 1melalui 7tepat satu kali. Anda dapat memberi sebagai program atau fungsi.

Digit dapat muncul sendiri atau digabungkan, selama Anda menggunakan masing-masing satu kali tanpa pengulangan. Misalnya, [12, 34, 56, 7]valid, apa adanya [1, 27, 6, 4, 35]dan [1234, 567], tetapi tidak [123, 34567]atau [3, 2, 1476]. Urutan nomornya terdaftar tidak masalah.

Jika Ntidak dapat dibuat dengan 1-7, kembalikan atau hasilkan apa-apa.

Informasi lainnya

  • Ini adalah kode golf, jadi kode terpendek dalam byte pada hari Kamis tanggal 15 Oktober menang.

  • Ajukan pertanyaan di komentar.

  • Apa pun yang saya tidak tentukan dalam tantangan terserah Anda.

  • Celah standar tidak diijinkan.

Contohnya

Ini dapat menghapus segala kebingungan:

Memasukkan

28

Keluaran

[1, 2, 3, 4, 5, 6, 7]

Memasukkan

100

Keluaran

[56, 7, 4, 31, 2]

Memasukkan

1234567

Keluaran

[1234567]

Memasukkan

29

Keluaran

Tidak ada, 29 tidak valid.

Memasukkan

1891

Keluaran

[1234, 657]

Memasukkan

370

Keluaran

[15, 342, 7, 6]

Saya akan menghasilkan lebih banyak jika dibutuhkan.

Berikut adalah pastebin dari semua angka yang mungkin dibuat dengan tujuh angka ini, milik FryAmTheEggman.

The_Basset_Hound
sumber
Untuk apa hasilnya 29?
Geobits,
4
Jika Anda ingin output tidak menjadi apa-apa, jangan masukkan (N/A)sebagai output.
mbomb007
1
@LukStorms [1234566, 1]bukan output yang valid, karena 6 diulang. Anda tidak boleh mengulangi angka dalam output.
The_Basset_Hound
2
Mungkin »... daftar angka yang dibuat dari angka desimal 1 hingga 7 yang jumlah hingga N« adalah kata-kata yang lebih jelas daripada yang saat ini dalam pertanyaan.
Paŭlo Ebermann
3
Untuk solusi kekuatan sedikit kurang brute: Ini sama dengan menetapkan koefisien power-of-10 untuk masing-masing 1, ..,, 7sehingga ada setidaknya sebanyak 1's sebagai 10' s, setidaknya sebanyak 10's sebagai 100' s, dan sebagainya.
xnor

Jawaban:

9

Pyth, 18 14 byte

hfqSjkTjkS7./Q

Terima kasih kepada @isaacg untuk bermain golf 2 byte dan membuka jalan untuk 2 lebih.

Kode akan macet jika tidak menghasilkan output, yang menyebabkan tidak ada output yang dihasilkan.

Ini akan bekerja untuk input ish kecil jika Anda cukup sabar, dan untuk input yang lebih besar jika diberikan cukup waktu dan memori.

Untuk memverifikasi bahwa kode bekerja sebagaimana dimaksud, Anda dapat mengganti 7dengan 3untuk jumlah dari angka 1 sampai 3 . Klik di sini untuk test suite.

Contoh berjalan

$ time pyth/pyth.py -c 'hfqSjkTjkS7./Q' <<< 28
(1, 2, 3, 4, 5, 6, 7)

real    4m34.634s
user    4m34.751s
sys     0m0.101s
$ time pyth/pyth.py -c 'hfqSjkTjkS7./Q' <<< 29 2>/dev/null

real    9m5.819s
user    9m6.069s
sys     0m0.093s

Bagaimana itu bekerja

           ./Q    Compute all integer partitions of the input.
 f                Filter the integer partitions:
    jkT             Join the integers with empty separator.
   S                Sort the characters of the resulting string.
      jkS7          Join [1, ..., 7] with empty separator.
  q                 Check both results for equality.
                  Keep the partition of `q' returned True.
h                 Retrieve the first element of the filtered list.
                  For a non-empty list, this retrieves the solution.
                  For the empty list, it causes an error and produces no output.
Dennis
sumber
2
Sudah selesai dilakukan dengan baik! Pendekatan yang cukup inovatif. `` `MS7`` lebih pendek dari r\1\8. Juga @ .. 0sama dengan h.
isaacg
@isaacg Terima kasih! Saya tidak yakin bagaimana saya ketinggalan h, tetapi saya tidak tahu Anda bisa menggunakan Scara itu. (Referensi char di interpreter online tidak menyebutkannya.) jkS7Tampaknya bahkan lebih pendek, karena saya tidak perlu slagi.
Dennis
5

Python 3, 109

def f(n,s=set('1234567'),l='0,'):[f(n,s-{x},l+x+c)for c in(',','')for x in s]or n-sum(eval(l))or~print(l[2:])

Fungsi yang mengambil angka dan menghasilkan tuple di sejenisnya 123,4567,. Ya, ini adalah tuple yang valid.

Idenya adalah untuk menghasilkan semua string yang mungkin seperti 43,126,7,5,yang memiliki digit 1melalui 7dipisahkan oleh koma, tanpa dua koma berturut-turut. Evaluasi ungkapan ini sebagai tuple, dan jumlahnya sama dengan n, cetak dan akhiri dengan kesalahan.

Untuk membangun semua string seperti itu, kami melacak serangkaian skarakter yang akan digunakan, dan mencoba menambahkan masing-masing dengan koma, yang membuat digit mengakhiri entri, atau tanpa, dalam hal ini digit selanjutnya akan bergabung dengannya.

Hubungan arus pendek yang digunakan untuk memeriksa bahwa skosong karena daftar-comp kosong, dan bahwa n==sum(eval(l)), dalam hal ini kita mencetak ldan mengakhiri dengan kesalahan dengan mengambil ~dari Nonekembali dengan mencetak (terima kasih kepada Sp3000 untuk ini.).

Saya percaya bahwa dalam Python 3.5, dua karakter dapat disimpan dengan menulis s={*'1234567'}(terima kasih Sp3000).

Ada beberapa gangguan kecil yang memakan chars. Salah satunya adalah bahwa dalam kasus yang lterlihat seperti 1234567tanpa koma, itu diurai sebagai nomor tunggal dan panggilan summemberikan kesalahan. Ini ditangani dengan retasan mulai ldengan elemen 0dan melepasnya saat mencetak. Ini biaya 6 karakter.

Iterasi di catas koma dan string kosong bertele-tele menjengkelkan for c in(',',''), karena Python 3 tidak mengizinkan tuple ini telanjang. Saya ingin ada beberapa char ?yang diabaikan dalam jumlah untuk melakukan ',?'kurang dari 4 karakter, tapi sepertinya tidak ada char seperti itu.


Metode lama:

Python 2, 117

def f(n,s={1,2,3,4,5,6,7},l=[],p=0):
 if{n,p}|s=={0}:print l;1/0
 if p:f(n-p,s,l+[p])
 for x in s:f(n,s-{x},l,p*10+x)

Menentukan fungsi yang mengambil nomor dan mencetak daftar.

Idenya adalah menggunakan rekursi untuk mencoba setiap cabang. Jalur variabel adalah

  • Jumlah yang tersisa ndibutuhkan
  • Set digit yang stersisa untuk digunakan
  • Daftar langka yang dibuat sejauh ini
  • Jumlah saat ini sebagian terbentuk p

Saat n==0dan skosong, cetak ldan akhiri karena kesalahan.

Jika angka yang terbentuk sebagian saat pini bukan nol, coba tambahkan ke daftar dan hapus dari jumlah yang tersisa.

Untuk setiap digit yang xdapat kita gunakan s, coba tambahkan pdan hapus s.

Tidak
sumber
4

Pyth, 23

#iRThfqQsiR10Ts./M.pS7q

Brute force naif, terlalu lambat online, membutuhkan waktu sekitar satu menit di komputer saya. Menggunakan pola "loop selamanya sampai pengecualian" yang umum dari golf pyth di mana mengakses daftar kombinasi yang difilter menyebabkan kesalahan pada angka yang tidak mungkin, misalnya 29.

Output seperti daftar pythonic, mis

1891
[1234, 657]
100
[1, 2, 34, 56, 7]
370
[12, 345, 6, 7]

Ini adalah pasta dari semua angka 10136 yang dapat dibuat dengan cara ini.

FryAmTheEggman
sumber
Bolehkah saya menggunakan tautan pastebin sebagai contoh?
The_Basset_Hound
@The_Basset_Hound Tentu saja, silakan.
FryAmTheEggman
3

Python 2.7, 178 172 169 byte

n=input()
for i in range(8**7):
 for j in len(set('%o0'%i))/8*range(128):
    s=''
    for c in'%o'%i:s+='+'[:j%2*len(s)]+c;j/=2
    if eval(s)==n:print map(int,s.split('+'));1/0

Perhatikan bahwa tiga baris terakhir seharusnya diindentasi dengan tab tetapi saya tidak tahu bagaimana melakukannya di editor ini.

Sunting: Ratakan satu lapisan sarang dengan bantuan Sp3000

xsot
sumber
Sayangnya,
menelanjangi
Ah oke, masih mencari cara di sekitar situs ini.
xsot
3

JavaScript (ES6), 165 196

Sunting Dipendekkan sedikit. Bisa menggunakan lebih pendek eval, tapi saya suka itu cepat

Brute force, memalukan lebih lama dari versi Pith, tetapi lebih cepat. Tes menjalankan cuplikan di bawah ini di peramban yang mendukung EcmaScript 6.

f=z=>{for(r=i=1e6;r&&++i<8e6;)for(m=/(.).*\1|[089]/.test(w=i+'')?0:64;r&&m--;t.split`+`.map(v=>r-=v,r=z))for(t=w[j=0],l=1;d=w[++j];l+=l)t+=l&m?'+'+d:d;return r?'':t}

function test() { O.innerHTML=f(+I.value) }

test()

// Less golfed

f=z=>{
  for(r=i=1e6; r&&++i<8e6;)
    for(m=/(.).*\1|[089]/.test(w=i+'')?0:64; r&&m--; t.split`+`.map(v=>r-=v,r=z))
      for(t=w[j=0],l=1;d=w[++j];l+=l)
        t+=l&m?'+'+d:d;
  return r?'':t
}
<input id=I value=28><button onclick=test()>-></button><span id=O></span>

edc65
sumber
Tidak perlu malu untuk lebih lama karena bahasa, saya sangat menikmati jawaban JS Anda, +1
FryAmTheEggman
1

Python 2, 270 268 byte

from itertools import*;P=permutations
x,d,f=range(1,8),[],input()
r=sum([[int(''.join(str(n)for n in i))for i in list(P(x,j))]for j in x],[])
z=1
while z:
 t=sum([[list(j)for j in P(r,z)]for i in x],[])
 v=filter(lambda i:sum(i)==f,t)
 if v:print v[0];break
 else:z+=1

Masih berusaha bermain golf.

Loop ini sampai ditemukan kecocokan.

Zach Gates
sumber
import asjarang diperlukan - bisa Anda lakukanfrom itertools import*;P=permutations
Sp3000
Ini lebih pendek untuk digunakan map(str,i)daripada pemahaman daftar, dan Anda dapat membuat daftar r secara langsung daripada dengan meratakan daftar bersarang:, r=[int(''.join(map(str,i)))for j in x for i in P(x,j)]dan hal serupa untuk t.
Ruth Franklin
Anda dapat menggunakan `n`sebagai ganti str(n), karena ntidak akan pernah berada di atas bilangan bulat maksimum.
mbomb007
1

Haskell (145 byte)

main=getLine>>=print.head.f[1..7].read
f[]0=[[]]
f b s=[n:j|(n,g)<-m b,j<-f g$s-n]
m b=[(d+10*z,g)|d<-b,(z,g)<-(0,filter(/=d)b):m(filter(/=d)b)]

Gunakan rekursi.

Tidak Terkumpul (337 bytes):

delete d = filter (/= d)
main = getLine >>= print . (`form` [1..7]) . read

form s [] | s == 0    = [[]]
form s ds | s <= 0    = []
form s ds | otherwise = [n:ns | (n, ds') <- makeNumbers ds, ns <- form (s-n) ds']

makeNumbers [] = []
makeNumbers ds  = [(d + 10 * n',ds') | d <- ds, (n',ds') <- (0,delete d ds):makeNumbers (delete d ds)]
jkabrg
sumber
0

Scala, 195 byte

Ini bukan yang paling efisien dan butuh lebih dari 15 menit untuk mendapatkan output selama 29 tetapi berhasil

def g(s: Seq[Int]): Iterator[Seq[Int]]=s.combinations(2).map(c=>g(c.mkString.toInt +: s.filterNot(c.contains))).flatten ++ Seq(s)
def f(i: Int)=(1 to 7).permutations.map(g).flatten.find(_.sum==i)

Ini beberapa output

scala> f(100)
res2: Option[Seq[Int]] = Some(Vector(46, 35, 12, 7))

scala> f(1891)
res3: Option[Seq[Int]] = Some(Vector(567, 1324))

scala> f(370)
res4: Option[Seq[Int]] = Some(Vector(345, 12, 6, 7))

scala> f(29)
res5: Option[Seq[Int]] = None
JoseM
sumber
0

Ruby, 105 byte

Paksaan! Periksa setiap subset panjang antara 0 dan 7 bilangan bulat antara 1 dan 7654321 dan lihat apakah ada yang cocok dengan kriteria kami. Anda mungkin tidak ingin menunggu ini berakhir.

->n{8.times{|i|[*1..7654321].permutation(i){|x|return x if
x.join.chars.sort==[*?1..?7]&&eval(x*?+)==n}}}

Untuk menjalankan dan memverifikasi algoritme, Anda dapat mempersempit ruang pencarian dengan mengganti 7654321dengan jumlah terbesar yang Anda tahu ada di jawabannya. Misalnya, 56 untuk n = 100, atau 1234 untuk n = 1891. Berikut ini adalah uji coba yang terakhir:

$ ruby -e "p ->n{8.times{|i|[*1..1234].permutation(i){|x|return x if x.join.chars.sort==[*?1..?7]&&eval(x*?+)==n}}}[gets.to_i]" <<< 1891
[657, 1234]
daniero
sumber
0 hingga 7 bilangan bulat? Anda harus menggunakan exaclty 7 integer: 1,2,3,4,5,6,7
edc65
@ edc65 Maksud Anda tepat 7 digit . Hasilnya adalah satu set bilangan bulat, dan ukuran set tergantung pada input.
daniero
Saya tidak berbicara bahasa Ruby, saya kira programnya berhasil, tetapi saya tidak mendapatkan penjelasannya. Jika bilangan bulat Anda kurang dari 1234567, bagaimana Anda mendapatkan 7654321?
edc65
@ edc65 Anda benar, saya harus mengubah nomor itu. Saya akan mencoba menjelaskannya dengan lebih baik juga.
daniero