2016-05-14 10 views
-1

Angenommen, es ist ein Array wie diese:in Ruby

list = ["a", "a", "a", "b", "b", "c", "d", "e", "e"] 

Wir wollen einen Zyklus schaffen, wo jeder nächste Element unterscheidet sich von dem vorhergehenden Element ist und das erste Element ist anders das letzte Element.

required = ["a", "b", "a", "b", "a", "c", "e", "d", "e"] 

Wie wird das in Rubin gemacht?

def create_cycle 
    temp = Array.new($input) 
    i, j, counter = 0 
    while i == 0 
    while (counter != $input.length) 
     j = rand(1..$input.length-1).floor 
     unless !($input[i][0].to_s.eql?$input[j][0]) 
     $solution.push($input[i]) 
     $solution.push($input[j]) 
     puts input[i], input[j] 
     $input.delete_at(i) 
     $input.delete_at(j) 
     counter = counter + 1 
     end 
    end 
    end 
end 

Ich versuche, dies zu lernen. Danke für Ihre Hilfe.

Zusätzliche Hinweise:

  1. Die Elemente a, b, c, d, e repräsentieren spezielle Format-Strings, wo
    eine bestimmte Eigenschaft ist unter ihnen gemeinsam, so dass das erste Element "a" Aktien ein Eigenschaft mit dem nächsten Element "a", aber ist nicht gleich der erste.
  2. Wenn es nicht möglich ist, einen Zyklus zu erstellen, genügt es, ein Flag in der Befehlszeile zu setzen.
+2

Was ist, wenn es nicht möglich ist? Sprich: [a, a, a, b]? – Anand

+0

Vielen Dank, dass Sie darauf hingewiesen haben, @Anand. Wir müssen den Benutzer nur informieren, falls ein Zyklus nicht möglich ist. Cary, danke für deinen Vorschlag. Ich werde das sofort einbeziehen. – Deucalion

Antwort

1

Ich könnte es wie folgt tun:

>> list = [a, a, a, b, b, c, d, e, e] 
>> list.sort.each_slice((list.size/2.0).round).reduce(:zip).flatten.compact 
=> [a, c, a, d, a, e, b, e, b] 

Die allgemeine Methode ist:

  1. sortiert die Liste, so dass alle identischen Elemente benachbarte
  2. teilen die Liste in der Hälfte aus der Mitte
  3. verschachteln die beiden Hälften zusammen
+0

Woher wissen Sie, dass die Elemente sortierbar sind? – sawa

+0

Woher wissen Sie, dass "Größe" für "a" definiert ist, und was macht das? – sawa

+0

s/'a' /' list'/und wenn 'sort' nicht definiert ist' group_by' + 'flatten' sind eine geeignete Alternative – user12341234

1

Angenommen, Sie kümmern sich nicht darum, dass die Reihenfolge die gleiche wie im ursprünglichen Array ist, und es ist in Ordnung, Duplikate zu haben, wenn es keine Möglichkeit gibt, und vorausgesetzt, die Liste ist vorsortiert, hier ist ein Ansatz - es fügt nur hinzu Elemente von Anfang und am Ende der Liste, bis es keine Elemente links:

def interleaver list 
    result = [] 
    el = list.first 
    while(el) 
    el = list.shift 
    if el 
     result << el 
    else 
     return result 
    end 
    el = list.pop 
    if el 
     result << el 
    else 
     return result 
    end 
    end 
    result 
end 

> a = 'a' 
> b = 'b' 
> c = 'c' 
> d = 'd' 
> e = 'e' 
> list = [a, a, a, b, b, c, d, e, e] 
> interleaver(list) 
=> ["a", "e", "a", "e", "a", "d", "b", "c", "b"] 

Aber wenn eine solche Verschachtelung nicht möglich ist, werden Sie Duplikate erhalten:

> list = [a, a, a, b] 
> interleaver(list) 
#=> ["a","b","a","a"] 
+0

Ah! Nett, sehr schlau. Danke, das wird definitiv funktionieren, solange es einen letzten Check gibt. Danke für deine Hilfe, @Anand. – Deucalion

1

Sie eine solche Zeichenfolge erhalten, oder demonstrieren, dass keine solche Zeichenfolge existiert, mit der folgenden rekursiven Methode.

-Code

def doit(remaining, partial=[]) 
    first_partial, last_partial = partial.first, partial.last 
    if remaining.size == 1 
    return ([first_partial, last_partial] & remaining).empty? ? 
     partial + remaining : nil 
    end 
    remaining.uniq.each_with_index do |s,i| 
    next if s == last_partial 
    rem = remaining.dup 
    rem.delete_at(i) 
    rv = doit(rem, partial + [s]) 
    return rv if rv 
    end 
    nil 
end 

Beispiele

list = %w| a a b | 
    #=> ["a", "a", "b"] 
doit list 
    #=> nil 

Das obige zeigt, dass die drei Elemente der list kann nicht die beiden Bestellanforderungen zu erfüllen permutiert werden.

list = %w| a a a b b c d e e | 
    #=> ["a", "a", "a", "b", "b", "c", "d", "e", "e"] 
doit list  
    #=> ["a", "b", "a", "b", "c", "b", "e", "d", "e"] 

Dies dauerte 0,0042 Sekunden, um auf einem neuartigen MacBook Pro zu lösen.

list = %w| a a a a a a a b b c d e e f f f g g g g h i i i i j j | 
    #=> ["a", "a", "a", "a", "a", "a", "a", "b", "b", "c", "d", "e", "e", 
    # "f", "f", "f", "g", "g", "g", "g", "h", "i", "i", "i", "i", "j", "j"] 
doit list  
    #=> ["a", "b", "a", "b", "a", "b", "a", "b", "c", "b", "d", "e", "f", 
    # "e", "f", "g", "f", "g", "h", "g", "h", "i", "j", "i", "j", "i", "j"] 

Dies dauerte 0,0059 Sekunden zu lösen.

Aus Neugier habe ich versucht, dann

list = (%w| a a a a a a a b b c d e e f f f g g g g h i i i i j j |).shuffle 
    #=> ["a", "c", "f", "b", "d", "i", "a", "a", "i", "a", "a", "g", "g", 
    # "a", "g", "i", "j", "b", "h", "j", "e", "e", "a", "g", "f", "i", "f"] 
doit list  
    #=> ["a", "c", "f", "b", "d", "i", "a", "i", "a", "g", "a", "g", "a", 
    # "g", "i", "g", "j", "b", "h", "j", "e", "a", "e", "g", "f", "i", "f"] 

Dies dauerte Keuchhusten 1,16 Sekunden zu lösen, was darauf hindeutet, dass es wünschenswert sein kann, vor der Art list (doit(list.sort)), wenn, natürlich, list sortierbar ist.

+0

Danke @Cary! Deine Kenntnisse der Rubin-Syntax überwältigen mich. Ich brauchte einige Zeit, um zu erkennen, was du getan hast. Danke für die Hilfe. – Deucalion