ブックライターを書く


10

以下は、開いた本のかなり単純なASCIIの描写です。

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

テキスト部分は右側のページにのみあり、幅7文字、高さ5であることに注意してください。また、本の上端には5つのバックスラッシュと10のアンダースコアがあることに注意してください。10はテキスト幅に3を加えたもので、5は10の半分です。

同じスケーリング形式を使用して、テキスト領域をw文字幅、h高さのテキスト領域に変更できます。ここで、w奇数の正の整数、hは任意の正の整数です。

一部のw × h本:1×1、1×2、3×2

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

上部のアンダースコアの数は常にw +3で、バックスラッシュの数は常に(w +3)/ 2です。

ゴール

ファイル名とwおよびhをコマンドライン引数として取り、それらのテキスト寸法の本をstdoutに出力し、ファイルの内容を表示するプログラムを記述します。

ファイルのテキストが1ページに収まらない場合、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文字(16進数で20から7E)のみが含まれていると想定することができます。
  • 単語の境界に関係なく、使用可能な各スポットに1文字を印刷します。
  • whオプションの引数で、デフォルトはそれぞれ7と5です。プログラムにはどちらも与えられないか、両方が与えられます。(入力は常に正しい形式であると想定できます。)
  • 最後のページの空のテキストスペースをスペースで埋めます。
  • Q 1ページしかない場合でも、終了する必要があります。

勝利

ボーナスが適用された後のバイト単位の最短プログラムが勝ちます。

ボーナス

  • すべての行が単語(または単語セグメント)で始まるように、先頭のスペースを削除します。たとえば| amet, |、最初の例ではになり| amet, c |ます。(-30バイト)
  • NまたはBを押した後(およびTその後にボーナスを実行した場合)、以前に描いた本の画面をクリアして、本が変化するページのように見えるようにします。(-20バイト)
  • 作成しTたテキストの間で瞬時に切り替えキーは、上から下、左から右へ、左から右、上から下(デフォルト)から引き出されています。最初のボーナスを実行した場合、上から下モードの列で機能するはずです。(-100バイト)

    だから例えば:

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

    なる

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

「画面をクリアする」ボーナスは、コードボーナスではなく言語のボーナスのようです...
John Dvorak

テキストで、ファイル名と本の寸法はSTDINからのものであると言いますが、その後、それらを引数として取ります。それでそれは何ですか?
John Dvorak

お気づきのように、末尾にスペースがないことに気づきました。しかし、それらも含めないように要求されますか?
John Dvorak 14

@JanDvorak申し訳ありませんが、これらは単なる引数にすぎません。末尾のスペースは必要ありません。決済が「コードボーナス」になる例を挙げていただけますか?
Calvin's Hobbies

1
@JanDvorak、私はもっと「POSIX端末でプログラムを実行する」ボーナスのようです。\033[2J\033[;H
Peter Taylor

回答:


3

C#535バイト

スコアは655バイトのコードで、クリアの場合は-20バイトのボーナス、Tキーの場合は-100バイトのボーナスです。仕様の一部を見逃していないとは言えません。

Wメソッドに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;}}

少しフォーマット:

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

ボーナス付き:先行スペースを削除(-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ループを削除してmainを呼び出すだけで、バイトを節約することもできます。

これは最適ではありませんが、出発点です。


publicキーワードは必要ないと思います...また、機能しimport java.*;ますか?

@professorfishも考えましたimport java.*;が、機能しません。また、メインメソッドは正確にpublic static void main(String[]c)(を含むpublic)である必要があります。そうでない場合、認識されません。しかし、もちろんクラスは公開されている必要はありません。
2014
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.