Örneği dizine dönüştürme


12

Topları sabit bir sayıya bir kutuya koyuyoruz . Bu bidonlar boşalmaya başlar.

Empty bin (a=4): 0 0 0 0 

Ve teker teker kutulara toplar ekliyoruz.

0 0 0 1  or
0 0 1 0  or
0 1 0 0  or
1 0 0 0

Kovaların kopya olmadan ve hiçbirini kaçırmadan alabileceği tüm olası durumlar arasında hızlı bir şekilde dolaşmaya ihtiyacımız var ve olası tüm kutuları saymak istemiyoruz. Bunun yerine her bin konfigürasyonuna bir indeks atarız.

Dizini, olası yapılandırmaları belirli bir şekilde sıralayarak atarız:

  1. Toplama göre artan şekilde sıralayın: önce 0 0 0 0, sonra 1 top eklenmiş olası konfigürasyonlar, sonra 2 vb.
  2. Ardından, ilk bölmeden sonuncuya kadar her bir toplamın içinde artan sırada sıralayın:

    0 0 0 2
    0 0 1 1
    0 0 2 0 
    0 1 0 1
    0 1 1 0 
    0 2 0 0 
    etc
    
  3. Dizin daha sonra bu listeden artan şekilde atanır:

    0 0 0 0  -> 1
    0 0 0 1  -> 2
    0 0 1 0  -> 3
    0 1 0 0  -> 4
    1 0 0 0  -> 5
    0 0 0 2  -> 6
    0 0 1 1  -> 7
    0 0 2 0  -> 8
    0 1 0 1  -> 9
    0 1 1 0  -> 10
    0 2 0 0  -> 11 
    

kurallar

Negatif olmayan tamsayılarla herhangi bir boyutta liste alan bir işlev veya program oluşturun ve dizinini yazdırın veya çıktısını alın. Sen varsayabiliriz bir en az 2. En kısa kod kazanır olmak. 0 dizinli çıktı veya 1 dizinli çıktı kullanabilirsiniz ancak hangisini kullandığınızı belirtin. Not: Buradaki tüm örnekler 1 dizinlidir.

Örnek kod

Golf yapılmaz, R cinsinden:

nodetoindex <- function(node){
  a <- length(node)
  t <- sum(node)
  if(t == 0) return(1)

  index <- choose(t-1 + a, a)

  while(sum(node) != 0){
    x <- node[1]
    sumrest <- sum(node)
    if(x == 0){
      node <- node[-1]
      next
    }
    a <- length(node[-1])
    index <- index + choose(sumrest + a, a) - choose(sumrest - x + a, a)
    node <- node[-1]
  }
  return(index + 1)
} 

Test senaryoları

10 10 10 10 -> 130571
3 1 4 1 5 9 -> 424407
2 9 -> 69
0 0 0 -> 1
0 0 1 -> 2
0 0 0 0 0 0 -> 1
1 0 0 0 0 1 -> 23

Sayımlar farklı sayıda basamak içerdiğinde, birleştirme işleminin sayısal değeri üzerinden sıralama nasıl çalışır?
TheBikingViking

@TheBikingViking hmm, bunu düşünmemiştim, örnek kodu ve test senaryolarını yansıtacak şekilde ifadeleri değiştirdim. Her toplamda, konfigürasyonlar önce ilk bölmede, sonra ikincisinde vb. Sıralanır.
JAD

Yanıtlar:


3

Jöle , 8 bayt

S0rṗLSÞi

Çevrimiçi deneyin!

Kaba kuvvet çözümü. İlk test durumu TIO için çok fazla, ancak dizüstü bilgisayarımda yerel olarak doğruladım. İkinci test durumu, masaüstü bilgisayarım için bile çok fazla RAM gerektirir.

Nasıl çalışır

S0rṗLSÞi  Main link. Argument: A (array)

S         Compute the sum s of A.
 0r       Create the range [0, ..., s].
    L     Yield the length l of A.
   ṗ      Cartesian power; yield the array of all l-tuples over [0, ..., s], in
          lexicographical order.
     SÞ   Sort the l-tuples by their sums. The sorting mechanism is stable, so
          l-tuples with the same sum are still ordered lexicographically.
       i  Find the index of A in the generated array of tuples.

Güzel. RAM hakkındaki düşünceniz bana bu zorluğun kaynağını hatırlattı. Tezim için bazı a = 8 ve mümkün olduğunca yüksek toplar için tüm olası diziler üzerinde döngü yapmam gerekiyordu . Dizileri endekslere dönüştürme ve sadece bunlar üzerinde döngü yapma fikri tam olarak RAM sınırlamasından geldi: P
JAD

Bu da örnek kodun neden bu kadar garip olduğu: P
JAD

1

Clojure, 152 bayt

#(loop[v[(vec(repeat(count %)0))]i 1](if-let[r((zipmap v(range))%)](+ r i)(recur(sort(set(for[v v i(range(count v))](update v i inc))))(+ i(count v)))))

Düşündüğüm kadar kolay değil. Daha az golf versiyonu:

(def f (fn[t](loop[v[(vec(repeat(count t)0))]i 1]
               (if-let[r((zipmap v(range))t)](+ r i)
                 (recur (sort-by (fn[v][(apply + v)v]) (set(for[v v i(range(count v))](update v i inc))))
                        (+ i(count v)))))))

Mevcut durumlar üzerinde döngüler v, öğelerinden vsıralarına kadar bir karma harita oluşturur , aranan durum bulunursa sıralaması döndürülür (+ daha önce görülen durumların sayısı). Bulunamazsa, yeni bir dizi olası durumla tekrarlanır.

Oh, aslında her bir döngü içindeki tüm durumların aynı toplamı olduğu için özel sıralama fonksiyonuna ihtiyacımız yok. Bu beklediğim kadar yavaş değil, [3 1 4 1 5 9]sadece 2.6 saniye sürdü.


1

Mathematica, 50 bayt

Bir liman Dennis'in cevabı .

0~Range~Tr@#~Tuples~Length@#~SortBy~Tr~Position~#&

Adsız tamsayı listesini girdi olarak alan ve çıktı olarak tek tamsayı içeren bir derinlik-2 listesi döndüren adsız işlev; örneğin, son test senaryosu için girdi {1,0,0,0,0,1}ve çıktı {{23}}.

Hafifçe çözülmemiş bir versiyon:

Position[SortBy[Tuples[Range[0,Tr[#]],Length[#]],Tr],#]&

Çoğunlukla Mathematica'daki ayrı ayrı baytları önek notasyonu ( function@nyerine function[n]) ve infix notasyonu ( a~function~byerine ) kullanarak kaydedebiliriz function[a,b]. Ancak bu, sonuçta ortaya çıkan kod, Mathematica'nın işlevleri uygulamak için içsel öncelik sırasına iyi uyduğu zaman işe yarar. Ben tür köşeli parantez altı setleri ile, aslında kaldırmak için çalıştı, burada hayret oldu hepsi bunların ve (hoş bracketless) ile altı bayt gönderilen kod kaydet.

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.