Bileşik dizide benzersiz bir öğe bulma

Çok şehirli bir uçuş planının başlangıç ​​noktasını temsil eden bir dizi dizinde havaalanı kodunu bulmam gereken bir sorunu çözmeye çalışıyorum. Örneğin: Bir dizi [['LAX', 'BWI'], ['BOS', 'SEA'], ['HNL', 'LAX'], ['SEA', 'HNL']] verildiğinde Her alt dizinin indeksi kalkış havaalanından ve ikincisi ise varış havalimanından, uçağın geldiği indeks noktasını bulmam gerekiyor, bu durumda yöntem ['BOS', 'SEA'] 'ı temsil etmek için 1'e dönecekti.

Bu kod çalışmaz ve her zaman dizideki son öğeyi döndürür

def find_start_point(list)
  start_point = nil
  list.each do |a|
    list.each do |b|
      if a[0] != b[1]
        start_point = list.index(a)
      end
    end
  end
  start_point
end
0

7 cevap

Ne yapmaya çalıştığını anlıyorum. Kalkış havaalanı, bir alt dizinin 0 dizinine dahil olan ancak hiçbir alt dizinin 1 dizini olmayan tek havaalanı olacaktır.

Ancak, çözümünüzde, 2 alt dizinin her bir kombinasyonunu (bir alt dizi ve kendisi de dahil olmak üzere ...) karşılaştırıyor ve sonra list dizinini döndürüyorsanız, > a [0]! = b [1] a alt dizisi için her zaman doğrudur. Bu çok fazla sonuç döndürüyor ve her zaman son dizini geri döndüreceksiniz. Örneğin, 3. alt dizinin 0 dizini olan 'SEA', 0 alt dizinin 1 dizini olan 'BWI' ile eşit değildir, bu nedenle start_point değeriniz şimdi 3 olur.

Tüm çalışmalarınızı sizin için yapmayacağım :), ama şunu önereyim: Yinelemelerinizi yaparken, hangi alt dizinin dizini 0'ın farklı bir alt dizinin dizini 1'e eşit olduğunu takip edin. Bu listeye dahil edilmeyen tek kişi olun.

Edit: Continue to work through my above suggestion for good practice, but here's a real quick and short solution:

def find_start_point(list)
  list.each_with_index do |sub, idx|
    return idx if list.flatten.count(sub[0]) == 1
  end
end

Bu, alt dizinin dizinini, o havaalanının başka hiçbir oluşumunun olmadığı bir dizini 0 ile döndürerek çalışır (dizinin tamamını düzleştirerek ve #count kullanarak)

1
katma

Dwenzel'in fikri üzerine inşa etmek:

airports = [['LAX', 'BWI'], ['BOS', 'SEA'], ['HNL', 'LAX'], ['SEA', 'HNL']]

departures, arrivals = airports.transpose

first_departure_index = departures.index{|dep| !arrivals.include?(dep)}
0
katma

Bunu yapabilirsin:

legs = [['LAX', 'BWI'], ['BOS', 'SEA'], ['HNL', 'LAX'], ['SEA', 'HNL']]

airports = legs.flatten 
  #=> ["LAX", "BWI", "BOS", "SEA", "HNL", "LAX", "SEA", "HNL"] 
legs.map(&:first).find { |ap| airports.count(ap) == 1 }
  #=> "BOS"

Bu, bunun yerine Array # transpose (diğer yanıtlarda yapıldığı gibi) veya Numaralandırılabilir şu tarihten beri: #zip :

legs.map(&:first)
  #=> ["LAX", "BOS", "HNL", "SEA"] 
legs.transpose.first
  #=> ["LAX", "BOS", "HNL", "SEA"] 
legs.first.zip(*legs[1..-1]).first
  #=> ["LAX", "BOS", "HNL", "SEA"] 

Bununla birlikte, cevap vermemdeki temel neden, gelecekte bazı ruby sürümlerinde görmek istediğim Array # fark yöntemine bir eklenti yapmaktır. burada tanımlanmıştır.

Bununla beraber, şunu yazabiliriz:

airports = legs.flatten 
  #=> ["LAX", "BWI", "BOS", "SEA", "HNL", "LAX", "SEA", "HNL"] 
(legs.map(&:first) - airports.difference(airports.uniq)).first
  #=> "BOS" 

Bunu not et:

airports.difference(airports.uniq)
  #=> ["LAX", "SEA", "HNL"]

bacaklarda bir kereden fazla görünen tüm havaalanları içerir; yani, tüm "ara" havaalanları.

0
katma

üzgünüm, kodumu açıklamak için yeterli zamanım yok - ama ne olduğunu çözmemek için hiçbir şeyin bu kadar zor olmadığını düşünüyorum :)

işte örnek çalışma

def find_start_point(list)
    start = []
    finish = []

    list.each do |l|
        start.push(l[0])
        finish.push(l[1])
    end

    start.each do |st|
        if !finish.include? st
            return start.index(st)
        end
    end

end
0
katma
trips = [['LAX', 'BWI'], ['BOS', 'SEA'], ['HNL', 'LAX'], ['SEA', 'HNL']]

arrivals = trips.map(&:last)

p trips.find{|fligth| ! arrivals.include? fligth[0] } #=> ["BOS", "SEA"]
0
katma

Ruby'nin sözdizimini aklınızdan çıkarmayı düşünüyorsanız, sadece bir tercüman edin ve tüm gelenleri kalkışlardan alın.

def flight_origin(arr)
  plan = arr.transpose
  plan[0].index((plan[0] - plan[1])[0])
end

flight_origin([['LAX', 'BWI'], ['BOS', 'SEA'], ['HNL', 'LAX'], ['SEA', 'HNL']]) # => 1

HTH

0
katma
def find_start(arr)
  flat = arr.flatten
  first, second = flat.reject { |val| flat.count(val) > 1}
  start_city = if flat.index(first) % 2 == 0 #if index of first is even
                 first
               else
                 second
               end
  arr.find { |pair| pair[0] == start_city }
end
0
katma
Biraz kafam karıştı. Bu nasıl çalışıyor?
katma yazar Harsh Gupta, kaynak
Kodunuzu çalıştırmayı ve sonuçları doğrulamayı denediniz mi? @Dwenzel gibi, uniq böyle işlemez.
katma yazar Harsh Gupta, kaynak
Uniq yönteminin işleyişi bu değil. Bir dizi TÜM havaalanını tekrar eder ve iade ederdi. öyleyse arr.flatten.uniq ["LAX", "BWI", "BOS", "SEA", "HNL"] 'dir. Burada işe yaramaz.
katma yazar dwenzel, kaynak
Sorunu doğru anlarsam, diziyi düzleştirdiyseniz, içeriği aynı sırada tek bir dizide tutarken tüm iç içe dizileri kaldırmak anlamına gelir, o zaman bu dizinin yalnızca iki benzersiz öğesi başlangıç ​​ve bitiş şehri olur. Başlangıç ​​kentinin düzleştirilmiş dizideki ilk, üçüncü, beşinci vb. Öğe olduğunu biliyoruz, yani eşit bir dizine sahip, yani iki benzersiz değerden hangisinin eşit dizine sahip olduğunu belirledik, sonra başlangıç ​​yaptık.
katma yazar mmartinson, kaynak
ilk, ikinci = [x, y] , ilk = [x, y] [0] ve ikinci = [x, y] [1 ile aynıdır. ]
katma yazar mmartinson, kaynak
Hey, bunun için özür dilerim, bu yöntemin farklı bir şey yaptığını tamamen aklımdan geçirdim. Düzenlenen sürüm, ilave bir adım eklenerek çalışır.
katma yazar mmartinson, kaynak