Kitap yazarı yazma


10

İşte açık bir kitabın oldukça basit bir ASCII tasviri:

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

Metin bölümünün yalnızca sağ sayfada olduğunu ve 7 karakter genişliğinde ve 5 yüksekliğinde olduğuna dikkat edin. Ayrıca kitabın üst kenarında 5 ters eğik çizgi ve 10 alt çizgi olduğunu unutmayın. 10, metin genişliği artı 3'ten gelir ve 5, 10'un yarısıdır.

Aynı ölçeklendirme formatını kullanarak, kitabı w karakterleri geniş ve h yüksekliğinde bir metin alanına sahip olacak şekilde yeniden boyutlandırabiliriz; burada w herhangi bir tek pozitif tam sayı ve h herhangi bir pozitif tam sayıdır.

Bazı W x h kitaplar: 1 x 1, 1 x 2, 3 x 2

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

Üstteki alt çizgi sayısı her zaman w +3 ve ters eğik çizgi sayısı her zaman ( w +3) / 2'dir.

Hedef

Komut satırı bağımsız değişkenleri olarak bir dosya adı ve w ve h alan bir program yazın ve stdout'a bu metin boyutlarına sahip bir kitap çıktısıyla dosyanın içeriğini görüntüleyin.

Dosya bir sayfaya sığmayacak kadar metin içeriyorsa, Nanahtar sonraki sayfayı yazdırmalı ve Bbir sayfa geriye gitmelidir. Bİlk sayfadan veya Nson sayfadan basılırsa hiçbir şey olmamalıdır . QTuşa basıldığında program durmalıdır .

Misal

Varsayalım f.txtiçeren Lorem ipsum dol?ve kullanıcı anahtar dizisi bastı N N B N N Q. Program şöyle bir şey çalıştırmalıdır:

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

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

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

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

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

>>>

Her kitaptan sonra yeni bir satır olduğuna ve sondaki boşluk olmadığına dikkat edin. Bu gereklidir.

notlar

  • Dosyanın yalnızca yazdırılabilir ASCII karakterleri (onaltılık 20 ila 7E) içerdiğini varsayabilirsiniz .
  • Sözcük sınırlarına bakılmaksızın, kullanılabilir her noktaya bir karakter yazdırın.
  • w ve h olan isteğe bağlı argümanlar varsayılan 7 ve 5, sırasıyla. Programınıza ya hiçbiri ya da ikisi birden verilmeyecektir. (Girdinin her zaman iyi biçimlendirildiğini varsayabilirsiniz.)
  • Son sayfadaki boş metin alanlarını boşluklarla doldurun.
  • Q yalnızca bir sayfa varsa yine de çıkmanız gerekir.

Kazanan

Bonuslar uygulandıktan sonra bayt cinsinden en kısa program kazanır.

Bonuslar

  • Baştaki boşlukları kaldırın, böylece her satır bir kelime (veya kelime parçası) ile başlar. örneğin | amet, |ilk örnekte olur | amet, c |. (-30 bayt)
  • Önceden çizilen kitapların ekranını Nveya Bdüğmesine basıldıktan sonra temizleyin (ve Tbundan sonra bonusu yaparsanız), böylece kitap değişen sayfalar yerinde gibi görünür. (-20 bayt)
  • TAnahtarı soldan sağa yukarıdan aşağıya doğru (varsayılan), soldan sağa doğru yukarıdan aşağıya doğru çizilen metin arasında anında geçiş yapın . İlk bonusu yaptıysanız, yukarıdan aşağıya modda sütunlar için çalışmalıdır. (-100 bayt)

    Yani mesela:

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

    olur

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

"ekranı temizle" bonusu, bir kod bonusu yerine bir dil bonusu gibi görünüyor ...
John Dvorak

Metin olarak, dosya adı ve kitap boyutlarının STDIN'den geldiğini söylüyorsunuz, ancak bunları bağımsız değişken olarak almaya devam ediyorsunuz. O zaman hangisi?
John Dvorak

Bildiriminiz sayesinde, takip eden boşlukların olmadığını fark ettim. Ama onları da dahil etmememiz gerekiyor mu?
John Dvorak

@JanDvorak Üzgünüm, sadece argüman olduklarını söyledim. Sondaki boşluklarınız YOK. Takas işleminin nerede "kod bonusu" olduğuna bir örnek verebilir misiniz?
Calvin'in Hobileri

1
@JanDvorak, bana bir "programı POSIX terminalinde çalıştır" bonusu gibi geliyor. \033[2J\033[;H
Peter Taylor

Yanıtlar:


3

C # 535bytes

Puan, takas için 655byte kod -20bayt bonus ve T tuşu için -100bayt bonus ... Sanırım, spesifikasyonda bir şey kaçırmadım eminim diyemem

W yönteminin s argümanını döndürmesini sağlayarak döngüleri daraltabilirim, ama bu çaba gerektirecekti, bu yüzden söz vermeyeceğim.

Golf kodu:

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

Biraz biçimlendirilmiş:

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

Bonus ile: Baştaki boşlukları kaldırın (-30 bayt) -> 1009 971 963 923 916

Ekranı temizlemek java ile değmez (sadece birkaç satır yazdırmam dışında. Ancak kullanıcının doğru konsol boyutunu kullanması gerekir)

Kod:

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

Güzel:

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

Programın sonsuza kadar çalışması gerekmiyorsa, while döngüsünü kaldırarak ve sadece main'yi çağırarak bazı baytlar kaydedebilirim.

Bu optimal değil, ama bir başlangıç.


publicAnahtar kelimelere ihtiyacınız olmadığından eminim ... Ayrıca import java.*;işe yarıyor mu?

@professorfish Ben de düşündüm import java.*;ama işe yaramıyor. Ve ana yöntemin tam olarak public static void main(String[]c)(dahil public) olması gerekir , aksi takdirde tanınmaz. Ama tabii ki sınıfın halka açık olması gerekmiyor.
tim
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.