Bill Gates'i geride bırakabilir misin?


13

Krep sıralama, bir spatula yığının herhangi bir noktasına yerleştirilebildiğinde ve üstündeki tüm krepleri çevirmek için kullanıldığında, bozuk bir krep yığınını boyut sırasına göre sıralamanın matematiksel probleminin konuşma dilidir. Bir krep sayısı P (n) , n krep için gereken minimum döndürme sayısıdır . 1

1979'da genç bir Bill Gates ve Christos Papadimitriou, P (n) = (5n + 5) / 3'ün üst sınırını kanıtlayan bir makale yazdı . 2

Gates'in (ve / veya Papadimitriou'nun) geliştirdikleri algoritmayı (muhtemelen 1979'dan sonra) kullanarak krep sıralama yapmak için bir program yazdığını varsaymanın güvenli olduğunu düşünüyorum. Gates, yetenekli bir programcı olduğundan, muhtemelen bu kodu olabildiğince golf oynamaya çalıştılar, ancak kaynak kodunun boyutu herkese açık değil (AFAIK).

Meydan okuma:

Maksimum döndürme sayısının Gates ve Papadimitriou tarafından bulunan sınırı aşmadığı gözleme sıralaması yapan bir işlev / program oluşturun. 3 Listenin tutarlı olduğu sürece artan mı yoksa azalan mı olacağını seçebilirsiniz.

N <50 olduğunu varsayabilirsiniz . Bu nedenle, döndürme sayısını sınırlamanız gerekir (bazı rastgele seçilmiş n -değerleri):

 n   P(n)
38   65
49   83
50   85

Çıktı, her kapaktan önce spatula konumu olmalıdır. Çıktı sıfır veya tek dizinli olabilir ve üstten mi yoksa alttan mı sayılacağını seçebilirsiniz.

Ek kurallar:

  • Çalışma zamanı belirleyici olmalıdır
  • Sabit bir zaman sınırı yoktur, ancak 50 öğeli bir liste için çıktı sağlayabilmeniz gerekir

Test listeleri:

En zor listeleri sağlayamıyorum (eğer öyleyse, bir kağıt yazarım, bir meydan okuma değil), bu yüzden işlevlerinizi / programlarınızı test edebileceğiniz bazı rastgele listeler vereceğim. Bu listeleri "kolay" olduğu ortaya çıkarsa başkalarını da ekleyebilirim.

9, 63, 62, 75, 45, 78, 59, 75, 69, 3, 28, 94, 51, 10, 45, 93, 97, 80, 72, 36, 80, 88, 30, 93, 84, 80, 17, 31, 6, 80, 76, 91, 9, 76, 38, 33, 22, 15, 45, 46, 15, 98, 2, 56, 90, 27, 27, 26, 69, 25
...
74, 89, 57, 52, 70, 96, 16, 5, 77, 84, 54, 13, 90, 64, 31, 80, 3, 25, 13, 19, 13, 34, 1, 79, 35, 43, 4, 19, 82, 29, 48, 95, 97, 28, 45, 62, 64, 82, 70, 34, 38, 15, 51, 83, 21, 66, 4, 42, 74, 84
...
62, 73, 7, 90, 83, 18, 12, 35, 72, 71, 99, 67, 87, 62, 65, 70, 14, 72, 55, 92, 87, 3, 7, 4, 4, 95, 49, 25, 4, 18, 49, 39, 26, 1, 45, 64, 23, 66, 39, 17, 33, 24, 58, 72, 77, 46, 99, 71, 10, 21

Umarım, Bill Gates ve Papadimitriou bu meydan okumayı görecek ve kodlarını sunacak, böylece aslında onları geride bırakıp bırakmadığınızı belirleyebiliriz.

3 Daha iyi üst sınırlar bulundu, ancak bunları önemsemenize gerek yok.


İlgili , ancak bir kopya değil. Oradaki cevaplar burada işe yaramazdı.
Stewie Griffin

O zamanlar oradaki çözümümde BFS kullandım, yine de minimum sayıda döndürme ile çözümü bulmak için burada (hafif güncelleme ile) çalışmalıdır.
mil

@miles daha sonra yayınlamaktan çekinmeyin. Tüm cevapları ayrıntılı olarak incelemedim, ama çoğu sadece saf yaklaşımı kullandı.
Stewie Griffin

Yanıtlar:


4

Python 2 (PyPy) , 238 235 222 bayt

a=input();n=len(a);r=range(n);a=zip(a,r);a=map(sorted(a).index,a)+[n]
def s(u,m):
 if m<1:return[0]
 for k in r:
  v=u[k::-1]+u[k+1:]
  if sum(1<abs(v[i]-v[i+1])for i in r)<m:
   p=s(v,m-1)
   if p:return[k]+p
print s(a,5*n/3)

* (2 boşluk = sekme)

Çevrimiçi deneyin!

Bir liste sıralamak için bir yöntem ödünç 13 bayt kaydedildi .

Bir kapağın, sıralandığında bitişik olacak bir çift "krep" i ayırıp ayırmadığını kontrol eden basit bir buluşsal yöntemle DFS. Artan sırada sıralar. Çıktı soldan 0 ile indekslenir, burada 0 ilk 2'yi çevirir vb. Kullanılan hamle sayısı (5/3)*n+1 < 5/3*(n+1)burada (18/11)*n < (5/3)*n+1 < 5/3*(n+1)ve (18/11)*nde daha sıkı bir üst sınır olduğu tespit edilirse , 2009 .

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.