Brainfuck in weniger als 100 Zeilen
Veröffentlicht: 22.02.2010 um 11:34 von Landei
Wenn man es drauf anlegt, kann man auch sehr kompaktes Java schreiben:
Das Programm nimmt ein Brainfuck-Programm als Kommandozeilenargument, oder führt alternativ ein "Hello World"-Programm aus.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 import java.util.Map; import java.util.HashMap; public class Brainfuck { private final String prog; private final Map<Integer,Integer> open2close = new HashMap<Integer, Integer>(); private final Map<Integer,Integer> close2open = new HashMap<Integer, Integer>(); public Brainfuck(final String p) { prog = p.replaceAll("[^\\+\\-\\<\\>\\[\\]\\,\\.]",""); List list = List.nil(); for(int pos = 0; pos < prog.length(); pos++) { if(prog.charAt(pos) == '[') { list = new List(pos,list); } else if(prog.charAt(pos) == ']') { if (list == List.nil()) { throw new IllegalArgumentException("Unbalanced [] braces."); } int open = list.head(); list = list.tail(); open2close.put(open, pos); close2open.put(pos, open); } } execute(0, new Tape()); } public void execute(final int pos, final Tape tape) { if (0 <= pos && pos < prog.length()) { char ch = prog.charAt(pos); int nextPos = 1 + ((ch == ']' && tape.cell != 0) ? close2open.get(pos) : (ch == '[' && tape.cell == 0) ? open2close.get(pos) : pos); execute(nextPos, tape.exec(ch)); } } public static void main(String ...args) { String prog = args.length == 1 ? args[0] : "++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<" + "+++++++++++++++.>.+++.------.--------.>+.>."; new Brainfuck(prog); } private static class Tape { private final List left; private final int cell; private final List right; public Tape() { this(List.nil(), 0, List.nil()); } private Tape(List left, int cell, List right) { this.left = left; this.cell = cell; this.right = right; } public Tape exec(char ch) { try { switch (ch) { case '+': return new Tape(left, (cell + 1) % 256, right); case '-': return new Tape(left, (cell + 255) % 256, right); case '<': return (left == List.nil()) ? new Tape(left, 0, new List(cell, right)) : new Tape(left.tail(), left.head(), new List(cell, right)); case '>': return (right == List.nil()) ? new Tape(new List(cell, left), 0, right) : new Tape(new List(cell, left), right.head(), right.tail()); case '.': System.out.print((char) cell); return this; case ',': return new Tape(left, System.in.read() % 256, right); case '[': case ']' : return this; } } catch (Exception ex) { ex.printStackTrace(); } return this; } } private static class List { private final int head; private final List tail; private static List nil = new List(0, null) { @Override public int head() { throw new UnsupportedOperationException(); } @Override public List tail() { throw new UnsupportedOperationException(); } }; public List(int head, List tail) { this.head = head; this.tail = tail; } public int head() { return head; } public List tail() { return tail; } public static List nil() { return nil; } } }
Das Programm nimmt ein Brainfuck-Programm als Kommandozeilenargument, oder führt alternativ ein "Hello World"-Programm aus.
Kommentare 6
Kommentare
-
Ha, jetzt weiß ich endlich was in meiner Signatur steht...*G*Veröffentlicht: 26.02.2010 um 09:45 von FArt
-
Und es ginge noch kompakter...
Aus
private final List left;
private final List right;
mache
private final List left, right;
Und das geht an zwei Stellen, sind zwei Zeilen gespart
8 Leerzeilen gelöscht. ist man schon bei 82 Zeilen...Veröffentlicht: 25.03.2010 um 17:14 von Dreamdancer
-
Veröffentlicht: 30.03.2010 um 11:07 von 0x7F800000
-
was ist denn List.nil() =)Veröffentlicht: 07.04.2010 um 21:40 von raiL
-
Veröffentlicht: 08.04.2010 um 09:05 von Sonecc
-
ah ups, dachte er hat ausversehen nach scala geswitched
Veröffentlicht: 20.04.2010 um 23:11 von raiL





