Anda dapat menulis sebuah program atau fungsi yang menerima bilangan bulat ganjil, positif n
, di mana n >= 3
, baik sebagai argumen fungsi, argumen baris perintah, atau pada STDIN (atau setara dengan sistem Anda), dan mencetak ke STDOUT (atau setara sistem) spiral ASCII yang berputar ke dalam searah jarum jam di mana tepi atas persis n
panjang karakter. Tepi kanan pertama harus n+1
panjang karakter, jelas. Contohnya,
Memasukkan:
11
Keluaran:
***********
*
********* *
* * *
* ***** * *
* * * * *
* * * * * *
* * *** * *
* * * *
* ******* *
* *
***********
Tangkapan:
- Program Anda harus menggunakan tidak lebih dari
O(log n)
memori . - Program Anda hanya dapat mencetak karakter
*
(ASCII 42),(ASCII 32),
<CR>
(ASCII 13) dan<LF>
(ASCII 10). - Program Anda harus mencetak string, bukan mengembalikannya dari fungsi.
- Pembatasan Big-O hanya pada memori , tidak ada batasan pada runtime .
- Baris baru tambahan adalah opsional.
- Jika bahasa Anda tidak mendukung tipe integer besar, Anda tidak harus mendukung lebih tinggi dari apa yang didukungnya, tetapi Anda mungkin tidak menggunakan ini sebagai trik untuk mengatakan "oh, well, saya tidak harus mendukung di atas X jadi saya hanya dapat membuat array besar ukuran maksimum setiap kali "
Celah standar dilarang, seperti biasa.
n
dalam memori O (1).n
membutuhkanlog n
bit. Semakinn
besar, demikian pula ruang yang dibutuhkan untuk menyimpannya. Apakah Anda mungkin mengatakan untuk melakukan ini dengan sejumlah variabel?n
?Jawaban:
C,
125121 byteVersi golf Ini tidak memiliki variabel
k
. Variabelk
digunakan dalam versi yang tidak diklik hanya untuk membantu keterbacaan. Jugafor
persyaratan loop diatur ulang dan satu set yang tidak perlu{}
dihapus. Set lain{}
dapat dihilangkan dengan bermigrasiputs("")
di dalam kurungj
loop di posisi inisialisasi, tetapi ini berarti baris baru di awal output, jadi saya belum melakukannya.Mencetak
n
lebar dengann+1
spiral tinggi seperti contohnya.Penjelasan
Pada dasarnya saya membagi dua nilai
n
(pembulatan ke bawah) dan menjalankan dua loop: satu luari
dari-n/2-1
ken/2+1
untuk mencetak baris (i=0
ditekan sehingga kita mendapatkann+1
baris) dan satu bagian dalamj
dari (-n/2
ken/2
Kami menggunakan untuk mencetak karakter.)expression & 1
Untuk mencetak garis-garis , dan kondisij*j<i*i
untuk memutuskan apakah akan mencetak garis-garis vertikal atau horizontal (vertikal di sisi-sisi di mana besaran absoluti
lebih besar, dan horizontal di atas dan bawah.) Penyesuaian+n
diperlukan untuk membantu penghentian yang benar tergantung pada apakahn/2
aneh atau tidak. bahkan.k
biasanya 1, dan memberikan penyesuaian untuk fakta bahwa nilai absoluti
rentang dari 1 hinggan/2+1
nilai absolutj
rentang dari 0 hinggan/2
. Jikak
selalu 1 kita akan mendapatkan persegi panjang konsentris, tetapi itu terbalik ke 0 ketikai==j&i<=0
sehingga baris diagonal sel terbalik, menghasilkan spiral.ungolfed dalam program tes
Keluaran
sumber
C, 118 byte
Kode sebelum golf terakhir:
Pengamatan kuncinya adalah polanya hampir merupakan serangkaian kotak konsentris. Dengan sedikit kerutan:
y = x + 1
diagonal perlu dibalik hingga ke tengah bentuk.Untuk selebihnya, kode ini hanya mengulang semua posisi, menghitung jarak Chebyshev dari pusat untuk setiap posisi, dan memancarkan satu dari dua karakter tergantung pada jarak genap atau ganjil. Dan memancarkan baris baru untuk posisi terakhir setiap baris.
Karena hanya ada beberapa variabel skalar, dan karakter dipancarkan satu per satu, penggunaan memori jelas konstan.
sumber
p
saya pikir Anda salah meta.codegolf.stackexchange.com/q/4939/15599 . Saya juga tidak yakin tentang mendeklarasikan variabel global saat mengirimkan fungsi. Jelas jawaban saya akan lebih pendek 4 byte jika saya melakukan ini. Saya sudah memulai posting meta meta.codegolf.stackexchange.com/q/5532/15599p
.C ++, 926 bytes
Ini tidak elegan, tetapi tidak memakan banyak memori untuk n besar. Lebih jauh lagi, ada (hampir pasti) sekitar 20 karakter yang dapat di-pegolf lebih jauh, tetapi saya tidak tahan melihatnya lagi.
Penjelasan Singkat:
Ini membagi garis dalam spiral menjadi dua jenis: yang dengan ****** di tengah, dan yang dengan \ s \ s \ s \ s \ s \ s di tengah. Maka jelas bahwa setiap baris terdiri dari beberapa "*" s, tengah, dan beberapa "*". Mencari tahu persis berapa banyak dari setiap hal itu sederhana jika Anda melihat polanya cukup lama. Yang sulit adalah mencetak pusat spiral yang saya kode pada dasarnya menggunakan kondisional. Ini akhirnya menjadi berguna karena saluran *** dan switch berubah menjadi ganjil / bahkan di sana.
Tes:
Input:
55
(Saya pikir yang besar terlihat paling keren)Keluaran:
Memasukkan:
3
Keluaran:
Catatan: Saya bukan seorang ilmuwan komputer / mahasiswa CS, dan saya tidak tahu bagaimana membuktikan bahwa ini menggunakan memori O (log n). Saya hanya bisa menentukan apa yang harus dilakukan berdasarkan tautan dalam pertanyaan. Saya akan berterima kasih jika seseorang dapat mengkonfirmasi / menolak jika jawaban ini valid. Logika saya untuk validitas jawaban ini adalah bahwa ia tidak pernah menyimpan variabel ukuran berdasarkan n kecuali input itu sendiri. Sebagai gantinya, untuk loop yang berjalan n kali menghitung nilai integer berdasarkan pada n. Ada jumlah yang sama dari nilai-nilai itu terlepas dari input.
Note2: Ini tidak berfungsi untuk n = 1 karena metode saya berurusan dengan tengah. Ini akan mudah untuk diperbaiki dengan persyaratan, jadi jika ada yang berada dalam beberapa karakter jawaban saya, saya akan memperbaikinya;)
Bermain dengannya di ideone.
sumber
n
. Contoh khas yang tidak memenuhi persyaratan adalah beberapa jenis string / buffer / array yang menampung garis keluaran lengkap.n=1
, karena saya tidak menganggap casing khusus menarik.Haskell, 151 byte
Contoh penggunaan:
Berkat kemalasan Haskell, ini berjalan dalam memori konstan. Ini menggunakan pendekatan yang jelas, yaitu perulangan
y
danx
dan memilih antara*
dan, tergantung pada
x
resp.y
genap atau ganjiln/2
genap atau ganjilsumber
Gangguan Umum - 346
Solusi berulang dengan penggunaan memori yang konstan. Hal-hal di atas banyak menggunakan variabel reader
#n=
dan#n#
. Meskipun ada pendekatan yang lebih langsung, di sini saya mulai dengan fungsi rekursif dan memodifikasinya untuk mensimulasikan rekursi dengangoto
pernyataan: ini mungkin tidak dapat dibaca.Output untuk semua nilai input dari 0 hingga 59 .
Versi rekursif asli, dengan informasi debug
(catatan:
terpri
berartinewline
)Sebagai contoh:
Lihat juga tempel ini dengan semua hasil dari 0 hingga 59 (tidak sama dengan di atas, yang ini lebih verbose).
Versi berulang, dengan informasi debug
sumber
n
dan tumpukan panggilan tumbuh sesuai, tetapi dalam kasus ini, kita dapat mensimulasikan rekursi dengan dua loop: satu dengann
penurunan dand
peningkatan (sampai n <= 3 ), dan satu lagi dengand
menurun ke nol. Saya tidak punya banyak waktu untuk mengerjakan ini sekarang, tetapi saya akan mencoba memperbarui jawabannya. Btw, ada cara yang lebih langsung untuk mencetak spiral, tetapi menyenangkan mencoba mendefinisikannya secara rekursif.CJam, 72 byte
Ini adalah konversi solusi C saya yang cukup langsung ke CJam. Tidak sesingkat yang biasanya Anda harapkan dari solusi CJam, tetapi yang ini benar-benar menderita dari pembatasan memori. Manfaat umum dari membangun hasil pada stack yang akan dibuang secara otomatis di akhir, dan menggunakan operasi daftar / string yang mewah, semua keluar jendela. Ini menghasilkan dan mengeluarkan solusi satu karakter pada satu waktu. Tumpukan hanya berisi beberapa bilangan bulat saat runtime, dan kosong di akhir.
Meskipun itu bukan tampilan yang bagus menggunakan bahasa golf, itu masih jauh lebih pendek daripada kode C hanya karena notasi lebih kompak.
Penjelasan:
sumber