Yığın değişimi


23

Sorun

Her S k (k = 1 - N) k sayısının N kopyasını içerdiğinde , S 1 den S N ye sahip N yığınınız olduğunu söyleyin .

Örneğin, N = 3 olduğunda istifler şöyle görünür:

1  2  3  <- top of stack
1  2  3
1  2  3  <- bottom of stack
=======
1  2  3  <- stack index

Burada 1, 2 ve 3 olarak endeksli 3 yığın var ve her biri kendi endeksinin N örneklerini içeriyor.

Amaç, N yığınlarını, her biri aynı şekilde yukarıdan aşağıya doğru 1'den N'ye kadar sayıları içerecek şekilde yeniden düzenlemektir.

örneğin N = 3 için amaç yığınları yeniden düzenlemek:

1  1  1
2  2  2
3  3  3
=======
1  2  3

Yığınlarla gerçekleştirebileceğiniz tek işlem , üstteki sayıyı yığınlardan birinden almak (haşhaş) ve sonra hemen farklı bir yığının (itme) üzerine yerleştirmektir . Bu, bu şartlara tabidir:

  • Bir sayı ancak bir yığına en üstteki sayıya eşit veya daha küçükse bir yığına itilebilir.

    • örneğin, bir 1bir olan bir yığını üzerine itilebilir 1, 2ya da 3en az, ancak 2sadece bir yığını üzerine itilebilir 2ya da 3üst (veya daha yüksek).

    • Bu, yığınların her zaman monoton olarak yukarıdan aşağıya doğru yükselme etkisine sahiptir .

  • Herhangi bir boş olmayan yığından atılabilir ve önceki kurşunun sağlandığı varsayılarak herhangi bir yığına itilebilir.

  • Herhangi bir sayı boş bir yığına itilebilir.

  • Yığınların maksimum yükseklik sınırı yoktur.

  • Yığınlar oluşturulamaz veya yok edilemez, her zaman N sayısı vardır.

Bu zorluk, zorunlu olarak en az hamlede değil, kesin bir şekilde, borsa değişimini tamamlamak için hangi fırlatacağı ve ne yapacağına karar vermekle ilgilidir.

(Bir deste kart ile pratik yapmak, sorunu hissetmek için iyi bir yoldur.)

Meydan okuma

Olumlu bir tamsayıda N (3 veya üstü olması zorunlu olan) alan bir program veya işlev yazın. Yığınları başlangıç ​​durumundan yeniden düzenlemek için gereken tüm pop-push eylemlerini gösteren bir dize yazdırın veya iade edin:

1  2  3  4  5
1  2  3  4  5
1  2  3  4  5
1  2  3  4  5
1  2  3  4  5
=============
1  2  3  4  5

(N = 5 durum)

Son haliyle:

1  1  1  1  1
2  2  2  2  2
3  3  3  3  3
4  4  4  4  4
5  5  5  5  5
=============
1  2  3  4  5

Çıktınızdaki her satır, boşlukla ayrılmış iki sayı içermelidir. İlk sayı, çıkacak yığının dizini ve ikinci sayı, basılacak yığının dizinidir. Tüm çizgilerin işlemlerini sırayla gerçekleştirmek, herhangi bir kurala uymadan yığınları doğru şekilde düzenlemelidir.

Örneğin, N = 3 durumu için geçerli bir potansiyel çıktı:

1 2  [move the top number on stack 1 to the top of stack 2]
1 2  [repeat]
1 2  [repeat]
3 1  [move the top number on stack 3 to the top of stack 1]
2 3  [etc.]
2 3
2 3
2 1
2 1
2 1
3 1
3 1
3 1
3 2
1 2
1 2
1 2
1 3
2 3
2 3
2 3
1 2
3 2
3 1

notlar

  • Çıktınız yok değil optimum olması gerekir , yalnızca doğru. yani, pop ve push sayısını en aza indirmenize gerek yok.

    • Yani, bazı hareketlerin art arda yapılıp derhal tersine çevrilip çözülmemesi sorun değil.
    • Aynı hamle aynı hamle tek bir hareketle atmak ve itmek 2 2de mümkündür (elbette anlamsız olsa da).
  • Çıktınız yapar deterministik ve sonlu olması gerektiğini.

  • Yığınların 1 tabanlı dizine sahip olduğunu unutmayın. 0 tabanlı dizine izin verilmiyor.

  • Tabii ki 9'dan büyük olan N, tek basamak N kadar iyi çalışmalıdır.

  • İstenirse , boşluk ve yeni satırların yerine herhangi iki farklı, basamaksız yazdırılabilir ASCII karakterini kullanabilirsiniz. Çıktıdaki izleyen bir yeni satır (veya yeni satır yerine).

puanlama

Bayt cinsinden en kısa kod kazanır. Tiebreaker daha yüksek oyla cevap verdi.

Değerli brownie puanları eğer algoritmasını en iyi şekilde gösterebilir.


"Küçük şeyler için ekstra puan" saçma sapan> _>
user48538

18
@ zyabin101 Brownies'te şansınızı kaybettiniz.
Calvin'in Hobileri

9
Hep böyle harika başlıklar buluyorsun!
Luis Mendo

@HelkaHomba-._(._.)_.-
user48538

N=3Optimum durumda kullanabileceğiniz olası çıktı mı ?
R. Kap,

Yanıtlar:


9

Pyth 96 94 bayt

Mt*Q+++bGdHM|%+y_GHQQg1 2++Qd1g2 3g2 1g3 1++Qd2Vr3QgNtN++QdN;g1QVStQVStQI<NHgnNHnNtH)++nN0dnNH

Burada dene

O nasıl çalışır?

Bu açıklama N = 5 kullanacaktır.

Bölüm 1: Her yığında alt katmanı yarat

Bunun ayrı bir kod parçasına ihtiyaç duymasının nedeni her yığının kullanılması gerektiğinden kaynaklanıyor: ilk 4 altlarına koymak için bir 5'e ve son yığının da 5'leri sağlaması gerekiyor. Bu, tüm 4 s'leri bir yere taşıyamayacağımıza, 5'leri koyacağımıza ve 4'leri geri alamayacağımız anlamına gelir.

Görselleştirme: (Parantez neyin taşınacağı anlamına gelir)

     _
11111 |
22222 |_ Can't move 4s here, not monotonically increasing
33333_|
(44444)------------??? Where to put the 4s?
55555 <- Must supply the 5 that will be moved

Bunun yerine, bu ilk değişimi yapmak için, ilk önce tüm 1'leri ikinci yığına taşıyacağız, bir 5'i ilk yığına (şimdi boş olan), 1'leri üçüncü yığına, 2'yi ilk yığına taşıyacağız yığını, 1'leri ilk yığına geri getirin ve son olarak 5'i ikinci yığına taşıyın.

(11111)-----.
2222211111<-'
===============================
5<---------.
2222211111 : (from stack 5)
===============================
5
22222(11111)-.
3333311111<--'
===============================
522222<-.
(22222)-'
3333311111
===============================
52222211111<-.
             |
33333(11111)-'
===============================
52222211111
5<-----.
33333  |
44444  |
555(5)-'

Artık yığınları taşımak için boş bir alana sahip olduktan sonra (yalnızca doğru noktaya yerleştirilmiş bir 5 içeren yığın 2), tüm 3'leri yığın 2'ye taşıyabilir ve yığın 5'e 5 yerleştirebiliriz. 4 yığını için de aynı şey, ve şimdi tüm 5'leri doğru yerdeyiz! Ve sadece bir şey daha: tüm 1'leri yığın 5'e taşıyacağız, böylece bir sonraki yığın değişimi için güzel bir kurulum elde edeceğiz.

522222(11111)-.
533333        |
544444        |
5             |
511111<-------'

Bölüm 2: Her şeyi yapın :)

Bu şimdi çok daha kolay, çünkü artık dolaşmaya ihtiyacımız olan diğer sayıları taşımak için her zaman boş bir yığınımız olacak. İlk önce 4'ün nerede olduğunu bulduk. Bir bit inceleme, her zaman başladığı yerden 1 yukarı veya son yığının üstünde 2 olacağını gösterecektir. Şimdi, sadece yığınları aşağıya indirmeye devam ediyoruz, eğer serbestse yığına 4 koyuyoruz, yoksa diğer numaraları 1 yığına yükseltiriz. Şimdi tüm 4'lerin yerinde.

522222<------.
533333<----. |
544444-.-.-'-'
5<-----' |
511111<--'
===============================
5433333
54
54
5411111
5422222

Şimdi, 3'lerin, 4'lerin nerede olduğu üstünde 2 yığın olduğunu fark ediyoruz. Bu, 4'lülerle aynı şeyi yapabileceğimiz anlamına gelir! Görünen o ki, yığın indeksini diğer tarafa sardığımız sürece bunu yapmaya devam edebiliriz.

5433333-'wrap around 543
54                   543
54                   54311111
5411111 .----------->54322222
5422222 |2 stacks up 543

Ve böylece, tüm stokları değiş tokuş edinceye kadar bunu yapmaya devam edebiliriz.

Kod açıklaması:

Her şeyden önce: (önemli) önceden tanımlanmış değişkenler.

Q: Evaluated input.
b: The newline character, '\n'
d: A space, ' '

2 lambda tanımı vardır.

M           | g(G)(H), used for moving Q numbers at a time.
            | We will call these Q numbers a "(number) block"
 t          | Tail, used to remove beginning newline
  *Q        | Repeat the following Q times
    +++bGdH | '\n' + G + ' ' + H. Just a whole bunch of concatenating.
            |
M           | n(G)(H), used for figuring out which stacks to move from
 |       Q  | If the following code is 0 (false), then use Q instead
  %     Q   | Mod Q
   +   H    | Add H
    y       | Multiply by 2
     _G     | Negate (remember in the explanation part 2? Always 2 stacks above?)

Yığın değişimi: bölüm 1

g1 2                       | Move the 1 block to stack 2
    ++Qd1                  | Move a Q to stack 1
         g2 3              | Move the 1 block to stack 3
             g2 1          | Move the 2 block to stack 1
                 g3 1      | Move the 1 block back to stack 1
                     ++Qd2 | Move a Q to stack 2
 v---Code-continuation---' |I don't have enough room!!!
Vr3Q                       | For N in range(3, Q)
    gNtN                   | Move the number block in stack N up 1
        ++QdN              | Move a Q to stack N
             ;g1Q          | End for loop; move the 1 block to the last stack

Yığın değişimi: bölüm 2

VStQ                           | For N in [1, 2, ..., Q - 1]
    VStQ                       | For H in [1, 2, ..., Q - 1]
        I<NH                   | If N < H
            g                  | Number block move
             nNH               |  (find number block)
                nNtH           |  (find the previous stack)
                    )          | End "For H"
                     ++nN0dnNH | Find start, move number to next location down

Zaten kek puanımı alamadığımı biliyorum, çünkü çok daha verimli ve daha karmaşık yöntemler görebiliyorum :(

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.