Setiap angka dapat direpresentasikan menggunakan urutan sisa panjang yang tak terhingga. Misalnya, jika kita mengambil angka 7, dan melakukan 7mod2
, maka 7mod3
, lalu 7mod4
, dan seterusnya, kita dapatkan 1,1,3,2,1,0,7,7,7,7,....
.
Namun, kita memerlukan urutan sisa sesingkat mungkin yang masih dapat digunakan untuk membedakannya dari semua angka yang lebih rendah. Menggunakan 7 lagi, [1,1,3]
adalah urutan terpendek, karena semua kalimat sebelumnya tidak dimulai dengan [1,1,3]
:
0: 0,0,0,0...
1: 1,1,1,1...
2: 0,2,2,2...
3: 1,0,3,3...
4: 0,1,0,4...
5: 1,2,1,0...
6: 0,0,2,1...
Catatan yang [1,1]
tidak berfungsi untuk mewakili 7, karena itu juga dapat digunakan untuk mewakili 1. Namun, Anda harus menampilkan [1]
dengan input 1.
Input output
Input Anda adalah bilangan bulat non-negatif. Anda harus menampilkan urutan atau daftar urutan sisa minimal seperti yang didefinisikan di atas.
Kasus uji:
0: 0
1: 1
2: 0,2
3: 1,0
4: 0,1
5: 1,2
6: 0,0,2
7: 1,1,3
8: 0,2,0
9: 1,0,1
10: 0,1,2
11: 1,2,3
12: 0,0,0,2
30: 0,0,2,0
42: 0,0,2,2
59: 1,2,3,4
60: 0,0,0,0,0,4
257: 1,2,1,2,5,5
566: 0,2,2,1,2,6,6
1000: 0,1,0,0,4,6,0,1
9998: 0,2,2,3,2,2,6,8,8,10
9999: 1,0,3,4,3,3,7,0,9,0
Berikut adalah 10.000 urutan pertama , jika Anda tertarik (nomor baris dimatikan oleh 1).
Ini adalah kode-golf , jadi buat sesingkat mungkin dalam bahasa favorit Anda. Poin bonus palsu untuk setiap jawaban yang cepat!
sumber
Jawaban:
Mathematica,
6053 byteAgak cepat (menangani 10.000 dalam ~ 0,1 detik, tetapi kemungkinan akan kehabisan memori untuk 100000).
Kode melempar kesalahan tetapi menghitung hasilnya dengan benar.
Penjelasan
Kami telah menemukan sebelumnya dalam obrolan bahwa pembagi yang diperlukan selalu dapat ditentukan sebagai daftar terpendek
{1, 2, ..., n}
yang kelipatannya paling sedikit melebihi input. Argumen singkat mengapa itu adalah: jika LCM kurang dari input, maka mengurangi LCM dari input akan membuat semua pembagi tidak berubah, sehingga representasi tidak unik. Namun, untuk semua input kurang dari LCM, sisanya akan menjadi unik, jika tidak perbedaan antara dua angka dengan sisa yang sama akan menjadi kelipatan yang lebih kecil dari semua pembagi.Adapun kode ... seperti biasa urutan membaca golf Mathematica agak lucu.
Ini memberi kita daftar
[1, 2, 3, ..., n+2]
untuk inputn
. The+2
adalah untuk memastikan bahwa ia bekerja dengan benar untuk0
dan1
.Peta
2~Range~#
(gula sintaksis untukRange[2,#]
) di atas daftar ini, jadi kami dapatkanIni adalah daftar calon pembagi (tentu saja secara umum itu jauh lebih banyak daripada yang kita butuhkan). Sekarang kita menemukan yang pertama dari mereka yang LCM melebihi input dengan:
Sintaks lebih lanjut:
x_
adalah pola yang cocok dengan salah satu daftar dan menyebutnyax
. The/;
menempel syarat untuk pola itu. Kondisi ini adalahLCM@@x>#
tempat@@
menerapkan fungsi ke daftar, yaituLCM@@{1,2,3}
berartiLCM[1,2,3]
.Akhirnya kami hanya mendapatkan semua sisanya, memanfaatkan fakta bahwa
Mod
adalahListable
, yaitu secara otomatis memetakan lebih daftar jika salah satu argumen adalah daftar (atau jika keduanya daftar panjang yang sama):sumber
Jelly , 14 byte
Ini menggunakan fakta bahwa solusi (jika ada) dari sistem kongruensi linier adalah modulo LCM moduli yang unik. Cobalah online! atau verifikasi semua kasus uji .
Bagaimana itu bekerja
sumber
MATL , 24 byte
Terima kasih kepada @nimi karena menunjukkan kesalahan pada versi sebelumnya dari jawaban ini (sekarang diperbaiki)
Ini kehabisan memori dalam kompiler online untuk dua test case terbesar (tetapi bekerja pada komputer dengan 4 GB RAM).
Cobalah online!
Penjelasan
Ini menerapkan definisi secara langsung. Untuk input
n
itu menghitung array 2D yang mengandungmod(p,q)
denganp
dari0
untukn
danq
dari1
ken+1
. Masingp
- masing adalah kolom, dan masing-masingq
adalah satu baris. Misalnya, dengan inputn=7
array iniSekarang kolom terakhir, yang berisi sisa-sisa
n
, adalah elemen-bijaksana dibandingkan dengan setiap kolom array ini. Ini menghasilkandi mana
1
menunjukkan kesetaraan. Kolom terakhir jelas sama dengan dirinya sendiri dan dengan demikian berisi semua. Kita perlu menemukan kolom yang memiliki jumlah awal terbanyak , selain kolom terakhir, dan mencatat jumlah awal tersebutm
,. (Dalam hal ini adalah kolom kedua, yang berisi yangm=3
awal). Untuk tujuan ini, kami menghitung produk kumulatif dari setiap kolom:lalu jumlah masing-masing kolom
dan kemudian urutkan tanpa-semakin dan ambil nilai kedua, yaitu
3
. Ini yang diinginkanm
, yang menunjukkan berapa banyak sisa yang harus kita ambil.sumber
Jelly ,
1311 byteIni tidak akan memenangkan poin brownies kecepatan ... Coba online! atau verifikasi kasus uji yang lebih kecil .
Bagaimana itu bekerja
sumber
Python 3.5,
1179578 byteMembutuhkan Python 3.5 dan sympy (
python3 -m pip install --user sympy
). Kredit ke @ Dennis untuk memberi tahu saya bahwa Python 3.5 memungkinkan*l
trik dengan argumen default.sumber
M>n and l
menjadil*(M>n)
.Python 2,
73706965 byteProgram lengkap. @Dennis menyimpan 4 byte dengan meningkatkan cara penanganan nol.
sumber
Haskell,
66605150 byteContoh penggunaan:
f 42
->[0,0,2,2]
. Ini adalah algoritma yang dijelaskan dalam jawaban @Martin Büttner .Saya akan menyimpan versi sebelumnya untuk referensi, karena cukup cepat:
Haskell, 51 byte
Dibutuhkan 0,03 untuk
f (10^100)
laptop lima tahun saya.Sunting: @xnor menemukan byte untuk disimpan. Terima kasih!
sumber
h i=mod i<$>[2..2+sum[1|l<-scanl1 lcm[2..i],l<=i]]
Pyth,
51 Bytes66 BytesCobalah!
Banyak lebih tinggi kecepatan 39 versi byte (tidak bekerja untuk 0-2):
Tampaknya berfungsi untuk angka yang sangat besar seperti 10 10 3
Catatan: jawaban ini tidak berfungsi untuk 0, 1, dan 2.Tetap!sumber
JavaScript (ES6),
8177 byteIni secara rekursif membangun jawaban sampai LCM melebihi angka aslinya. GCD juga dihitung secara rekursif, tentu saja.
Sunting: Disimpan 4 byte berkat @ user81655.
sumber
Ruby, 52 byte
Solusi ini memeriksa setiap kemungkinan
m
mulai dari 2 yang merupakan sisa yang membuat urutan unik. Apa yang membuatm
unik terakhir bukanlah sisanya itu sendiri, tetapi bahwa itum
adalah anggota terakhir dari rentang terkecil di(2..m)
mana kelipatan paling umum (LCM) dari rentang itu lebih besar daripadan
. Hal ini disebabkan oleh Teorema Sisa Cina, di mana untuk secara unik menentukan angkan
dengan jumlah sisa, LCM dari sisa tersebut harus lebih besar darin
(jika memilihn
dari(1..n)
; jika memilihn
daria..b
, jika memilih dari , LCM hanya perlu lebih besar daripadab-a
)Catatan: Saya meletakkan
a<<n%m
di akhir kode karenauntil n<t=t.lcm(m+=1)
hubungan arus pendek sebelumnyaa
telah menerima elemen terakhir untuk membuatnya unik.Jika ada yang punya saran bermain golf, beri tahu saya di komentar atau di obrolan PPCG .
Tidak melakukan pelanggaran:
sumber
Julia,
3633 byteCobalah online!
sumber
Python 3.5,
194181169152149146 byte:( Terima kasih kepada @ Sherlock9 untuk 2 byte! )
Bekerja dengan sempurna, dan juga cukup cepat. Menghitung urutan sisa
100000
output minimal[0, 1, 0, 0, 4, 5, 0, 1, 0, 10, 4, 4]
dan hanya membutuhkan waktu sekitar 3 detik. Bahkan bisa menghitung urutan untuk input1000000
(1 juta), output[0, 1, 0, 0, 4, 1, 0, 1, 0, 1, 4, 1, 8, 10, 0, 9]
, dan butuh sekitar 60 detik.Penjelasan
Pada dasarnya apa fungsi ini adalah pertama-tama membuat daftar,,
y
dengan semua dij mod i
manaj
setiap bilangan bulat dalam kisaran0=>7
(termasuk 7) dani
setiap bilangan bulat dalam kisaran0=>100
. Program kemudian masuk kewhile
loop tak terbatas dan membandingkan jumlah konten yang sama dari masing-masing sublist dalam sublist pertama hingga kedua dari terakhiry
(y[:-1:]
) dengan jumlah item yang sama di sublist terakhir (y[-1]
) daftary
. Ketika sublisty[-1]
adalah berbeda daripada sublist lain, loop rusak dari, dan benar minimal urutan sisanya dikembalikan.Misalnya, jika inputnya 3,
y
akan menjadi:Kemudian, ketika masuk ke loop sementara, ia membandingkan setiap sublist dalam daftar
y[:-1:]
dengan jumlah item yang sama dalam sublisty[-1]
. Sebagai contoh, pertama-tama akan membandingkan[[0],[1],[0]]
dan[1]
. Karena sublist terakhir ada di sisay
, itu akan melanjutkan dan kemudian membandingkan[[0,0],[0,1],[0,2]]
dan[1,0]
. Karena[1,0]
sekarang BUKAN dalam sisay
dalam urutan tertentu , itu adalah urutan pengingat minimal, dan karena itu,[1,0]
akan dikembalikan dengan benar.sumber
y[:c:]
sama dengany[:c]
C89, 105 byte
Kompilasi (dengan peringatan) menggunakan
gcc -std=c89
. Mengambil nomor tunggal pada stdin, dan menampilkan urutan sisa yang dipisahkan oleh spasi di stdout.sumber
C, 89 byte
Kompilasi dengan gcc. Cobalah online: n = 59 , n = 0 .
sumber