文字列を並べ替え、


29

文字列を並べ替えると、通常は次のようになります。

         ':Iaaceeefggghiiiiklllllmnnooooprrssstttttuuyyyy

はい、それがソートされた最初の文でした。

あなたが見ることができるように、繰り返される文字が多い、aaeeettttt、9つのスペースなど。

128最初の複製のASCII値256、2番目、3843番目などにASCII値を追加し、再度並べ替えて新しい文字列(同じ文字を取得するためのモジュラス128)を出力すると、文字列が取得されます。

 ':Iacefghiklmnoprstuy aegilnorstuy egilosty iloty lt    

(単一の先頭スペースと4つの末尾スペースに注意してください)。

文字列は"順ソート"され<space>':I....uy<space>aeg....uy<space>egi....ty<space>iloty<space>lt<space><space><space><space>

数字を含む文字列を使用すると、これを視覚化する方が簡単かもしれません。文字列111222334は「ソート」されたとき:になります123412312

チャレンジ:

驚くことではありませんが、挑戦は上記の説明に従って文字列をソートするコードを書くことです。

入力文字列には、32〜126の範囲(チルダまでのスペース)の印刷可能なASCII文字のみが含まれると想定できます。


テストケース:

**Test cases:**
 *:Tacest*es*s*

If you sort a string you'll typically get something like:
 ':Iacefghiklmnoprstuy aegilnorstuy egilosty iloty lt    

Hello, World!
 !,HWdelorlol

#MATLAB, 114 bytes
 #,14ABLMTbesty 1A

f=@(s)[mod(sort(cell2mat(cellfun(@(c)c+128*(0:nnz(c)-1),mat2cell(sort(s),1,histc(s,unique(s))),'un',0))),128),''];
'()*+,-0128:;=@[]acdefhilmnoqrstuz'(),0128@acefilmnorstu'(),12celmnostu'(),12celnstu(),clnst(),cls(),cs(),()()()()

これはなので、バイト単位でカウントされた各言語の最短コードがrefを獲得します。


タイトルは少しわかりにくいので、このことを考えて説明を無視しました。
魔法のタコUr

文字列の代わりに文字のリストを出力できますか?
小麦ウィザード

文字列を入力できる場合、出力も文字列にする必要があります。文字のリストがあなたの言語で文字列を入出力する通常の方法であれば、それは問題ありません。たとえば{'S', 'g', 'i', 'n', 'r', 't'}、Pythonで出力することはできません"String"。「通常の」方法はであるためです。
スティーヴィーグリフィン

上記のコメントを修正します。文字列は文字のリストので、文字のリストは受け入れられます。ただし、文字列のリストは受け入れられません。つまり、リスト内の要素に2番目の文字を追加できる場合、その要素は受け入れられません。例として、次のよう{'a','b'}に各文字に文字を追加できるため、Matlabでは受け入れられません{'aa','b'}。入力と出力は同じ形式である必要があります。
スチューウィーグリフィン

@StewieGriffin上記の説明に従ってソートされたと言うとき。ソートアルゴリズムはASCII値を変更するプロセスに従う必要がありますか、それともそのアルゴリズムと同じ出力を生成する必要があるだけですか?
ジョージリース

回答:


15

Pyth、5バイト

s.T.g

テストスイート

非常に簡単:グループ化と並べ替え、転置、連結。

s.T.g
s.T.gkQ    Implicit variables
   .gkQ    Group the input input lists of elements whose values match when the
           identity function is applied, sorted by the output value.
 .T        Transpose, skipping empty values. This puts all first characters into
           a list, then all second, etc.
s          Concatenate.

Pythには新しいJになるためのすべてがあります。すごいです
-shabunc

3
@shabunc新しいJを見たい場合は、github.com
DennisMitchell / jellyを

13

ゼリー、3バイト

ĠZị

オンラインでお試しください!

使い方

ああ、この挑戦​​はゼリーのためだけに作られました。

グループ原子(Ġ)配列を受け取り1配列の同一要素に対応する入力およびグループインデックスなどを。インデックスグループの配列は、対応する要素をキーとしてソートされます。これは、まさにこの課題に必要な順序です。

次に、zipアトム(Z)は、生成された(不規則な)インデックスの行列の行と列を入れ替えます。これは、単純にマトリックスの列を読み取ることで構成され、その列に存在しない要素をスキップします。その結果、最も低いコードポイントを持つ文字の最初のインデックス、次に2番目に低いコードポイントを持つ文字の最初のインデックス、…、次に最も低いコードポイントを持つ文字の2番目のインデックスなどが取得されます。

最後に、インデックス解除アトム()は、生成された順序ですべてのインデックスで入力配列の要素を取得します。結果は2Dの文字配列になり、Jellyはそれを印刷する前に平坦化します。


1 Jellyには文字列型はなく、文字の配列のみがあります。


「ああ、この挑戦​​はゼリーのためだけに作られたものです。」- > 3バイトの答え
geisterfurz007停止この混乱

私が言ったように、ほとんどゼリーのために作られました。:)
デニス

10

Python 3、109 105 104 103 99 93 90 88 81 79 69バイト

FlipTackのおかげで2バイト節約

flornquakeがダムエラーをキャッチしたため、7バイトが節約されました

xnorのおかげで2バイト節約

デニスのおかげで10バイト節約

a=[*input()]
while a:
    for c in sorted({*a}):print(end=c);a.remove(c)

説明

スプラットを使用して文字列をリストに変換し、そのリストを変数に格納することから始めますa。次にa、空のリストではないがa、ソートされた順序での各一意のメンバーを調べ、それを印刷して、リストからその文字のコピーを削除します。

したがって、各反復印刷は、に存在する各文字のコピーを1つ印刷しaます。


1
@StewieGriffin setはソートされていないセットです。
FlipTack

2
@StewieGriffinを印刷すると、それらはASCII値ではなく正確にソートされます。よく見かけますが、ある種のハッシュでソートされていると思います。
小麦ウィザード

1
あなたは作ることができf、文字列の代わりのリストは、数バイトを保存します。
flornquake

1
服用する場合a=list(input())、あなたは行うことができますa.remove(c)、これは純節約です。
-xnor

1
Python 3に切り替えると、多くのバイトを節約できます。tio.run/nexus/…-
デニス

6

Haskell、44バイト

import Data.List
concat.transpose.group.sort

使用例:

Prelude Data.List> concat.transpose.group.sort $ "If you sort a string you'll typically get something like:"
" ':Iacefghiklmnoprstuy aegilnorstuy egilosty iloty lt    "

並べ替え、等しい文字を文字列のリストにグループ化し(例"aabbc"-> ["aa","bb","c"])、再度転置して単一の文字列にフラット化します。


6

Python 2、75バイト

lambda s:`zip(*sorted((s[:i].count(c),c)for i,c in enumerate(s)))[1]`[2::5]

オンラインでお試しください!


1
有効かどうかはわかりませんがlambda s:`[sorted((1e9+s[:i].count(c),c)for i,c in enumerate(s))]`[18::21]、最大長の文字列には有効です9e9
xnor

@xnorをドロップして[]に変更18する17と、2バイト節約できます。 lambda s:`sorted((1e9+s[:i].count(c),c)for i,c in enumerate(s))`[17::21]
小麦ウィザード

@xnor少なくとも、これは有効な32ビットPythonゴルフでなければなりません。をzip削除しようとしましたが、追加1e9が私に起こったことはないと思います...ありがとう!
デニス

@WheatWizard良い目。ありがとう!
デニス

文字列にバックスラッシュが含まれている場合、これは失敗します。
リン

4

Dyalog APL、21文字= 39 バイト

t[0~⍨∊⍉(⊢⌸t)[⍋∪t←⍞;]]

t[... ] インデックスt(まもなく定義される)with ...

0~⍨ から削除されたゼロ

 入隊した(平坦化された)

 転置された

(⊢⌸t)[... ;] keyed * t、行インデックス付き...

   ソートするインデックス

   のユニークな文字

  t←tの値を持つ

   プロンプトテキスト入力

TryAPLオンライン!


⊢⌸t行(長方形のテーブルの場合はゼロで埋められます)がtの各一意の文字のインデックスをリストするテーブルを作成します。


1
どのグリフがより高価ですか?
レン

1
@wptreanorを使用すると、文字ごとに1バイトではなく、全体がUTF-8になります。
アダム

4

C、109 106 105 104 102 100 97 98 96 91のバイト

98バイトまでバックアップ、f(n)を再利用可能にするためにjを初期化するために必要

strlenの代わりにputsを使用して最小96バイトB-)

strlenに戻らなければならなかったのは奇妙ですが、for(; i ++;)ループを取り除いたので、今では91バイトになりました。どうやら、putsのmanページは読みます。

"RETURNS
   If successful, the result is a nonnegative integer; otherwise, the result is `EOF'."

...そもそも働いていたのは幸運だった

char*c,i,j;f(m){for(j=strlen(m);j;++i)for(c=m;*c;c++)if(*c==i){*c=7,putchar(i),j--;break;}}

テストコード...

main(c,v)char**v;
{
    char test[] = "If you sort a string you'll typically get something like: ";
    char test2[] = "Hello, World!";

    f(test);puts("");    
    f(test2);puts("");    
}

ここにいくつかのテストケースがあります、今はこれをゴルフする時間です

C:\eng\golf>a.exe
 ':Iacefghiklmnoprstuy aegilnorstuy egilosty iloty lt
 !,HWdelorlo

最初のテストケースで末尾のスペースが残っていますか?
スティーヴィーグリフィン

最初のテストケースには3つの末尾スペースがあります...これは、入力文字列に末尾スペースを含めなかったためです
;

4

Mathematica、68 60 59バイト

Split[Characters@#~SortBy~ToCharacterCode]~Flatten~{2}<>""&

文字列を受け入れます。文字列を出力します。

文字のリストが許可された場合(46バイト):

Split[#~SortBy~ToCharacterCode]~Flatten~{2,1}&

使用するバージョンSort(40バイト):

Split@Sort@Characters@#~Flatten~{2}<>""&

Sortここでは使用できないため、このバージョンは私の答えにはなりません。Sort文字コードではなく、正規の順序で並べ替えます。


私は数学を知らないので、これで十分かもしれませんが、このコメントを読みましたか?
スティーヴィーグリフィン

@StewieGriffin Welp、いや。私はそれを修正できますが、それは文字列とChar []の区別がない言語に不公平な利点を与えませんか?関連メタディスカッション
ジョンファンミン

いい視点ね。修正しました。元のコメントを参照してください。公平?これがあなたの答えを有効にするかどうかはわかりません。
スティーヴィーグリフィン

@StewieGriffin Mathematicaは文字と文字列を区別しません。Charactersコマンドでも、長さ1の文字列のリストを技術的に出力します。
ジョンファンミン

1
@StewieGriffin これも関連があると思います。私はそれが文字列など、長さ1つの文字列のリスト、文字の配列、バイトの配列が、それも、あらゆる合理的な形式の入力を可能にし、より良いことだと思う
ngenisis

3

Python 2、77 76バイト

d={}
def f(c):d[c]=r=d.get(c,c),;return r
print`sorted(input(),key=f)`[2::5]

stdinからの入力として引用符付き文字列を受け取ります。

オンラインでお試しください!


関数は再利用可能でなければならないため、これは許可されていないと思います。それをプログラムにすることもできます。
-xnor

私はこのメソッドが本当に好きで、変化する関数でソートします。タプルのネストも巧妙です。
xnor

@xnorありがとう、修正。
flornquake

3

JavaScript(ES6)、79バイト

f=s=>s&&(a=[...new Set(s)]).sort().join``+f(a.reduce((s,e)=>s.replace(e,``),s))
<input oninput=o.textContent=f(this.value)><pre id=o>

一意の文字セットを抽出し、並べ替え、元の文字列から削除し、残りの文字列の並べ替えを再帰的に計算することにより機能します。私が面白いと思った81バイトのソリューション:

f=s=>s&&(s=[...s].sort().join``).replace(r=/(.)(\1*)/g,"$1")+f(s.replace(r,"$2"))

3

J, 16 15 bytes

/:+/@(={:)\;"0]

This is a verb that takes and returns one string. Try it online!

Miles saved a byte, thanks!

Explanation

Nothing too fancy here: sort primarily by order of occurrence, secondarily by char value.

/:+/@(={:)\;"0]  Input is y.
          \      Map over prefixes:
  +/              Sum
    @(   )        of
      =           bit-array of equality
       {:         with last element.
                 This gives an array of integers whose i'th element is k
                 if index i is the k'th occurrence of y[i].
           ;     Pair this array
            "0   element-wise
              ]  with y
/:               and sort y using it as key.

I think you can save a byte moving summation to the outside of the parentheses `+/@(={:)`
miles

@Miles Oh yeah, because a train has infinite rank. Nice, thanks!
Zgarb

3

Mathematica, 55 bytes, non-competing

(Sort@Characters@#//.{a___,b_,b_,c___}:>{a,b,c,b})<>""&

Edit: Unfortunately, Mathematica's sort is not by character codes, but by alphabetical order, where uppercase immediatly follows lowercase (ie Hi There is sorted to { , e, e, h, H, i, r, T}).

This works using patterns:

//.{a___,b_,b_,c___}:>{a,b,c,b}
    a___       c___              (Three _) a zero or more members, named a and c
         b_,b_                   exactly one member, repeated twice (since they have the same name)
                    :>           Delayed Rule (replace left hand side with right hand side.)
                                 Delayed Rule evaluate on each substitution, avoiding conflicts with predefined variables
                      {a,b,c,b}  put one of the b-named member after all other sequences
//.                              repeat until no change (aka Replace Repeated)

1
One minor thing: Rule (->) should be RuleDelayed (:>) (no change in byte count) because both sides of Rule has variables. Rule can cause conflicts with pre-existing definitions. For instance: a=3;5/.{a_->a} returns 3, not 5. (a_->a evaluates to a_->3 -- if you use a_:>a, it stays that way and a=3;5/.{a_:>a} returns 5).
JungHwan Min

I marked your answer non-competing because it does not do what the question specifies (sort by character code, not in canonical order).
JungHwan Min

@JungHwanMin fixed to RuleDelayed. thanks.
spacemit

2

Brainf*ck, 458 226 bytes

,[>>>>>>,]<<<<<<[[-<<<+<<<]>>>[>>>[>>>>>>]<<<[>>--[<->--]<-<[>->+<[>]>[<+>-]<<[<]>-]>>.[[-]<]<<<[[>>>>>>+<<<<<<-]<<<]>>>>>>]>>>[>>>[>>>>>>]<<<[>>--[<->--]<-<[>->+<[>]>[<+>-]<<[<]>-]>>[-<+<+>>]<[->>+<<]<[<<<<<<]>>>]>>>]]<<<<<<]

Try it online! - BF

Numberwang, 262 226 bytes

8400000087111111442111911170004000400000071114002241202271214020914070419027114170270034427171114400000091111112711170000007000400040000007111400224120227121402091407041902711417027004219190071420091171411111170007000771111117

Try it online! - NW

I put both of these here because they are identical code.


2

PHP, 83 bytes

for($s=count_chars($argv[1]);$s=array_filter($s);$c%=128)echo$s[++$c]--?chr($c):'';

Unfortunately you can't have unset in a ternary so I need to use the annoyingly long array_filter.
Use like:

php -r "for($s=count_chars($argv[1]);$s=array_filter($s);$c%=128)echo$s[++$c]--?chr($c):'';" "If you sort a string you'll typically get something like:"

2

Python 2, 70 bytes

f=lambda s,i=0,c='':s[i>>7:]and(s.count(c)>i>>7)*c+f(s,i+1,chr(i%128))

Try it online

This is very inefficient. The test link changes the i>>7 to i>>5 and sets the recursion limit to 10000. Assumes the inputs only has ASCII values up to 126.

Uses the div-mod trick to iterate through two loops: minimum counts i/128 in the outer loop and ASCII values i%128 in the inner loop. Includes a character c with the given ASCII value if the number of times it appears in the string is at least its minimum count.

The code uses a trick to simulate the assignment c=chr(i%128) so that it can be referenced in the expression (s.count(c)>i>>7)*c. Python lambdas do not allow assignment because they only take expressions. Converting to a def or full program is still a net loss here.

Instead, the function pushes forward the value chr(i%128) to the next recursive call as an optional input. This is off by one because i has been incremented, but doesn't matter as long as the string doesn't contain special character '\x7f' (we could also raise 128 to 256). The initial c='' is harmless.


2

V, 37 36 bytes

Thanks @DJMcMayhem for the byte!

Í./&ò
dd:sor
Íî
òͨ.©¨±«©±À!¨.«©/±³²

Try it online!

Not sure I like the regex at the end, but I needed to make the ò break somehow.

Explain

Í./&ò                    #All chars on their own line
dd:sor                   #Delete empty line, sort chars
Íî                       #Join all lines together s/\n//
òͨ.©¨±«©±À!¨.«©/±³² #until breaking s/\v(.)(\1+)\1@!(.+)/\3\2\1

Íî (or :%s/\n//g) is shorter than VGgJ
DJMcMayhem

1

Perl 6, 68 bytes

{my \a=.comb.sort;[~] flat roundrobin |a.squish.map({grep *eq$_,a})}

I was a little surprised to find that there's no built-in way to group like elements in a list. That's what the squish-map bit does.


1
I get "This Seq has already been iterated" unless I rename a to @a (+2 bytes). Also, grep *eq$_, can be written grep $_, (-3 bytes) since a string is a valid smart-matcher.
smls

1
{[~] flat roundrobin |.comb.classify(~*){*}.sort»[*]} -- This variation is only 54 bytes.
smls

@smis I don't see that error. Maybe we're using different versions? I'm on rakudo-star-2016.10. Anyway, your solution puts mine to shame, you should post it as a separate answer.
Sean

I'm using a bleeding-edge Rakudo compiled from the main branch of the git repo this week. Anyway, I posted the classify-based solution as a separate answer now.
smls

1

JavaScript (ES6), 77 75 bytes

s=>(a=[],x={},[...s].sort().map(c=>a[x[c]=n=-~x[c]]=(a[n]||'')+c),a).join``

Stable sorts the lexicographically sorted string by nth occurence

F=s=>(a=[],x={},[...s].sort().map(c=>a[x[c]=n=-~x[c]]=(a[n]||'')+c),a).join``

const update = () => {
  console.clear();
  console.log(F(input.value));
};
input.oninput = update;
update();
#input {
  width: 100%;
  box-sizing: border-box;
}
<input id="input" type="text" value="         ':Iaaceeefggghiiiiklllllmnnooooprrssstttttuuyyyy" length=99/>
<div id="output"></div>


1+~~ is the same as -~.
Neil

@Neil Awesome thanks -2 bytes
George Reith

1

Perl 6, 54 bytes

{[~] flat roundrobin |.comb.classify(~*){*}.sort»[*]}

Explanation:

  • { }: A lambda that takes one argument -- e.g. 21211.
  • .comb: Split the input argument into a list of characters -- e.g. (2,1,2,1,1).
  • .classify(~*): Group the characters using string comparison as the grouping condition, returning an unordered Hash -- e.g. { 2=>[2,2], 1=>[1,1,1] }.
  • {*}: Return a list of all values of the Hash -- e.g. [2,2], [1,1,1].
  • .sort: Sort it -- e.g. [1,1,1], [2,2].
  • »[*]: Strip the item containers the arrays were wrapped in due to being in the hash, so that they won't be considered as a single item in the following step -- e.g. (1,1,1), (2,2).
  • roundrobin |: Zip the sub-lists until all are exhausted -- e.g. (1,2), (1,2), (1).
  • flat: Flatten the result -- e.g. 1, 2, 1, 2, 1.
  • [~]: Concatenate it to get a string again -- e.g. 12121.

(Credit for the roundrobin approach goes to Sean's answer.)


1

05AB1E, 15 bytes

{.¡"ä"©¹g׫øJ®K

Try it online! or as a Test suite

Explanation

{                # sort input
 .¡              # group by equal elements
   "ä"©          # push "ä" and store a copy in the register
       ¹g×       # repeat the "ä" input-nr times
          «      # concatenate the result to each string in the grouped input
           ø     # zip
            J    # join to string
             ®K  # remove all instances of "ä" in the string

10 of the 15 bytes are for getting around 05AB1E's way of handling zipping strings of different length.


1

FSharp, 194 190 170 140 133 bytes

let f=Seq.map
let(@)=(>>)
f int@Seq.groupBy id@f(snd@Seq.mapi((*)128@(+)))@Seq.concat@Seq.sort@f((%)@(|>)128@byte)@Array.ofSeq@f char

Using Seq instead of Array saves a couple of bytes

Defining a shorter name, and using another maps to avoid a (fun ->) block

It turns out F# can map a char to an in, so removing the shortened name of System.Text.Encoding.ASCII, and adding in another map saves me 20 bytes!

Returning a char array instead of a string, saves me 30 bytes!

I no longer need to make sure it's a string, saves me 7 bytes


0

JavaScript (ES6), 114 bytes

Separated with newline for clarity, not part of byte count:

s=>[...s].map(a=>(m[a]=-~m[a])*128+a.charCodeAt(),m={})
.sort((a,b)=>a-b).map(a=>String.fromCharCode(a%128)).join``

Demo

`**Test cases:**
 *:Tacest*es*s*

If you sort a string you'll typically get something like:
 ':Iacefghiklmnoprstuy aegilnorstuy egilosty iloty lt    

Hello, World!
 !,HWdelorlol

#MATLAB, 114 bytes
 #,14ABLMTbesty 1A

f=@(s)[mod(sort(cell2mat(cellfun(@(c)c+128*(0:nnz(c)-1),mat2cell(sort(s),1,histc(s,unique(s))),'un',0))),128),''];
'()*+,-0128:;=@[]acdefhilmnoqrstuz'(),0128@acefilmnorstu'(),12celmnostu'(),12celnstu(),clnst(),cls(),cs(),()()()()`.split`\n\n`.map(s=>(p=s.split`\n`,console.log(`${p[0]}\n\n${r=f(p[0])}\n\nmatch: ${r==p[1]}`)),
f=s=>[...s].map(a=>(m[a]=-~m[a])*128+a.charCodeAt(),m={}).sort((a,b)=>a-b).map(a=>String.fromCharCode(a%128)).join``)


The same bytecount as my Matlab code, and the exact same approach. Haven't attempted to golf mine yet though. I'll probably upvote later if you add an explanation :-) (I've made a principle out of not upvoting answers without explanations, even when I understand it) :-)
Stewie Griffin

0

Clojure, 79 bytes

#(for[V[(group-by(fn[s]s)%)]i(range 1e9)k(sort(keys V))c[(get(V k)i)]:when c]c)

An anonymous function, returns a sequence of characters. Supports up-to 10^9 repetitions of any characters, which should be plenty.



0

Ruby, 59+1 = 60 bytes

Adds one byte for the -n flag. Port of @PatrickRoberts' dictionary solution.

d={};print *$_.chars.sort_by{|c|d[c]||=0;c.ord+128*d[c]+=1}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.