Doğru sırayla şeker yemek


36

Şeker yemeye gelince, kendimi tipik ev sahibinden daha yüksek standartlarda tutuyorum. "Karıştırmak" ile "en iyisini sona saklamak" arasında hassas bir denge var.

Bu mücadelede, her karakterin bir şeker parçasını temsil ettiği bir karakter dizisi verilecek. Farklı karakterler (büyük / küçük harfe duyarlı) farklı şeker türlerini temsil eder. Ardından, programınız aşağıdaki prosedüre göre doğru şeker tüketimi sırasını belirlemelidir. Bu görevi gerçekleştirmek için eksiksiz bir program (STDIN / STDOUT) veya adlandırılmış bir işlev yazabilirsiniz.

Diyelim ki şekerim saklıyor oroybgrbbyrorypoprr. Öncelikle, şekeri, bağ kırıcı olarak daha düşük ASCII karakter değerleri kullanarak, daha büyük miktarlarda, aynı tipteki yığınlar halinde sıralarım.

rrrrrr
oooo
bbb
yyy
pp
g

Sonra her şeker sırasını alıyorum ve eşit aralıklarla onları eşit aralıklarla alıyorum. Örneğin, 3 parça şeker varsa, biri yolun 1 / 3'ü, yolun 2 / 3'ü ve sonuna yerleştirilir.

.r.r.r.r.r.r
..o..o..o..o
...b...b...b
...y...y...y
.....p.....p
...........g

Daha sonra, son şeker siparişimi oluşturmak için her sütundan aşağıya iniyorum rorbyroprbyorrobypg.

Giriş

Şeker parçasını içeren bir ip. Yukarıdaki örneğin girişi olabilir:

oroybgrbbyrorypoprr

Çıktı

Şekeri içeren bir ip, doğru tüketim sırasına göre yeniden düzenlenmiştir.

rorbyroprbyorrobypg

puanlama

Bu kod golfü. Bayt cinsinden en kısa cevap kazanır. Standart kod-golf kuralları geçerlidir.


Şeker sayıları eşit değilse, sadece daha büyük bir alan ekler misiniz? Diyelim ki bu durumda bir şekerleme daha olsaydı ızgara nasıl görünürdü?
Vajura

38
Sonunda nasıl şeker yemeyi bilen biri.
Michael M.

12
Yani ... temelde şeker taklidi.
COTO

9
Bu aslında şekeri nasıl yediğime çok yakın. :)
Emil

3
Bir kişi ne kadar açgözlü olabilir? Yenilecek şeker sayısında bir sınır var mı?
Simyacı

Yanıtlar:


12

CJam, 78 68 61 45 42 39 31 30 bayt

l$:L{L\/,~}${:DM+:MD/,LD/,d/}$

Giriş dizesini STDIN ile alır

Özyinelemenin yaklaşımından ilham aldı, ancak biraz farklı. Transpoze veya dikdörtgen gerek yok!

Nasıl çalışır:

l$:L                              "Sort the input line and store it in L";
    {     }$                      "Sort the string based on this code block output";
     L\/,~                        "Sort based on number of occurrences of each";
                                  "character in the full string";
            {               }$    "Sort the sorted string again";
             :DM+:M               "Store each character in D, add to M and update M";
                   D/,            "Count occurrences of D in M";
                      LD/,        "Count occurrences of D in L";
                          d/      "Sort string based on the ratio of two occurrences";

(CJam'ın artık sözdizimi kadar şişkinliğe ihtiyaç duymasından dolayı Pyth ile artık tamamlayamayacağı için)

Burada dene


4
LCM'ye ihtiyacınız olduğunu sanmıyorum; herhangi bir çoklu çalışması gerekir. Bu Değiştirmeye izin vermelidir {_@_@{_@\%}h;/*}ile :.
Dennis

<facepalm> bunu düşünmedi.
Doktor

Boyunuzu yarıya indirdiğiniz için tebrikler!
isaacg

Bu konuda alaycı hissediyorum: D
Optimizer

11

Pyth , 25

shCoc/NhN/zhNm>o_/zZSzdUz

Bu cevaptan ilham alan tamamen yeni bir algoritma kullanır .

(implicit)          z = input()
(implicit)          print
s                   combine list of strings into one string
 h                  first list in
  C                 matrix transpose of (e.g. first characters in first list, etc.)
   o                order_by(lambda N:
    c                        float_div(
     /NhN                              N.count(N[0]),
     /zhN                              z.count(N[0])),
    m                        map(lambda d:
     >                           slice_head(
      o                                     order_by(lambda Z:
       _/zZ                                          -1*z.count(Z),
       Sz                                            sorted(z)),
      d                                     d),
     Uz                          range(len(z))

Adım adım:

  1. İlk önce karakterleri ortaklıklarına göre sıraladık, bağları alfabetik olarak kırdık. Bu o_/zZSz. oPython sorted(<stuff>,key=<stuff>)ile aynıdır , tuş için lambda ifadesi bulunur, ancak onu bir dize olarak tutar.

  2. Uzunluk dan Sonra o tellerden önekleri bir listesini oluşturmak len(z)1. uzunluğa >piton en eşdeğerdir <stuff>[<int>:].

  3. Ardından, bu önek dizeleri listesini, 0'da sol kenar ve 1'i sağ olan kesirli konuma göre soruyu görülen dikdörtgen düzenindeki ilk karakterin ilk sırasına göre yeniden sıralıyoruz. /NhNÖnek içindeki ilk karakterin kaç kere önyargıda bulunduğunu sayarken, önek içindeki ilk karakterin kaç /zhNsayısını bir delik olarak gösterir. Bu, bir gruptaki her karakterin önderlik ettiği her öneki 1/k, bu karakterin en sağındaki en k/ksolundan en soluna kadar farklı bir kesir atar . Önek listesinin bu numaraya göre sıralanması, düzende uygun konumu verir. Bağlar, önceden sayma işlemine tabi tutulur; bunlar ilk önce sayma, sonra alfabetik olarak istenir.

  4. Son olarak, her önek dizgisinden ilk karakteri çıkarmamız, bunları tek bir dizgede birleştirmemiz ve yazdırmamız gerekiyor. İlk karakterleri çıkarmak hC. CListede, aslında zip(*x)Python 3'te bir matris transpoze gerçekleştirir h. Sonuç matrisinin ilk satırını çıkarır. Bu aslında tek satırdır, çünkü 1 karakterlik ön ekin varlığı, diğer tüm tam satırların oluşmasını engeller. sbu dizideki karakterleri tek bir dizgede toplar. Baskı çok açık.

Ölçek:

$ pyth -c 'shCoc/NhN/zhNm>o_/zZSzdUz' <<< 'oroybgrbbyrorypoprr'
rorbyroprbyorrobypg

Artımlı program parçaları oroybgrbbyrorypoprr:

Sub-Piece                  Output

Sz                         bbbgoooopprrrrrryyy
o_/zNSz                    rrrrrroooobbbyyyppg      (uses N because o uses N on first use.)
m>o_/zNSzdUz               ['rrrrrroooobbbyyyppg', 'rrrrroooobbbyyyppg', 'rrrroooobbbyyyppg', 'rrroooobbbyyyppg', 'rroooobbbyyyppg', 'roooobbbyyyppg', 'oooobbbyyyppg', 'ooobbbyyyppg', 'oobbbyyyppg', 'obbbyyyppg', 'bbbyyyppg', 'bbyyyppg', 'byyyppg', 'yyyppg', 'yyppg', 'yppg', 'ppg', 'pg', 'g']
oc/NhN/zhNm>o_/zZSzdUz     ['roooobbbyyyppg', 'obbbyyyppg', 'rroooobbbyyyppg', 'byyyppg', 'yppg', 'rrroooobbbyyyppg', 'oobbbyyyppg', 'pg', 'rrrroooobbbyyyppg', 'bbyyyppg', 'yyppg', 'ooobbbyyyppg', 'rrrrroooobbbyyyppg', 'rrrrrroooobbbyyyppg', 'oooobbbyyyppg', 'bbbyyyppg', 'yyyppg', 'ppg', 'g']
Coc/NhN/zhNm>o_/zZSzdUz    [('r', 'o', 'r', 'b', 'y', 'r', 'o', 'p', 'r', 'b', 'y', 'o', 'r', 'r', 'o', 'b', 'y', 'p', 'g')]
shCoc/NhN/zhNm>o_/zZSzdUz  rorbyroprbyorrobypg

Eski cevap:

Pyth , 34

ssCm*+t*u*G/zHS{-zd1]kd/zdo_/zNS{z

Bu program, belirli bir alt listeyi kaç kez çoğaltacağınızı hesaplayarak çalışır. Alt liste benziyor ['', '', '', '', ... , 'r']. Bu alt listenin toplam uzunluğu, diğer tüm şekerlerin oluşum sayısının ürünüdür u*G/zHS{-zd1. Tam alt liste, boş dizgenin listesinin çoğaltılmasıyla yapılır, ]kçoğu kez, ardından çıkartma ve eleman ile tşeker ismini sonuna kadar ekler +d.

Daha sonra, bu alt liste, girişte şekerin bulunduğu kadar çoğaltılır ve /zdher şekerin listesinin eşit uzunlukta olmasını sağlar.

Şimdi, bu fonksiyonun tüm benzersiz şekerler üzerinde uygun sıralama düzeninde ( o_/zNS{z) eşleştirilmesiyle , soru ifadesindekine benzer bir dikdörtgene sahibiz, ancak periyotlar yerine boş dizelerimiz var. Bir matris transpose ( C) yapmak ve ardından iki toplama ( ss) yapmak son dizgiyi verir.

Doğrulama:

$ pyth programs/candy.pyth <<< 'oroybgrbbyrorypoprr'
rorbyroprbyorrobypg

4
Pyth, dil sözdiziminin kendisinde şifrelemeyi destekliyor gibi görünüyor!
Doktor

@ Optimize Edici Şifreleme? Neden bahsediyorsun?
isaacg,

Güzel! Muhtemelen for döngüsünü bir haritaya çevirmeyi asla düşünmezdim. Çok daha temiz.
FryAmTheEggman

Kaynak koduna bak. Şifreli bir mesaj gibi görünüyor.
Doktor

2
En son algoritmanın adım adım örneğini verebilir misiniz? Oldukça lütfen :)
Doktor

6

Perl 5 - 62

61 kod + 1 bayrağı.

#!perl -n
print map/(.$)/,sort map/(.$)/*$_/$$1.~$_.$1,map++$$_.$_,/./g

İlk önce girişi karakter dizisine ayırın - /./g.

Sayıları değişkenlerde bırakarak her harfe oluşum indeksi ekleyin $a.. $zile map++$$_.$_. Şimdi dizi:

1o
1r
2o
1y
1b
1g
2r
2b
3b
2y
3r
3o
4r
3y
1p
4o
2p
5r
6r

Sonra bunu bir sıralama anahtarına birleştirerek dönüştürün: oran $_/$$1, bağ kırıcı ~$_ve ASCII değer bağ kırıcı $_. Bu, sonuçta ortaya çıkacak (açıklık için eklenmiş boşluklarla).

0.25 18446744073709551614 o
0.166666666666667 18446744073709551614 r
0.5 18446744073709551613 o
0.333333333333333 18446744073709551614 y
0.333333333333333 18446744073709551614 b
1 18446744073709551614 g
0.333333333333333 18446744073709551613 r
0.666666666666667 18446744073709551613 b
1 18446744073709551612 b
0.666666666666667 18446744073709551613 y
0.5 18446744073709551612 r
0.75 18446744073709551612 o
0.666666666666667 18446744073709551611 r
1 18446744073709551612 y
0.5 18446744073709551614 p
1 18446744073709551611 o
1 18446744073709551613 p
0.833333333333333 18446744073709551610 r
1 18446744073709551609 r

Bu sözlük (varsayılan) sıraya göre sıralanabilir. Sonunda son karakteri çıkarıp yazdırın:print map/(.$)/


5

Python 3.x - 124 bayt

C=input()
print("".join(s[1]for s in sorted(enumerate(C),key=lambda
t:((C[:t[0]].count(t[1])+1+1e-10)/C.count(t[1]),t[1]))))

Bu bir algoritmanın dikdörtgen metodundan çok daha havalı!
isaacg

4

Mathematica, 123 119 118 bayt

f=FromCharacterCode[s=SortBy;#&@@@s[Join@@(s[Tally@ToCharacterCode@#,-Last@#&]/.{x_,n_}:>({x,#/n}&~Array~n)),{Last}]]&

Adlandırılmış bir işlevi tanımlar f. Ungolfed:

f = FromCharacterCode[
   s = SortBy;
   # & @@@ s[
     Join @@ (
       s[
         Tally@ToCharacterCode@#,
         -Last@# &
         ] /. {x_, n_} :> ({x, #/n} &~Array~n)
       ),
     {Last}
     ]
   ] &

Yerleşik rasyonel türleri kullanmak, bunun için iyi bir fikir gibi göründü. Tabii ki, bu CJam yakın hiçbir yerde. Temel olarak, mücadelede gösterilen ızgarayı çiftlerin bir listesi olarak temsil ediyorum. Çiftteki ilk şey karakter kodudur, ikincisi ise 1'den küçük veya ona eşit bir kesirdir (son sütun 1'dir). Tek tek karakterlerin zaten doğru sırada olduğundan emin olduktan sonra, istenen sonucu elde etmek için bunu sadece bahsedilen kesir ile sabit bir şekilde sıralamam gerekiyor.


3

Pyth 45 47 48 51

Bu da neredeyse kesinlikle daha ileri golf olabilir;)

Ko_/zNS{zFGK~Y]*+*t/u*GHm/zdK1/zG]k]G/zG)ssCY

Her bir iç listenin bir satır dizeleri ve şekerlemenin adı olduğu bir liste listesi oluşturarak çalışır. Bu liste aktarılır ve daha sonra iç listeler birleştirilir ve bu listeler birleştirilir.

Bana toplamı hatırlattığın için teşekkürler @isaacg!


2
sdizeleri listesinde olduğu gibi çalışır j"".
isaacg

3

APL: 38

v⌷⍨⊂⍋⌽(n/-n),⍪∊+\¨n⍴¨÷n←{≢⍵}⌸v←{⍵[⍋⍵]}

Açıklama:

v←{⍵[⍋⍵]}    orders input string
n←{≢⍵}⌸v     counts how many times each element appears in v
∊+\¨n⍴¨÷n     makes incremental sums in each letter "group" 
⍋⌽(n/-n),⍪   appends number of elements in letter group and orders the obtained matrix
v⌷⍨⊂         orders vector v with computed indices

Tryapl.org'da test edilebilir


2

R - 166 karakter

library("plyr");s=function(a){l=table(strsplit(a,s="")[[1]]);l=ldply(l[order(-l,names(l))],function(n)data.frame(seq_len(n)/n));paste(l[order(l[[2]]),1],collapse="")}

asılsız versiyon

library("plyr")
s <- function(a) {
    tbl <- table(strsplit(a, split = "")[[1]])
    tbl <- tbl[order(-tbl, names(tbl))]
    tbl <- ldply(tbl, function(n) {data.frame(seq_len(n)/n)})
    paste(tbl[order(tbl[[2]]),1], collapse = "")
}

Açıklama:

  • Tek tek karakterlere ayırma
  • Her karakterin sayısını gösteren tablo
  • Tabloyu en sık ve sonra sözcük sıralamasına göre sıralayın
  • 1 / n, 2 / n, 3 / n, ... n-1 / n, 1 değerlerinde seçim için dizin konumları, burada n, şekerlerin sayısıdır
  • Şeker adlarını dizine göre ordersıralama ( sıralamada kararlıdır, bu nedenle dizinde bir bağ özellikle son şekerler için önemli olduğunda en sık / sözcük adlandırma sırasını koruyacaktır)
  • Çıkış dizesini oluşturmak için şeker adlarını bir araya getirin

Sorunun matris doğası bana R'nin bu konuda bir şansa sahip olabileceğini düşündürdü, ancak yapabileceğim algoritmanın en iyi yorumlanması 211 karakterdi:

l=function(a){l=table(strsplit(a,s="")[[1]]);l=l[order(-l,names(l))];o=Reduce(`*`,l);m=matrix("",nc=o,nr=length(l));for(r in seq_along(l)){x=l[r];for(c in seq_len(x)*o/x){m[r,c]<-names(x)}};paste(m,collapse="")}

ungolfed:

l <- function(a) {
    tbl <- table(strsplit(a, split = "")[[1]])
    tbl <- tbl[order(-tbl, names(tbl))]
    o <- Reduce(`*`, tbl)
    m <- matrix("", ncol = o, nrow = length(tbl))
    for (r in seq_along(tbl)) {
        for (c in seq_len(tbl[r])*o/tbl[r]) {
            m[r,c] <- names(tbl[r])
        }
    }
    paste(m, collapse="")
}

2

Pyth, 29 bayt

Bu benim doğrudan bir çevirisidir CJam answe Pyth içinde r

oc/|$Y.append(N)$YN/zNo_/zZSz

Burada çevrimiçi deneyin


Bu çözümün arkasında oldukça uzun bir hikaye var ve @isaacg bu yeni dili anlamamda bana çok yardımcı oldu.

İdeal olarak bu, CJam kodumun ( 17 bayt ) kelime çevirisine tam kelimedir :

oc/~kNN/zNo_/zZSz

bunun anlamı:

o         order_by(lambda N:
 c                 div(
  /                    count(
   ~kN                       k+=N,                #Update k (initially ""), add N
   N                         N),                  #Count N in updated k
  /zN                  count(z, N)),
 o                 order_by(lambda Z:
  _                         neg(
   /zZ                          count(z, Z)),
  Sz                        sorted(z)))

Ancak ne yazık ki Python bir +=çağrıda hiçbir şey döndürmüyor , bu nedenle geçerli bir Python kodu değildi, bu nedenle Pyth'deki geçersiz bir Pyth kodu, lambda yalnızca bir return ifadesi olabilir.

Sonra çeşitli yöntemlere baktım ve sonunda Python'un kullanabileceğim list.appendbir Nonedeğer verdiğini öğrendim . Kodun yapılması ( 19 bayt ):

oc/|aYNYN/zNo_/zZSz

bunun anlamı:

o         order_by(lambda N:
 c                 div(
  /                    count(
   |aYN                      (Y.append(N) or
    Y                         Y)                 #Update Y (initially []), append N
   N                         N),                 #Count N in updated Y
  /zN                  count(z, N)),
 o                 order_by(lambda Z:
  _                         neg(
   /zZ                          count(z, Z)),
  Sz                        sorted(z)))

Ancak ne yazık ki, aPyend'ten (append) desteği kaldırılmış ve desteği olan sürüm desteği yok o.

Güncelleme: aPyth'e şimdi destek eklendi, böylece yukarıdaki 19 baytlık kod çevrimiçi derleyicide çalışacak. Ancak bu OP'den sonra eklenen yeni bir özellik olduğundan, onu puanım olarak koymayacağım ve 29 bayt kodunu benim çözümüm olarak bırakıyorum.

Bu nedenle, bu durumda ham Python'a güvenmek zorunda kaldım, böylece kodu

o         order_by(lambda N:
 c                 div(
  /                    count(
   |$Y.append(N)$            (Y.append(N) or
    Y                         Y)                 #Update Y (initially []), append N
   N                         N),                 #Count N in updated Y
  /zN                  count(z, N)),
 o                 order_by(lambda Z:
  _                         neg(
   /zZ                          count(z, Z)),
  Sz                        sorted(z)))
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.