Perusahaan Anda baru saja memulai suatu proyek, dan untuk pertama kalinya Anda memutuskan untuk menggunakan gaya pemrograman kode fungsional. Namun bos Anda benar-benar malu-malu dan tidak ingin menggunakan fungsi bawaan, dan mengharuskan Anda untuk menerapkan sendiri fungsi-fungsi utama. Secara khusus Anda perlu menulis fungsi: Map
, Nest
, Apply
, Range
, Fold
dan Table
dalam bahasa pada pilihan Anda. Bosnya orang yang sangat sibuk, dan dia ingin programnya sesingkat mungkin, jadi dia tidak membuang waktu untuk membaca. Dia juga ingin agar Anda tidak menggunakan loop, oleh karena itu Anda akan memiliki pengurangan 10% pada jumlah byte karena tidak menggunakan loop.
Persyaratan rinci fungsi di bawah ini:
Peta
The Map
Fungsi mengambil dua parameter: f
dan list
di mana f
adalah fungsi dan list
merupakan daftar nilai. Ini harus mengembalikan f
diterapkan ke setiap elemen list
. Karena itu akan berfungsi seperti itu:
Map(f,{a,b,c})
kembali
{ f(a), f(b), f(c) }
dan
Map(f, {{a,b},{b,c}})
kembali
{ f({a,b}), f({b,c})}
Sarang
The Nest
Fungsi mengambil tiga parameter juga: f
, arg
, times
di mana f
adalah fungsi, arg
adalah argumen mulai, dan times
adalah berapa kali fungsi ini diterapkan. Itu harus mengembalikan ekspresi dengan waktu yang f
diterapkan times
ke arg
. Karena itu akan berfungsi seperti itu:
Nest(f, x, 3)
kembali
f(f(f(x)))
dan
Nest(f, {a,b}, 3)
kembali
f(f(f({a,b})))
Menerapkan
The Apply
Fungsi mengambil dua parameter: f
dan args
di mana f
adalah fungsi dan args
daftar. Itu harus berlaku f
untuk args
. Karena itu:
Apply(f, {a,b,c})
kembali
f(a,b,c)
Jarak
The Range
Fungsi mengambil satu bilangan bulat r
dan output bilangan bulat hingga jumlah itu. Karena itu:
Range(5)
kembali
{ 1, 2, 3, 4, 5}
Melipat
The Fold
Fungsi mengambil tiga parameter f
, arg
, others
di mana f
adalah fungsi, arg
adalah parameter sederhana, dan others
daftar. Ini akan berfungsi seperti itu:
Fold(f, x, {a, b, c, d})
kembali
f(f(f(f(x,a),b),c),d)
Meja
Fungsi-fungsi tabel harus mengambil fungsi f
, dan parameter yang disebut iterator
dalam bentuk: {iMin, iMax}
where iMin
and iMax
integer. Anda harus menerapkan f
rentang yang ditentukan. Karena itu:
Table(f, {0, 5})
kembali
{f(0), f(1), f(2), f(3), f(4), f(5)}
Saya telah menggunakan definisi fungsi-fungsi ini dari halaman pemrograman fungsional Mathematica , jadi pergilah ke sana jika Anda memerlukan panduan lebih lanjut. Perhatikan bahwa Anda tidak perlu mengimplementasikan semua versi fungsi yang ditampilkan di halaman itu, tetapi hanya yang ditulis dalam posting ini.
Celah Standar tidak diizinkan seperti biasa.
Jika bahasa Anda tidak memungkinkan fungsi untuk diteruskan sebagai argumen, Anda perlu menerapkan kemampuan ini, dan menambahkannya ke dalam jawaban Anda. Namun byte-count dari operasi ini tidak akan ditambahkan ke total.
Ini adalah kode golf sehingga kode terpendek menang. Semoga berhasil!!!
sumber
Table
kerjanya di sini. Apakah teladan Anda seharusnyaTable(f, {x, 0, 5})
? Saya juga tidak mendapatkan tujuanx
sama sekali, karena itu hanya menerapkan fungsi ke kisaran.Jawaban:
Haskell,
banyak byte sebelumnya menghitung127 * 0,9 = 114,3 byteTidak ada loop, hanya rekursi.
#
adalah peta:(*2) # [1,2,3]
->[2,4,6]
&
adalah sarang:((*2) & 3) 4
->48
i
berlaku:i (*2) 7
->14
r
kisaran:r 4
->[1,2,3,4]
?
dilipat:((+) ? 0) [1,2,3,4]
->10
%
adalah tabel:(*2) % (2,4)
->[4,6,8]
Seperti yang diminta versi yang ungolfed dengan komentar. Catatan,
&
dan?
merupakan operator infix ternary, yang membutuhkan tanda kurung tambahan saat dipanggil atau pola cocok.Terima kasih kepada @dfeuer dan @Zgarb untuk beberapa petunjuk bermanfaat
sumber
m#q=reverse$f((:).m)[]q
,. Panjangnya sama dengan milik Anda, tetapi jauh lebih sulit untuk dibaca.!
dengan membuat nama bukan operator:i f=f
.Python 2, 305.1 byte (-10%
376369366349339 byte)Saat diperluas, setara dengan:
Tidak ada loop!
Ya, itu sangat sulit
eval
dan jika bos Anda tidak tahan, maka mereka akan BENCI eval. Tapi, mereka harus tahan dengan ituCara melakukannya
range
di lambda dihargai jadi saya tidak harus melakukan fungsi apa pun (Shudder.).Penjelasan:
m=lambda f,l:eval("["+"f(l.pop()),"*len(l)+"][::-1]")
n=lambda f,x,l:eval("f("*l+"*x"+")"*l)
r=lambda i:e("r(i-1)+"*(i>1)+"[i]")
eval
ed, baik kembali[0]
atau menggunakan rekursi untuk mendapatkan hasil sebelumnya dan menambahkan indeks saat ini ke daftar. Benarkah?a=lambda f,a:eval("f(a["+
r (len (a))[1:-1].replace(",","-1],a[")+"-1])")
a
. Benarkah itu!f=lambda f,x,l:eval("f("*len(l)+"x,["+
r (len (l))[1:-1].replace(",","-1]),l[")+"-1])")
t=lambda f,n,x:eval("[f("+
r (x) [n-1:].replace(",","),f(")[1:-1]+")]")
Peta, sarang, jangkauan, terapkan, lipat, tabel.
Terima kasih @Zgarb untuk lambda untuk jangkauannya!
sumber
r=lambda i:[]if i<1 else r(i-1)+[i]
? Tidak ada loop, hanya rekursi.eval
untuk menunjukkan kepada mereka bagaimana agar loop tidak terlalu buruk :)e=eval
:r=lambda i:e("r(i-1)+"*(i>1)+"[i]")
Javascript ES6, 197 * 0.9 = 177.3 byte
Peta (
M=(f,l)=>F((a,b)=>[...a,f(b)],[],l)
):Penggunaan Lipat untuk menggabungkan hasil yang
f
diterapkan ke setiap anggotal
ke daftar kosong. Menggunakan fungsi bawaan mengurangi ini keM=(f,l)=>l.map(f)
(tidak menggunakannya karena tampaknya murah ...?).Sarang (
N=(f,x,n)=>f(--n?N(f,x,n):x)
):Terapkan
f
secara berulang sampain
dikurangi menjadi 0.Terapkan (
A=(f,l)=>f(...l)
):Menggunakan penyebaran (
...
) operator untuk menerapkanl
kef
.Rentang (
R=n=>n--?[...R(n),n+1]:[]
):Concat
n
panggilan rekursif dari Rentang sampain
decremented ke 0.Lipat (
F=(f,x,l,n=l.length)=>n--?f(F(f,x,l,n),l[n]):x
):Menerapkan panggilan rekursif dari Fold dan
n
elemenl
kef
hinggan
dikurangi menjadi 0. Menggunakan fungsi bawaan mengurangi ini menjadiF=(f,x,l)=>l.reduce(f,x)
(sekali lagi, tampak murah ...).Tabel (
T=(f,i)=>([n,x]=i,M(q=>f(q+n-1),R(x-n+1)))
):Pertama menginisialisasi
n
danx
ke iMin dan iMax menggunakan destructure ([n,x]=i
), kemudian menggunakan Range untuk membangun tabel nilai dari iMin ke iMax.f
kemudian diterapkan di atas tabel menggunakan Peta dan hasilnya dikembalikan.sumber
Python 3, 218 byte
Versi tidak terbaca:
Versi (lebih) dapat dibaca:
Meskipun hanya satu lambda sekaligus:
Fungsi peta
P
P=lambda f,x:[f(_)for _ in x]
Hanya iterator sederhana. Tidak banyak bicara di sini.
Fungsi sarang
Y
Y=lambda f,x,z:Y(f,f(x),z-1)if z else x
Berulang hingga
z
mencapai angka nol, terapkanf
setiap saat. Klausa if pada akhirnya terasa kikuk; mungkin ada cara yang lebih baik untuk mengakhiri rekursi.Terapkan fungsi
T
T=lambda f,x:f(*x)
Python memiliki operator ekspansi yang bagus untuk melakukan semua pekerjaan berat untuk saya.
Fungsi rentang
H
H=lambda f,x=0:(H(f-1)if~-f else[])+[f]
Yang ini lebih sulit daripada yang saya harapkan. Akhirnya mengambil pendekatan rekursif. Sekali lagi, konstruksi if-else membutuhkan banyak byte, dan saya rasa ini dapat ditingkatkan. Mengapa ia memiliki boneka
x=0
, Anda bertanya? Itu sehingga ketika saya kompres denganexec
, saya bisa mengganti=lambda f,x
bukan hanya=lambda f
.Fungsi lipat
O
O=lambda f,x,z:O(f,f(x,z[0]),z[1:])if z else x
Cukup senang dengan yang ini. Hanya memotong elemen pertama dari array setiap kali berulang, sampai tidak ada yang tersisa.
Fungsi tabel
N
N=lambda f,x:(N(f,[x[0],x[1]-1])if x[1]-x[0]else[])+[f(x[1])]
Yang ini mengerikan dan saya yakin ada ruang untuk perbaikan. Mencoba menggunakan rentang dan fungsi peta yang sebelumnya ditentukan untuk
map(f,range(x,y))
semacam konstruksi, tetapi tanpa banyak keberhasilan. Akhirnya melakukan pendekatan rekursif yang mengerikan yang memiliki kesamaan dengan fungsi rentang.Semua lambda dibungkus
exec
dengan denganreplace
untuk mempersingkat jumlah byte secara signifikan.sumber
[f(_)for _ in x]
dapat disingkat menjadimap(f,x)
, tetapi kemudian saya ingat apa tantangannyaJulia, 181 byte
Tidak ada bonus untuk saya; Saya menggunakan loop secara bebas. Maaf bos, tetapi loop di Julia efisien!
Menambahkan elips setelah argumen ke suatu fungsi memecah array, tuple, atau apa yang Anda miliki ke dalam argumen fungsi biasa. Kalau tidak, fungsi akan berpikir Anda mencoba untuk melewatkan array (atau tuple, dll.). Tidak ada efek untuk argumen tunggal.
Nama fungsi:
M
N
A
R
F
T
sumber
tinylisp , 325 * 0,9 = 292,5
Bahasa lebih baru dari pertanyaan, tetapi tidak akan menang.
Menentukan fungsi
A
(berlaku),M
(peta),N
(sarang),R
(rentang),T
(tabel), danF
(lipat), bersama dengan fungsi pasangan pembantu.T
mengharapkan daftar dua bilangan bulat untuk argumen keduanya.Tinylisp bahkan tidak memiliki konstruksi loop; semuanya dilakukan dengan menggunakan rekursi. Beberapa fungsi-fungsi ini tidak berulang , jadi jika Anda memanggil mereka pada daftar besar mereka mungkin akan meniup tumpukan panggilan. Mereka semua dapat diimplementasikan dengan rekursi ekor ... tetapi akan membutuhkan lebih banyak byte, dan ini adalah kode golf.
Berikut adalah versi yang diperluas dengan spasi putih dan kata-kata nyata untuk nama, yang seharusnya cukup mudah dibaca jika Anda terbiasa dengan Lisp. (Saya telah alias sebagian besar builtinisp builtin kecuali untuk
q
(kutipan) dani
(jika).)Penjelasan lebih lanjut tersedia atas permintaan.
Output sampel
Menggunakan lingkungan REPL dari implementasi referensi saya. Saya menggunakan
q
(kutipan) untuk fungsi unary dans
(kurangi) sebagai fungsi biner untuk contoh-contoh ini, serta fungsi@
(didefinisikan dalam kode ini) yang mengembalikan daftar argumennya.sumber
Python 2.x: 450,6 byte (493 byte sebelum diskon 10%)
Jawaban golf:
Pertanyaan ini menyenangkan. Saya memutuskan untuk menulis fungsi saya tanpa menggunakan padanan Python (meskipun itu mungkin merupakan celah yang valid) dan untuk menulis fungsi seolah-olah Python mendukung rekursi ekor. Untuk membuat ini berfungsi, saya menggunakan banyak parameter opsional yang memungkinkan panggilan yang diperlukan masih berfungsi.
Di bawah ini saya memiliki daftar yang tidak dipisahkan untuk setiap fungsi.
Apply
:Map
:Nest
:Perhatikan bahwa fungsi ini mensyaratkan bahwa yang lulus
function
dapat mewakili beberapa argumen secara beragam. Pendekatan lain adalah untuk menegakkan bahwa fungsi selalu menerima satu daftar, tetapi itu akan mengharuskan fungsi yang berlalu dapat menafsirkan daftar argumen. Ada beberapa asumsi, jadi saya memilih yang paling sesuai dengan sistem.Range
:Fold
:Table
:Berikut ini contoh keluaran menggunakan fungsi pembantu berikut:
sumber
Ceylon,
370 * 0,9 = 333364 * 0,9 = 327,4Sebagian besar fungsi tersebut sudah tersedia dalam paket bahasa Ceylon (meskipun terkadang dengan tanda tangan yang sedikit berbeda), tetapi kami mendefinisikannya di sini seperti yang diminta dalam pertanyaan.
Sebenarnya hanya dua fungsi (
t
danf
) yang benar-benar menggunakan rekursi (masing-masing daftar dan bilangan bulat), yang lain didasarkan pada ini. (Aplikasi sedikit outlier, itu tidak benar-benar berhubungan dengan yang lain.)Saya menafsirkan "Daftar" sebagai tipe Sequential Ceylon, yang merupakan urutan elemen (mungkin kosong) yang tidak dapat diubah.
[R*]
singkatanSequential<R>
- untuk beberapa alasan kita juga dapat menulisnyaR[]
, yang lebih pendek satu byte.Tipe fungsi adalah
Callable<R, A>
, di manaA
adalah tipe tuple untuk argumen, seperti[X, Y, Z]
(yaitu beberapa subtipeAnything[]
). Sebagai jalan pintas kita dapat menulisR(X,Y,Z)
bukanCallable<R,[X,Y,Z]>
.Aku alias
Integer
sebagaiI
untuk menyimpan beberapa byte.Ini adalah versi yang diformat (dan sedikit dikomentari):
Menggunakan "loop"
Tabel dan Peta dapat diimplementasikan lebih pendek menggunakan loop (sebenarnya, pemahaman urutan):
Meskipun saya tidak yakin apakah penggunaan
..
operator untuk rentang bilangan bulat dianggap sebagai menggunakan fungsi bawaan. Jika ini dibolehkan, kode yang dihasilkan ada di sini, panjang 312:(Itu bisa dibuat lebih pendek dengan mendefinisikan
r(I i) => 1..i
, menghasilkan skor 301. Meskipun itu terlihat lebih seperti curang.)Jika
..
tidak diizinkan, kami harus menerapkannya lagi. Kita dapat menggunakan implementasi ini untukr
dant
(dengan yang dim
atas):Ini menghasilkan 348 byte, lebih baik daripada versi yang sepenuhnya rekursif, tetapi tidak setelah menerapkan bonus.
sumber
Groovy (146 Bytes) (146 * 90% = 131,4)
PS Saya tidak tahu apa yang Anda pertimbangkan sebagai 'loop' dalam konteks ini, saya hanya menerapkan bonus setelah saya diberitahu dalam komentar oleh OP dan akan menghapus jika 2-3 pengguna tambahan mengatakan fungsi dan iterator pengumpulan ini. adalah loop dan saya tidak pantas mendapatkan bonus. Juga, jika Anda ingin memanggil saya untuk menggunakan 1..it, silakan lakukan dan saya akan memperbaikinya / memperbarui bytecount saya.
Contoh Input / Output
Keluaran
Cobalah sendiri: https://groovyconsole.appspot.com/edit/5203951758606336
sumber