2009-04-03 14 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 

Qualcuno vorrebbe fare una pugnalata per spiegare cosa fa? È apparso come una risposta in una domanda che ho posto sul codice che è too clever. Ma è troppo intelligente per me dire se è semplicemente uno scherzo. Se non lo fosse, sarei interessato a sapere come funziona, se qualcuno si preoccupasse di spiegare.Se questo codice non è uno scherzo, come diavolo funziona?

+0

nulla rispetto a http://www.rubyinside.com/advent2006/4-ruby-obfuscation.html: P – Aziz

+0

@firoso: tornare a slashdot se si desidera troll un forum IT. – Juliet

risposta

15

EDIT: La persona che ha pubblicato l'esempio originale offuscato dato the actual source code nella sua risposta. Ha anche pubblicato un corrected version of the obfuscated code, perché, come ho notato, parte di esso non aveva senso anche quando si rimuoveva la sintassi funky.

Questo è un codice piacevolmente offuscato. Come nel caso del codice più offuscato, sono soprattutto molti operatori ternari e un ostinato rifiuto di inserire spazi bianchi in cui una persona normale farebbe lo stesso. Qui è fondamentalmente la stessa cosa scritta più normalmente:

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 

Il metodo di inserimento non è sintatticamente valido (che manca un nome di metodo ad una parte), ma questo è in sostanza quello che fa, per quanto posso dire. L'offuscamento in questo metodo è piuttosto spessa:

  1. Invece di fare solo @l = whatever, utilizza instance_variable_get() e instance_variable_set(). Ancora peggio, alias instance_variable_get() per essere solo g().

  2. Esso avvolge la maggior parte delle funzionalità in una funzione lambda, a cui passa il nome dello @l. Quindi chiama questa funzione con la sintassi meno nota di func[arg1, arg2], che equivale a func.call(arg1, arg2).

9

Sembra un'implementazione di un albero binario in poche righe. Mi scuso se la mia comprensione della sintassi ruby ​​è limitata:

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 

Speranza che aiuta un po '...:/

8

E 'iniziato come questo:

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 

Credo in realtà rotto quando ero accorciamento giù. La versione a nove linee non funziona. Mi sono divertito a prescindere. : P

Questa era la mia parte preferita:

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

Questo è acutally facendo uso di assegnazione in parallelo per salvare un paio di caratteri. È possibile espandere questa riga a:

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

Ho giurato che quando ho letto il post iniziale mi stavo chiedendo perché l'avevo già visto prima. Poi mi sono ricordato di un gruppo di noi che sputavano cose orribili da fare per scrivere la lezione. –

+0

Haha, sì. Ohhh, 2150. – Burke

+0

Huh, ho appena realizzato che il mio trucco per l'assegnazione parallela è in realtà un personaggio più lungo del semplice "def inizializzare d; @ d = d; end'. È un po 'più bello però, penso: P – Burke

7

Ho pubblicato il codice originale. Scusa, ma non mi sono preoccupato di controllare che avessi fatto bene, e un sacco di cose sono state tolte a causa di meno di segni.

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 

Questo è quello che dovrebbe essere simile.

Problemi correlati