“Izgarayı Doldur” Sorunu


36

Basit kuralları olan ama önemsiz olmayan algoritmalara sahip bir meydan okuma. :-)

Görev

Boşluk ile ayrılmış tamsayılar biçiminde girdi alın:

N A B S

Burada N, A ve B arasındaki benzersiz sayılarla (tam sayılar) doldurulan 2B kare matrisin yan uzunluğu . Bu matristeki her satır ve sütun için, toplam daima aynıdır: S. (Başka bir deyişle, matris yarı sihirli bir karedir).

Not:

Tüm sayılar pozitif. İstisna, 0 olabilir A.

Örnekler

İçin

3 1 10000 2015

geçerli bir çözüm

görüntü tanımını buraya girin

İçin

8 1 300 500

geçerli bir çözüm

görüntü tanımını buraya girin

Çıktı

Çıktınız bir ASCII tablosu olmalıdır. Yukarıdaki ilk örnek için örnek:

 384  159 1472
1174  499  342
 457 1357  201

Boşluklarla dolu sağa tamsayılar. Her sütunun genişliği, o sütundaki en büyük tamsayının genişliğidir.

puanlama

Bu , bayt cinsinden en kısa kod kazanır. Standart boşluklar uygulanır (özellikle bu problemi çözmek için yerleşikler hakkında). Yanlış veya başka şekilde imkansız olan girişlere (negatif sayılar dahil) dikkat etmeniz gerekmez. Lütfen yukarıdaki ikinci örnek için cevabınıza bir örnek çıktı verin (zorunlu).


1
Doğru şekilde toplanıp benzersiz olana kadar A ve B arasında rasgele sayılar üretmemize izin var mı?
lirtosiast

Sadece kontrol etmek, A, Bve Nnegatif olabilir?
xnor

2
Minxomat, gelebileceğim en iyi çözüm olduğunu söylemiyorum, mümkün olan en kısa olabileceğini söylüyorum.
lirtosiast

3
@LuisMendo Göreve göre örnek çıktı üretmek zorundasınız. Bunu, yaşamınız boyunca kaba kuvvet yaklaşımıyla yönetebilirseniz, etkilendim. :-). Bunu ekarte edebilirim, ama çok bulanık olurdu, çünkü en popüler çözüm (GA olan) hala rastgelelik içeriyor. Ayrıca, birisi zaten bir çözüm üzerinde çalışabilecekse, kuralları değiştirmek istemiyorum.
mınxomaτ

1
All @minxomat senin üç argüman çok iyi noktaları :-) vardır
Luis Mendo

Yanıtlar:


19

CJam, 119 91 bayt

q~:M;),>:R;(:L{{R{ML)d/-Y#)mr}$L/L<2{{M1$:+-+}%z}*:U:+__O|=R*-}gU{:s_:,:e>f{Se[}}%zSf*N*}M?

Bu kesin olarak doğru, deterministik olmayan bir yaklaşım.

Masaüstümde ikinci test durumu genellikle 10 dakikadan daha kısa bir sürede bitiyor.

İlk vaka anında biter. CJam tercümanında çevrimiçi olarak deneyin .

Örnek çalışma

$ cjam grid.cjam <<< '8 1 300 500'
77  66  37 47  56  46 86  85
63 102  70 72  49  54 81   9
62  69  58 57  71  17 48 118
64  65  67 87  53  44 80  40
73  60  55 89  51  76 84  12
68  59  28 78  74  38 50 105
61  75  52 43 125  83 42  19
32   4 133 27  21 142 29 112

Fikir

Zaman sınırları olmadan, geçerli bir kare bulana kadar rastgele kareler oluşturabiliriz. Bu yaklaşım, bu fikre dayanarak iki optimizasyon ekler:

  • Yerine sözde-rasgele bir yan uzunluğu kare üretilmesi N , biz yan uzunluğunun kareler oluşturmak N-1 , bir oluşturmak için bir sütun eklemek N x (N-1) satır toplamı sahip dikdörtgen S , o zaman bir sıra bir kare meydana getirmek üzere yan uzunluk N sütunları toplamı sahip S .

    Tüm sütunların elemanlarının toplamı NS olacağından ve ilk N-1 satırlarının elemanlarının toplamı (N-1) S olduğundan, son satır da S toplamına sahip olacaktır .

    Bununla birlikte, bu işlem geçersiz bir matris oluşturabilir, çünkü son satırın ve sütunun tüm öğelerinin benzersiz veya [A ... B] aralığında olacağının garantisi yoktur .

  • [A ... B] ' de benzersiz tam sayılardan oluşan bir kareyi ve rastgele sıradaki N-1 yan uzunluğu seçmek çok uzun sürecektir. Bir şekilde , önceki madde işaretinde detaylandırılmış olan işlemi uyguladıktan sonra geçerli bir N yan kare uzunluğu ile sonuçlanma şansı yüksek olan karelere öncelik vermeliyiz .

    Her satırın ve sütunun toplam S toplamına sahip olması gerektiği düşünüldüğünde , elemanlarının ortalama S / N değeri vardır . Bu nedenle, bu ortalamaya yakın daha fazla eleman seçmek şansımızı arttırmalıdır.

    [A ... B] ' deki her I için , rastgele 0 ile (I - S / N) 2 + 1 arasında bir kayan nokta seçer ve [A ... B] öğelerini toplanan kayan noktalara göre sıralarız. İlk N 2 sayılarını tutarız ve bunları kare şeklinde okuma sırasına yerleştiririz.

    Her adımda 0 ile (I - S / N) 2 + 1 arasındaki tüm gerçek sayıların mükemmel bir şekilde dağılmış olduğu varsayıldığında , tüm karelerin sıfıra düşme olasılığı yoktur, bu da işlemin sonunda biteceği anlamına gelir.

kod

q~          e# Read all input from STDIN and evaluate it.
:M;         e# Save "S" in M and discard it from the stack.
),>:R;      e# Transform "A B" into [A ... B], save in R and discard.
(:L         e# Save "N - 1" in L and keep it on the stack.
{           e# If L is non-zero:
  {         e#   Do:
    R{      e#     For each I in R:
      ML)d/ e#       Compute M/Double(L+1).
      -Y#   e#       Subtract the result from I and square the difference.
      )mr   e#       Add 1 and pick a non-negative Double below the result.
    }$      e#     Sort the values of I according to the picks.
    L/      e#     Split the shuffled R into chunks of length L.
    L<      e#     Keep only the first L chunks.
    2{      e#     Do twice:
      {     e#       For each row of the  L x L array.
        M1$ e#       Push M and a copy of the row.
        :+- e#       Add the integers of the row and subtract their sum from M.
        +   e#       Append the difference to the row.
      }%    e#
      z     e#       Transpose rows and columns.
    }*      e#
    :U:+    e#     Save the result in U and concatenate its rows.
    __O|    e#     Push two copies. Deduplicate the second copy.
    =R*     e#     Push R if all elements are unique, an empty array otherwise.
    -       e#     Remove the result's elements from U's elements.
  }g        e#   If the resulting array is non-empty, repeat the loop.
  U{        e#   For each row in U:
    :s      e#     Convert its integers into strings.
    _:,     e#     Copy and replace each string with its length.
    :e>     e#     Compute the maximum length.
    f{      e#     For each integer, push the maximum length; then
      Se[   e#       Left-pad the integer with spaces to that length.
    }       e#
  }%        e#
  z         e#   Transpose rows with columns.
  Sf*N*     e#   Join columns by spaces, rows by linefeeds.
}M?         e# Else, push M.
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.