Pengantar dan Kredit
Hari ini tanpa pembuka yang mewah: Harap laksanakan takewhile
.
Variasi dari ini (pada struktur data non-sepele) adalah tugas di program pemrograman fungsional universitas saya. Tugas ini sekarang ditutup dan telah dibahas di kelas dan saya memiliki izin profesor saya untuk mempostingnya di sini (saya bertanya secara eksplisit).
Spesifikasi
Memasukkan
Masukan akan berupa daftar (atau konsep padanan bahasa Anda) dari bilangan bulat positif.
Keluaran
Outputnya harus berupa daftar (atau konsep padanan bahasa Anda) dari bilangan bulat positif.
Melakukan apa?
Tugas Anda adalah mengimplementasikan takewhile
(bahasa built-in diizinkan) dengan predikat bahwa angka yang dipertimbangkan bahkan (untuk fokus pada takewhile).
Jadi Anda mengulangi daftar dari awal hingga akhir dan sementara kondisi (genap) berlaku, Anda menyalin ke daftar-output dan segera setelah Anda menekan elemen yang tidak membuat kondisi tersebut benar, Anda batalkan operasi dan output (contoh langkah demi langkah di bawah ini). Fungsionalitas tingkat tinggi ini juga disebut takeWhile ( takewhile
).
Kasing sudut potensial
Urutan daftar output dibandingkan dengan daftar input mungkin tidak dapat diubah, misalnya [14,42,2]
tidak menjadi [42,14]
.
Daftar kosong adalah input dan output yang valid.
Yang menang?
Ini adalah kode-golf sehingga jawaban tersingkat dalam byte menang!
Aturan standar berlaku tentu saja.
Vektor Uji
[14, 42, 2324, 97090, 4080622, 171480372] -> [14, 42, 2324, 97090, 4080622, 171480372]
[42, 14, 42, 2324] -> [42, 14, 42, 2324]
[7,14,42] -> []
[] -> []
[171480372, 13, 14, 42] -> [171480372]
[42, 14, 42, 43, 41, 4080622, 171480372] -> [42, 14, 42]
Contoh Langkah-demi-Langkah
Example Input: [42, 14, 42, 43, 41, 4080622, 171480372]
Consider first element: 42
42 is even (21*2)
Put 42 into output list, output list is now [42]
Consider second element: 14
14 is even (7*2)
Put 14 into output list, output list is now [42,14]
Consider third element: 42
42 is even (21*2)
Put 42 into output list, output list is now [42,14,42]
Consider fourth element: 43
43 is not even (2*21+1)
Drop 43 and return the current output list
return [42,14,42]
Jawaban:
Mathematica, 18 byte
Lain bawaan built-in yang dikalahkan oleh faktor 3 oleh golf golf tanpa built-in ...
sumber
Haskell, 13 byte
span
membagi daftar input menjadi sepasang daftar tepat sebelum elemen pertama di mana predikat (->even
) salah.fst
mengambil elemen pertama dari pasangan.Versi alternatif, 13 byte:
break
adalah kebalikan darispan
, yaitu membagi daftar pada elemen pertama di mana predikatnya benar.Tentu saja ada juga
tapi itu 14 byte.
sumber
MATL , 6 byte
Cobalah online!
Penjelasan
sumber
to~Y<)
juga berfungsi, tapi saya suka ini lebih baik :-)Hexagony , 19
Dapat dibaca:
Cobalah online!
Ini mungkin bisa di-golf dengan satu atau dua byte, tetapi itu mungkin memerlukan beberapa tata letak yang benar-benar cerdik, yang mungkin lebih mudah ditemukan melalui brute force (bahkan jika mungkin butuh waktu agak lama untuk menemukannya).
Penjelasan tingkat tinggi
Program ini sebagian besar mengikuti kodesemu ini:
Yang menyalahgunakan bagaimana Hexagony mencoba membaca angka begitu STDIN kosong (mengembalikan nol). Terima kasih banyak untuk Martin atas bantuannya dalam pendekatan ini.
Penjelasan Lengkap
Saya masih belum mengutak-atik Mono untuk menjalankan IDE esoterik fantastis Timwi , jadi saya mencondongkan tubuh ke Martin untuk memberi saya beberapa gambar cantik yang membantu!
Pertama, sedikit primer pada aliran kontrol dasar dalam Hexagony. Pointer instruksi pertama (IP), yang merupakan satu-satunya yang digunakan dalam program ini, dimulai di kiri atas kode sumber heksagonal, dan mulai bergerak ke arah kanan. Setiap kali IP meninggalkan tepi segi enam, itu bergerak
side_length - 1
baris menuju tengah segi enam. Karena program ini menggunakan panjang sisi tiga segi enam, IP akan selalu bergerak dua baris ketika ini terjadi. Satu-satunya pengecualian adalah jika bergerak dari baris tengah, di mana ia bergerak menuju bagian atas atau bawah hexagon, tergantung pada nilai dari tepi memori saat ini.Sekarang sedikit tentang persyaratan. Satu-satunya persyaratan dalam Hexagony untuk aliran kontrol adalah
>
,<
dan tepi tengah hexagon. Ini semua mengikuti aturan konstan: jika nilai pada tepi memori saat ini adalah nol atau aliran kontrol negatif bergerak ke kiri dan jika positif kontrol mengalir ke kanan. Lebih besar dari dan kurang dari tanda kurung mengarahkan IP pada sudut enam puluh derajat, sedangkan tepi segi enam mengontrol ke mana baris IP melompat.Hexagony juga memiliki model memori khusus, di mana semua data disimpan di tepi grid heksagonal yang tak terbatas. Program ini hanya menggunakan tiga sisi: satu untuk menyimpan dua, satu untuk nomor yang sedang dibaca, dan satu untuk nomor modulo dua. Itu terlihat seperti:
Saya tidak akan menjelaskan dengan hati-hati di mana kita berada di memori pada setiap titik selama penjelasan program, jadi kembali ke sini jika Anda bingung dengan di mana kita berada dalam memori.
Dengan semua itu, penjelasan sebenarnya bisa dimulai. Pertama, kita mengisi tepi "2" dalam memori dengan angka 2, lalu kita jalankan perintah no-op dan pindahkan penunjuk memori ke kanan (
2.}
).Selanjutnya, kita mulai loop program utama. Kami membaca angka pertama dari STDIN dan kemudian kami menekan conditional (
?<
). Jika tidak ada angka yang tersisa di STDIN, ini membaca nol ke tepi memori saat ini, jadi kami belok kiri ke@
, yang mengakhiri program. Kalau tidak, kita pantulkan cermin, pindahkan penunjuk memori ke belakang dan ke kiri, bungkus sekitar segi enam untuk menghitung sisa membagi input dengan 2 dan kemudian tekan kondisional lain (/"%>
).Jika sisanya adalah satu (yaitu angkanya ganjil), kita belok kanan mengikuti jalur biru di atas dimulai dengan mengeksekusi no-op lagi, lalu kita lilitkan ke bagian bawah segi enam, kalikan tepi saat ini dengan 10 dan kemudian tambahkan delapan, bangkit dari beberapa mirror, lakukan penggandaan dan penambahan yang sama lagi, dapatkan 188 di tepi saat ini, membungkus kembali ke atas segi enam, menjalankan no-op lagi, dan akhirnya mengakhiri program (
.8/\8.@
). Hasil berbelit-belit ini adalah kecelakaan yang membahagiakan, saya awalnya telah menulis sedikit logika yang lebih sederhana, tetapi memperhatikan bahwa saya dapat menghapusnya demi no-op, yang saya pikir lebih sesuai dengan semangat Hexagony.Jika sisanya nol kita sebaliknya belok kiri mengikuti jalan merah, di atas. Ini menyebabkan kita untuk memindahkan penunjuk memori ke kiri, dan kemudian mencetak nilai di sana (nilai input) sebagai angka. Cermin yang kita temui bertindak sebagai no-op karena arah yang kita bergerak (
{/!
). Lalu kami mencapai ujung hexagon yang bertindak bersyarat dengan hanya satu hasil, karena nilai input dari sebelumnya sudah diuji menjadi positif, jadi kami selalu bergerak ke kanan (jika Anda membayangkan diri Anda menghadap ke arah IP) . Kami kemudian mengalikan input dengan 10 dan menambahkan dua, hanya untuk mengubah arah, membungkus dan menimpa nilai baru dengan nilai ascii dari huruf kapital M, 77. Kemudian kami menekan beberapa mirror, dan keluar melewati tepi tengah segi enam dengan trampolin (2<M\>$
). Karena 77 positif, kita bergerak ke arah bagian bawah segi enam dan karena trampolin lewati instruksi pertama (!
). Kami kemudian mengalikan tepi memori saat ini dengan 10 dan menambahkan 8, mendapatkan 778. Kami kemudian menampilkan nilai ini mod 256 (10) sebagai karakter ASCII, yang kebetulan merupakan baris baru. Akhirnya kita keluar dari segi enam dan membungkus kembali ke yang pertama?
yang menimpa 778 dengan nilai input berikutnya.sumber
Pyth,
1397 byteKredit ke @FryAmTheEggman untuk 2 (cukup rumit) byte!
Penjelasan:
Uji di sini .
sumber
G
s yang diperkenalkan, satu untuk kondisis%R2G
dan satu sebagai argumen untuk fungsiP
.Jelly , 5 byte
Cobalah online! atau verifikasi semua kasus uji .
Bagaimana itu bekerja
sumber
Python 2,
4342 byteFungsi memodifikasi argumennya di tempat .
Terima kasih kepada @xnor karena bermain golf dari byte dengan cara yang sangat cerdas!
Uji di Ideone .
sumber
"1'"in`map(bin,x)`
untuk Python 2.ed, 13
Karena programmer nyata menggunakan The Standard Text Editor .
Mengambil input sebagai satu bilangan bulat di setiap baris; output dalam format yang sama.
Ini hanya menemukan angka ganjil pertama (angka yang berakhir dengan angka ganjil) dan menghapus dari baris itu sampai akhir file.
sumber
Clojure, 21 byte
Clojure akhirnya hampir bersaing! (terima kasih untuk tugasnya menjadi built-in) Lihat secara online https://ideone.com/BEKmez
sumber
Python,
4544 byteUji di Ideone .
sumber
R, 25 byte
Atau sederajat
sumber
05AB1E,
87 bytePenjelasan
Cobalah online
Solusi 8 byte sebelumnya
Penjelasan
Cobalah online
sumber
Brainf ***, 263 byte
Saya mengambil sedikit cuplikan dari sini
Saya akan memberikan penjelasan tetapi bahkan saya tidak tahu bagaimana ini bekerja lagi.
Mengharapkan input sebagai angka yang dipisahkan oleh spasi (mis.
2 432 1
)sumber
+
dan>
menggunakan beberapa logika?>
lebih efisien tetapi saya tidak cukup memahaminya sekarangPyth, 7 byte
Coba di sini!
Apa yang saya coba lakukan di Pyke tetapi indeks rusak di atm itu
sumber
Racket, 22 byte
The
λ
karakter dihitung sebagai 2 byte.Saya belum pernah melihat Racket digunakan sebelumnya dalam salah satu jawaban kode golf yang pernah saya lihat, jadi saya harus melakukannya setidaknya sekali!
sumber
Labirin , 14 byte
Input dan output adalah daftar yang dipisahkan oleh linefeed (meskipun pada prinsipnya, input dapat menggunakan pemisah non-digit).
Cobalah online!
Ini mungkin adalah program Labirin paling ringkas yang pernah saya tulis.
Menariknya,
takewhile(odd)
jauh lebih sederhana:Penjelasan
Primer Labirin biasa:
?
dalam hal ini), bergerak ke timur.Aliran utama melalui program ini adalah satu loop di sekeliling:
Seperti yang terjadi, kita tahu bahwa bagian atas tumpukan adalah nol setelahnya
!
dan"
agar IP dijamin tidak berbalik ke tengah.`
dan%
di sisi lain digunakan sebagai kondisi di mana IP mungkin bergerak ke arah tengah sehingga@
menghentikan program, atau mungkin terus bergerak di sekeliling.Mari kita lihat kode di loop:
Dan kemudian loop dimulai kembali.
Itu menimbulkan pertanyaan mengapa
takewhile(odd)
jauh lebih sederhana. Ada dua alasan:0
(yang genap), kami tidak memerlukan pemeriksaan EOF terpisah. Lagipula daftar itu akan terpotong pada saat itu.N % 2
ini0
(sebagai lawan1
), yang berarti bukan kontrol kondisional mengalir kita hanya bisa membagi salinan lainN
olehN % 2
: jika input aneh, yang hanya daunN
dan bahkan kami mendapat menyingkirkanN % 2
(sehingga kita don' t need;
), tetapi jika inputnya genap, itu akan menghentikan program dengan kesalahan (diam) pembagian demi nol.Oleh karena itu, kode lainnya adalah loop sederhana yang tidak memungkinkan untuk bercabang sama sekali.
sumber
Brachylog ,
1916 bytePenjelasan
Hari ini saya mempelajari trik yang rapi (yang digunakan dalam jawaban 19 byte):
~b.hH
lebih pendek daripada:[H]rc.
menambahkan elemen pada awal daftar. Yang pertama berarti "Output adalah hasil dengan item tambahan di awal, dan item pertama dari Output adalahH
" , sedangkan yang lainnya langsung "Output adalah gabungan dari[[H], Result]
".sumber
J, 10 byte
Penjelasan
sumber
1{.2&|<;._2]
menarik (meskipun lebih lama)$
sebagai ganti{.
Python, 41 byte
Memotong
l
hingga indeks kemunculan pertama nomor ganjil. Indeks ditemukan dengan mencari1
dalam modulo nilai-nilai2
. Untuk menjaga agar tidak ada nomor ganjil yang ditemukan, a1
diletakkan di ujung.sumber
C #, 50 byte
sumber
a=>a.TakeWhile(x=>x%2<1);
CJam , 11 byte
Berkat @ Dennis untuk dua koreksi dan satu byte off!
Ini adalah blok kode (setara dengan fungsi; diizinkan secara default) yang mengharapkan array input pada stack, dan meninggalkan array output pada stack.
Cobalah online!
Penjelasan
sumber
Retina , 17 byte
Linefeed tambahan sangat penting. Input dan output adalah daftar yang dipisahkan oleh ruang.
Cobalah online!
Ini adalah penggantian regex sederhana, cocok dengan angka ganjil pertama (yaitu angka yang berakhir dengan digit ganjil), dan jika mungkin ruang yang mendahuluinya serta semuanya setelahnya dan menggantinya dengan string kosong, yaitu semua elemen dari sana selanjutnya dihapus dari input.
Seperti yang Leaky Nun tunjukkan, dengan mengambil daftar dalam biner, kita dapat menyimpan 6 byte, tetapi tampaknya sedikit curang, jadi saya mungkin akan terus menghitung versi desimal:
sumber
JavaScript (Firefox 30-57), 30 byte
sumber
V , 13 byte
Cobalah online!
Penjelasan:
Dengan mudah, kode yang sama berfungsi untuk memverifikasi semua kasus uji secara bersamaan.
sumber
Dyalog APL , 11 byte
2|
sisa pembagian dari pembagian dengan 2~
meniadakan∧\
AND-scan (mati dari 0 pertama)/⍨
pilih dimanasumber
Ruby, 25 byte
Saya pikir saya kehilangan ...
sumber
->a{a.take_while &:even?}
atau setidaknya->a{a.take_while(&:even?)}
?Pyke, 8 byte
Interpreter diperbaiki, gunakan tautan lain
Menggunakan metode Dennis 'kecuali fungsi split_at saya termasuk perubahan - mungkin bug
Atau dengan perbaikan bug, 7 byte
Coba di sini!
Atau setelah perbaikan bug ke-2, 6 byte
Coba di sini!
Penjelasan:
sumber
GolfScript, 11 byte
Ini adalah program GolfScript lengkap yang membaca literal array GolfScript string (misalnya
[28 14 7 0]
) dan mencetak array yang sama dengan elemen aneh pertama dan semuanya setelah dihapus:Cobalah online. (Juga: Versi diperpanjang dengan test harness. )
Versi de-golf dengan komentar:
Solusi ini didasarkan pada
{ },
operator filter GolfScript , yang menjalankan konten blok kode pada setiap elemen array, dan memilih elemen-elemen array yang kode di blok mengembalikan nilai yang benar (yaitu bukan nol) pada atas tumpukan.Jadi, misalnya,
{1&},
akan memilih semua angka ganjil dalam array, dan{~1&},
akan memilih semua angka genap. Maka tantangannya adalah membuat filter yang memilih angka genap sampai menemukan angka ganjil pertama , dan setelah itu tidak memilih angka sama sekali.Solusi yang saya gunakan adalah mengganti bit-mask konstan
1
(digunakan untuk mengekstrak bit terendah dari setiap nomor input) dengan variabel pada stack yang menyimpan hasil (0 atau 1) dari iterasi loop filter sebelumnya (dan diinisialisasi ke 1 sebelum loop). Jadi, segera setelah filter mengembalikan 0 sekali, bitmask juga diatur ke 0, mencegah filter untuk kembali lagi 1.sumber
Keempat, 114 byte
Keempat tidak benar-benar memiliki daftar. Parameter harus didorong ke tumpukan dalam urutan terbalik, seperti yang tipikal dalam Keempat. Hasilnya akan ditinggalkan di tumpukan dalam urutan yang sama. Ini tidak berfungsi pada Ideone karena alasan tertentu, tetapi bekerja pada repl. Baris baru diperlukan untuk menghapus semacam ambiguitas?
Cobalah online
Tidak disatukan, dengan komentar:
Program ini (usaha saya sebelumnya) mencetak hasilnya hingga mencapai angka ganjil. Semua yang tersisa (tidak diambil) akan ditinggalkan di tumpukan.
Gagal jika hanya bilangan bulat
sumber
Befunge, 35 Bytes
Kode ini menangani angka antara 0 dan 65535
Masukkan format :
Berikut adalah versi yang menampilkan nilai di akhir proses:
Anda dapat menguji kode di sini , tetapi Anda harus menambahkan garis trailing dengan spasi tambahan, karena ini menafsirkan:
Saya tidak tahu apakah ini dapat diterima, karena saya tidak menghitung jejak ini dalam byte byte
nb: tampaknya karena saya menyimpan nomor dalam kode, penerjemah tidak akan membiarkan program ini berjalan dua kali dengan benar cara. Anda harus memuatnya kembali.
Bagaimana cara kerjanya: Penerjemah mengikuti panah dan melewatkan instruksi ketika melewati '#'
Titik abu-abu adalah tes, dan garis merah menghapus variabel yang tidak dibutuhkan dari tumpukan
Dengan menggunakan interpreter di atas, nilai yang disimpan ditampilkan dalam kode menggunakan representasi mereka (saya tidak tahu formatnya). Ya, Befunge adalah bahasa yang cukup reflektif
sumber