Jadikan pseudocode saya nyata

8

Saya punya beberapa pseudocode Java yang menggunakan spasi alih-alih kurung kurawal, dan saya ingin Anda mengubahnya.

I / O

Program Anda harus mengambil file input bersama dengan nomor yang menunjukkan berapa banyak ruang yang digunakan untuk membuat blok. Ini sebuah contoh:

$ convert.lang input.p 4
// Konversi menggunakan 4 spasi sebagai pembatas blok
$ convert.lang input.p 2
// Konversi menggunakan 2 spasi sebagai pembatas blok

Maka harus mengkonversi hasil menggunakan pembatas blok yang ditentukan dan output hasilnya ke stdout.

Daging program

Blok terbuka dengan :dan setiap baris dalam blok itu indentasi menggunakan pembatas blok, seperti kode Python.

sementara (benar):
    System.out.println ("Test");

Masing :- masing diganti dengan a {, dan a }ditambahkan ke ujung blok.

while (true) {
    System.out.println ("Test");
}

Contohnya

Memasukkan:

Tes kelas publik:
    public static static utama (String [] args):
        System.out.println ("Java is verbose ...");

Keluaran:

$ convert Test.pseudojava 4
Tes kelas publik {
    public static public void (String [] args) {
        System.out.println ("Java is verbose ...");
    }
}

Memasukkan:

utama():
  printf ("Hello World");

Keluaran:

$ convert test.file 2
main () {
  printf ("Hello World");
}

Memasukkan:

def generic_op (the_stack, func):
    # Kode penanganan op generik
    b = the_stack.pop ()
    jika isinstance (b, daftar):
        jika b:
            kembali
        top = b.pop (0)
        sementara b:
            top = func (top, b.pop (0))
        the_stack.push (atas)
    lain:
        a = the_stack.pop ()
        mengembalikan func (a, b)

Keluaran:

$ convert code.py 4
def generic_op (the_stack, func) {
    # Kode penanganan op generik
    b = the_stack.pop ()
    if isinstance (b, list) {
        jika b {
            kembali
        }
        top = b.pop (0)
        sementara b {
            top = func (top, b.pop (0))
        }
        the_stack.push (atas)
    }
    lain {
        a = the_stack.pop ()
        mengembalikan func (a, b)
    }
}

Mencetak gol

Kode dengan jumlah byte terkecil menang!

tahap
sumber
1
Bisakah kita berasumsi bahwa input tidak mengandung komentar?
Martin Ender
1
@ MartinBüttner Mungkin berisi komentar, tetapi komentar tidak akan berisi ':'. Pada dasarnya ya.
fase
3
Bagaimana dengan label, yang merupakan alasan umum bahwa sebuah garis akan berakhir di titik dua dalam sumber Java yang valid?
Peter Taylor
1
Saya belum pernah melihat label di mana pun kecuali awal dari sebuah garis.
SuperJedi224
2
Saya baru saja diingatkan betapa saya membenci Jawa.
lirtosiast

Jawaban:

5

Perl, 41 byte

#!perl -p0
1while s/( *).*\K:((
\1 .*)+)/ {\2
\1}/

Menghitung shebang sebagai dua, input diambil dari stdin. Argumen baris perintah tidak perlu disediakan. Konteks bersarang yang valid dapat ditentukan (dan dicocokkan) tanpa mengetahui ukuran lekukan.


Regex Break-Down

( *)                   # as many spaces as possible (\1)
    .*                 # as many non-newline characters as possible \
                         (greediness ensures this will always match a full line)
      \K               # keep all that (i.e. look-behind assertion)
        :              # colon at eol (newline must be matched next)
         (
          (
           \n\1        # newline with at least one more space than the first match
                .*     # non-newlines until eol
                  )+   # as many of these lines as possible
                    )  # grouping (\2)

Contoh Penggunaan

in1.dat

public class Test:
    public static void main(String[] args):
        System.out.println("Java is verbose...");

Keluaran

$ perl py2java.pl < in1.dat
public class Test {
    public static void main(String[] args) {
        System.out.println("Java is verbose...");
    }
}

in2.dat

main():
  printf("Hello World");

Keluaran

$ perl py2java.pl < in2.dat
main() {
  printf("Hello World");
}

in3.dat

def generic_op(the_stack, func):
    # Generic op handling code
    b = the_stack.pop()
    if isinstance(b, list):
        if b:
            return
        top = b.pop(0)
        while b:
            top = func(top, b.pop(0))
        the_stack.push(top)
    else:
        a = the_stack.pop()
        return func(a, b)

Keluaran

$ perl py2java.pl < in3.dat
def generic_op(the_stack, func) {
    # Generic op handling code
    b = the_stack.pop()
    if isinstance(b, list) {
        if b {
            return
        }
        top = b.pop(0)
        while b {
            top = func(top, b.pop(0))
        }
        the_stack.push(top)
    }
    else {
        a = the_stack.pop()
        return func(a, b)
    }
}
primo
sumber
Saya baru saja menulis ini di ruby
Bukan bahwa Charles
2

Python 3, 299 265 byte

import sys;s=int(sys.argv[2]);t="";b=0
for l in open(sys.argv[1]):
 h=l;g=0
 for c in l:
  if c!=" ":break
  g+=1
 if g/s<b:h=" "*g+"}\n"+h;b-=1
 if l.strip().endswith(":"):h=l.split(":")[0];h+=" {";b+=1
 t+=h+"\n"
b-=1
while b>-1:
 t+=" "*(b*s)+"}\n"b-=1
print(t)

Boom bam pow.

Algoritma yang digunakan:

// global vars
string total // total program yang dimodifikasi
int b // indent buffer

baris melalui baris: // iterate atas setiap baris
  string mline = "" // baris yang akan ditambahkan ke total

  // hitung jumlah spasi sebelum garis (bisa jauh lebih mudah)
  int spasi = 0 // total ruang
  c melalui baris: // pelajari setiap karakter dalam barisan
    if c! = "": // jika char saat ini bukan spasi (artinya kita pergi melalui mereka semua
        break // break iterating melalui chars
    spasi ++ // menambah spasi karena kita telah menekan spasi (hurr derr)

  jika spasi / SPACE_SETTING <b: // jika jumlah indentasi dari baris saat ini kurang dari buffer indentasi
    mline = "} \ n" + line // tambahkan braket penutup ke awal baris
    b-- // pengurangan buffer

  if line.endswith (":"): // jika baris diakhiri dengan `:`
    hapus: dari baris
    mline + = "{" // append {
    b ++ // buffer kenaikan
  total + = mline // tambahkan baris yang dimodifikasi ke total

cetak (total)
tahap
sumber
Bisakah Anda memasukkan penjelasan?
TanMath
@TanMath Menambahkan algoritma yang saya gunakan
fase
Apakah ini berfungsi dengan Python 2?
wb9688
@ wb9688 Tidak tahu, saya hanya mengujinya dengan Python 3
phase
Saya baru saja menguji, dan itu bekerja dengan Python 2
wb9688
2

Ruby, 70

x=$_+"
"
1while x.sub! /^(( *).*):
((\2 .*?
)*)/,'\1 {
\3\2}
'
$><<x

Menambahkan baris tambahan. Tidak perlu parameter ukuran blok indent.

Jalankan ini dengan -n0(ini benar-benar 68 + 2). Terima kasih banyak kepada @primo karena telah menghemat lebih dari selusin byte.

Bukan itu Charles
sumber
Saya pikir -p0juga berfungsi untuk ruby ​​( -0membaca semua input sekaligus, -pmenyimpan stdin ke $_, dan mencetak otomatis di akhir).
primo
@rimo Poin bagus. Seandainya tidak jelas dengan komentar saya di atas, ini bukan port kode Anda, tetapi pekerjaan saya sendiri yang melakukan persis apa yang Anda lakukan (tetapi dengan lebih banyak byte)
Bukan karena Charles
Saya mengerti benar, hanya memberikan tip untuk menghapus (agak bertele-tele) x=$<.readlines*''. Sementara aku melakukan itu, sub!juga memiliki dua parameter yang berlebihan (bukan dari satu paramater + blok) yang menerima string pengganti, sehingga Anda dapat menggunakan \1, \2, dll bukan perlu untuk menggabungkan semuanya.
primo
@primo Terima kasih! Saya mencoba versi dua-parameter sebelumnya dan meninggalkannya di beberapa titik tadi malam.
Bukannya Charles