正しい順序でキャンディーを食べる


36

キャンディーを食べるということになると、私は一般的な素人よりも高い基準を守っています。「それを混ぜる」と「最後のベストを保存する」の間に微妙なバランスがあります。

このチャレンジでは、各文字がキャンディーを表す文字列が与えられます。異なる文字(大文字と小文字が区別されます)は、異なる種類のキャンディーを表します。次に、プログラムは、以下の手順に基づいて、キャンディーの正しい消費順序を決定する必要があります。このタスクを実行するために、完全なプログラム(STDIN / STDOUT)または名前付き関数のいずれかを作成できます。

私のキャンディスタッシュがであるとしましょうoroybgrbbyrorypoprr。最初に、キャンディーを同じタイプの山にソートし、上部にあるより多くの量で、より低いASCII文字値をタイブレーカーとして使用します。

rrrrrr
oooo
bbb
yyy
pp
g

次に、キャンディーの各行を間隔を空けて等間隔に配置します。たとえば、キャンディーが3つある場合、1つは道の3分の1、2分の3、最後に配置されます。

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

次に、各列を下って最終的なキャンディの注文を作成しますrorbyroprbyorrobypg

入力

キャンディスタッシュを含む文字列。上記の例の入力は次のとおりです。

oroybgrbbyrorypoprr

出力

キャンディーを含む文字列が正しい消費順序に再編成されました。

rorbyroprbyorrobypg

得点

これはコードゴルフです。バイト単位の最短回答が優先されます。標準のコードゴルフ規則が適用されます。


キャンディーの数が不均一な場合は、より大きなスペースを追加するだけですか この場合、もう1つrキャンディーがある場合、グリッドはどのように見えるでしょうか?
バジュラ14年

38
最後に、キャンディーの食べ方を知っている人。
マイケルM. 14年

12
だから...基本的にキャンディディザリング。
COTO

9
これは実際に私がキャンディを食べる方法に非常に近いものです。:)
エミル

3
1人でどれだけ貪欲になれますか?食べられるキャンディーの数に制限はありますか?
アルキミスト14年

回答:


12

CJam、78 68 61 45 42 39 31 30バイト

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

STDINを介して入力文字列を取得します

再帰のアプローチに触発されましたが、少し異なります。転置や長方形はまったく必要ありません!。

使い方:

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はもはやPythを完了できませんでした)

ここで試してみてください


4
LCMは必要ないと思います。どんな倍数でも動作するはずです。これは、あなたが交換することができなければならない{_@_@{_@\%}h;/*}:
デニス14年

<facepalm>はそれを考えていませんでした。
オプティマイザー14年

長さを半分にしたおめでとうございます!
isaacg 14年

私はそのことに皮肉を感じます:D
オプティマイザー14年

11

ピス、25

shCoc/NhN/zhNm>o_/zZSzdUz

この答えに触発された、まったく新しいアルゴリズムを使用します

(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))

ステップバイステップ:

  1. まず、文字をその共通性でソートし、アルファベット順に分けます。これがありますo_/zZSzoPythonのsorted(<stuff>,key=<stuff>)キーと同じですが、キーとしてラムダ式を使用しますが、文字列として保持する点が異なります。

  2. 次に、その文字列のプレフィックスのリストlen(z)を長さ1 から生成します。これ>はpython'sと同等<stuff>[<int>:]です。

  3. 次に、このプレフィックス文字列のリストを、質問で見られる長方形レイアウトのプレフィックスの最初の文字の小数位置(0は左端、1は右)で並べ替えます。/NhN接頭辞の最初の文字が接頭辞に何回出現するかをカウント/zhNし、文字列の接頭辞の最初の文字の出現回数を穴として提供します。これにより、グループ内の各文字が先頭にある各プレフィックスに、その文字1/kの右端から左端まで、異なる割合が割り当てられますk/k。この番号でプレフィックスリストを並べ替えると、レイアウト内の適切な位置が決まります。ネクタイは、必要に応じて最初にカウント順、次にアルファベット順の事前の順序を使用して壊れます。

  4. 最後に、各プレフィックス文字列から最初の文字を抽出し、それらを1つの文字列に結合して印刷する必要があります。最初の文字の抽出はhCです。C実際zip(*x)にPython 3でリストの行列転置を実行しhます。結果の行列の最初の行を抽出します。これは実際には唯一の行です。これは、1文字のプレフィックスが存在すると、他の完全な行が形成されないためです。sこのタプルの文字を合計して1つの文字列にします。印刷は暗黙的です。

テスト:

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

増分プログラムピース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

古い答え:

ピス、34

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

このプログラムは、特定のサブリストを複製する回数を計算することにより機能します。サブリストは次のようになり['', '', '', '', ... , 'r']ます。このサブリストの合計の長さは、他のすべてのキャンディーの出現回数の積ですu*G/zHS{-zd1。完全なサブリストは、空の文字列、のリスト]kを何度も複製し、で要素を削除tし、末尾にキャンディ名を追加することで構築され+dます。

次に、このサブリストは、キャンディーが入力で見つかった回数だけ複製され、/zd各キャンディーのリストの長さが等しくなるようにします。

これで、この関数がすべての一意のキャンディーに適切なソート順(o_/zNS{z)でマップされると、質問文の長方形に似た長方形が作成されますが、ピリオドではなく空の文字列が使用されます。行列の転置(C)の後に2つの加算(ss)を実行すると、最終的な文字列が得られます。

検証:

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

4
Pythは言語構文自体で暗号化をサポートしているようです!
オプティマイザー14年

@Optimizer Encryption?あなたは何について話していますか?
isaacg

いいね!おそらくforループをマップに変更することは考えていなかっただろう。ずっときれい。
FryAmTheEggman 14年

ソースコードを見てください。暗号化されたメッセージのように見えます。
オプティマイザー14年

2
最新のアルゴリズムのステップごとの例を教えてもらえますか?かなりしてください:)
オプティマイザー14年

6

Perl 5-62

61コード+ 1フラグ。

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

最初に入力を文字配列に分割します- /./g

変数でカウントを残して、各文字に出現インデックスを追加します$a。.. $zmap++$$_.$_。配列は次のとおりです。

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

次に、それを連結キーに変換します:ratio $_/$$1、count tie breaker ~$_およびASCII value tie breaker $_。これにより、結果がわかりやすくなります(わかりやすくするためにスペースを追加しています)。

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

これは、辞書式(デフォルト)の順序でソートできます。最後に最後の文字を抽出して印刷します:print map/(.$)/


5

Python 3.x-124バイト

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]))))

これは、四角形の方法よりもアルゴリズムが格段に優れています!
isaacg 14年

4

Mathematica、123 119 118バイト

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

名前付き関数を定義しますf。ゴルフをしていない:

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

組み込みの合理的な型を使用することは、このための良いアイデアのように思えました。もちろん、これはCJamの近くにはありません。基本的に、チャレンジで表示されるグリッドをペアのリストとして表しています。ペアの最初のものは文字コードで、2番目は1以下の端数としての位置です(最後の列は1です)。個々のキャラクターがすでに正しい順序になっていることを確認したので、希望の結果を得るために、この分数でこれを安定してソートする必要があります。


3

ピス 45 47 48 51

これはほぼ確実にさらにゴルフすることができます;)

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

リストのリストを作成することにより機能します。各内部リストは空の文字列とキャンディの名前の行です。このリストは転置され、次に内部リストが結合され、続いてこれらのリストが結合されます。

合計について思い出させてくれてありがとう@isaacg!


2
s文字列のリストでとして機能しj""ます。
isaacg 14年

3

APL:38

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

説明:

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でテストできます


2

R-166文字

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="")}

無償版

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 = "")
}

説明:

  • 個々のキャラクターに分割
  • 各キャラクターの数を表にする
  • テーブルを最も頻繁に並べ替えてから、字句順に並べ替えます
  • 1 / n、2 / n、3 / n、... n-1 / n、1での選択のインデックス位置(nはキャンディーの数)
  • キャンディーの名前をインデックスで並べ替えます(並べ替えorderが安定しているため、インデックスのタイ、特に最後のキャンディーで特に重要な場合に、最も頻繁に使用される/語彙の命名順序を維持します)
  • キャンディー名を連結して出力​​文字列を作成します

この問題の行列の性質から、Rがこれに挑戦しているのではないかと思いましたが、私ができるアルゴリズムの文字通りの最良の解釈は211文字です

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="")}

なし:

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バイト

これはPythでの私のCJam answe rの直接翻訳です

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

こちらからオンラインでお試しください


このソリューションの背後にはかなり長い話があり、@ isaacgはこの新しい言語を理解する上で大いに役立ちました。

理想的には、これは私のCJamコードの正確な単語から単語への翻訳です(17バイト):

oc/~kNN/zNo_/zZSz

つまり:

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)))

しかし悲しいことに、Pythonは+=呼び出しで何も返さないため、有効なPythonコードではなかったため、Pythと同様に無効なPythコードでした。ラムダはreturnステートメントにしかなれません。

次に、さまざまなメソッドを調べて、Python list.appendNone値を返すことがわかりました。これを使用できます。コードを(19バイト)にする:

oc/|aYNYN/zNo_/zZSz

つまり:

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)))

しかし、悲しいことに、a(append)のサポートはPythから削除され、サポートするバージョンはをサポートしていませんo

更新:aサポートがPythに追加され、上記の19バイトコードがオンラインコンパイラで動作するようになりました。しかし、これはOPの後に追加された新しい機能であるため、スコアとして設定せず、29バイトコードを解決策として使用していません。

そのため、その場合は生のPythonに依存し、コードを

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)))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.