Misalkan Anda merangkai untaian Froot Loops untuk kalung, gelang, tali sepatu, atau apa pun. Ada 6 warna lingkaran: r ed, o range, y ellow, g reen, b lue, dan p urple. Anda ingin untai Anda mulai dengan warna merah di bagian paling kiri dan siklus dalam urutan pelangi ke kanan, berakhir dengan warna ungu. Artinya, Anda ingin membuatnya sehingga untai Anda dapat diwakili oleh string yang roygbp
diulang beberapa kali (mungkin 0).
Masalahnya adalah, Anda sudah menggantungkan loop Anda, dan tidak dalam urutan tertentu. Loop mana yang harus Anda makan dan tidak makan sehingga Anda dapat memaksimalkan jumlah siklus pelangi yang benar dari kiri ke kanan, dengan loop merah pertama dan loop ungu terakhir?
Tulis program atau fungsi yang mengambil string karakter acak roygbp
dan mencetak atau mengembalikan string dengan panjang yang sama dengan e
di tempat loop untuk makan dan n
di tempat loop untuk tidak makan.
Misalnya, jika untai Froot Loop Anda terlihat seperti
inputnya akan
gorboypbgbopyroybbbogppbporyoygbpr
dan dari kiri ke kanan kita dapat menemukan 3 roygbp
urutan pelangi lengkap , tetapi beberapa loop perlu dimakan. Dengan demikian hasilnya akan
eenenneennenennneeeeneennenennnnne
menghasilkan untai 3 siklus sempurna:
Jika tidak ada siklus pelangi lengkap dalam input maka output akan menjadi semua e
dan untai berakhir tanpa loop. misalnya input proygb
memiliki output eeeeee
. Sebaliknya, proygbp
memiliki output ennnnnn
.
Anda dapat mengasumsikan semua untai input memiliki setidaknya satu loop.
Kode terpendek dalam byte menang.
r
atau bisaoygbproygbpr
juga memenuhi syarat?Jawaban:
Pyth, 31 byte
Sangat tidak efisien, penjelasan segera hadir.
yUlz
menghasilkan semua himpunan bagian yang mungkin dari semua indeks yang mungkinz
(input) secara berurutan. Misal jika inputnya adalahabc
:Kemudian
hf!
temukan yang pertamaT
dalam daftar di atas sedemikian rupa sehingga:jk.DzT"roygbp"k
salah..D
mengambil string dan daftar indeks, dan menghapus elemen pada indeks tersebut. Begitu.D"abcd",1 3
juga"ac"
. Karena.D
mengembalikan daftar (yang seharusnya tidak terjadi, akan diperbaiki dalam versi Pyth yang akan datang), saya menggunakanjk
(k
is""
) untuk bergabung bersama kembali ke sebuah string. Bagian ini:_"roygbp"k
menggantikan setiap instance dari siklus dengan string kosong.Karena string kosong itu salah, paragraf di atas menjelaskan bagaimana saya menemukan kumpulan indeks terkecil yang diperlukan untuk dimakan untuk mendapatkan string yang hanya terdiri dari siklus.
:*lz\n_\e
kemudian mengubah daftar indeks menjadinnnneeennene
string.sumber
Hexagony ,
920722271 byteEnam jenis buah loop, menurut Anda? Untuk itulah Hexagony dibuat .
Oke, tidak. Ya Tuhan, apa yang saya lakukan pada diri saya sendiri ...
Kode ini sekarang merupakan segi enam dengan panjang sisi 10 (dimulai pada 19). Mungkin bisa di-golf lagi, mungkin bahkan sampai ukuran 9, tapi saya pikir pekerjaan saya selesai di sini ... Untuk referensi, ada 175 perintah aktual di sumbernya, banyak di antaranya berpotensi mirror yang tidak perlu (atau ditambahkan untuk membatalkan perintah dari persimpangan jalan).
Terlepas dari linearitas yang tampak, kode ini sebenarnya dua dimensi: Hexagony akan mengatur ulang menjadi segi enam reguler (yang juga merupakan kode yang valid, tetapi semua spasi putih adalah opsional dalam Hexagony). Berikut adalah kode yang tidak dilipat dalam semua ... yah saya tidak ingin mengatakan "cantik":
Penjelasan
Saya bahkan tidak akan mencoba dan mulai menjelaskan semua jalur eksekusi yang berbelit-belit dalam versi golf ini, tetapi algoritme dan alur kontrol keseluruhannya identik dengan versi yang tidak diklik ini yang mungkin lebih mudah dipelajari untuk orang yang benar-benar penasaran setelah saya menjelaskan algoritme:
Jujur saja, di paragraf pertama aku hanya setengah bercanda. Fakta bahwa kita sedang berurusan dengan siklus enam elemen sebenarnya sangat membantu. Model memori Hexagony adalah kisi heksagonal tak terbatas di mana setiap tepi kisi berisi integer presisi sewenang-wenang yang ditandatangani, diinisialisasi ke nol.
Berikut adalah diagram tata letak memori yang saya gunakan dalam program ini:
Bit lurus panjang di sebelah kiri digunakan sebagai string diakhiri 0 dengan
a
ukuran sewenang-wenang yang dikaitkan dengan huruf r . Garis putus-putus pada huruf-huruf lain mewakili jenis struktur yang sama, masing-masing diputar 60 derajat. Awalnya, penunjuk memori menunjuk pada tepi berlabel 1 , menghadap ke utara.Bit linier pertama dari kode mengatur "bintang" tepi pada huruf-huruf
roygbp
serta mengatur tepi awal1
, sehingga kita tahu di mana siklus berakhir / dimulai (antarap
danr
):Setelah ini, kita kembali ke tepi berlabel 1 .
Sekarang ide umum dari algoritma ini adalah ini:
e
tepi yang berlabel ? , karena selama siklus tidak lengkap, kita harus mengasumsikan bahwa kita harus memakan karakter ini juga. Setelah itu, kami akan bergerak di sekitar cincin ke karakter berikutnya dalam siklus.e
dalam ? tepi dengann
s, karena sekarang kami ingin siklus yang tetap pada kalung itu. Kemudian kita beralih ke kode pencetakan.e
dann
). Kemudian kami mencari tepi 1 (untuk melewati sisa siklus yang berpotensi tidak lengkap) sebelum pindah ke kode pencetakan juga.e
untuk setiap karakter. Lalu pindah ke ? edge terkait dengan karakter. Jika negatif, kami cukup menghentikan program. Jika positif, kami cukup mencetaknya dan beralih ke karakter berikutnya. Setelah kami menyelesaikan siklus, kami kembali ke langkah 2.Hal lain yang mungkin menarik adalah bagaimana saya menerapkan string ukuran sewenang-wenang (karena ini adalah pertama kalinya saya menggunakan memori tidak terbatas dalam Hexagony).
Bayangkan kami di beberapa titik di mana kita masih membaca karakter untuk r (sehingga kita dapat menggunakan diagram seperti) dan sebuah [0] dan sebuah 1 telah diisi dengan karakter (segala sesuatu utara-barat dari mereka masih nol ). Misalnya mungkin kita baru saja membaca dua karakter pertama
og
dari input ke tepi itu dan sekarang sedang membaca ay
.Karakter baru dibaca ke dalam tepi. Kami menggunakan ? edge untuk memeriksa apakah karakter ini sama dengan
r
. (Ada trik yang bagus di sini: Hexagony hanya dapat membedakan antara positif dan non-positif dengan mudah, jadi memeriksa kesetaraan melalui pengurangan itu menjengkelkan dan membutuhkan setidaknya dua cabang. Tetapi semua huruf kurang dari faktor 2 dari satu sama lain, jadi kita dapat membandingkan nilai dengan mengambil modulo, yang hanya akan memberikan nol jika sama.)Karena
y
berbeda darir
, kami memindahkan (unlabelled) tepi kiri di dan saliny
sana. Kita sekarang bergerak lebih jauh di sekitar segi enam, menyalin karakter salah satu ujung lanjut setiap kali, sampai kami memilikiy
di seberang tepi di . Tapi sekarang sudah ada karakter dalam [0] yang tidak ingin kita timpa. Sebaliknya, kita "drag" yangy
sekitar segi enam berikutnya dan memeriksa sebuah 1 . Tapi ada karakter di sana juga, jadi kita pergi segi enam lebih jauh. Sekarang [2] masih nol, jadi kami saliny
ke dalamnya. Penunjuk memori sekarang bergerak kembali di sepanjang tali menuju cincin bagian dalam. Kita tahu kapan kita telah mencapai awal string, karena tepi (tidak berlabel) antara a [i] semuanya nol sedangkan ? positif.Ini mungkin akan menjadi teknik yang berguna untuk menulis kode non-sepele dalam Hexagony secara umum.
sumber
Hexagony , 169 byte
Saya terinspirasi oleh jawaban Martin Büttner (ini esolang-nya juga) dan memutuskan saya bisa melakukannya dalam ukuran 8. (Saya yakin itu mungkin juga dalam ukuran 7, tetapi sangat sulit. Saya sudah menghabiskan empat hari tanpa -Hentikan ini.)
Ditata secara heksagon:
Program tidak benar-benar menggunakan
#
instruksi, jadi saya telah menggunakan karakter itu untuk menunjukkan sel mana yang sebenarnya tidak digunakan. Selain itu, setiap sel no-op yang dilalui hanya dalam satu arah adalah cermin (misalnya_
jika dilintasi secara horizontal), sehingga Anda tahu semua.
karakter dilintasi lebih dari satu arah.Penjelasan
Pada awalnya, kami menjalankan urutan instruksi
r''o{{y''g{{b''p"")"
. Ini berserakan sedikit sembarangan di kode karena saya meremasnya setelah saya menulis segalanya. Saya menggunakan]
untuk beralih ke penunjuk instruksi berikutnya beberapa kali; dengan cara ini saya pada dasarnya bisa teleport ke sudut lain segi enam. Seluruh program dijalankan oleh penunjuk instruksi # 3.Memori sekarang terlihat sebagai berikut, dengan ujung-ujung penting yang berlabel nama yang akan saya gunakan dalam penjelasan ini:
Tepi berlabel berarti sebagai berikut:
in
: Kami menggunakan tepi ini untuk menyimpan karakter yang kita baca dari STDIN.%
: Kami menggunakan tepi ini untuk melakukan operasi modulo pada karakter dibaca dari STDIN (in
) dan saat ini karakter “valid” (r
,o
, dll), yang akan0
jika mereka sama. Saya mencuri trik ini dari jawaban Martin Büttner, tetapi program lainnya berbeda.#
: Selama kita membaca karakter "tidak valid" (yaitu warna yang perlu kita makan), kita menambah keunggulan ini. Jadi, edge ini mengingat berapa banyak yange
perlu kita hasilkan nanti.r?
: Selalu0
kecuali di mana bagianr
(merah) berada. Ini memberitahu kita ketika kita telah menyelesaikan suatu siklus.Program ini menghasilkan sebagai berikut:
#
. Jika tidak, pindah ke segmen memori berikutnya dalam urutan searah jarum jam.r?
positif, kami telah membuat seluruh revolusi. Buat putaran lengkap dan hasilkan#
e
s dan 1n
per segmen. Ini mengatur masing-masing#
kembali ke0
. (e
Letaknya ditempatkan pada tepi yang tidak berlabel, tetapi untukn
kami menyalahgunakan#
ujungnya, yang kami atur0
menggunakan*
(perkalian) setelahnya, yang berfungsi karena kami tahu bahwa semua%
tepinya nol pada saat ini.)#
+1e
hingga Anda kembali ke tempatr?
yang positif, lalu keluar.Setelah selesai berjalan, memori terlihat kira-kira sebagai berikut di akhir. Anda akan melihat tepi berisi
101
(kode ASCIIe
); salah satuin
ujungnya adalah-1
(EOF); semua#
tepi berada pada 0; dan penunjuk memori berakhir dir?
tepi positif .sumber
Retina ,
1488579 byteAnda dapat menjalankan ini dari file sumber tunggal dengan
-s
bendera juru bahasa.Penjelasan
Mari kita dapatkan hal-hal sederhana terlebih dahulu:
Tambahkan
#roygbp
ke akhir string, yang akan kita gunakan untuk menghitung siklus huruf secara dinamis.Langkah (panjang) berikutnya mencari tahu loop mana yang harus disimpan dan menggantikannya
n
. Kami akan melihat bagaimana ini bekerja sedikit.Ini menghilangkan helper pencarian kami di akhir string.
Ini menggantikan semua karakter yang tidak diganti pada langkah kedua dengan
e
, menyelesaikan transformasi.Sekarang mari kita kembali ke langkah kedua.
Struktur dasar menggunakan trik, yang saya temukan beberapa bulan lalu untuk mengganti karakter yang dipilih dalam pertandingan global:
di mana
...
sesuai dengan pola kompleks yang sewenang-wenang. Ini cocok dengan karakter yang akan diganti.
dan kemudian mulai melihat ke belakang (yang harus Anda baca dari kanan ke kiri). Tampilan di balik menangkap semuanya hingga karakter yang cocok ke dalam grupprefix
. Kemudian beralih ke tampilan depan , yang sekarang dimulai dari awal string dan dapat berisi pola yang kompleks. Setelah karakter yang ingin kami ganti dalam pola itu, kami menempatkan tampilan opsional di belakang , yang memeriksa apakahprefix
grup cocok di sini. Jika ya, itu menangkap string kosong ke dalamflag
kelompok. Jika tidak, karena itu opsional, itu tidak mempengaruhi keadaan mesin regex sama sekali dan diabaikan. Akhirnya, setelah lookahead berhasil dicocokkan, hanya\k<flag>
bagian ujung yang tersisa yang hanya cocok jika bendera ditetapkan pada beberapa titik selama perhitungan.Sekarang mari ungolf regex panjang sedikit dengan menggunakan kelompok bernama dan mode freespacing:
Saya harap Anda mengenali garis besar umum dari atas, jadi kita hanya perlu melihat apa yang saya isi
...
.Kami ingin menangkap karakter berikutnya dalam siklus ke grup
char
. Kami melakukan ini dengan juga mengingat string dari#
ke karakter saat ini dicycle
. Untuk mendapatkan karakter berikutnya, kami menggunakan lookahead untuk mencari#
. Sekarang kami mencoba untuk mencocokkancycle
dan kemudian mencocokkan karakter berikutnya dichar
. Ini biasanya dimungkinkan, kecualichar
karakter terakhirp
. Dalam hal ini,\k<cycle>
akan cocok dengan seluruh sisa string dan tidak akan ada karakter yang tersisa untuk ditangkapchar
. Jadi backtracks engine, menghilangkan referensi-balik kecycle
dan hanya cocok dengan karakter pertamar
sebagai gantinya.Sekarang kita memiliki karakter berikutnya dalam siklus
char
, kita mencari kemungkinan kemunculan berikutnya dari karakter itu.*?\k<char>
. Ini adalah karakter yang ingin kami ganti, jadi kami beri tandaprefix
centang setelahnya. Langkah-langkah ini (temukan yang berikutnyachar
dalam siklus, cari kejadian selanjutnya, tetapkan flag jika sesuai) sekarang cukup diulangi dengan a+
.Itulah sebenarnya yang ada untuk menemukan urutan siklik, tetapi kita juga perlu memastikan bahwa kita berakhir pada a
p
. Ini cukup mudah: cukup periksa bahwa nilai yang saat ini disimpan dalamchar
cocok denganp
di akhir string.*\k<char>$
. Ini juga memastikan bahwa string pencarian kami tidak digunakan untuk menyelesaikan siklus yang tidak lengkap, karena kami memerlukan trailingp
untuk pemeriksaan ini.sumber
Python 2,
133 130 126121 byteLoop pertama mendapat siklus, dan yang kedua menghapus siklus yang tidak lengkap
Disimpan 3 byte berkat JF dan 5 dari DLosc
sumber
r
dann
seperti inir=n=''
:?R=r.count
tidak bekerja seperti string yang berubah jadiR
adalah''.count
bahkan ketikar
berubah.Perl 5,
7665 byteSejumput ekspresi reguler murni murni.
Pertama menemukan apa yang tidak boleh dimakan. Apa yang tersisa bisa dimakan.
Uji
sumber
[^o]*
dll., Dapatkah Anda menggunakan.*?
(non-greedy quantifier)?\s
sebagai ganti\n
dalam kelas karakter negatif dari versi pertama.r(.*?)o(.*?)y(.*?)g(.*?)b(.*?)p
n$1n$2n$3n$4n$5n
[^n\s]
e
(4 file, 57 byte).Lua, 101 byte
Menggunakan pola Lua secara kreatif; Saya pikir ini pendekatan yang menarik.
Ia mengganti semua karakter yang tidak dimakan dengan "*", menggantikan semua karakter alfanumerik dengan "e", lalu mengganti semua "*" dengan "n".
sumber
Javascript (ES6), 118
Biola diuji di Firefox. Saya mendengar Chrome mendukung fungsi panah sekarang, tetapi saya belum mengujinya di Chrome.
Tidak Disatukan:
sumber
...
notasi.melongo, 96
Membangun pola pencarian
"([^r]*)r([^o]*)o([^y]*)y([^g]*)g([^b]*)b([^p]*)p"
dan penggantian"\\1n\\2n\\3n\\4n\\5n\\6n"
. Setelah penggantian itu menyatakan semua makanan ("e"), itu bukan bagian dari pelangi lengkap.Kombinasi ini secara otomatis memastikan, bahwa tidak ada pelangi akan dirugikan selama operasi ini, dan tidak ada pelangi yang terputus muncul di akhir.
sumber
Pyth, 42 byte
Cobalah online: Demonstrasi
sumber
CJam, 41 byte
Pendekatan brute-force yang mencoba semua variasi makan / tidak makan dan memilih salah satu yang menghasilkan kalung terpanjang dan valid.
Cobalah online di juru bahasa CJam .
sumber
CJam, 50 byte
Cobalah online
Ini sedikit lebih lama dari beberapa kiriman lainnya, tetapi sangat efisien dengan kompleksitas linier. Memindai melalui string input, dan mencocokkan karakter satu per satu.
Bagian inti dari algoritma ini sebenarnya cukup kompak. Sekitar setengah dari kode adalah untuk menghapus siklus tidak lengkap di akhir.
sumber
C90, 142-146 byte (hingga 119, tergantung)
Beroperasi dalam waktu linier untuk memakan loop buah secara efisien yang tidak dapat menjadi bagian dari pelangi yang cantik. Kemudian, sebuah postprocess membunuh semua loop parsial di bagian akhir.
Berikut ini empat versi:
Versi 1 (146 byte), panggilan dengan
[name] [string]
:main(int a,char**b){char*v=b[1],*s="roygbp",i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';while(k-->0)v[--i]='e';puts(v);}
Versi 2 (142 byte), panggil dengan
[name] [string] [rainbow order]
:main(int a,char**b){char*v=b[1],*s=b[2],i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';while(k-->0)v[--i]='e';puts(v);}
Ini memungkinkan Anda untuk menentukan pesanan pelangi Anda sendiri dengan warna apa pun yang Anda inginkan asalkan tidak
n
atau tidake
. Ini sebenarnya membuat kode lebih pendek!Versi 3 (123 byte), sebut seperti versi 1: Yang
main(int a,char**b){char*v=b[1],*s="roygbp",i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';puts(v);}
ini memberi Anda pelangi sebanyak mungkin! Pelangi trailing tidak lengkap menunjukkan janji! Kita seharusnya tidak memakannya!
Versi 4 (119 byte), panggilan seperti versi 2:
main(int a,char**b){char*v=b[1],*s=b[2],i=0,k=0;for(;v[i];++i)if(s[k]==v[i]){++k;k%=6;v[i]='n';}else v[i]='e';puts(v);}
Sama seperti versi 3, tetapi JENIS RAINBOW MOAR!
Batasan kecil: mesin harus memiliki karakter yang sudah ditandatangani (case umum), dan string harus cukup pendek. Menghasilkan jejak
\n
untuk kejelasan.Versi 1 adalah satu-satunya yang jelas melewati persyaratan, meskipun versi 2 dapat diperdebatkan. Versi 3 dan 4 adalah interpretasi pertanyaan yang kurang benar (tapi masih menyenangkan).
sumber
Pyth, 38 byte
Saya tahu ini jauh lebih lama dari jawaban orlp, tetapi yang ini berjalan dalam waktu linier: o)
Cobalah di sini .
Secara singkat, program ini menggantikan semua karakter setelah 'p' akhir dengan spasi, lalu beralih ke setiap karakter dalam string yang dihasilkan. Jika karakter adalah yang berikutnya dalam urutan 'roygbp', cetak 'n', jika tidak cetak 'e'.
Saya kesulitan menemukan cara yang lebih singkat untuk memproses string input.
_>_zJ
khususnya terasa canggung, tetapi<Jz
tidak memberikan string yang diperlukan saatJ == 0
, yaitu ketika input berakhir dengan 'p'.sumber
Haskell, 138 byte
g
melakukannya.sumber
f
danz
sebagai infix:'n'%'n'='n'
dll. Juga, beberapa tanda kurung dalam definisig
dapat dihapus$
.Javascript (ES6),
8582 byteAturan "kalung harus diakhiri dengan ungu" pada awalnya merupakan rintangan besar, meningkatkan skor saya dari 66 menjadi 125, tetapi saya menemukan cara yang lebih singkat untuk itu (untungnya!).
Penjelasan:
Kode ini memotong setiap karakter dalam input dan menggantikan masing-masing dengan
r
ataue
dengan logika ini:p
, DAN karakter adalah yang berikutnya dalam pelangi, simpan (ganti dengann
).e
).Tidak Disatukan:
Saran diterima!
sumber
Python 2, 254 byte
Loop!
Permisi permainan kata-kata. : P
sumber