Schreiben Sie einen Buchautor

10

Hier ist eine ziemlich einfache ASCII-Darstellung eines offenen Buches:

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

Beachten Sie, dass sich der Textabschnitt nur auf der rechten Seite befindet und 7 Zeichen breit und 5 hoch ist. Beachten Sie auch, dass der obere Rand des Buches 5 Backslashes und 10 Unterstriche aufweist. Die 10 kommt aus der Textbreite plus 3 und die 5 ist die Hälfte von 10.

Mit demselben Skalierungsformat können wir die Größe des Buches so ändern, dass der Textbereich w Zeichen breit und h hoch ist, wobei w eine ungerade positive Ganzzahl und h eine beliebige positive Ganzzahl ist.

Einige w × h Bücher: 1 × 1, 1 × 2, 3 × 2

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

Die Anzahl der Unterstriche oben beträgt immer w +3 und die Anzahl der Backslashes beträgt immer ( w +3) / 2.

Tor

Schreiben Sie ein Programm, das einen Dateinamen und w und h als Befehlszeilenargumente verwendet und ein Buch mit diesen Textabmessungen an stdout ausgibt, wobei der Inhalt der Datei angezeigt wird .

Wenn die Datei mehr Text enthält, als auf eine Seite passt, Nsollte der Schlüssel die nächste Seite drucken und Beine Seite zurückgehen. Es sollte nichts passieren, wenn Bvon der ersten Seite oder Nvon der letzten Seite gedrückt wird. Das Programm sollte anhalten, wenn die QTaste gedrückt wird.

Beispiel

Angenommen, f.txtenthält Lorem ipsum dol?und der Benutzer hat die Tastenfolge gedrückt N N B N N Q. Das Programm sollte ungefähr so ​​laufen:

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

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

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

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

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

>>>

Beachten Sie, dass nach jedem Buch eine neue Zeile und keine nachgestellten Leerzeichen stehen. Dies ist erforderlich.

Anmerkungen

  • Sie können davon ausgehen, dass die Datei nur druckbare ASCII-Zeichen enthält (Hex 20 bis 7E).
  • Drucken Sie unabhängig von den Wortgrenzen ein Zeichen an jeder verfügbaren Stelle.
  • w und h sind optionale Argumente, die standardmäßig 7 bzw. 5 sind. Ihr Programm erhält entweder keine oder beide. (Sie können davon ausgehen, dass die Eingabe immer gut geformt ist.)
  • Füllen Sie alle leeren Textbereiche auf der letzten Seite mit Leerzeichen.
  • Q sollte immer noch zum Beenden erforderlich sein, wenn nur eine Seite vorhanden ist.

Gewinnen

Das kürzeste Programm in Bytes nach Anwendung der Boni gewinnt.

Boni

  • Entfernen Sie führende Leerzeichen, sodass jede Zeile mit einem Wort (oder Wortsegment) beginnt. zB | amet, |im ersten Beispiel würde werden | amet, c |. (-30 Bytes)
  • Löschen Sie den Bildschirm von zuvor gezeichneten Büchern, nachdem Sie diese gedrückt haben Noder Bgedrückt haben (und Twenn Sie den Bonus danach ausführen), damit das Buch so aussieht, als ob die Seiten wechseln. (-20 Bytes)
  • Lassen Sie die TTaste sofort zwischen dem von links nach rechts von oben nach unten (Standardeinstellung) gezeichneten Text und von links nach rechts von oben nach unten wechseln. Wenn Sie den ersten Bonus gemacht haben, sollte er für Spalten im Top-to-Bottom-Modus funktionieren. (-100 Bytes)

    Also zum Beispiel:

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

    wird

    |\
    | \
    |  \______
    |  ||     |
    \  || Lrm |
     \ || oe  |
      \||_____|
    
Calvins Hobbys
quelle
Der "Clear the Screen" -Bonus scheint eher ein Sprachbonus als ein Codebonus zu sein ...
John Dvorak
Sie sagen im Text, dass die Dateinamen- und Buchdimensionen von STDIN stammen, aber dann nehmen Sie sie als Argumente. Welches ist es dann?
John Dvorak
Ich habe dank Ihrer Mitteilung festgestellt, dass es keine nachgestellten Leerzeichen gibt. Aber müssen wir sie auch nicht einbeziehen?
John Dvorak
@ JanDvorak Sorry, ich meinte, sie sind nur Argumente. Sie müssen KEINE nachgestellten Leerzeichen haben. Können Sie ein Beispiel geben, wo das Clearing zu einem "Codebonus" wird?
Calvins Hobbys
1
@ JanDvorak, es scheint mir eher ein Bonus "Programm in einem POSIX-Terminal ausführen" zu sein. \033[2J\033[;H
Peter Taylor

Antworten:

3

C # 535 Bytes

Die Punktzahl beträgt 655 Byte Code -20 Byte Bonus für das Löschen und -100 Byte Bonus für T-Taste ... Ich kann nicht sagen, dass ich sicher bin, dass ich etwas in der Spezifikation nicht verpasst habe

Ich kann versuchen, die Schleifen zu reduzieren, indem die W-Methode das Argument s zurückgibt, aber das würde Aufwand erfordern, also keine Versprechen.

Golfcode:

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

Ein bisschen formatiert:

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
quelle
4

Java, 1039 1001 993 953 946

Mit Bonus: Entfernen Sie führende Leerzeichen (-30 Bytes) -> 1009 971 963 923 916

Das Löschen des Bildschirms lohnt sich mit Java nicht (außer wenn ich nur ein paar Zeilenumbrüche drucke. Dann muss der Benutzer die richtige Konsolengröße verwenden).

Code:

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

Ziemlich:

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

Wenn das Programm nicht für immer ausgeführt werden muss, kann ich auch einige Bytes sparen, indem ich die while-Schleife entferne und einfach main aufrufe.

Dies ist nicht optimal, aber es ist ein Anfang.

tim
quelle
Ich bin mir ziemlich sicher, dass Sie die publicSchlüsselwörter nicht benötigen ... Funktioniert das auch import java.*;?
@professorfish Ich habe auch darüber nachgedacht import java.*;, aber es funktioniert nicht. Und die Hauptmethode muss genau public static void main(String[]c)(einschließlich public) sein, sonst wird sie nicht erkannt. Aber die Klasse muss natürlich nicht öffentlich sein, guter Fang.
Tim