Yığındaki çorapları nasıl verimli bir şekilde eşleştirebilirim?


3911

Dün çorapları temiz çamaşırlardan eşleştiriyordum ve yaptığım şekilde çok etkili olmadığını anladım. Ben saf bir arama yapıyordum - bir çorap seçmek ve çiftini bulmak için kazık "yineleme". Bu n / 2 * n / 4 = N yineleme gerektirir 2 ortalama / 8 çorap.

Bir bilgisayar bilimcisi olarak ne yapabileceğimi düşünüyordum? Elbette bir O (NlogN) çözümü elde etmek için sıralama (boyut / renk / ... 'e göre) akla geldi.

Karma veya yerinde olmayan çözümler bir seçenek değildir, çünkü çoraplarımı çoğaltamıyorum (eğer yapabilirsem güzel olabilir).

Yani, soru temel olarak:

Elemanları niçeren bir çift çorap göz önüne alındığında 2n(her bir çorabın tam olarak bir eşleşen çifti olduğunu varsayalım), bunları logaritmik ekstra alana kadar verimli bir şekilde eşleştirmenin en iyi yolu nedir? (Gerekirse bu miktarda bilgiyi hatırlayabileceğime inanıyorum.)

Aşağıdaki yönleri ele alan bir cevabı takdir edeceğim:

  • Çok sayıda çorap için genel bir teorik çözüm.
  • Gerçek çorap sayısı o kadar büyük değil, eşime inanmıyorum ve 30'dan fazla çiftim var. (Ve çoraplarımı ve onunki arasında ayrım yapmak oldukça kolaydır; bu da kullanılabilir mi?)
  • Eleman ayırt etme problemine eşdeğer mi?

448
Çamaşır yığınından tam olarak eşleştirmek için güvercin deliği prensibini kullanıyorum. 3 farklı renk çorap (Kırmızı, Mavi ve Yeşil) ve her renkten 2 çift var. Her seferinde 4 çorap alıyorum ve her zaman bir çift oluşturup işe başlıyorum.
Srinivas

59
Yine başka bir güvercin deliği prensibi: n / 2 +1 çorapların bir alt kümesini alırsanız , bu alt kümede en az bir çift olmalıdır .
Ocak'ta wildplasser

40
Harika bir soru! İlgili bir sorun hakkındaki makalemle ilgilenebilirsiniz
Eric Lippert

336
Neden bir çocuk doğurmuyorsunuz ve waitpidböylece ebeveyn olarak kendiniz çorap bile ayırmıyorsunuz?
Mxyk

137
Bu sorunu sadece beyaz diz boyu çoraplarla çözdüm. Hepsi eşleşir. Yığınından rastgele herhangi iki çorap alabilirim ve eşleşeceklerdi. Çorapları eşleştirmeyerek sorunu daha da basitleştiriyorum. Tüm çoraplarımı eşleştirip eşleştirmediğim bir çorap çekmecem var. Her sabah çekmeceden rastgele iki tane alıyorum. Onu O (0) 'ya indirdim. Bundan daha basit olamaz. :)
Lee

Yanıtlar:


2449

Sıralama çözümleri önerilmiştir, ancak sıralama biraz fazladır : Düzene ihtiyacımız yoktur; sadece eşitlik gruplarına ihtiyacımız var .

Yani hash yeter (ve daha hızlı).

  1. Her çorap rengi için bir yığın oluşturun . Giriş sepetinizdeki tüm çorapları tekrarlayın ve renk yığınlarına dağıtın .
  2. Her kazık üzerinde tekrarlayın ve başka bir metrikle (örneğin desen) ikinci kazık kümesine dağıtın
  3. Tüm çorapları görsel olarak hemen işleyebileceğiniz çok küçük yığınlara dağıtana kadar bu şemayı tekrar tekrar uygulayın.

Bu tür özyinelemeli karma bölümleme, SQL Server tarafından büyük veri kümeleri üzerinde karma birleştirme veya karma toplaması gerektiğinde yapılır. Yapı girdi akışını bağımsız birçok bölüme dağıtır. Bu şema, rastgele miktarda veri ve çoklu CPU'lara doğrusal olarak ölçeklenir.

Her bir grubun çok hızlı bir şekilde işlenecek kadar küçük olması için yeterli sayıda kova sağlayan bir dağıtım anahtarı (karma anahtarı) bulursanız, özyinelemeli bölümlemeye ihtiyacınız yoktur . Ne yazık ki, çorapların böyle bir özelliği olduğunu sanmıyorum.

Her çorapta "PairID" adlı bir tamsayı varsa, PairID % 10(son hane) 'ye göre kolayca 10 kovaya dağıtılabilir .

Düşünebileceğim en iyi gerçek dünya bölümleme, bir yığın dikdörtgen oluşturmaktır : bir boyut renk, diğeri desen. Neden bir dikdörtgen? Çünkü kazıklara rasgele erişime O (1) ihtiyacımız var. (Bir 3D küboid de işe yarayacaktır, ancak bu çok pratik değildir.)


Güncelleme:

Paralellik ne olacak ? Birden fazla insan çorapları daha hızlı eşleştirebilir mi?

  1. En basit paralelleştirme stratejisi, birden fazla işçinin giriş sepetinden alması ve çorapları yığınlara koymasıdır. Bu sadece çok fazla ölçekleniyor - 100 kişinin 10 kazık üzerinde savaştığını hayal edin. Senkronizasyon maliyetleri (el çarpmaları ve insan iletişimi olarak kendini gösterir) verimliliği ve hızlanmayı tahrip eder (bkz. Evrensel Ölçeklenebilirlik Yasası !). Bu çıkmazlara eğilimli mi? Hayır, çünkü her çalışan bir seferde sadece bir kazığa erişmelidir. Sadece bir "kilit" ile bir kilitlenme olamaz. Canlı kilitler , insanların kazıklara erişimi nasıl koordine ettiğine bağlı olarak mümkün olabilir. Sadece rastgele geri çekmeyi kullanabilirlerağ kartları gibi, hangi kartın ağ kablosuna yalnızca erişebileceğini belirlemek için bunu fiziksel düzeyde yapın. Onun için çalışırsa NIC , insanlar için çalışmak yanı gerekir.
  2. Her işçinin kendi kazık kümesi varsa neredeyse süresiz ölçeklenir . İşçiler daha sonra giriş sepetinden büyük çorap parçaları alabilirler (nadiren yaptıkları için çok az çekişme) ve çorapları dağıtırken senkronize olmaları gerekmez (çünkü yerel iplik yığınları vardır). Sonunda, tüm işçilerin kazık kümelerini birleştirmeleri gerekiyor. Eğer işçiler bir toplama ağacı oluşturuyorsa, O (log (işçi sayısı * işçi başına kazık)) içinde yapılabileceğine inanıyorum .

Eleman farklılığı sorunu ne olacak ? Makalede belirtildiği gibi, eleman farklılığı problemi çözülebilir O(N). Bu çorap problemi için de aynıdır (ayrıca O(N), sadece bir dağıtım adımına ihtiyacınız varsa (sadece insanlar hesaplamalarda kötü olduğu için birden fazla adım önerdim - dağıtırsanız bir adım yeterlidir md5(color, length, pattern, ...), yani tüm özelliklerin mükemmel bir karması ).

Açıkçası, bundan daha hızlı gidemeyiz O(N), bu yüzden en uygun alt sınıra ulaştık .

Çıktılar tam olarak aynı olmamasına rağmen (bir durumda, sadece bir boolean. Diğer durumda, çorap çiftleri), asimtotik karmaşıklıklar aynıdır.


72
Bu tam olarak yaptığım şey! Kazıkları çorabın açılma stiline bağımlı hale getiriyorum (sadece beyazım var), bu da bana bunların her birini hızla eşleştirmek için yeterli "kova" veriyor.
Scott Chamberlain

29
Bunu çoraplarımla denedim (kolayca 30+ çiftim var) ve adam HIZLI. Bulduğum bir sorun, yeterince iyi bir karma algoritmasına sahip olmadığım zaman (herhangi bir desen olmadan çok sayıda beyaz çorap aldım) bu yüzden zorlaşıyor. Bu durumda, bunu yapmanın en iyi yolu ne olurdu?
NothingsImpossible

56
Karma çarpışma saldırılarının kötü bir web sunucusu için böyle hissetmesi imkansız! Beyaz çoraplar bazı özelliklere göre ayırt edilebilir mi? Onları dağıtabileceğiniz bir şey olmalı. Aksi takdirde, çiftleri keyfi olarak oluşturabilirsiniz.
usr

37
Bu, doğru cevap olduğunu kabul ettiğim bir Radix Sort. @MarkPeters Bir arama tablosuna ihtiyacınız olduğunu düşünmüyorum. Çoraplar üzerinde tek bir doğrusal geçiş çorapları sayı vektörlerine dönüştürebilir ve bu da "çorap segmentinin" kovaya eşlenmesini önemsiz hale getirir. Çoraplar dize ile vektörlere bağlanabilir, böylece sonunda başka bir doğrusal geçişe ihtiyacınız yoktur.
Sivri

49
Üniversiteye gittiğim bir adamın aslında PairID'si vardı. Her bir çift çorabın üzerine iplikle dikildi: 1, 2, 3, 4 ...
Ryan Lundy

579

İnsan beyninin mimarisi modern bir CPU'dan tamamen farklı olduğundan, bu soru pratik bir anlam ifade etmiyor.

İnsanlar, "eşleşen bir çift bulmanın" çok büyük olmayan bir set için bir işlem olabileceği gerçeğini kullanarak CPU algoritmalarını kazanabilirler.

Algoritmam:

spread_all_socks_on_flat_surface();
while (socks_left_on_a_surface()) {
     // Thanks to human visual SIMD, this is one, quick operation.
     pair = notice_any_matching_pair();
     remove_socks_pair_from_surface(pair);
}

En azından gerçek hayatta kullandığım şey bu ve çok verimli buluyorum. Dezavantajı, düz bir yüzey gerektirmesidir, ancak genellikle bol miktarda bulunur.


229
çorap sayısı arttıkça, insanın SIMD'si bir CPU'dan daha iyi olamaz.
Yalan Ryan

25
En iyi cevap, IMO. Bir bilgisayar algoritmasındaki günlük sorunu azaltmak eğlenceli ve zeki (ve SO için uygun) olsa da, ~ 60 çorap kadar küçük bir set için insan gözünün / beyninin çözünürlük gücünü kullanmak çok daha mantıklıdır.
drug_user841417

13
@LieRyan Çoraplar eşit olarak dağıtılırsa, doğum günü paradoksu nedeniyle (renkleri şüphesiz ki kesin hassasiyetle ayırt edemediğiniz sürece) yeterince küçük bir çorap setinde bir çift fark edeceksiniz, bu yüzden buradaki darboğaz olmaz insan renk eşleştirme algoritması ancak yayılma adımı.
Thomas

13
@ dpc.ucore.info Hayır, çünkü farklı dokuma manşet desenleri, manşet uzunlukları, toplam uzunlukları ve siyah tonları var (eşim muhtemelen bu sonuncusu için fiziksel olarak bana zarar verir).
Christian


258

Durum 1 : Tüm çoraplar aynı (bu arada gerçek hayatta yaptığım şey).

Bir çift yapmak için herhangi birini seçin. Sabit zaman.

Durum 2 : Sabit sayıda kombinasyon vardır (sahiplik, renk, boyut, doku vb.).

Sayı tabanı sıralaması kullanın . Karşılaştırma gerekmediği için bu sadece doğrusal bir zamandır.

Durum 3 : Kombinasyon sayısı önceden bilinmemektedir (genel durum).

İki çorabın çift olup olmadığını kontrol etmek için karşılaştırma yapmalıyız. O(n log n)Karşılaştırma tabanlı sıralama algoritmalarından birini seçin .

Bununla birlikte, çorap sayısının nispeten az (sabit) olduğu gerçek hayatta, bu teorik olarak optimal algoritmalar iyi çalışmaz. Teorik olarak ikinci dereceden zaman gerektiren sıralı aramadan daha fazla zaman alabilir.


8
> Teoride ikinci dereceden zaman gerektiren sıralı aramadan daha fazla zaman alabilir. Evet, bu yüzden bunu yapmaktan nefret ediyorum, belki de tüm çoraplarımı fırlatmalı ve dava 1 ile başlamalıyım
Nils

57
tüm özdeş çoraplara sahip olmanın aşağı tarafı, farklı oranlarda yaşlanma eğilimindedir. Böylece hala ne kadar yıpranmış olduklarına bağlı olarak onları eşleştirmeye çalışıyorsunuz. (desenle eşleşmekten daha zordur)
SDC

118
60 çift özdeş çorap sahibi olma sorunu, "eşleştirmeyi kolaylaştırdığı için" insanlara bilgisayarlarla çalıştığınız izlenimini vermesidir.
Steve Ives

13
Durum 1 , çiftleri katlama gibi bir işlem söz konusu olduğunda sabit bir süre değildir. Bu durumda, en küçük sabit faktörle (kanıtı okuyucu için bir egzersiz olarak kalan) doğrusal bir zamandır. Bir çifti ve çorap dolu bir kovayı katlamak muhtemelen aynı zamana sahip olamaz. Ancak, doğrusal olarak ölçeklenir. Amdahl yasasına göre, sınırsız bir hıza sahiptir ve ek yükü görmezden gelir. Gustafson yasasına göre, yeterli sayıda işçi (miktarı okuyucu için bir egzersiz olarak bırakılır) verildiğinde bir çifti katlamak için gereken sayıda çifti katlayabilir ve yükü göz ardı edebilirsiniz.
acelent

7
@PauloMadeira Sıralama sabit bir zamandır - sadece yığını alıp çekmecenize koyun. Bu durumda tek işlem aslında çorapları ayaklarınıza koymaktır ve bu da sabittir. Performans, muhtemelen uzayda bir miktar fedakarlık ile çorap giymenin ertelenmiş uygulamasıyla elde edilir (katlanmamış çorapların tüketilen alanı katlanmıştan daha büyüktür). Buna değer olduğunu iddia ediyorum; Bu argümanı genellikle eşimle kaybederim.
Travis

157

Algoritmik olmayan yanıt, ancak bunu yaptığımda "verimli":

  • Adım 1) mevcut tüm çoraplarınızı atın

  • adim 2) Walmart'a gidin ve 10 - n paket beyaz ve m siyah paketlerle satın alın. Günlük yaşamda başka renklere gerek yok.

Yine de zaman zaman bunu tekrar yapmak zorundayım (kayıp çoraplar, hasarlı çoraplar, vb.) Ve mükemmel iyi çorapları çok sık atmaktan nefret ediyorum (ve aynı çorap referansını satmaya devam etmelerini diledim!) Farklı bir yaklaşım.

Algoritmik cevap:

İkinci çorap yığını için sadece bir çorap çiziyorsanız, yaptığınız gibi, saf bir aramada eşleşen çorap bulma olasılığınız oldukça düşüktür.

  • Bu yüzden beşini rastgele alın ve şekillerini veya uzunluklarını ezberleyin.

Neden beş? Genellikle insanlar, çalışma belleğindeki beş ila yedi farklı öğeyi hatırlarlar - bir RPN yığınının insan eşdeğeri gibi - beş güvenli bir varsayılan değerdir .

  • 2n-5 yığınından bir tane alın.

  • Şimdi çizdiğiniz beşin içinde bir eşleşme arayın (görsel desen eşleştirme - insanlar küçük bir yığınla iyidir), eğer bir tane bulamazsanız, bunu beşinize ekleyin.

  • Yığından rastgele çorap almaya devam edin ve bir maç için 5 + 1 çoraplarınızla karşılaştırın. Yığınız büyüdükçe performansınızı düşürecek, ancak oranlarınızı artıracaktır. Çok daha hızlı.

Bir maçın% 50'si için kaç örnek çizmeniz gerektiğini hesaplamak için formülü yazmaktan çekinmeyin. IIRC hipergeometrik bir yasa.

Bunu her sabah yapıyorum ve nadiren üçten fazla berabere ihtiyacım var - ama nbenzer çiftler (yaklaşık 10, kayıp olanları verin veya alın) mşekilli beyaz çoraplarım var. Şimdi stok yığınımın boyutunu tahmin edebilirsiniz :-)

BTW , bir çifte her ihtiyacım olduğunda tüm çorapları ayırmanın işlem maliyetlerinin toplamının, bir kez yapmaktan ve çorapları bağlamaktan çok daha az olduğunu buldum. Tam zamanında çalışır, çünkü çorapları bağlamak zorunda kalmazsınız ve aynı zamanda azalan marjinal bir dönüş de vardır (yani, çamaşırın bir yerinde ve ihtiyacınız olan iki veya üç çorap aramaya devam edersiniz. çoraplarınızı eşleştirmeyi bitirdiğinizde zaman kaybetmezsiniz).


25
'Algoritmik olmayan' cevap için oy verin. Bu tam olarak yaptığım şey ve harika çalışıyor. Yıkanmış çorapları arkaya yerleştirip sabah çekmecenin önünden çekerek çorap stoğunu 'döndürürseniz' sorun olmaz. Tüm çoraplar eşit şekilde aşınır. Birinde biraz aşınma fark ettiğimde, tüm çorap sınıfını tamamen değiştirmek için alışveriş listesine koydum. Eski çoraplar için, Goodwill'e en iyi% 20'yi verdim (bir bakkal kesesine bağlandım, böylece geri karışmazlar) ve geri kalanını fırlatırım. Çorap boşa harcamıyorsunuz, bu noktada% 80'inde yine de 6 ay kaldı.
FastAl

2
BTW (1) Çoraplarınızı bağlamak elastik olanın gergin şekilde depolanmasını sağlar ve çok daha hızlı başarısız olur. Sahip olduğunuz benzersiz çorap türlerini sınırlamak, ciltlemeyi birleştirir. (2) Eşsiz çorapları sınırlamanın bir dezavantajı, belirli moda endişeleri olan insanlar için yöntemin uygun olmayabilir.
FastAl

3
Buraya özellikle "algoritmik olmayan" cevabınızı göndermek için geldim. Gerçek bilgisayar biliminde olduğu gibi, çoğu insan verilere ve yapısına asla yeterince dikkat etmez.
bkconrad

Bu algoritmik yaklaşımı her sabah kullanıyorum ve bir cazibe gibi çalışıyor! Ayrıca, daha sonra atmak için farklı bir kazığa yıpranmış çoraplar koydum (maalesef, çöpe atma zamanını bulmadan önce orijinal kazığa tekrar ulaşmayı başardılar).
Donatas Olsevičius

3
«N beyaz paket ve m siyah paket. Günlük yaşamda başka renklere gerek yok »Kolay çorap seçimi için iyi bir standart kural, pantolonlarınızın rengine veya kemerinizin rengine uymalarıdır. Bu nedenle, en sık kullanılan renkler muhtemelen siyah, mavi, gri ve biraz kahverengi olacaktır. Birinin beyaz çoraplara ihtiyacı olduğuna inanmak zor.
Andrea Lazzarotto

106

Yaptığım şey, ilk çorabı alıp bırakmam (örneğin, çamaşır kabının kenarında). Sonra başka bir çorap alıp ilk çorapla aynı olup olmadığını kontrol ediyorum. Eğer öyleyse, ikisini de kaldırırım. Değilse, ilk çorabın yanına koydum. Sonra üçüncü çorabı alıp ilk ikisiyle karşılaştırırım (eğer hala oradalarsa). Vb.

Bu yaklaşım, çorapların "çıkarılması" nın bir seçenek olduğu varsayılarak bir dizide kolayca uygulanabilir. Aslında çorapları “çıkarmanıza” bile gerek yok. Çorapların sınıflandırılmasına ihtiyacınız yoksa (aşağıya bakın), o zaman onları hareket ettirebilir ve tüm çorapları dizide çiftler halinde düzenlenmiş bir dizi ile sonlandırabilirsiniz.

Çoraplar için tek işlemin eşitliği karşılaştırmak olduğunu varsayarsak, bu algoritma temelde hala bir n 2 algoritmasıdır, ancak ortalama durum hakkında bilmiyorum (bunu hesaplamayı hiç öğrenmedim).

Ayırma, elbette verimliliği, özellikle de diğer iki çorap arasına kolayca çorap "ekleyebileceğiniz" gerçek hayatta. Aynı hesaplamada bir ağaç da elde edilebilirdi, ama bu ekstra alan. Ve elbette, NlogN'e geri döndük (ya da sıralama ölçütleri ile aynı olan, ancak aynı çiftten olmayan birkaç çorap varsa) biraz daha fazla.

Bunun dışında hiçbir şey düşünemiyorum, ama bu yöntem gerçek hayatta oldukça verimli görünüyor. :)


7
Bu da benim yaptığım şeydir (sadece boşluk bırakırsanız eklerin de O (1) olduğunu unutmayın), ancak teorik olarak çok sayıda çorap ile zayıf ölçeklendirir.
Mooing Duck

15
teorik olarak çok sayıda çorap türü ile zayıf bir şekilde ölçeklendiriliyor
Steven Lu

@StevenLu - Dediğim gibi - sıralansanız da sıralamasanız da n * n veya nLogn. Yani herhangi bir sıralama algoritması kadar zayıf ölçeklenir. Daha hızlı istiyorsanız, numaralandırın ve sayı tabanı sıralaması kullanın.
Vilx-

Bu, esasen bulunan ama eşleşmeyen çorapları karma tabanlı bir aramada saklar. İdeal bir karma ile O (n), ama eğer hash dejenere olmaya başlayacak kadar depolanmış çorapınız varsa, buna göre daha karmaşık hale gelir.
Jon Hanna

3
diğer 2 çorap arasına çorap sokmak çorap eşleştirme amacına ne değer katar? çorapların kardinalitesi yoktur. : -x
JoeBrockhaus

60

Bu yanlış soruyu soruyor. Sorulması gereken doğru soru, çorapları ayırmak için neden zaman harcıyorum? Seçtiğiniz X para birimi için boş zamanınızı değerlendirdiğinizde yıllık olarak ne kadar tutar?

Ve çoğu zaman, bu sadece herhangi bir boş zaman değil, yatakta geçirebileceğiniz veya kahvenizi yudumlayabileceğiniz veya biraz erken bırakarak ve trafiğe yakalanamayacağınız sabah serbest zamanı.

Geri adım atmak ve problemin etrafında bir yol düşünmek genellikle iyidir.

Ve bir yolu var!

Beğendiğin bir çorap bul. İlgili tüm özellikleri dikkate alın: farklı aydınlatma koşullarında renk, genel kalite ve dayanıklılık, farklı iklim koşullarında konfor ve koku emilimi. Ayrıca önemli olan, depolamada elastikiyetini kaybetmemeleri gerektiğinden, doğal kumaşlar iyidir ve plastik bir ambalajda mevcut olmalıdırlar.

Sol ve sağ ayak çorapları arasında fark yoksa daha iyidir, ancak kritik değildir. Çoraplar sol-sağ simetrik ise, bir çift bulmak O (1) işlemidir ve çorapların sıralanması yaklaşık O (M) işlemidir, burada M evinizdeki çoraplarla çevrili yerlerin sayısıdır, ideal olarak bazı küçük sabit sayı.

Farklı sol ve sağ çoraplara sahip süslü bir çift seçerseniz, sol ve sağ ayak kovalarına tam kova sıralaması yapmak O (N + M) alır, burada N çorap sayısıdır ve M yukarıdakiyle aynıdır. Başka biri, ilk çifti bulmak için ortalama yinelemeler için formül verebilir, ancak kör arama ile bir çift bulmak için en kötü durum, makul N için astronomik olarak olası olmayan durum olan N / 2 + 1'dir. Bu, gelişmiş görüntü kullanılarak hızlandırılabilir. Mk1 Eyeball ile ayrılmamış çorap yığınını tararken tanıma algoritmaları ve sezgisel tarama .

Yani, O (1) çorap eşleştirme verimliliğini (simetrik çorap varsayarak) elde etmek için bir algoritma:

  1. Hayatınızın geri kalanı için kaç çift çorap ihtiyacınız olacağını veya belki de bir daha asla çorap giymeye gerek kalmadan emekli oluncaya ve daha sıcak iklimlere geçene kadar tahmin etmeniz gerekir. Eğer gençseniz, evlerimizde çorap ayırıcı robotlara sahip olmamızın ne kadar süreceğini de tahmin edebilirsiniz ve tüm sorun önemsiz hale gelir.

  2. Seçtiğiniz çorapları toplu olarak nasıl sipariş edebileceğinizi ve ne kadar tutacağını ve teslim ettiklerini öğrenmeniz gerekir.

  3. Çorapları sipariş et!

  4. Eski çoraplarından kurtul.

Alternatif bir adım 3, yıllar boyunca bir seferde birkaç çift aynı miktarda daha ucuz çorap satın alma maliyetlerini karşılaştırmayı ve çorap ayırma maliyetini eklemeyi içerir, ancak sözümü söyleyin: toplu olarak satın almak daha ucuzdur! Ayrıca, depolamadaki çoraplar, hisse senedi fiyatı enflasyon oranında değer artışı gösterir, bu da birçok yatırımda elde edeceğinizden daha fazladır. Daha sonra yine depolama maliyeti var, ancak çoraplar bir dolabın üst rafında gerçekten fazla yer kaplamaz.

Sorun çözüldü. Yani, sadece yeni çoraplar alın, eskilerinizi atın / bağışlayın ve hayatınızın geri kalanında her gün para ve zaman tasarrufu yaptığınızı bildikten sonra mutlu bir şekilde yaşayın.


Ömür boyu (75 yıl olduğu varsayılır) çorap temini (ayda 4 çift tükettiğinizi varsayarsak, 3600 çift yapar) toplam 1 1/2 kübik yarda (yeni bir çift çorap 20 kübik inç aldığını varsayarak) alacaktır. Bu muazzam bir alan. Size kabaca bir küp olan bir kutuda teslim ettiklerini varsayarsak, bu sandık bir tarafta yaklaşık 3 feet 4 inç olacaktır.
AJMansfield

2
@AJMansfield geçerli bir endişe. Ancak, birkaç numaranıza katılmıyorum. Sadece 40 yıllık bir zaman aralığı (25 ... 65) alıyorum (ebeveyn / yurt / vb. Ayrıca, bir çiftin orijinal ambalajında ​​0,5x4x6 inç daha fazla olduğunu düşünüyorum. Bu sayılar uzay tahmininizi biraz düşürür!
hyde

Adım 4 gereksiz yere israf, -1.
Dan Bechard

2
AJMansfield'ın ölçümleriyle karıştırılabilecek başkaları için rehber, metriğe bir çeviri: »toplam 1,14 m³ (yeni bir çift çorap 327 cm³ alır). Bu muazzam bir alan. Size kabaca bir küp olan bir kutuda teslim ettiklerini varsayarsak, bu sandık bir tarafta yaklaşık 1.04 m olacaktır. «
Joey 28/13

Merak temelli bir soru nasıl "yanlış soru" olabilir? Klasik StackOverflow ...
Timmmm

52

Teorik sınır O (n) 'dir, çünkü her bir çorağa dokunmanız gerekir (bazıları zaten bir şekilde eşleştirilmedikçe).

Sayı tabanı sıralamasıyla O (n) elde edebilirsiniz . Sadece kovalar için bazı özellikler seçmeniz gerekir.

  1. İlk önce (onun, benimki) seçim yapabilirsiniz - bunları 2 kazığa ayırın,
  2. sonra renkleri kullanın (renkler için herhangi bir sıraya sahip olabilir, örneğin renk adına göre alfabetik olarak) - bunları renklere göre yığınlara ayırın (aynı yığındaki tüm çoraplar için ilk siparişi 1. adımdan tutmayı unutmayın),
  3. sonra çorabın uzunluğu,
  4. sonra doku, ....

Sınırlı sayıda özellik seçebilir, ancak her çifti benzersiz olarak tanımlayabilecek yeterli nitelikleri seçerseniz, k sınırlı olduğunu düşünebilirsek O (k * n) 'de yapılmalıdır.


3
Çoraplar genellikle 4 paket halinde ve daha büyük olarak gelir, çünkü bu daha ucuzdur, ancak bu da onları ayırt edilemez hale getirir. Buna karşı olmak için, eşim satın aldığım her yeni çorap üzerine küçük bir iz dikiyor. İşaret, her çift için farklı bir renkte veya renk biterse farklı bir şekildedir. Bu yaklaşımla sınırlı bir öznitelik setine bile ihtiyacınız yoktur. Her çift için benzersiz bir sayı dikin. :) Ekstra puan için binary komutunu kullanın.
Vilx-

29
@ Vilx- NEDEN?!? Bütün mesele ayırt edilemez değil mi?
FLUP

2
@flup - Bence bütün mesele daha büyük paketler halinde satmak. :) Bana gelince, bu onları çiftler halinde giymeye yardımcı olur. Aksi taktirde üç çok yıpranmış çorap ve bir tane de yeni çorap giyebilirim. Biraz aptalca.
Vilx-

13
O (n) 'nin hesaplanmasına katılmıyorum. $ K $ nedir? $ k $, özellik sayısıdır. Ben $ k $ $ O (log n) $ olduğunu iddia ediyorum çünkü her çifti benzersiz olarak tanımlamak için yeterli olmalıdır. 2 çiftiniz varsa (siyah beyaz), renk ($ k = 1, n = 2 $) yeterlidir. Bir çift siyahınız varsa, kısa; bir çift siyah, uzun; bir çift beyaz, kısa; ve bir çift beyaz, uzun - sonra $ k = 2, n = 4 $. O zaman $ k $ 'ı sınırlarsak, aynı zamanda $ n $' ı sınırlarız. Eğer $ n $ sınırlayacaksak, sipariş hesaplaması artık mantıklı değil.
emory

3
@emory, bence $eşyalarınızı kod-y olarak göstermek için karakteri değil backtick'i arıyorsunuz .
Xymostech

33

Pratik bir çözüm olarak:

  1. Hızla kolayca ayırt edilebilen çorap yığınları yapın. (Renge göre söyle)
  2. Her yığını hızlıca sıyırın ve çorap uzunluğunu karşılaştırma için kullanın. Bir insan olarak, en kötü durumdan kaçınan bölmeye kullanmak için oldukça hızlı bir karar verebilirsiniz. (Paralel olarak birden fazla çorap görebilirsiniz, bunu kendi yararınıza kullanın!)
  3. Yığın çiftlerini ve çift çorapları anında bulmak için rahat olduğunuz bir eşiğe ulaştıklarında yığınları sıralamayı bırakın

Eğer 8 renk ve ortalama bir dağılım ile 1000 çorapınız varsa, her 125 çoraptan 4 yığınını c * n zamanında yapabilirsiniz. 5 çorap eşiği ile her yığını 6 koşuda sıralayabilirsiniz. (Sağ kazığa çorap atmak için 2 saniye saymak, 4 saatten az sürecektir.)

Sadece 60 çorap, 3 renk ve 2 çeşit çorap (sizin / eşinizin) varsa, her 10 çorap yığınını 1 koşuda sıralayabilirsiniz (Tekrar eşik = 5). (2 saniye saymanız 2 dakika sürecektir).

İlk kova sıralaması işleminizi hızlandıracaktır, çünkü n çoraplarınızı c*nzaman içinde k kovalarına böler, böylece sadece c*n*log(k)iş yapmanız gerekir . (Eşiği dikkate almamak). Yani n*c*(1 + log(k))iş hakkında yaptığınız her şey , burada c bir kazık üzerine çorap atma zamanı.

Bu yaklaşım c*x*n + O(1)kabaca sürece herhangi bir yönteme kıyasla daha uygun olacaktır log(k) < x - 1.


Bilgisayar biliminde bu yardımcı olabilir: n şeylerden oluşan bir koleksiyonumuz, üzerimizde bir siparişimiz (uzunluk) ve aynı zamanda bir denklik ilişkimiz var (ekstra bilgi, örneğin çorap rengi). Eşdeğerlik ilişkisi, orijinal koleksiyonun bir bölümünü oluşturmamıza izin verir ve her eşdeğerlik sınıfında siparişimiz hala korunur. Bir şeyin eşdeğerlik sınıfıyla eşlenmesi O (1) 'de yapılabilir, bu nedenle her öğeyi bir sınıfa atamak için yalnızca O (n) gerekir. Şimdi ek bilgilerimizi kullandık ve her sınıfı sıralamak için herhangi bir şekilde ilerleyebiliriz. Avantajı, veri kümelerinin zaten önemli ölçüde daha küçük olmasıdır.

Yöntem, birden fazla denklik ilişkimiz varsa, iç içe yerleştirilebilir -> renk üzerindeki yığınları, dokudaki her yığın bölümünde, uzunluktaki sıralamaya göre yapmak. Yaklaşık eşit büyüklüğe sahip 2'den fazla öğe içeren bir bölüm oluşturan herhangi bir eşdeğerlik ilişkisi, sıralama üzerine bir hız artışı getirecektir (doğrudan kazığına bir çorap atayabilmemiz koşuluyla) ve sıralama daha küçük veri kümelerinde çok hızlı bir şekilde gerçekleşebilir.


3
İnsan optimizasyonu: Bir insan olarak, adım 2 için, çorapları kabaca artan sırada aşağıya doğru eğmelisiniz, sonra sıralanana kadar biraz daha ince ve daha küçük taneciklerle tekrarlayın, kabuk sıralaması gibi. Bu, bir insan için (görsel tahmin) karşılaştırma takası tabanlı bir yaklaşımdan çok daha hızlı olacaktır.
AndrewC

28

Yanlış sorunu çözmeye çalışıyorsunuz.

Çözüm 1: Kirli çorapları çamaşır sepetinize her koyduğunuzda, küçük bir düğüme bağlayın. Bu şekilde yıkamadan sonra herhangi bir ayıklama yapmanız gerekmeyecektir. Bunu bir Mongo veritabanına bir dizin kaydettirmek gibi düşünün. Gelecekte bazı CPU tasarrufları için küçük bir çalışma.

Çözüm 2: Kışsa, eşleşen çorap giymeniz gerekmez. Biz programcıyız. Çalıştığı sürece kimsenin bilmesine gerek yok.

Çözüm 3: Çalışmayı yayın. Kullanıcı arayüzünü engellemeden böyle karmaşık bir CPU işlemini eşzamansız olarak gerçekleştirmek istiyorsunuz. Şu çorap yığınını alın ve bir torbaya doldurun. Bir çifti yalnızca ihtiyacınız olduğunda arayın. Bu şekilde gereken iş miktarı çok daha az fark edilir.

Bu yardımcı olur umarım!


5
Bir düğüme çorap (veya herhangi bir giysi) bağlamak, çamaşır makinesinin çamaşırları yıkama yeteneğini azaltır ve bunların çözülmesini çok daha zor hale getirir. Çözüm 2, işlerin durumu ilerledikçe bakımı zorlaştırır; 6 ay sonra, bir çift şort ve spor ayakkabısı giymek için iki siyah ayak bileği çorapına ihtiyaç duyduğunuzda, 6 ay boyunca ne yaparsanız yapın, bu çifti aynı durumda (kirli / temiz, benzer aşınma) bulmanın daha az muhtemel olmasını sağlar. Çözüm 3 daha az "asenkron" ve daha düz "tembel" dir; ihtiyacınız olan minimum işi tam olarak ihtiyacınız olduğunda yapın.
KeithS

Re: çözüm 2: İnsanlar eşleşen çorap giymediğimi bilecekler çünkü onları Birks'imde görecekler :)
Bob Probst

@BobProbst Evet ama diğer programcılarınız da Birks ile eşsiz çoraplar giyecekler ve bu yüzden sadece onlar olmadığını fark etmekten mutluluk duyacaklar.
Francesco Pasa

27

Bu soru aslında derin bir felsefi. Temelde insanların problemleri çözme gücünün (beynimizin “ıslatıcısı”) algoritmalarla gerçekleştirilebilecekle eşdeğer olup olmadığı ile ilgilidir.

Çorap sıralama için bariz bir algoritma:

Let N be the set of socks that are still unpaired, initially empty
for each sock s taken from the dryer
  if s matches a sock t in N
    remove t from N, bundle s and t together, and throw them in the basket
  else
    add s to N

Şimdi bu problemdeki bilgisayar bilimi adımlarla ilgili

  1. msgstr "eğer s N'de bir çorap t ile eşleşirse". Şimdiye kadar gördüklerimizi ne kadar çabuk "hatırlayabiliyoruz"?
  2. msgstr "t'yi N'den kaldır" ve "s'yi N'ye ekle". Şimdiye kadar gördüklerimizi takip etmek ne kadar pahalı?

İnsanlar bunları gerçekleştirmek için çeşitli stratejiler kullanacaktır. İnsan hafızası olan çağrışımlı , saklanan değerlerin özellik setleri gelen değerlerin kendisi ile eşleştirilmiş bir karma tablo gibi bir şey. Örneğin, "kırmızı araba" kavramı, bir kişinin hatırlayabildiği tüm kırmızı arabalarla eşleşir. Mükemmel hafızası olan biri mükemmel bir haritaya sahiptir. Çoğu insan bu konuda (ve diğer birçok durumda) kusurludur. İlişkilendirilebilir haritanın kapasitesi sınırlıdır. Eşlemeler uyuyabilir çeşitli koşullar altında (bir bira çok fazla) var olmama, hata olarak kaydedilme ("Ben adı Nettie değil Betty olmasına rağmen") ya da gerçeğin değiştiğini gözlemlememize rağmen asla üzerine yazılmayacak ("babamın arabası" çağrıştırıyor) "turuncu Firebird" aslında kırmızı Camaro için takas olduğunu biliyordu).

Çorap durumunda, mükemmel hatırlama, bir çoraba bakmak, sher zaman kardeşinin hafızasını üretir, sabit zamanda tbulmak için yeterli bilgi (ütü masasında bulunduğu yer) t. Fotoğrafik hafızaya sahip bir kişi, hem 1 hem de 2'yi sürekli olarak hatasız olarak başarır.

Mükemmel hafızadan daha azı olan bir kişi, takip etme kabiliyetindeki özelliklere göre birkaç sağduyu denklik sınıfını kullanabilir: boyut (papa, anne, bebek), renk (yeşilimsi, kırmızıımsı, vb.), Desen (argyle, düz, vb.) , stil (footie, diz boyu vb.). Böylece ütü masası kategoriler için bölümlere ayrılır. Bu genellikle kategorinin belleğe göre sabit bir zamanda bulunmasına izin verir, ancak daha sonra "kova" kategorisinde doğrusal bir arama yapılması gerekir.

Hafızası veya hayal gücü olmayan biri (üzgünüm) çorapları bir yığın halinde tutacak ve tüm kazığın doğrusal bir aramasını yapacak.

Düzgün bir ucube, birisinin önerdiği gibi çiftler için sayısal etiketler kullanabilir. Bu, insanın bir CPU ile tam olarak aynı algoritmaları kullanmasına izin veren toplam bir sıralamanın kapısını açar: ikili arama, ağaçlar, karmalar vb.

Bu nedenle "en iyi" algoritma, onu çalıştıran ıslatıcı yazılımın / donanımın / yazılımın özelliklerine ve çiftlere toplam bir emir vererek "aldatma" isteğimize bağlıdır. Kesinlikle bir "en iyi" meta- algoritma, dünyanın en iyi çorap-sıralayıcısını kiralamaktır: sabit bir zaman araması, ekleme, ve silin. Hem insanlar hem de bunun gibi makineler tedarik edilebilir. Eğer bir tane varsa, tüm çorapları N çiftleri için O (N) zamanında eşleştirebilirsiniz, bu en uygunudur. Toplam sipariş etiketleri, bir insan veya donanım bilgisayarında aynı sonucu elde etmek için standart karma işlevini kullanmanızı sağlar.


Tamam, bu daha iyi, yine de oldukça yanlış olmasına rağmen ... bu soru bununla ilgili değil. Church-Turing tezinin doğru olup olmadığı, hem insanlar hem de bilgisayarlarımız çorapları sıralayabilir. (Gerçek şu ki, son derece sınırlı bir varlık olan insanlar Turing Machines'den çok daha az hesaplama gücüne sahiptir ... ve aynı şey bilgisayarlarımız için de geçerlidir, ancak sınırlamalar farklıdır.)
Jim Balter

Katılmıyorum. Elbette mevcut bilgisayarlarımızdan herhangi biri TM yerine esasen ve muazzam bir DFA'dır (modulo i / o farklılıkları). Bununla birlikte, vücudumuz gibi herhangi bir analog cihaz sonsuz bir bandı taklit edebilir. Zihinlerimizin hesaplama şekli hakkında henüz yararlı bir karakterizasyonumuz yok.
Gene

İnsanlar veya diğer fiziksel cihazlar için sonsuz bant yoktur, çünkü insan beynindeki hiçbir şey sonsuz çözünürlüğe sahip değildir ve olamaz. Ayrıca bazı sinirbilimi öğrenmeye de yardımcı olacaktır. Her durumda, bir tane enjekte etme arzunuz ne olursa olsun, burada derin bir felsefi soru yoktu. Ama ne olacağına inan ... Burası bu tür tartışmaların yeri değil ve daha önce de çok kez yaşadım. Ama her zaman TM-eşdeğeri olduğunu düşünen en basit sorunları (hepsi biziz) zar zor çözebilen insanlar tarafından eğleniyorum.
Jim Balter

22

Maliyet: Hareketli çoraplar -> yüksek, çorapları bulma / arama -> küçük

Yapmak istediğimiz şey, hareket sayısını azaltmak ve arama sayısını telafi etmektir. Ayrıca, karar önbelleğinde daha fazla şey tutmak için Homo Sapiens'in çok değerli ortamını kullanabiliriz.

X = Sevgiler, Y = Eşlerin

Tüm çorapların A yığından:

İki çorap seçin, karşılık gelen X çorapını X hattına ve Y çorapını bir sonraki uygun konuma yerleştirin.

A boşalana kadar yapın.

Her X ve Y çizgisi için

  1. İlk çorabı sırayla seçin, karşılık gelen çorabı bulana kadar çizgi boyunca arama yapın.

  2. İlgili bitmiş çorap hattına koyun.

  3. İsteğe bağlı Hattı ararken ve bakmakta olduğunuz çorap bir öncekiyle aynı iken, bu çoraplar için 2. adımı uygulayın.

İsteğe bağlı olarak birinci adıma geçmek için, önbellek yeterince büyük olduğundan, çoraplardan birinin gözlemlediğiniz satırdaki geçerli çorapla eşleşip eşleşmediğini hızlı bir şekilde belirleyebileceğimiz için iki yerine iki hat alırsınız. Eğer üç kolunuz olacak kadar şanslıysanız, konunun hafızasının yeterince büyük olması nedeniyle aynı anda üç çorabı ayrıştırabilirsiniz.

Hem X hem de Y boşalana kadar yapın.

Bitti

Bununla birlikte, bu, seçim sıralaması olarak benzer karmaşıklığa sahip olduğundan, I / O (hareketli çoraplar) ve arama (çizgi için bir çorap arama) hızlarından dolayı geçen süre çok daha azdır.


22

İşte karşılaştırma tabanlı modelde bir Omega (n log n) alt sınırı. (Tek geçerli işlem iki çorap karşılaştırmasıdır.)

2n çoraplarınızın bu şekilde düzenlendiğini bildiğinizi varsayalım :

p 1 p 2 p 3 ... p n p f (1) p f (2) ... p f (n)

burada f, {1,2, ..., n} kümesinin bilinmeyen bir permütasyonudur. Bunu bilmek sorunu zorlaştıramaz. N var! olası çıktılar (birinci ve ikinci yarı arasındaki eşleşmeler), yani log (n!) = Omega (n log n) karşılaştırmalarına ihtiyacınız vardır. Bu sıralama ile elde edilebilir.

Eleman farklılığı sorununa bağlantılarla ilgilendiğiniz için: eleman farklılığına bağlı Omega'nın (n log n) kanıtlanması daha zordur, çünkü çıktı ikili evet / hayırdır. Burada, çıktı bir eşleme olmalıdır ve olası çıktıların sayısı iyi bir sınır elde etmek için yeterlidir. Bununla birlikte, eleman farklılığına bağlı bir varyant vardır. Size 2n çorap verildiğini ve benzersiz bir şekilde eşleştirilip eşleştirilemeyeceğini merak edin. Sen göndererek ED gelen bir azalma (a alabilirsiniz 1 , bir 2 , ..., bir n ) (a 1 , a 1 , a 2 , a 2 , ..., bir n , bir n ). (Parentetik olarak, ED'nin sertliğinin kanıtı topoloji yoluyla çok ilginçtir.)

Sadece eşitlik testlerine izin verirseniz orijinal problem için bir Omega (n 2 ) olması gerektiğini düşünüyorum . Sezgim: Testten sonra kenar eklediğiniz bir grafiği düşünün ve grafik yoğun değilse çıktının benzersiz bir şekilde belirlenmediğini iddia edin.


19

Ben çorap p çiftleri ( n = 2p bireysel çorap) için, aslında bu nasıl :

  • Kazıktan rastgele bir çorap alın.
  • İlk çorap için veya önceden seçilen tüm çoraplar eşleştirilmişse, çorap önünüzdeki eşleştirilmemiş çoraplardan oluşan bir "dizinin" ilk "yuvasına" yerleştirilmelidir.
  • Seçili bir veya daha fazla eşleştirilmemiş çorapınız varsa, mevcut çorapınızı dizideki eşleştirilmemiş tüm çoraplara karşı kontrol edin.
    • Dizinizi oluştururken çorapları genel sınıflara veya tiplere (beyaz / siyah, ayak bileği / mürettebat, atletik / elbise) ayırmak ve sadece benzerleri karşılaştırmak için "detaya inmek" mümkündür.
    • Kabul edilebilir bir eşleşme bulursanız, her iki çorabı bir araya getirin ve diziden çıkarın.
    • Bunu yapmazsanız, geçerli çorap dizideki ilk açık yuvaya koyun.
  • Her çorapla tekrarlayın.

Bu şemanın en kötü senaryosu, her çorap çiftinin tam olarak eşleşmesi gereken kadar farklı olması ve seçtiğiniz ilk n / 2 çorapların farklı olmasıdır. Bu sizin O (n 2 ) senaryonuzdur ve çok olası değildir. Eşsiz çorap tipi t sayısı p = n / 2 çiftinden azsa ve her tipteki çoraplar (genellikle aşınmayla ilgili terimlerle) bu tür herhangi bir çorabın herhangi biriyle eşleştirilebileceği kadar benzer ise diğer, yukarıda görüldüğü kadarıyla o, hiç karşılaştırmak zorunda kalacak çorap sayısıdır t , bundan sonra gelecek bir sen çekin iradeeşleştirilmemiş çoraplardan birini eşleştirin. Bu senaryo, ortalama çorap çekmecesinde en kötü durumdan çok daha olasıdır ve en kötü durum karmaşıklığını genellikle t << n olan O (n * t) değerine düşürür .


1
Bu muhtemelen zihinsel süreçlerime oldukça yakın. Önceden sıralama optimizasyonu katmanı var. Atletik çoraplarım beyazlarla, elbise çoraplarım da renklerle yıkanıyor. Bu, iki yük çamaşırını bir araya getirmediğim sürece çoraplarımın türüne göre zaten gruplandırılmış olduğu anlamına gelir. Beyaz yük gerçekten hızlı gidiyor (birçok özdeş çorap), ancak elbise çorapları daha uzun sürüyor. Diğer anahtar ipucu - sıralama için daha fazla bellek açın (önce tüm çorap olmayanları katlayın ve çıkarın ve daha sonra eşleştirme algoritmasını çalıştırın)
orh

17

Gerçek dünya yaklaşımı:

Mümkün olduğunca çabuk, çorapları ayrılmamış tüylerden birer birer çıkarın ve önünüzdeki yığınlara yerleştirin. Kazıklar, tüm çoraplar aynı yöne bakacak şekilde, alandan verimli bir şekilde düzenlenmelidir; kazık sayısı kolayca ulaşabileceğiniz mesafe ile sınırlıdır. Bir çorap koymak için bir kazık seçimi - mümkün olduğunca hızlı bir şekilde - görünüşte çorap gibi bir yığın üzerine çorap koymak; ara sıra tip I (ait olmadığı bir kazığa çorap koymak) veya tip II (mevcut çorap gibi bir yığın var olduğunda bir çorap koymak) hatası tolere edilebilir - en önemli husus hızdır .

Tüm çoraplar kazık olduktan sonra, çiftler oluşturarak ve bunları kaldırarak çok çoraplı yığınlardan hızla geçin (bunlar çekmeceye doğru gidiyor). Kazıkta eşleşmeyen çoraplar varsa, bunları en iyi şekilde (mümkün olduğunca hızlı kısıtlama içinde) kazıklayın. Tüm çoklu çorap yığınları işlendiğinde, tip II hataları nedeniyle eşleştirilmemiş kalan çift çorapları eşleştirin. Vay canına, işin bitti - ve bir sürü çorapım var ve büyük bir kısmı kirlenene kadar onları yıkamıyorum. Başka bir pratik not: Bir çift çoraptan birinin üstünü diğerinin üzerine çevirir, elastik özelliklerinden yararlanırım, böylece çekmeceye taşınırken ve çekmecede iken birlikte kalırlar.


15

Sorunuzdan çamaşırla ilgili çok fazla gerçek deneyiminiz olmadığı açıktır :). Az sayıda eşleştirilemeyen çorap ile iyi çalışan bir algoritmaya ihtiyacınız var.

Şimdiye kadar verilen cevaplar, insan örüntü tanıma yeteneklerimizi iyi kullanmıyor. Set oyunu bunu nasıl yapacağınıza dair bir ipucu sunuyor: tüm çorapları iki boyutlu bir alana yerleştirin, böylece onları hem iyi tanıyabilir hem de ellerinizle kolayca ulaşabilirsiniz. Bu sizi yaklaşık 120 * 80 cm kadar bir alanla sınırlar. Oradan tanıdığınız çiftleri seçin ve kaldırın. Boş alana ekstra çorap koyun ve tekrarlayın. Kolayca tanınabilen çorapları olan insanlar için yıkarsanız (küçük çocuklar akla gelir), önce bu çorapları seçerek bir sayı tabanı sıralaması yapabilirsiniz. Bu algoritma yalnızca tek çorap sayısı düşük olduğunda iyi çalışır


Genellikle böyle yaparım. Her seferinde kalan tüm çorapları tekrarlamaktan çok daha iyi çalışır.
yu_ominae

Güzel bir yaklaşım ve bence bazı gerçek CS sorunlarına da uygulanabilir. Lütfen buna bir örnek ekleyebilir misiniz (problemleri çözmek için benzer bir yaklaşım kullanabileceğimiz bir CS problemi)? Ayrıca, bu çözüm milyonlarca çorap için nasıl ölçeklenir?
amit

Bence bu temel olarak 20 Ocak'ta stackoverflow.com/a/14423956 , diğer cevap ile aynı th olduğunu . Her ikisi de +1. İnsan görme sistemi büyük ölçüde paraleldir.
Ness Ness

15

İlk çorabı alın ve bir masanın üzerine yerleştirin. Şimdi başka bir çorap seçin; ilk alınanla eşleşiyorsa, ilkinin üstüne yerleştirin. Değilse, masaya ilkinden küçük bir mesafe koyun. Üçüncü bir çorap seçin; önceki ikisinden biriyle eşleşiyorsa, üstüne yerleştirin ya da üçüncüsüne biraz mesafe bırakın. Tüm çorapları alana kadar tekrarlayın.


1
Tek geçerli cevap bu. Diğerleri, benzer çoraplar arasında ayrım yapmak için en fazla zaman harcandığını göz ardı eder (böylece hepsini fiziksel görünümle bir araya getirmek onu daha da kötüleştirir).
entonio

Eğlenmek için küçük bir python programına çorap kazık bu yöntemi yazdım gist.github.com/justinfay/53b574cf0a492f6795ef
Justin Fay

12

Bir kazıktaki çorapları eşleştirmenin ne kadar verimli olduğunu söylemek için önce makineyi tanımlamamız gerekir, çünkü eşleştirme, normalde bir temel için kullanılan bir turlama veya rastgele erişim makinesi tarafından yapılmaz. algoritmik analiz.

Makine

Makine, insan denilen gerçek dünya öğesinin bir soyutlamasıdır. Çevreden bir çift gözle okuyabilir. Makine modelimiz ise 2 kol kullanarak çevreyi manipüle edebiliyor. Mantıksal ve aritmetik işlemler beynimiz kullanılarak hesaplanır (umarım ;-)).

Ayrıca, bu enstrümanlarla yapılabilecek atomik işlemlerin içsel çalışma zamanını da dikkate almalıyız. Fiziksel kısıtlamalar nedeniyle, bir kol veya göz tarafından gerçekleştirilen operasyonların sabit olmayan zaman karmaşıklığı vardır. Bunun nedeni, sonsuz büyüklükte bir çorap yığınını bir kolla hareket ettiremememiz veya bir gözün, sonsuz çorabın üstündeki çorapların üst çorabını göremememizdir.

Ancak mekanik fizik bize bazı güzellikler de veriyor. En fazla bir çorabı bir kolla hareket ettirmekle sınırlı değiliz. Bir çiftini aynı anda hareket ettirebiliriz.

Dolayısıyla, önceki analize bağlı olarak, aşağıdaki işlemler azalan sırada kullanılmalıdır:

  • mantıksal ve aritmetik işlemler
  • çevresel okumalar
  • çevresel değişiklikler

İnsanların sadece çok sınırlı miktarda çorapları olduğu gerçeğinden de yararlanabiliriz. Böylece çevresel bir modifikasyon, kazıktaki tüm çorapları içerebilir.

Algoritma

İşte benim önerim:

  1. Yığındaki tüm çorapları yere ser.
  2. Yerdeki çoraplara bakarak bir çift bulun.
  3. Hiçbir çift yapılamayacak şekilde 2'den tekrarlayın.
  4. Yerde çorap kalmayıncaya kadar 1'den tekrarlayın.

Operasyon 4 gereklidir, çünkü çorapları yere yayarken bazı çoraplar başkalarını gizleyebilir. İşte algoritmanın analizi:

Analiz

Algoritma yüksek olasılıkla sona erer. Bunun nedeni, 2. adımda bir çift çorap bulamamasıdır.

nÇorap çiftlerinin aşağıdaki çalışma zamanı analizi için , çorapların en az yarısının 2n1. adımdan sonra gizlenmediğini varsayalım . Ortalama durumda n/2çiftleri bulabiliriz . Bu, döngü adım 4 yürütme O(log n)süreleri olduğu anlamına gelir . Adım 2 yürütme O(n^2)süreleri. Böylece şu sonuca varabiliriz:

  • Algoritma O(ln n + n)çevresel modifikasyonları içerir (adım 1 O(ln n)artı her bir çorap çiftini yerden alarak)
  • Algoritma, O(n^2)2. adımdaki çevresel okumaları içerir
  • Algoritma, O(n^2)adım 2'de bir çorapla başka bir çorap karşılaştırmak için mantıksal ve aritmetik işlemleri içerir

Biz toplam çalışma zamanı karmaşıklık var Yani ve çevre okuma ve çevre yazma işlemleri için faktörler çorap makul bir süre için sırasıyla. Mantıksal ve aritmetik işlemlerin maliyeti göz ardı edilir, çünkü 2 çorapın aynı çifte ait olup olmadığına karar vermek için sabit miktarda mantıksal ve aritmetik işlem gerektirdiğini varsayıyoruz. Bu, her senaryoda mümkün olmayabilir.O(r*n^2 + w*(ln n + n))rw


1
Bu stackoverflow.com/a/14423956 ve stackoverflow.com/a/14468913 ile aynı olduğunu düşünüyorum.
Ness

@WillNess Yep, biraz daha fazla açıklama ile
SpaceTrucker

12
List<Sock> UnSearchedSocks = getAllSocks();
List<Sock> UnMatchedSocks = new list<Sock>();
List<PairOfSocks> PairedSocks = new list<PairOfSocks>();

foreach (Sock newSock in UnsearchedSocks)
{
  Sock MatchedSock = null;
  foreach(Sock UnmatchedSock in UnmatchedSocks)
  {
    if (UnmatchedSock.isPairOf(newSock))
    {
      MatchedSock = UnmatchedSock;
      break;
    }
  }
  if (MatchedSock != null)
  {
    UnmatchedSocks.remove(MatchedSock);
    PairedSocks.Add(new PairOfSocks(MatchedSock, NewSock));
  }
  else
  {
    UnmatchedSocks.Add(NewSock);
  }
}

12

Daha az işlem, daha az zaman tüketimi vaat etmeyecek başka bir çözümle ortaya çıktım, ancak çok sayıda çorap eşleştirmesinde daha az zaman tüketimi sağlamanın yeterli bir sezgisel olup olmayacağını görmeye çalışmalıyım.

Önkoşullar: Aynı çorapların olduğunun garantisi yoktur. Aynı renkteyse, aynı boyuta veya desene sahip oldukları anlamına gelmez. Çoraplar rastgele karıştırılır. Tek sayıda çorap olabilir (bazıları eksik, kaç tane olduğunu bilmiyoruz). Bir değişken "indeksi" hatırlamaya hazırlayın ve 0 olarak ayarlayın.

Sonuçta bir veya iki yığın olacaktır: 1. "eşleşti" ve 2. "eksik"

Sezgisel:

  1. En farklı çorapları bulun.
  2. Eşleşmesini bulun.
  3. Eşleşme yoksa, "eksik" yığın üzerine koyun.
  4. En belirgin çoraplar kalmayana kadar 1'den itibaren tekrarlayın.
  5. 6 çoraptan daha azı varsa, 11'e gidin.
  6. Tüm çorapları komşusu ile körü körüne eşleştirin (paketlemeyin)
  7. Tüm eşleşen çiftleri bulun, paketleyin ve paketlenmiş çiftleri "eşleşen" kazığa taşıyın; Yeni eşleşme olmasaydı - "index" değerini 1 arttırır
  8. Eğer "endeks" 2'den büyükse (bu çorap numarasına bağlı olabilir, çünkü daha fazla çorapla körü körüne eşleştirme şansı daha azdır) 11'e gidin
  9. Gerisini karıştır
  10. 1'e git
  11. "Dizin" i unut
  12. Çorap seç
  13. Çiftini bul
  14. Çorap için çift yoksa, "eksik" kazığa taşıyın
  15. Eşleşme bulduysa, çifti paketleyin ve "eşleşen" yığına taşıyın
  16. Hala daha fazlası varsa bir çorap 12'ye gider
  17. Sadece bir tane kaldıysa 14'e gidin
  18. Gülümseme memnun :)

Ayrıca, sanki bunların çıkarılması gibi hasarlı çoraplar için kontrol eklenebilir. 2 ile 3 arasında ve 13 ile 14 arasında yerleştirilebilir.

Herhangi bir deneyim veya düzeltme duymak için sabırsızlanıyorum.


Bunu yazdıktan sonra her seferinde kullanıyorum. Biraz daha verimli olmamı sağladı ve iş şimdi daha az sıkıcı.
Sasa

11

Çorapları sıraladığımda , aynı renk / desen tipindeki diğer çorapların yanına çorap bırakarak yaklaşık bir yarıçap sıralaması yapıyorum . Ben yerde / yakınında kesin bir maç görebildiğim dışında çorap düşmek üzereyim Bu noktada çifti ayıklamak.

Hemen hemen tüm diğer algoritmalar ( usr tarafından en yüksek puanlama cevabı dahil ) sıralayın, ardından çiftleri kaldırın. Bir insan olarak, bir kerede düşünülen çorap sayısını en aza indirmenin daha iyi olduğunu düşünüyorum.

Bunu şu şekilde yaparım:

  1. Belirgin bir çorap seçmek (neyi ilk önce kazıkta yakalarsa).
  2. Çorapları, kazıktan buna benzerlik temelinde çekerek bu kavramsal yerden bir radyus sıralaması başlatmak.
  3. Yeni çorabı, ne kadar farklı olduğuna bağlı olarak, geçerli kazığa yakın bir yere yerleştirin. Kendini özdeş olduğu için çorabı bir başkasının üstüne koyarsanız, çifti orada oluşturun ve çıkarın. Bu, gelecekteki karşılaştırmaların doğru yeri bulmak için daha az çaba gerektirdiği anlamına gelir.

Bu, insanın O (1) zamanında bulanık eşleşme yeteneğinden yararlanır, bu da bir hesaplama cihazında bir karma haritanın kurulmasına eşdeğerdir.

Öncelikle farklı çorapları çekerek, daha az farklı olan özellikleri daha önce "yakınlaştırmak" için alan bırakırsınız.

Fluro rengini, çizgili çorapları ve üç çift uzun çorapları ortadan kaldırdıktan sonra, çoğunlukla beyaz çoraplarla kabaca ne kadar yıpranmış olduklarına göre sıralanabilir.

Bir noktada, çoraplar arasındaki farklar, diğer insanların farkı fark etmeyecek kadar küçüktür ve daha fazla eşleştirme çabasına gerek yoktur.


10

Ne zaman bir çorap toplarsan, bir yere koy. Daha sonra aldığınız bir sonraki çorap, eğer ilk çorapla eşleşmiyorsa, ilk çorapın yanına yerleştirin. Varsa, bir çift var. Bu şekilde kaç kombinasyonun olduğu önemli değildir ve aldığınız her çorap için sadece iki olasılık vardır - ya zaten çorap dizinizde bir eşleşme var, ya da değil, yani dizideki bir yere ekleyin.

Bu aynı zamanda dizideki tüm çoraplarınızı neredeyse hiç olmayacağınız anlamına gelir, çünkü çoraplar eşleştirildikçe çıkarılır.


Yaptığım şey bu ... O (n)
Pykler

2
@Pykler - En iyi durumda O (n) ve en kötü durumda O (n * n).
Vilx-

2
Benim için bir O (1) gördüğüm ve daha önce ve eşleşen için bekleyen yerleştirilen ki bir çorap maç etmektir zaten görülen tüm çorap kafanızda, bir tam benzersiz karma yaratamazsınız varsayarak Thats karma
Pykler

10

'N' boyutunda bir karma tablo düşünün.

Normal dağılım olduğunu varsayarsak, en az bir çorabın bir kovaya eşlenmesi için tahmini 'ekleme' sayısı NlogN'dir (yani, tüm kovalar doludur)

Bunu başka bir bulmacanın parçası olarak türetmiştim, ancak yanlış olduğum için mutlu olurum. İşte aynı blog makalem

'N', sahip olduğunuz benzersiz renklerin / çorap desenlerinin sayısının yaklaşık bir üst sınırına karşılık gelsin.

Bir çarpışmaya (aka: bir eşleşme) sahip olduğunuzda, o çorap çiftini çıkarmanız yeterlidir. Aynı deneyi bir sonraki NlogN çorap serisiyle tekrarlayın. Bunun güzelliği, insan zihninin çalışma şekli nedeniyle NlogN paralel karşılaştırmalar (çarpışma çözümü) yapabilmenizdir. :-)


10

Gerçek ya da benzer bir veri yapısı olan çoraplar çift olarak sağlanacaktır.

En basit cevap, çiftin ayrılmasına izin vermeden önce, çift için, sol ve sağ çorap için bir işaretçi içeren, böylece çorapların doğrudan veya çiftleri aracılığıyla yönlendirilmesini sağlayan tek bir veri yapısı başlatılmış olmalıdır. Bir çorap ortağına bir işaretçi içerecek şekilde genişletilebilir.

Bu, herhangi bir hesaplama eşleştirme sorununu bir soyutlama katmanıyla kaldırarak çözer.

Aynı fikri çorap eşleştirme pratik sorununa uygularken, görünen cevap: çoraplarınızın eşleştirilmemesine izin vermeyin. Çoraplar bir çift olarak sağlanır, çekmeceye bir çift olarak (belki de toplanarak), bir çift olarak giyilir. Ancak eşleştirmenin mümkün olmadığı nokta yıkayıcıdadır, bu nedenle gerekli olan tek şey çorapların birlikte kalmasını ve verimli bir şekilde yıkanmasını sağlayan fiziksel bir mekanizmadır.

İki fiziksel olasılık vardır:

Her çorap için bir işaretçi tutan bir 'çift' nesne için çorapları bir arada tutmak için kullandığımız bir bez torbaya sahip olabiliriz. Bu büyük bir yük gibi görünüyor.

Ancak her çorapın diğerine referans vermesi için düzgün bir çözüm vardır: bir popper (veya Amerikalıysanız bir 'snap düğmesi'), örneğin:

http://www.aliexpress.com/compare/compare-invisible-snap-buttons.html

Sonra tüm yaptığınız çoraplarınızı çıkardıktan ve çamaşır sepetinize koyduktan hemen sonra bir araya getirin ve yine çoraplarınızı 'çift' konseptinin fiziksel bir soyutlamasıyla eşleştirme ihtiyacı sorununu ortadan kaldırdınız.


Bu soruya cevap vermez, çünkü zaten eşleştirilmiş verilerle işlem yapmak kolaydır, soru, verilerin EŞSİZ OLDUĞUNDA ve eşleştirmek istediğinizde ne yapılması gerektiğidir.
amit

8

"Taşıma" işlemi oldukça pahalıysa ve "karşılaştırma" işlemi ucuzsa ve tüm seti yine de, aramanın orijinal depolama biriminden çok daha hızlı olduğu bir ara belleğe taşımanız gerekir ... sıralamayı zorunlu hale getirin hareket.

Kurumaya ayırma sürecini entegre etmenin onu bir esinti haline getirdiğini buldum. Yine de her çorap almak ve asmak (hareket) gerekir ve bu dizeleri belirli bir yere asmak için hiçbir maliyeti hakkında bana. Şimdi sadece tamponun (dizelerin) aramasını zorlamamak için çorapları renk / gölgeye göre yerleştirmeyi seçtim. Daha koyu sol, daha parlak sağ, daha renkli ön vs. Şimdi her çorabı asmadan önce, eğer bir eşleştirme zaten varsa "sağ çevresine" bakıyorum - bu 2-3 diğer çorapla "taramayı" sınırlar - ve eğer , Diğerini hemen yanına asıyorum. Sonra kuruduktan sonra tellerden çıkarırken onları çiftler halinde yuvarlarım.

Şimdi bu, en iyi cevaplar tarafından önerilen "renklerle yığınlar oluşturma" dan çok farklı görünmeyebilir, ancak ilk olarak, ayrık yığınları değil, aralıkları seçerek, "mor" un "kırmızı" veya "mavi" kazığa gidip gitmediğini sınıflandırmada sorunum yok; sadece arasında gidip geliyor. Ve sonra iki işlemi entegre ederek (kurumaya ve ayırmaya), asılıyken sıralamanın ek yükü, ayrı sıralamanın ne olacağının% 10'u kadardır.


Bu yaklaşımın diğer iki avantajı daha vardır: hat kurutma, çamaşır kurutma makinesinden daha az çorap IME kaybeder ve ayırma işlemi çamaşırların geri kalanına uzatılabilir, bu nedenle (örneğin) tüm havlular, ve depolanmış ve doğrudan depolarına alınır. Aynı zamanda, iki düşük çaba geçişinde çalışır, kıyafetleri kaldırır ve tekrar indirir.
cphlewis

8

Şu anda çoraplarımı eşleştirmeyi bitirdim ve bunu yapmanın en iyi yolunun şu olduğunu gördüm:

  • Çoraplardan birini seçin ve koyun (o çift için bir 'kova' oluşturun)
  • Bir sonraki bir öncekinin çiftiyse, mevcut kepçeye koyun, aksi takdirde yeni bir tane oluşturun.

En kötü durumda, n / 2 farklı kepçeye sahip olacağınız ve mevcut kepçenin çiftini içeren kepçenin n-2 tespitine sahip olacağınız anlamına gelir. Açıkçası, bu algoritma sadece birkaç çiftiniz varsa iyi çalışır; 12 çift ile yaptım.

Çok bilimsel değil, ama iyi çalışıyor :)


Bu, bir O (n ^ 2) algoritmasıdır, çünkü yeni bir çorap çıkardığınızda her bir kovayı tekrarlamanız gerekir. Ancak, aynı parti içinde satın alınan çorapların bile onları etkili bir şekilde çift benzersiz (hatta tek benzersiz) yapan küçük farklılıkları olduğu düşünüldüğünde, yine de daha iyi bir yol yoktur
Semisonic

Kabul et, ama algoritmam insanın eşleştirme yaptığını varsayıyor. Bu nedenle, eşleşen kovayı ararken zihninizde bir tür önbellek olacaktır, bu yüzden zaten kovalar üzerinde yineleme yapmanız gerekmez. Eşleştirme sırasında kafamdaki bu önbellek mekanizması için ne tür bir veri yapısı oluşturulduğundan emin değilim.
maestro

8

Benim çözümüm, resmi olarak O(n)"ekstra" alan gerektirdiğinden gereksinimlerinize tam olarak uymuyor . Ancak, koşullarım dikkate alındığında, pratik uygulamamda çok etkilidir. Bu yüzden bence ilginç olmalı.

Diğer Görevle Birleştir

Benim durumumdaki özel koşul, kurutma makinesini kullanmam, sadece kumaşlarımı sıradan bir kumaş kurutucusuna asmam. Bezleri asmak O(n)işlemleri gerektirir (bu arada, her zaman burada bin paketleme problemini düşünürüm) ve doğası gereği problem doğrusal "ekstra" alan gerektirir. Kovadan yeni bir çorap aldığımda, çift zaten asılıysa, çiftinin yanına asmayı denemek için. Eğer yeni bir çift bir çorap onun yanında biraz boşluk bırakın.

Oracle Machine Daha İyi ;-)

Açıkçası, eşleşen bir çorapın zaten bir yerde asılı olup olmadığını kontrol etmek için biraz ekstra iş gerektirir ve çözüm yaratacaktır. O(n^2)1/2 bir bilgisayar için katsayısı ile . Ancak bu durumda "insan faktörü" aslında bir avantajdır - O(1)zaten asılmışsa eşleşen çorapları genellikle çok hızlı bir şekilde (neredeyse ) tanımlayabilirim (muhtemelen bazı algılanamayan beyin içi önbellekleme söz konusudur) - bir tür düşünün Oracle Machine ;-) 'de olduğu gibi sınırlı "oracle" Biz, bazı durumlarda dijital makinelere göre bu avantajlara sahibiz ;-)

Neredeyse alın O(n)!

Böylece çorapları eşleştirme problemini bezleri asma problemine bağlayarak O(n)ücretsiz olarak "ekstra alan" elde ediyorum ve zaman içinde olan bir çözüme sahibim O(n), basit asılı bezlerden biraz daha fazla iş gerektiriyor ve hemen tüm çiftlere erişmeye izin veriyor çok kötü bir Pazartesi sabahı bile çorap ... ;-)


8

Umarım bu soruna yeni bir şey katabilirim. Tüm cevapların önişleme yapabileceğiniz iki nokta olduğunu ihmal ettiğini fark ettim. , genel çamaşır performansınızı yavaşlatmadan .

Ayrıca, büyük aileler için bile çok sayıda çorap almamız gerekmiyor. Çoraplar çekmeceden çıkarılır ve giyilir ve daha sonra yıkanmadan önce kaldıkları bir yere (belki bir çöp kutusu) atılırlar. Demek bin'e LIFO-Stack demezken, bunu kabul etmenin güvenli olduğunu söyleyebilirim.

  1. insanlar her iki çorapını da kabın aynı bölgesine fırlatırlar,
  2. çöp kutusu herhangi bir noktada rastgele değildir ve bu nedenle
  3. bu kutunun tepesinden alınan herhangi bir alt küme genellikle bir çiftin her iki çorapını da içerir.

Bildiğim tüm çamaşır makinelerinin boyutu sınırlı olduğu için (kaç tane çorap yıkamanız gerektiğine bakılmaksızın) ve çamaşır makinesinde gerçek randomizasyon meydana geldiğinden, kaç tane çorapımız olursa olsun, her zaman neredeyse hiç içermeyen küçük alt setlerimiz vardır. singletonların.

İki ön işleme aşamamız, sadece temiz değil aynı zamanda kuru çoraplar elde etmek için "çorapları çamaşır ipine takmak" ve "çorapları çamaşır ipinden almak" tır. Çamaşır makinelerinde olduğu gibi, çamaşır ipleri sonludur ve sanırım çoraplarımızın görünür olduğu hattın tüm kısmına sahibiz.

İşte put_socks_on_line () için algoritma:

while (socks left in basket) {
 take_sock();
 if (cluster of similar socks is present) { 
   Add sock to cluster (if possible, next to the matching pair)
 } else {
  Hang it somewhere on the line, this is now a new cluster of similar-looking socks.      
  Leave enough space around this sock to add other socks later on 
 }
}

Çorapları dolaşırken veya en iyi eşleşmeyi aramak için zamanınızı boşa harcamayın, tüm bunlar O (n) 'da yapılmalıdır, bu da onları sadece sıralanmamış çizgiye koymak için ihtiyacımız olacak. Çoraplar henüz eşleşmedi, hatta sadece birkaç benzerlik kümemiz var. Burada "iyi" kümeler oluşturmamıza yardımcı olduğu için sınırlı bir çorap setimiz olması yararlıdır (örneğin, çorap setinde sadece siyah çoraplar varsa, renklere göre kümelenme yolu olmaz)

Take_socks_from_line () için algoritma şöyledir:

while(socks left on line) {
 take_next_sock();
 if (matching pair visible on line or in basket) {
   Take it as well, pair 'em and put 'em away
 } else {
   put the sock in the basket
 }

Kalan adımların hızını artırmak için, bir sonraki çorabı rastgele seçmemek, ancak her kümeden çoraptan sonra sırayla çorap almak akıllıca olacaktır. Her iki önişleme adımı, çorapları hatta veya sepete koymaktan daha fazla zaman almaz, bu da ne olursa olsun yapmamız gerekir, bu nedenle çamaşır performansını büyük ölçüde arttırmalıdır.

Bundan sonra, karma bölümleme algoritmasını yapmak kolaydır. Genellikle, çorapların yaklaşık% 75'i zaten eşleştirilmiş ve beni çok küçük bir çorap alt kümesiyle bırakıyor ve bu alt küme zaten (biraz) kümelenmiş (ön işleme adımlarından sonra sepetime fazla entropi eklemiyorum). Başka bir şey, geri kalan kümelerin aynı anda ele alınacak kadar küçük olma eğilimindedir, bu nedenle tüm kümeyi sepetten çıkarmak mümkündür.

İşte sort_remaining_clusters () için algoritma:

while(clusters present in basket) {
  Take out the cluster and spread it
  Process it immediately
  Leave remaining socks where they are
}

Bundan sonra, sadece birkaç çorap kaldı. Bu, daha önce eşleştirilmemiş çorapları sisteme soktuğum ve kalan çorapları herhangi bir özel algoritma olmadan işlediğim yerdir - kalan çoraplar çok azdır ve görsel olarak çok hızlı işlenebilir.

Kalan tüm çoraplar için, meslektaşlarının hala yıkanmamış olduğunu ve bir sonraki yineleme için onları bıraktığını varsayıyorum. Zamanla eşleştirilmemiş çorapların büyümesini kaydederseniz (bir "çorap sızıntısı"), çöp kutunuzu kontrol etmelisiniz - rastgele olabilir (orada uyuyan kediniz var mı?)

Bu algoritmaların çok fazla varsayım aldığını biliyorum: bir çeşit LIFO yığını, sınırlı, normal bir çamaşır makinesi ve sınırlı, normal bir çamaşır ipi gibi davranan bir çöp kutusu - ancak bu hala çok sayıda çorapla çalışıyor.

Paralellik hakkında: Her iki çorabı aynı ambalaja attığınız sürece, tüm bu adımları kolayca paralelleştirebilirsiniz.


Çoraplar, bazı veritabanındaki rasgele nesneleri eşleştirmek için kullanılan metaforlardır.
amit

1
Anladım, yazar olduğunuzu görmedim. Eğer genel bir çözüm istiyorsanız, bunu gerçekten söylemeliydiniz. Her neyse, genel bir çözüm bulmanız gerekmedikçe, hesaba kattığınız herhangi bir bilgiyi dikkate almanın yanlış bir tarafı yoktur - çözümün tekrar kullanılabilirliğinden vazgeçmek, daha iyi performansa neden olabilir. Bu durumda, kullanım durumu ve mevcut veri tabanının bir bütün olarak ele alınması faydalı olacaktır. Bununla birlikte, özel sorunuzun bu özel cevabı benzer görünümlü çoraplarla, örneğin farklı boyutlardaki siyah çoraplarla ilgili sorunlara sahiptir, bu nedenle bazı durumlarda geçerli değildir.
Philipp Flenker

1
Ayrıca, veritabanında rastgele nesnelerin eşleştirilmesi hakkında bir soru sorduğunuz için> 2k upvotes almadınız. Soruyu özellikle çorapların doğası (verilerin aksine, çoğaltamayacağınız) nedeniyle kısıtladınız, hatta çoraplarınızı eşinizin çoraplarından kolayca ayırt edebileceğiniz gerçeğini kullanmaya teşvik ettiniz. Çoraplar hakkında bir soru sorarsanız, cevapların veritabanları ile ilgili olmasını beklemeyin ;-)
Philipp Flenker

1
Birkaç varsayım vardır: normal bir çamaşır makinesi, a, normal çamaşır çizgisi ve her iki çorapları da aynı anda çöp kutusuna atmanız gerçeği, bu da çoğu durumda her iki çorapın da aynı makinede olduğu ve bu nedenle ayrılacak kalan çoraplar küçüktür. Ancak, keyfi nesneleri veritabanında saklamakla ilgili gerçekten bir cevap istediğiniz için, çözümümü daha ayrıntılı tartışmak gerçekten yararlı mı?
Philipp Flenker

1
Söylediğim gibi, diğer insanlar tarafından cevaplanan eleman farklılığı sorunu dışında, istediğiniz her şeye hitap ettiğimi düşünüyorum. Burada bir şüphe olmaya çalışmıyorum, ama bir süre önce bu cevapta çok çaba harcadım ve şimdi bazı cevaplardan geçip orijinal soruyu cevaplamadıklarını iddia ettiğiniz için hayal kırıklığına uğradım . Neden tüm ipliği yalnız bırakmıyorsunuz - sorduktan 2 yıl sonra hala ilginç bir okuma?
Philipp Flenker

8

O (1) zaman alan bir sürece yönelik çabamı azaltmak için basit adımlar attım.

Girişlerimi iki tür çoraptan birine indirerek (eğlence için beyaz çoraplar, iş için siyah çoraplar), sadece elimdeki iki çoraptan hangisine sahip olduğumu belirlemem gerekiyor. (Teknik olarak, asla birlikte yıkanmadıkları için işlemi O (0) süresine düşürdüm.)

İstenen çorapları bulmak ve mevcut çoraplarınıza olan ihtiyacı ortadan kaldırmak için yeterli miktarda satın almak için biraz çaba sarf etmek gerekir. Bunu siyah çorap ihtiyacımdan önce yaptığım gibi, çabam çok azdı, ancak kilometre değişebilir.

Böyle popüler bir çaba, çok popüler ve etkili kodda birçok kez görülmüştür. Örnekler arasında # DEFINE'ing pi ile birkaç ondalık basamak bulunur (başka örnekler de vardır, ancak şu anda akla gelen budur).


7

Deseni karma olarak kullanarak, eşsiz çoraplar için kullanılacak bir karma tablosu oluşturun. Çorapları tek tek yineleyin. Çorabın karma tablosunda bir desen eşleşmesi varsa, çorabı masadan çıkarın ve bir çift yapın. Çorabın eşleşmesi yoksa, masaya koyun.


Soruda özellikle belirtildiği gibi, yerinde değil nasıl yapılır?
amit

7

N çift çorapınızı sıralama sorunu O (n) 'dir . Onları çamaşır sepetine atmadan önce , sol tarafını sağ tarafa geçirirsiniz. Onları çıkardığınızda, ipliği kesip her çifti çekmecenize koyun - n çiftinde 2 işlem, yani O (n).

Şimdi bir sonraki soru kendi çamaşırınızı yapıp yapmadığınız ve eşinizin kendi çamaşırınızı yapıp yapmadığıdır. Bu tamamen farklı bir problem alanında bir problemdir . :)


Bu, çorapların sadece bir metafor olduğu sorusuna cevap vermez.
amit

Soru, çorapların eşleşmemiş bir kazıktan nasıl eşleştirileceği, eşleştirilmekten nasıl kaçınılacağı değil.
amit
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.