Tulis penulis buku

10

Berikut ini adalah penggambaran buku terbuka ASCII yang cukup sederhana:

|\
| \
|  \
|   \
|    \__________
|    ||         |
|    || Lorem i |
\    || psum do |
 \   || lor sit |
  \  ||  amet,  |
   \ || consect |
    \||_________|

Perhatikan bahwa porsi teks hanya di halaman kanan dan lebar 7 karakter kali 5 tinggi. Perhatikan juga bahwa tepi atas buku ini memiliki 5 garis miring terbalik dan 10 garis bawah. 10 berasal dari lebar teks ditambah 3 dan 5 adalah setengah dari 10.

Dengan menggunakan format skala yang sama kita dapat mengubah ukuran buku untuk memiliki area teks w luas karakter dan h tinggi, di mana w adalah setiap aneh bilangan bulat positif dan h adalah setiap bilangan bulat positif.

Beberapa w × h buku: 1 × 1, 1 × 2, 3 × 2

                    |\
          |\        | \
|\        | \____   |  \______
| \____   | ||   |  |  ||     |
| ||   |  | || L |  \  || Lor |
\ || L |  \ || o |   \ || em  |
 \||___|   \||___|    \||_____|

Jumlah garis bawah di atas selalu w + 3 dan jumlah garis miring terbalik selalu ( w + 3) / 2.

Tujuan

Tulis progam yang menggunakan nama file dan w dan h sebagai argumen baris perintah, dan output buku dengan dimensi teks tersebut menjadi stdout, menampilkan isi file.

Ketika file memiliki lebih banyak teks daripada yang akan muat dalam satu halaman Nkunci harus mencetak halaman berikutnya dan Bharus kembali halaman. Tidak ada yang terjadi jika Bditekan dari halaman pertama atau Nditekan dari halaman terakhir. Program harus berhenti ketika Qtombol dipukul.

Contoh

Misalkan f.txtberisi Lorem ipsum dol?dan pengguna telah menekan urutan tombol N N B N N Q. Program harus menjalankan sesuatu seperti ini:

>>> bookmaker f.txt 3 2
|\
| \
|  \______
|  ||     |
\  || Lor |
 \ || em  |
  \||_____|

|\
| \
|  \______
|  ||     |
\  || ips |
 \ || um  |
  \||_____|

|\
| \
|  \______
|  ||     |
\  || dol |
 \ || ?   |
  \||_____|

|\
| \
|  \______
|  ||     |
\  || ips |
 \ || um  |
  \||_____|

|\
| \
|  \______
|  ||     |
\  || dol |
 \ || ?   |
  \||_____|

>>>

Perhatikan bahwa ada baris baru setelah setiap buku dan tidak ada spasi tambahan. Ini wajib diisi.

Catatan

  • Anda dapat menganggap file hanya berisi karakter ASCII yang dapat dicetak (hex 20 hingga 7E).
  • Cetak satu karakter di setiap tempat yang tersedia, terlepas dari batasan kata.
  • w dan h adalah argumen opsional yang masing-masing default ke 7 dan 5. Program Anda tidak akan diberikan keduanya atau keduanya. (Anda dapat berasumsi bahwa input selalu terbentuk dengan baik.)
  • Isi semua ruang teks kosong di halaman terakhir dengan spasi.
  • Q harus tetap diminta untuk berhenti jika hanya ada satu halaman.

Kemenangan

Program terpendek dalam byte setelah bonus diterapkan menang.

Bonus

  • Hapus spasi terdepan sehingga setiap baris dimulai dengan kata (atau segmen kata). misalnya | amet, |dalam contoh pertama akan menjadi | amet, c |. (-30 byte)
  • Kosongkan layar buku yang ditarik sebelumnya setelah NatauB ditekan (dan Tjika Anda melakukan bonus setelah ini) sehingga buku itu tampak seperti halaman yang berubah di tempat. (-20 byte)
  • Buat Ttombol langsung beralih antara teks yang ditarik dari kiri ke kanan atas-ke-bawah (default), ke kiri-ke-kanan atas-ke-bawah. Jika Anda melakukan bonus pertama itu harus bekerja untuk kolom dalam mode top-to-bottom. (-100 byte)

    Jadi misalnya:

    |\
    | \
    |  \______
    |  ||     |
    \  || Lor |
     \ || em  |
      \||_____|
    

    menjadi

    |\
    | \
    |  \______
    |  ||     |
    \  || Lrm |
     \ || oe  |
      \||_____|
    
Hobi Calvin
sumber
bonus "bersihkan layar" tampaknya merupakan bonus bahasa daripada bonus kode ...
John Dvorak
Anda mengatakan dalam teks bahwa nama file dan dimensi buku berasal dari STDIN, tetapi kemudian Anda melanjutkan untuk mengambilnya sebagai argumen. Lalu, mana yang benar?
John Dvorak
Saya perhatikan, terima kasih atas pemberitahuan Anda, bahwa tidak ada spasi tambahan. Tetapi apakah kita diharuskan untuk tidak memasukkan mereka juga?
John Dvorak
@ JanDvorak Maaf, maksud saya mereka hanya argumen. Anda tidak perlu spasi tambahan. Bisakah Anda memberi contoh di mana kliring menjadi "kode bonus"?
Calvin Hobbies
1
@JanDvorak, menurut saya lebih merupakan bonus "jalankan program di terminal POSIX". \033[2J\033[;H
Peter Taylor

Jawaban:

3

C # 535bytes

Skor kode 655bytes -20byte bonus untuk kliring, dan -100byte bonus untuk kunci T ... Saya pikir, tidak bisa mengatakan saya yakin saya belum melewatkan sesuatu di spec

Saya dapat mencoba dan menutup loop dengan meminta metode W mengembalikan argumen s, tetapi itu membutuhkan usaha, jadi tidak ada janji.

Kode golf:

using C=System.Console;using K=System.ConsoleKey;class P{static void W(int x,int y,string s){C.SetCursorPosition(x,y);C.Write(s);}static void Main(string[]a){int b=a.Length,w=b>0?int.Parse(a[0]):7,h=b>1?int.Parse(a[1]):5,p=0,i,j,o,T=1;var F=System.IO.File.ReadAllText("f.txt");b=(w+3)/2;S:C.Clear();for(i=0;i<w+3;i++){W(o=i+b+1,b-1,"_");W(o,h+b+1,"_");}for(i=0;i<h+2;){W(0,i,"|");W(b,o=i+++b,"||");W(b+w+4,o,"|");}for(i=0;i<b;){W(i+1,i,"\\");W(i,++i+h+1,"\\");}for(i=0;i<w;i++)for(j=0;j<h;)if((o=T>0?j++*w+p+i:i*h+p+j++)<F.Length)W(i+b+3,j+b,F[o]+"");K k=C.ReadKey(1>0).Key;p+=k==K.N&p<F.Length-w*h?w*h:k==K.B&p>0?-w*h:0;T=k!=K.T?T:-T;if (k!=K.Q)goto S;}}

Diformat sedikit:

using C=System.Console;
using K=System.ConsoleKey;

class P
{
    static void W(int x,int y,string s)
    {
        C.SetCursorPosition(x,y);
        C.Write(s);
    }

    static void Main(string[]a)
    {
        int b=a.Length,w=b>0?int.Parse(a[0]):7,h=b>1?int.Parse(a[1]):5,p=0,i,j,o,T=1;
        var F=System.IO.File.ReadAllText("f.txt");
        b=(w+3)/2;

    S:
        C.Clear();

        for(i=0;i<w+3;i++)
        {
            W(o=i+b+1,b-1,"_");
            W(o,h+b+1,"_");
        }

        for(i=0;i<h+2;)
        {
            W(0,i,"|");
            W(b,o=i+++b,"||");
            W(b+w+4,o,"|");
        }

        for(i=0;i<b;)
        {
            W(i+1,i,"\\");
            W(i,++i+h+1,"\\");
        }

        for(i=0;i<w;i++)
            for(j=0;j<h;)
                if((o=T>0?j++*w+p+i:i*h+p+j++)<F.Length)
                    W(i+b+3,j+b,F[o]+"");

        K k=C.ReadKey(1>0).Key;
        p+=k==K.N&p<F.Length-w*h?w*h:k==K.B&p>0?-w*h:0;
        T=k!=K.T?T:-T;
        if (k!=K.Q)
            goto S;
    }
}
VisualMelon
sumber
4

Jawa, 1039 1001 993 953 946

Dengan bonus: Hapus spasi terdepan (-30 byte) -> 1009 971 963 923 916

Membersihkan layar tidak sesuai dengan java (kecuali jika saya hanya mencetak beberapa baris baru. Tetapi kemudian pengguna harus menggunakan ukuran konsol yang benar)

Kode:

import java.io.*;import java.util.*;class B {static int w=7,h=5,p,l;static String t="",o,u=" ",y="\\";public static void main(String[]c)throws Exception{if(c.length>1){w=Integer.valueOf(c[1]);h=Integer.valueOf(c[2]);}Scanner s=new Scanner(new FileReader(c[0]));while(s.hasNext()){t+=s.nextLine();}l=t.length();s = new Scanner(System.in);while(true){int q=w+3,z=q/2,i=0,j=0,a=w*h;o="";for(;i<z;i++)o+="\n|"+r(u,i)+y;o+=r("_", q);for(;j<h+2-z;j++){o+="\n|"+r(u,i-1)+"||";if(j==0)o+=r(u,w+2);else o+=u+t()+u;o+="|";}for(;i>0;i--){o+="\n"+r(u,z-i)+y+r(u,i-1)+"||";if(i>1)o+=u+t()+" |";}o+=r("_",w+2)+"|";System.out.print(o);switch(s.next().charAt(0)){case'Q':return;case'B':p=p>a?p-2*a:p-a;break;case'N':p=p>l?p-a:p;}}}static String t(){int e=p+w>l?l:p+w;String r="";if(p<=e)r=t.substring(p,e);r=r.replaceAll("^\\s+","");int y=r.length();p+=w;return y==w?r:r+r(u,w-y);}static String r(String s,int i){return new String(new char[i]).replace("\0",s);}

Cantik:

import java.io.*;import java.util.*;
class B {
    static int w=7,h=5,p,l; // w = text width, h = text height, p = current position in text
    static String t="",o,u=" ",y="\\";
    public static void main(String[]c)throws Exception{
        // get w and h of text, default to 7x5
        if(c.length>1){w=Integer.valueOf(c[1]);h=Integer.valueOf(c[2]);}
        // read file
        Scanner s=new Scanner(new FileReader(c[0]));while(s.hasNext()){t+=s.nextLine();}         
        l=t.length();
        // read input
        s = new Scanner(System.in);
        while(true){
            // print book
        int q=w+3,z=q/2,i=0,j=0,a=w*h; // q = number of underscores at the top, z = number of backslashes
        o="";
        // print top of book
        for(;i<z;i++)o+="\n|"+r(u,i)+y;
        o+=r("_", q);
        // print middle of book (hp-z lines). right now: i = z -1
        for(;j<h+2-z;j++){o+="\n|"+r(u,i-1)+"||";if(j==0)o+=r(u,w+2);else o+=u+t()+u;o+="|";}
        // print bottom of book
        for(;i>0;i--){o+="\n"+r(u,z-i)+y+r(u,i-1)+"||";if(i>1)o+=u+t()+" |";}
        o+=r("_",w+2)+"|";
        System.out.print(o);
        // user input
            switch(s.next().charAt(0)){                
                case'Q':return;
                case'B':p=p>a?p-2*a:p-a;break;
                case'N':p=p>l?p-a:p;
            }
        }       
    }

    /** return w characters of string t, from given position p. increase p*/
    static String t(){
        int e=p+w>l?l:p+w;
        String r="";        
        if(p<=e)r=t.substring(p,e);
        r=r.replaceAll("^\\s+",""); // remove leading spaces (cost:28 chars)
        int y=r.length();
        p+=w;
        return y==w?r:r+r(u,w-y);
    }
    static String r(String s,int i){return new String(new char[i]).replace("\0",s);} // repeat given string i times

Jika program tidak harus berjalan selamanya, saya juga bisa menyimpan beberapa byte dengan menghapus loop sementara dan hanya memanggil main.

Ini tidak optimal, tapi ini awal.

tim
sumber
Saya cukup yakin Anda tidak memerlukan publickata kunci ... Juga, tidak import java.*;berfungsi?
@professorfish saya memikirkan import java.*;juga, tetapi tidak berhasil. Dan metode utama memang harus tepat public static void main(String[]c)(termasuk public), jika tidak maka tidak dikenali. Tetapi kelas tentu saja tidak harus terbuka untuk umum, tangkapan yang bagus.
tim