เขียนนักเขียนหนังสือ


10

นี่เป็นภาพ ASCII ที่ค่อนข้างธรรมดาของหนังสือที่เปิดอยู่:

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

ขอให้สังเกตว่าส่วนของข้อความนั้นอยู่ที่หน้าขวาเท่านั้นและมีความกว้าง 7 ตัวอักษรโดยสูง 5 นอกจากนี้โปรดสังเกตว่าขอบด้านบนของหนังสือมี 5 แบ็กสแลชและ 10 ขีด 10 มาจากความกว้างของข้อความบวก 3 และ 5 คือครึ่งหนึ่งของ 10

โดยใช้รูปแบบการปรับขนาดเดียวกันกับที่เราสามารถปรับขนาดหนังสือเล่มนี้จะมีพื้นที่ข้อความWตัวอักษรกว้างและเอชสูงที่Wใด ๆแปลกจำนวนเต็มบวกและเอชเป็นจำนวนเต็มบวกใด ๆ

หนังสือw × hบางเล่ม: 1 × 1, 1 × 2, 3 × 2

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

จำนวนขีดล่างที่ด้านบนจะเป็นw +3 เสมอและจำนวนของเครื่องหมายแบ็กสแลชจะอยู่เสมอ ( w +3) / 2

เป้าหมาย

เขียน progam ที่ใช้ชื่อไฟล์และwและhเป็นอาร์กิวเมนต์บรรทัดคำสั่งและเอาท์พุทหนังสือที่มีขนาดข้อความเหล่านั้นไปยัง stdout โดยแสดงเนื้อหาของไฟล์

เมื่อไฟล์มีข้อความมากกว่าที่จะพอดีในหน้าเดียวNคีย์ควรพิมพ์หน้าถัดไปและBควรกลับไปหน้า ไม่ควรเกิดอะไรขึ้นถ้าBกดจากหน้าแรกหรือNกดจากหน้าสุดท้าย โปรแกรมควรหยุดเมื่อQกดปุ่ม

ตัวอย่าง

สมมติว่าf.txtมีและใช้งานได้กดลำดับที่สำคัญLorem ipsum dol? N N B N N Qโปรแกรมควรใช้งานดังนี้:

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

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

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

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

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

>>>

โปรดสังเกตว่ามีการขึ้นบรรทัดใหม่หลังจากหนังสือทุกเล่มและไม่มีช่องว่างต่อท้าย สิ่งนี้จำเป็น

หมายเหตุ

  • คุณอาจคิดว่าไฟล์นั้นมีอักขระ ASCII ที่พิมพ์ได้เท่านั้น(ฐานสิบหกถึง 20)
  • พิมพ์หนึ่งตัวละครในแต่ละจุดที่มีอยู่โดยไม่คำนึงถึงขอบเขตของคำ
  • wและhเป็นอาร์กิวเมนต์ที่เป็นทางเลือกซึ่งค่าดีฟอลต์คือ 7 และ 5 ตามลำดับ โปรแกรมของคุณจะไม่ได้รับหรือทั้งสองอย่าง (คุณอาจสันนิษฐานว่าอินพุตมีรูปแบบที่ดีเสมอ)
  • เติมช่องว่างข้อความใด ๆ ในหน้าสุดท้ายด้วยช่องว่าง
  • Q ควรจะยังคงต้องออกหากมีเพียงหนึ่งหน้า

การชนะ

โปรแกรมที่สั้นที่สุดในหน่วยไบต์หลังจากโบนัสถูกนำไปใช้ชนะ

โบนัส

  • ลบช่องว่างนำหน้าเพื่อให้ทุกบรรทัดเริ่มต้นด้วยคำ (หรือส่วนคำ) เช่นในตัวอย่างแรกจะกลายเป็น| amet, | | amet, c |(-30 ไบต์)
  • ล้างหน้าจอของหนังสือที่วาดก่อนหน้านี้หลังจากNหรือBกด (และTถ้าคุณทำโบนัสหลังจากนี้) เพื่อให้ดูเหมือนว่าหนังสือหน้าการเปลี่ยนแปลงในสถานที่ (-20 ไบต์)
  • กำหนดให้Tปุ่มสลับระหว่างข้อความที่ถูกดึงจากซ้ายไปขวาบนลงล่าง (ค่าเริ่มต้น) ถึงบนซ้ายไปขวาจากบนลงล่าง หากคุณได้โบนัสแรกมาแล้วควรทำงานกับคอลัมน์ในโหมดจากบนลงล่าง (-100 ไบต์)

    ตัวอย่างเช่น:

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

    กลายเป็น

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

ดูเหมือนจะเป็นโบนัส "ล้างหน้าจอ" ซึ่งเป็นโบนัสภาษาแทนที่จะเป็นรหัสโบนัส ...
John Dvorak

คุณพูดเป็นข้อความว่าชื่อไฟล์และขนาดหนังสือมาจาก STDIN แต่คุณจะใช้เป็นอาร์กิวเมนต์ แล้วมันคืออะไร?
John Dvorak

ฉันสังเกตเห็นขอบคุณการแจ้งเตือนของคุณว่าไม่มีช่องว่างต่อท้าย แต่เราจำเป็นต้องไม่รวมไว้ด้วยหรือไม่?
John Dvorak

@JanDvorak ขออภัยฉันหมายถึงพวกเขาเป็นเพียงข้อโต้แย้ง คุณต้องไม่มีช่องว่างต่อท้าย คุณสามารถยกตัวอย่างว่าการล้างข้อมูลกลายเป็น "รหัสโบนัส" หรือไม่?
งานอดิเรกของ Calvin

1
@ JanDvorak ดูเหมือนว่าฉันจะเป็นมากกว่า "การเรียกใช้โปรแกรมใน POSIX terminal" โบนัส \033[2J\033[;H
Peter Taylor

คำตอบ:


3

C # 535bytes

คะแนนคือ 655bytes ของรหัส -20byte โบนัสสำหรับการล้างและ -100byte โบนัสสำหรับปุ่ม T ... ฉันคิดว่าไม่สามารถบอกได้ว่าฉันแน่ใจว่าฉันไม่ได้พลาดบางอย่างในสเปค

ฉันอาจลองและยุบลูปโดยใช้วิธี W คืนค่าอาร์กิวเมนต์ แต่ก็ต้องใช้ความพยายามดังนั้นจึงไม่มีสัญญา

รหัส Golfed:

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

ฟอร์แมตเล็กน้อย:

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

ชวา 1039 1001 993 953 946

พร้อมโบนัส: ลบช่องว่างนำหน้า (-30 ไบต์) -> 1009 971 963 923 916

การล้างหน้าจอไม่คุ้มค่ากับ java (ยกเว้นถ้าฉันพิมพ์บรรทัดใหม่ขึ้นมาสองสามบรรทัด แต่จากนั้นผู้ใช้ต้องใช้ขนาดคอนโซลที่ถูกต้อง)

รหัส:

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

น่ารัก:

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

หากโปรแกรมไม่จำเป็นต้องรันตลอดไปฉันสามารถบันทึกบางไบต์ด้วยการลบ while loop และเพียงแค่เรียก main

สิ่งนี้ไม่เหมาะสม แต่เป็นการเริ่มต้น


ฉันค่อนข้างแน่ใจว่าคุณไม่ต้องการpublicคำหลัก ... นอกจากนี้ยังใช้import java.*;งานได้?

@professorfish ฉันคิดimport java.*;เช่นกัน แต่ก็ใช้งานไม่ได้ และวิธีการหลักไม่จำเป็นต้องมีอย่างแน่นอนpublic static void main(String[]c)(รวมถึงpublic) มิฉะนั้นจะไม่ได้รับการยอมรับ แต่คลาสของหลักสูตรไม่จำเป็นต้องเปิดเผยต่อสาธารณะ
ทิม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.