Viết một người viết sách


10

Dưới đây là mô tả ASCII khá đơn giản về một cuốn sách mở:

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

Lưu ý rằng phần văn bản chỉ ở trên trang bên phải và có 7 ký tự rộng 5 ký tự. Cũng lưu ý rằng cạnh trên của cuốn sách có 5 dấu gạch chéo ngược và 10 dấu gạch dưới. Số 10 xuất phát từ chiều rộng văn bản cộng với 3 và 5 là một nửa của 10.

Sử dụng cùng một định dạng tỷ lệ, chúng ta có thể thay đổi kích thước cuốn sách để có một vùng văn bản w ký tự rộng và h cao, trong đó w là bất kỳ số nguyên dương lẻ nào và h là bất kỳ số nguyên dương nào.

Một số sách w × h : 1 × 1, 1 × 2, 3 × 2

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

Số lượng dấu gạch dưới ở trên cùng luôn là w +3 và số dấu gạch chéo ngược luôn luôn là ( w +3) / 2.

Mục tiêu

Viết một progam lấy tên tệp và wh làm đối số dòng lệnh và xuất một cuốn sách có các kích thước văn bản đó thành thiết bị xuất chuẩn, hiển thị nội dung của tệp.

Khi tệp có nhiều văn bản hơn sẽ vừa trong một trang, Nkhóa sẽ in trang tiếp theo và Bsẽ quay lại một trang. Không có gì xảy ra nếu Bđược nhấn từ trang đầu tiên hoặc Nđược nhấn từ trang cuối cùng. Chương trình sẽ dừng khi Qnhấn phím.

Thí dụ

Giả sử f.txtchứa Lorem ipsum dol?và người dùng đã nhấn chuỗi phím N N B N N Q. Chương trình sẽ chạy một cái gì đó như thế này:

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

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

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

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

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

>>>

Lưu ý rằng có một dòng mới sau mỗi cuốn sách và không có dấu cách. Điều này là bắt buộc.

Ghi chú

  • Bạn có thể giả sử tệp chỉ chứa các ký tự ASCII có thể in (hex 20 đến 7E).
  • In một ký tự ở mỗi vị trí có sẵn, bất kể ranh giới từ.
  • whcác đối số tùy chọn mặc định là 7 và 5 tương ứng. Chương trình của bạn sẽ được cung cấp hoặc không hoặc cả hai. (Bạn có thể cho rằng đầu vào luôn được hình thành tốt.)
  • Điền vào bất kỳ không gian văn bản trống nào trên trang cuối cùng với khoảng trắng.
  • Q vẫn nên được yêu cầu thoát nếu chỉ có một trang.

Chiến thắng

Chương trình ngắn nhất tính bằng byte sau khi tiền thưởng được áp dụng sẽ thắng.

Tiền thưởng

  • Xóa các khoảng trắng hàng đầu để mỗi dòng bắt đầu bằng một từ (hoặc phân đoạn từ). ví dụ | amet, |trong ví dụ đầu tiên sẽ trở thành | amet, c |. (-30 byte)
  • Xóa màn hình của những cuốn sách được vẽ trước đó sau Nhoặc Bđược nhấn (và Tnếu bạn thực hiện phần thưởng sau này) để cuốn sách trông giống như các trang thay đổi của nó. (-20 byte)
  • Tạo Tkhóa ngay lập tức chuyển đổi giữa văn bản được vẽ từ trái sang phải từ trên xuống dưới (mặc định), từ trên xuống dưới từ trái sang phải. Nếu bạn đã thực hiện phần thưởng đầu tiên, nó sẽ hoạt động cho các cột ở chế độ từ trên xuống dưới. (-100 byte)

    Ví dụ:

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

    trở thành

    |\
    | \
    |  \______
    |  ||     |
    \  || Lrm |
     \ || oe  |
      \||_____|
    

phần thưởng "xóa màn hình" dường như là phần thưởng ngôn ngữ hơn là phần thưởng mã ...
John Dvorak

Bạn nói trong văn bản rằng tên tệp và kích thước sách đến từ STDIN, nhưng sau đó bạn tiến hành lấy chúng làm đối số. Đó là cái gì vậy?
John Dvorak

Tôi đã nhận thấy, nhờ thông báo của bạn, rằng không có dấu cách. Nhưng chúng tôi có bắt buộc không bao gồm chúng không?
John Dvorak

@JanDvorak Xin lỗi, ý tôi là họ chỉ là đối số. Bạn cần phải KHÔNG có dấu cách. Bạn có thể đưa ra một ví dụ về nơi thanh toán bù trừ trở thành "phần thưởng mã" không?
Sở thích của Calvin

1
@JanDvorak, đối với tôi, phần lớn là "chạy chương trình trong thiết bị đầu cuối POSIX". \033[2J\033[;H
Peter Taylor

Câu trả lời:


3

C # 535byte

Điểm số là 655byte mã -20byte tiền thưởng để xóa và phần thưởng -100byte cho phím T ... Tôi nghĩ, không thể nói rằng tôi chắc chắn mình đã bỏ lỡ điều gì trong thông số kỹ thuật

Tôi có thể thử và thu gọn các vòng lặp bằng cách có phương thức W trả về đối số s, nhưng điều đó sẽ đòi hỏi nỗ lực, vì vậy không có lời hứa.

Mã đánh gôn:

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;}}

Định dạng một chút:

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;
    }
}

4

Java, 1039 1001 993 953 946

Với phần thưởng: Xóa các khoảng trắng hàng đầu (-30 byte) -> 1009 971 963 923 916

Xóa màn hình không đáng với java (trừ khi tôi chỉ in một vài dòng mới. Nhưng sau đó người dùng phải sử dụng kích thước bàn điều khiển chính xác)

Mã số:

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);}

Đẹp:

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

Nếu chương trình không phải chạy mãi mãi, tôi cũng có thể lưu một số byte bằng cách loại bỏ vòng lặp while và chỉ gọi chính.

Điều này không tối ưu, nhưng đó là một sự khởi đầu.


Tôi khá chắc chắn rằng bạn không cần publictừ khóa ... Ngoài ra, có import java.*;hoạt động không?

@professorfish Tôi cũng nghĩ import java.*;vậy, nhưng nó không hoạt động. Và phương thức chính cần phải chính xác public static void main(String[]c)(bao gồm public), nếu không nó không được công nhận. Nhưng tất nhiên lớp học không cần phải công khai, nắm bắt tốt.
tim
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.