2009-04-03 4 views
7
class Tree 
    def initialize*d;@d,=d;end 
    def to_s;@l||@r?",>":@d;end 
    def total;(@d.is_a?(Numeric)[email protected]:0)+(@[email protected]: 0)+(@[email protected]: 0);end 
    def insert d 
    alias g instance_variable_get 
    p=lambda{|s,o|d.to_s.send(o,@d.to_s)&& 
     (g(s).nil??instance_variable_set(s,Tree.new(d)):g(s).insert(d))} 
    @d?p[:@l,:]:@d=d 
    end 
end 

Möchte jemand einen Versuch unternehmen zu erklären, was das bedeutet? Es erschien als eine Antwort in einer Frage, die ich über Code fragte, der too clever ist. Aber es ist zu schlau, um zu sagen, ob es nur ein Witz ist. Wenn es nicht ist, würde mich interessieren, wie es funktioniert, sollte jemand sich erklären wollen.Wenn dieser Code kein Witz ist, wie auf der Erde funktioniert es?

+0

nichts im Vergleich zu http://www.rubyinside.com/advent2006/4-ruby-obfuscation.html: P – Aziz

+0

@firoso: gehen Sie zurück zu Slashdot, wenn Sie ein IT-Forum trollen wollen. – Juliet

Antwort

15

EDIT: Die Person, die das ursprüngliche verschleierte Beispiel gepostet gab the actual source code in seiner Antwort. Er hat auch eine corrected version of the obfuscated code gepostet, weil, wie ich schon sagte, einige davon keinen Sinn ergeben, selbst wenn Sie die funky Syntax entfernt haben.

Das ist einige gut verschleierten Code. Wie bei den meisten verschleierten Codes handelt es sich meist um eine Vielzahl von ternären Operatoren und eine hartnäckige Weigerung, Leerzeichen in eine normale Person einzutragen. Hier ist im Grunde die gleiche Sache mehr normal geschrieben:

class Tree 
    def initialize(*d) 
    @d, = d # the comma is for multiple return values, 
      # but since there's nothing after it, 
      # all but the first are discarded. 
    end 
    def to_s 
    @l || @r ? ",>" : @d 
    end 
    def total 
    total = @d.is_a?(Numeric) ? @d : 0 
    total += @l.total if @l 
    total += @r.total if @r 
    end 
    def insert(arg) 
    if @d 
     if @l 
     @l.insert(arg) 
     else 
     @l = Tree.new(arg) 
     end 
    else 
     @d = arg 
    end 
    end 
end 

Die Insert-Methode ist nicht syntaktisch gültig (es ist ein Methodennamen an einem Teil fehlt), aber das ist im Wesentlichen, was es tut, soweit ich das beurteilen kann. Die Verschleierung in dieser Methode ist ziemlich dick:

  1. Statt nur @l = whatever tun, verwendet es instance_variable_get() und instance_variable_set(). Schlimmer noch, es alias instance_variable_get(), nur g() zu sein.

  2. Es enthält den größten Teil der Funktionalität in einer Lambda-Funktion, an die es den Namen @l übergibt. Dann ruft es diese Funktion mit der weniger bekannten Syntax func[arg1, arg2] auf, die func.call(arg1, arg2) entspricht.

9

Dies scheint eine Binärbaumimplementierung in sehr wenigen Zeilen zu sein. Ich entschuldige mich, wenn mein Verständnis für die Ruby-Syntax beschränkt ist:

class Tree     // defining the class Tree 

    def initialize *d;  // defines the initializer 
     @d = d;    // sets the node value 
    end 

    def to_s;     // defines the to_s(tring) function 
     @l || @r ? ",>" : @d; // conditional operator. Can't tell exactly what this 
           // function is intending. Would think it should make a 
           // recursive call or two if it's trying to do to_string 
    end 

    def total;    // defines the total (summation of all nodes) function 
     @d.is_a ? (Numeric) // conditional operator. Returns 
      ? @d    // @d if the data is numeric 
      : 0    // or zero 
     + (@l ? @l.total : 0) // plus the total for the left branch 
     + (@r ? @r.total : 0) // plus the total for the right branch 
    end 

    def insert d    // defines an insert function 
     ??     // but I'm not going to try to parse it...yuck 
    end 

Hoffnung, dass einige hilft ...:/

8

Es begann als dies aus:

class Tree 
    include Comparable 

    attr_reader :data 

    # Create a new node with one initial data element 
    def initialize(data=nil) 
    @data = data 
    end 

    # Spaceship operator. Comparable uses this to generate 
    # <, <=, ==, =>, >, and between? 
    def <=>(other) 
    @data.to_s <=> other.data.to_s 
    end 

    # Insert an object into the subtree including and under this Node. 
    # First choose whether to insert into the left or right subtree, 
    # then either create a new node or insert into the existing node at 
    # the head of that subtree. 
    def insert(data) 
    if [email protected] 
     @data = data 
    else 
     node = (data.to_s < @data.to_s) ? :@left : :@right 
     create_or_insert_node(node, data) 
    end 
    end 

    # Sum all the numerical values in this tree. If this data object is a 
    # descendant of Numeric, add @data to the sum, then descend into both subtrees. 
    def total 
    sum = 0 
    sum += @data if (@data.is_a? Numeric) 
    sum += [@left, @right].map{|e| e.total rescue 0}.inject(0){|a,v|a+v} 
    sum 
    end 

    # Convert this subtree to a String. 
    # Format is: <tt>\<data,left_subtree,right_subtree></tt>. 
    # Non-existant Nodes are printed as <tt>\<></tt>. 
    def to_s 
    subtree = lambda do |tree| 
     tree.to_s.empty? ? "<>" : tree 
    end 
    "<#{@data},#{subtree[@left]},#{subtree[@right]}>" 
    end 

    private ############################################################ 
    # Given a variable-as-symbol, insert data into the subtree incl. and under this node. 
    def create_or_insert_node(nodename, data) 
    if instance_variable_get(nodename).nil? 
     instance_variable_set(nodename, Tree.new(data)) 
    else 
     instance_variable_get(nodename).insert(data) 
    end 
    end 

end 

Ich glaube, ich es tatsächlich brach, als ich es nach unten verkürzt wurde. Die Neun-Zeilen-Version funktioniert nicht ganz. Ich hatte trotzdem Spaß. : P

Das war mein Lieblingsteil:

def initialize*d;@d,=d;end 

Diese acutally Verwendung paralleler Zuordnung macht ein paar Zeichen zu speichern. Sie könnten diese Zeile erweitern:

def initialize(*d) 
    @d = d[0] 
end 
+0

Ich habe geschworen, als ich den ersten Post gelesen habe. Ich habe mich gefragt, warum ich das schon mal gesehen habe. Dann erinnerte ich mich an einen Haufen von uns, der schreckliche Dinge ausstieß, um die Klasse zu schreiben. –

+0

Haha, ja. Ohhh, 2150. – Burke

+0

Huh, ich habe gerade festgestellt, dass mein Trick mit der parallelen Zuweisung eigentlich ein Charakter ist, der länger ist als nur 'def initialisiere d; @ d = d; end'. Es ist allerdings ein bisschen toller, denke ich: P – Burke

7

Ich habe den ursprünglichen Code veröffentlicht. Entschuldigung, aber ich habe mir nicht die Mühe gemacht, nachzusehen, ob ich es richtig gemacht habe, und eine Menge Zeug wurde wegen weniger als Zeichen entfernt.

class Tree 
    def initialize*d;@d,=d;end 
    def to_s;@l||@r?"<#{@d},<#{@l}>,<#{@r}>>":@d;end 
    def total;(@d.is_a?(Numeric)[email protected]:0)+(@[email protected]: 0)+(@[email protected]: 0);end 
    def insert d 
    alias g instance_variable_get 
    p=lambda{|s,o|d.to_s.send(o,@d.to_s)&& 
     (g(s).nil??instance_variable_set(s,Tree.new(d)):g(s).insert(d))} 
    @d?p[:@l,:<]||p[:@r,:>]:@d=d 
    end 
end 

So sollte es aussehen.