# Make my pseudocode real

I've got some Java pseudocode that uses whitespace instead of curly braces, and I want you to convert it.

## I/O

Your program should take an input file along with a number designating how many spaces are used to indent a block. Here's an example:

$convert.lang input.p 4 // Convert using 4 spaces as the block delimiter$ convert.lang input.p 2
// Convert using 2 spaces as the block delimiter


It should then convert the result using the specified block delimiter and output the result to stdout.

## The meat of the program

Blocks open with : and each line within the block is indented using the block delimiter, like Python code.

while(true):
System.out.println("Test");


Each : is replaced with a {, and a } is appended to the end of the block.

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


## Examples

Input:

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

Output:

$convert Test.pseudojava 4 public class Test { public static void main(String[] args) { System.out.println("Java is verbose..."); } } Input: main(): printf("Hello World");  Output: $ convert test.file 2
main() {
printf("Hello World");
}

Input:

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)

Output:

$convert code.py 4 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) } }  ## Scoring The code with the least amount of bytes wins! • Can we assume that the input contains no comments? – Martin Ender Oct 19 '15 at 7:19 • @MartinBüttner It may contain comments, but the comments won't contain ':'. Basically, yes. – phase Oct 19 '15 at 7:32 • What about labels, which are the usual reason that a line would end in a colon in valid Java source? – Peter Taylor Oct 19 '15 at 8:11 • I've never seen a label anywhere but the beginning of a line. – SuperJedi224 Oct 19 '15 at 13:20 • I've just been reminded of how much I hate Java. – lirtosiast Nov 16 '15 at 4:46 ## 3 Answers # Perl, 41 bytes #!perl -p0 1while s/( *).*\K:(( \1 .*)+)/ {\2 \1}/  Counting the shebang as two, input is taken from stdin. A command line argument need not be provided. Any valid nesting context can be determined (and matched) without knowing the indentation size. 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)  Sample Usage in1.dat public class Test: public static void main(String[] args): System.out.println("Java is verbose...");  Output $ 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");


Output

$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)  Output $ 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)
}
}

• i just wrote this in ruby – Not that Charles Nov 16 '15 at 7:54

# Python 3, 299 265 bytes

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.

Algorithm used:

//global vars
string total //total modified program
int b //indent buffer

line thru lines: //iterate over every line
string mline = "" //line to be added to the total

//calculate the amount of spaces before the line (could be a lot easier)
int spaces = 0 //total spaces
c thru line: //go through every character in the line
if c != " ": //if the current char isn't a space (meaning we went though all of them
break //break out of iterating through chars
spaces++ //increment the spaces because we've hit a space (hurr derr)

if spaces/SPACE_SETTING < b: //if indent count of the current line is less than the indent buffer
mline = "}\n" + line //add closing bracket to beginning of line
b-- //decrement buffer

if line.endswith(":"): //if the line ends with a :
remove : from line
mline += " {" //append {
b++ //increment buffer
total += mline //add modified line to total

print(total)

• Can you include an explanation? – TanMath Nov 16 '15 at 5:22
• @TanMath Added the algorithm I used – phase Nov 16 '15 at 5:39
• Does it work with Python 2? – wb9688 Nov 17 '15 at 7:16
• @wb9688 No idea, I only tested it with Python 3 – phase Nov 17 '15 at 7:17
• I just tested, and it works with Python 2 – wb9688 Nov 17 '15 at 7:25

# Ruby, 70

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


Adds a trailing newline. Does not need the indent block-size parameter.

Run this with -n0 (this is really 68+2). Thank you greatly to @primo for saving over a dozen bytes.

• I think -p0 also works for ruby (-0 reads all input at once, -p stores stdin into $_, and auto-prints it at the end). – primo Nov 16 '15 at 8:47 • @primo Good point. In case it wasn't clear with my comment above, this isn't a port of your code, but my own work that does exactly what yours does (but with more bytes) – Not that Charles Nov 16 '15 at 15:01 • I understood correctly, just providing a tip to remove the (rather verbose) x=$<.readlines*''. While I'm doing that, sub! also has a two parameter overload (rather than one paramater + block) that accepts a replacement string, so you can use \1, \2, etc. instead of needing to concatenate it all. – primo Nov 16 '15 at 15:08
• @primo Thanks! I tried the two-parameter version before and abandoned it at some point last night. – Not that Charles Nov 16 '15 at 16:53