数字のペアの説明で並べ替える


17

正の整数を指定すると、ペアで取得した数字で記述される新しい数字を作成できます(数字の奇数の場合は、先頭に0を追加します)。

例えば:

  • 1234は1つ、2つ、3つの4として読み取ることができます。したがって、1234の出力は2444です。

  • 643の桁数は奇数なので、先頭にゼロを追加して偶数にします。この場合、0643は次のように読み取ることができます:ゼロ6秒、4つの3秒。したがって、出力は3333になります。

(これはOEIS A056967です)。

タスク:正の整数の配列が与えられた場合、数字ペアで記述された値で昇順に並べ替えます。同じ値につながる入力番号の間で順序は関係ありません。

入力:正の整数の配列/リスト/セット。入力の先頭のゼロ許可され、文字列/数字のリストなどとして入力されます。許可されていません-入力は、言語が使用できる限り整数/数値型に近いものでなければなりません。

出力:上記の方法でソートされた配列で、通常の方法(関数の戻り値/ STDOUT / voidへの叫びなど)で返されます。それらを個別に印刷し、数値、文字列、またはリストとして返すことができます。桁。

テストケース

Input 
Output

[19, 91, 2345, 2023]
[19, 2023, 2345, 91]

[25257, 725, 91, 5219, 146125, 14620512]
[725, 5219, 14620512, 91, 146125, 25257]

[123130415 3335 91 111111111 528 88]
[528, 111111111, 123130415, 3335, 88, 91]

[1 21 33 4 5]
[1 4 5 21 33]

[3725, 10, 2537, 1, 1225, 2512]
[10, 1, 1225, 2512, 2537, 3725]

[125, 26, 1115, 1024] 
[1115, 1024, 125, 26]

(4番目のテストケースでは、1、4、5はすべて0に評価されるため、任意の順序で相互に並べ替えることができます。同様に、5番目のテストケースでは、10と1の両方が0に評価されるため、いずれかの順序。)

(関連:表示内容を言うOne 1、Two 1's、One 2 One 1

サンドボックス内の質問を明確にする手助けをしてくれたKevin Cruijssenに感謝します。


2
入力として数字のリストのリストを使用できますか?数字のリストのリストを出力できますか?
Mr Xcoder

@ Mr.Xcoder入力は、数字のリストではなく、整数のリストである必要があります。ただし、出力が数字のリストのリストである場合があります(それが何らかの形で便利な場合)。
スンダ

@mnelが指摘したように、私の答えは10桁以上の数字では機能しません。そのままにしておくのは合法ですか、それとも32バイトのコストで変更する必要がありますか。
JayCe

@JayCe私が正しく理解している場合、制限はRの整数型の制限であるstrtoiためです-整数を返すため-正しいですか?もしそうなら、それは問題ありません、それはそのまま合法です。
スンダ

あなたは正しいです!そのままにしておきます。
JayCe

回答:


5

APL(Dyalog)、26バイト

1バイトを保存してくれたngnに感謝:)

{⍵[⍋⌽↑,⍨⌿⍴⌿0 10⊤⍵⊤⍨⍴⍨100]}

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

Dzaima&NGNからのインスピレーション


100⊥⍣¯1⊢⍵-> ⍵⊤⍨⍵/10026で動作します。
jslip

私は実際に与えられたテストケースのWSFULLsたくない
H.PWiz

26はMAXWS = 1Mで可能である
NGN

100⊥⍣¯1⊢⍵->⍵⊤⍨⍴⍨100
ngn

1
@ H.PWizとここに26バイトの異なるソリューションがあります{⍵[⍋⌽↑,⍨⌿⍴⌿⊃⊥⍣¯1/10 100⍵]}
。– ngn

3

R、141バイト

(s<-scan(,""))[order(strtoi(sapply(s,function(x)paste(strrep((m=matrix(c(if(nchar(x)%%2)0,el(strsplit(x,""))),2))[2,],m[1,]),collapse=""))))]

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

むしろ面倒な答え-しかし、それはすべてのテストケースで動作します。桁ペア出力を構築し、これに従って入力をソートします。


今日の午後に取り組んでいたので、別の回答にアプローチを投稿しましたが、中断されました。クレジットなしで私はあなたからインスピレーションを得なかったことを保証するために;)
digEmAll

@digEmAll心配なし:)-実際、私vはあなたの他の答えから変数の名前をとったと思います-私はv前に使用したことがありません。そして素敵な使用 intToUtf8
JayCe

ああ、私は本当に1文字の変数名にreallyしています!いいえ、真剣に...盗むように感じる「類似の」代替を投稿する
たびに

strtoiは10桁を超える整数に対してNAを返します(as.numericはそうではありません)
-mnel

@mnel指摘してくれてありがとう!私はスンダで確認しましたが、整数型の制限のため、そのままにしておくことができます:)
JayCe

3

R、120バイト

(v=scan())[order(sapply(v,function(n,e=nchar(n))sum((a=rep((x=n%/%10^(0:(e-1-e%%2))%%10)[!0:1],x[!1:0]))*10^seq(a=a))))]

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

  • @sundarの「算術」提案のおかげで-11バイト!

説明のないゴルフされていないコード:

# define a function G which takes a number 'n' and uncompress it multiplied by 10
# e.g. 2735 -> 775550, 61345 -> 355550 etc.
G=function(n){
  e = nchar(n)                   # get the n.of digits in the compressed number

  x = n%/%10^(0:(e-1-e%%2))%%10  # split 'n' into vector of digits reversed adding 
                                 # trailing zero if 'e' is odd (e.g. 123 -> c(0,3,2,1))

  even = x[!0:1]                 # take only the odd elements of 'x' (= even digits)
  odd  = x[!1:0]                 # take only the even elements of 'x' (= odd digits)
                                 # N.B. :
                                 # these tricks work because !0:1 is c(TRUE,FALSE)
                                 # and V[c(TRUE,FALSE)] exploits the fact that R 
                                 # automatically recycles the logical indexes up to the
                                 # length of the vector V

  a = rep(even,odd)              # repeat each value in 'even' 'odd' times obtaining the
                                 # uncompressed number as digits vector. Note that in
                                 #  case of single digit 'n', 'a' will be an empty vector

  sum(a*10^seq(a=a))             # multiplies 'a' * 10^(1:length(a)) and sum 
                                 # obtaining the uncompressed number multiplied by 10
                                 # N.B. in case of empty 'a', we get 0
}

v = scan()                       # take vector v from stdin

w = sapply(v,G(n))               # apply G to all numbers of 'v'

v[order(w)]                      # use the uncompressed values as weights to sort 'v'

[!1:0]前にそれを見たことがない-トリックが本当いいです。
JayCe

@sundar:説明を追加;)
digEmAll

1
いいね 私はそれらの[!1:0]フェラーがきちんとした何かを隠しているのを知っていました。私はこれとRゴルフのヒントで遊んで、数字から数字を算術的に取得しようとしas.doubleましたが、132バイトのバージョンを
思いつきました

@sundar:算術的アプローチを考えていませんでした... 11バイト節約しました、ありがとう!
digEmAll

2

Pyth、14バイト

oir9c.[Z2jNT2T

ここで試してみてください!| テストスイート!| 数字のリストI / Oを含む12バイト

使い方?

oir9c.[Z2jNT2T – Full program.
o              – Sort the input list by the results of the following code (variable: N).
         jNT   – Cast the current element to a list of digits.
     .[Z2      – Pad it on the left with 0s to the nearest multiple of 2.
    c       2  – Split in pieces of length 2.
  r9           – Run length decode.
 i           T – Cast the list of digits to a base 10 integer.

2

ゼリー、10バイト

ṚẋƝm2ṚFḌµÞ

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

テストスイートをチェックしてください!

使い方

ṚẋƝm2ṚFḌµÞモナドリンク/フルプログラム。| 例:[25257、725、91、5219、146125、14620512]
        µÞ入力リストをモナドリンクの結果でソートします。例:725
N Nを数字配列に昇格させ、逆にします。| [5、2、7]
 consecutive連続する2つの数字x、yごとに、xy回繰り返します。| [[5、5]、[2、2、2、2、2、2、2、2]]
   m2 Modular2。この配列の他のすべての要素を取得します。| [[5、5]]
     Ṛ逆。| [[5、5]]
      Fフラット化。| [5、5]
       decimal 10進数から整数に変換します。| 55

それは間違いなく偶然です。同じ数字を表さない25373725ください。
エリックアウトゴルファー

それをキャッチするテストケースを教えてください。質問に追加しますか。
スンダ

@sundarとしてエリックは、言いました[2537, 3725]。私は、それゆえ私は答えにそのノート含まれ、これは偶然の一致であることを疑ったことはありません
氏Xcoder

@ Mr.Xcoderテストケースが追加されました、ありがとう。
スンダ

2

Perl 6、53バイト

*.sort(+*.flip.comb.rotor(2).map({[x] $_}).join.flip)

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

値のリストを取得し、数値のペアが示すものでソートする匿名のWhateverラムダ。

この場合、数値を逆にしてrotorから、リストを2つずつ呼び出して、数値の各ペアを取得しています。これは、奇数の長さの数字の最初の数字を除外しますが、それはその数字の倍数に変換されるので、0大丈夫です。さらに、[x]正しく使用するために値を並べます。



2

Haskell89 88バイト

ovsのおかげで1バイト節約

import Data.List
(%)=mod
m?n|n<1=0|n%100<10=m?div n 100|w<-n-10=m*10?w+m*n%10
sortOn(1?)

最後の行は、次のように使用できる匿名関数を定義しています。

> sortOn(1?)[19, 91, 2345, 2023]
[19,2023,2345,91]

コア機能は(?)、乗数m、および残りのRLE入力を追跡する中置演算子によって提供されますn(?)減算する10 n桁がある間、10を継続的に減算します。これにより、最終桁の別のコピーを出力の前にプッシュします(乗算器を介して、m毎回10ずつ増加します)。10の位がなくなると、最後の2桁が破棄され、数が0に減るまでプロセスが繰り返されます。最後に、演算子(最初の乗数は1)をソートキーとして使用します。


1
m?n|n<1=0|n%100<10=m?div n 100|w<-n-10=m*10?w+m*n%101バイト短いです。
ovs

2

、10バイト

ÖödṁΓ*C_2d

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

説明

ÖödṁΓ*C_2d    Full function
Ö             Sort the input list by the result of...
 ö            The composition of these four functions:
         d      Convert to a list of digits
      C_2       Split into length-2 sublists starting at the end
   ṁ            Map the following function and concatenate the results:
    Γ*            Repeat the list tail X times, where X is the list head
  d             Convert back to an integer

2

Dyalog APL、41 39 36 35 31 30 29バイト

f←⊂⌷¨⍨∘⍋{10⊥∊⍴⌿0 10100⊥⍣¯1⊢⍵}¨

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

-2 Cows quack
-4に感謝(ベース変換のアイディアに-4を追加)ngnに
感謝-2ありがとう、H.PWiz


⊃,/になることができます
Kritixi Lithos

@Cowsquack私は組み込みを忘れていたことを知っていた:p
dzaima

{⍺⍴⍨⍎⍵}->⍴⍨∘⍎
ngn

もちろん@ngn、私はすべてのJOT /電車の事を覚えていることはできません
dzaima

ここでは-1バイト別のトリックだ- trainify {⍵[⍋F ⍵]}として⊂⌷¨⍨∘⍋F
NGN

2

C(gcc)(32ビットシステム)、188 177 176バイト

char*p,*q,c[99],b[99]="0";i;d(x){for(p=b+!(sprintf(b+1,"%d",x)&1),q=c;i=*p++;++p)for(i-=48;i--;*q++=*p);*q=0;atoi(c);}m(int*a,int*b){return d(*a)-d(*b);}s(l,c){qsort(l,c,4,m);}

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

上のamd64追加フラグを-m32コンパイルするため。

使用法s(x,n);ここでx、ソートする整数の配列を指しn、その配列の長さです。

2番目のテストケースは間違った結果を返し25257ます2222277777。変換すると32ビット整数がオーバーフローするため、その番号のない5番目のテストケースが追加されるためです。

説明:

char*p,                                     // d(): input pointer
    *q,                                     // d(): output pointer
    c[99],                                  // d(): output buffer
    b[99]="0";                              // d(): input buffer
                                            //      (fixed first char 0)
i;                                          // d(): repeat counter

d(x){                                       // conversion function
    for(
            p=b+!(sprintf(b+1,"%d",x)&1),   // print number in decimal to
                                            // input buffer, starting at second
                                            // character, initialize input
                                            // pointer to first or second char
                                            // depending on the length of the
                                            // number
            q=c;                            // initialize output pointer
            i=*p++;                         // set repeat counter to digit and
                                            // point to next digit, stop when
                                            // NUL character is found
            ++p)                            // point to next digit after loop
        for(i-=48;i--;*q++=*p);             // inner loop, append current digit
                                            // i-48 ('0') times to output buffer
    *q=0;                                   // terminate output with NUL
    atoi(c);                                // convert to number, 'return' not
                                            // needed as atoi() leaves result
                                            // on the stack
}

m(int*a,int*b){                             // comparison function for qsort
    return d(*a)-d(*b);                     // return difference of converted
}                                           // values

s(l,c){                                     // sorting function
    qsort(l,c,4,m);                         // only "wrap" qsort, assuming
}                                           // sizeof(int) is 4

あなたの関数は、d()あなただけの最後の2桁の数字を読み、このような出力を構築することにより、多くのバイトを保存することができ、長いので、それらに関連する文字列と機能は次のとおりです。o;u;i;d(x){for(u=1,o=0;x;x/=100)for(i=0;i++<x%100/10;o+=x%10*u,u*=10);x=o;}m(int*a,int*b){u=d(*a)-d(*b);}s(l,c){qsort(l,c,4,m);}あなたの意志も宣言して初期化を回避することでバイトの保存char秒。
杏仁

良いアイデア-整数値で作業すると、これはまったく異なるアプローチになると思うので、答えを投稿することを検討する必要がありますか?:)
フェリックスパルメン

提案b-~sprintf(b+1,"%d",x)%2の代わりにb+!(sprintf(b+1,"%d",x)&1)
ceilingcat

@Annyoのx/10%10代わりに提案するx%100/10
ceilingcat


1

Brachylog、18バイト

{↔ġ₂ẹ{Ċj₎|Ȯt}ˢ↔c}ᵒ

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

説明

3つの異なるケースを考慮するために必要な小さなもののロード:奇数の桁、0倍の数字のペア、および通常のペア。

{               }ᵒ     Order the Input according to the output of this predicate
 ↔                       Reverse the number
  ġ₂                     Group into pairs; the last digit is alone if there are
                           an odd number of them
    ẹ{      }ˢ           For each group:
      Ċ                    If there are two elements
       j₎                  Juxtapose the first one as many times as the second
                             element (won't work if the second element is 0)
         |                 Else
          Ȯ                If there is one element (odd number of digits)
           t               just take that element
                           (Else don't select anything, i.e. 0 repetitions)
              ↔c         Reverse and concatenate back into an integer

これ|Ȯtは不要だと思いますし、実際にはソートが間違っています:0ではなく1でパディングするのと同じです。したがって、[125、26、1]を与えると、[1、ではなく[1、26、125]としてソートされます。 、125、26]。
スンダ

1

Perl 5、76バイト

ワンライナーの代わりの関数。

非常に簡単:g入力を数値順にソートし、数値のh変換に使用します。h正規表現を使用してこれを行いますs/(.)(.)/$2x$1/gre(おそらく十分に読み取り可能です)。そして、0左パディングはで行われる0 x("@_"=~y///c%2)."@_"(ここで、y///c書き込みの短絡方法がされlengthx繰り返し演算子とで.連結)。

sub h{(0 x("@_"=~y///c%2)."@_")=~s/(.)(.)/$2x$1/gre}sub g{sort{h($a)-h$b}@_}

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

ただし、Perlの短い回答がいくつか期待されています!


1

網膜、44バイト

^.?((..)*)$
$1 $&
%)`\G(\d)(.)
$1*$2
N`
.+ 

オンラインでお試しください!行の先頭でソートキーを生成するのは難しくなりますが、短いソート段階では全体で3バイトの節約になります。説明:

%)`

各行に最初の2つのステージを個別に適用します。

^.?((..)*)$
$1 $&

偶数の末尾の数字を照合してコピーします。

\G(\d)(.)
$1*$2

各桁のペアを説明されている値に置き換えます。これ\G\dにより、スペースで一致が停止します。

N`

数値順に並べ替えます。

.+ 

ソートキーを削除します。


これは、キーでソートするための賢いトリックです。良いもの。
スンダ-復活モニカ

1

05AB1E20 19 バイト

ΣDgÉi¦}2ôε`sиJ}J0ìï

+1バイトのバグを修正し、@ sundarのおかげで-2バイトでゴルフができました

オンラインそれを試してみたり、すべてのテストケースを確認してください

間違いなくゴルフをすることができます。

説明:

Σ                    # Sort by:
 Dg                  #  Duplicate the current number, and take it's length
                     #   i.e. 25257 → 5
                     #   i.e. 4 → 1
   Éi }              #  If this length is odd:
     ¦               #   Remove the first digit
                     #    i.e. 25257 → '5257'
                     #    i.e. 4 → ''
       2ô            #  Then split the number in pieces of 2
                     #   i.e. '5257' → ['52','57']
                     #   i.e. '' → []
         ε    }      #  And map each to:
          `          #   Push both digits to the stack
                     #    i.e. '52' → '5' and '2'
           s         #   Swap them
            и        #   Repeat the first digit the second digit amount of times
                     #    i.e. '2' and '5' → ['2','2','2','2','2']
             J       #   Join the list of digits together
                     #    i.e. ['2','2','2','2','2'] → '22222'
               J     #  Join all numbers back together again
                     #   i.e. ['','22222','77777'] → '2222277777'
                     #   i.e. [] → ''
                0ì   #  Prepend a 0 (because `Σ` will put all '' at the back)
                     #   i.e. 2222277777 → '02222277777'
                     #   i.e. '' → '0'
                  ï  #  Cast it to an integer, because sorting is done string-wise by
                     #  default despite 05AB1E's interchangeability of strings and numbers;
                     #  and it's also to remove all leading zeros
                     #   i.e. '02222277777' → 2222277777
                     #   i.e. '0' → 0

1

アタッシュ、50バイト

SortBy!N@Flip##~`&&>PadRight&0&2=>Chop&2@Flip@List

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

説明

SortBy!N@Flip##~`&&>PadRight&0&2=>Chop&2@Flip@List      anonymous function, argument: [a1..aN]
SortBy!                                                 sort the given array by grading f[ai]
                                                        e.g. 42513
                                              List      digits of ai
                                                        e.g. [4, 2, 5, 1, 3]
                                         Flip@          flip the digits around
                                                        e.g. [3, 1, 5, 2, 4]
                                  Chop&2@               chop into groups of 2
                                                        e.g. [[3, 1], [5, 2], [4]]
                    PadRight&0&2=>                      pad each group to size 2 with 0's
                                                        e.g. [[3, 1], [5, 2], [0, 4]]
                  &>                                    using each sub array as arguments...
               ~`&                                      ...repeat the 2nd the 1st amount of times
                                                        e.g. [[1, 1, 1], [2, 2, 2, 2, 2], []]
             ##                                         then:
         Flip                                           reverse the groups
                                                        e.g. [[2, 2, 2, 2, 2], [1, 1, 1]]
       N@                                               then convert it to an number
                                                        e.g. 22222111


1

Japt、13バイト

ñ_ì_ò2n)®rçì

試すかすべてのテストケースを実行してください


説明

ñ_                :Sort by passing each integer through a function
  ì_              :  Split to an array of digits, pass it through the following function and implicitly convert back to an integer
    ò2n)          :    Starting from the end of the array, split at every second element
        ®         :    Map
         rç       :      Reduce X & Y by repeating X Y times
           Ã      :    End mapping
            ¬     :    Join



0

Java 11、204 189バイト

L->{L.sort((a,b)->Long.compare(s(a+""),s(b+"")));}long s(String s){var r="";for(int l=s.length(),i=l%2;i<l;)r+=s.split("")[++i].repeat(s.charAt(i++-1)-48);return r.isEmpty()?0:new Long(r);}

Longのリストをパラメーターとして受け取り、この入力リストを(新しいリストを返さずに)ソートします。

オンラインで試してください(注:Java 11はまだTIO上にないため、String.repeat(int)エミュレートさrepeat(String,int)れます。バイトカウントは同じままです。)

説明:

L->{                     // Method with ArrayList<Long> parameter and no return-type
  L.sort(                //  Sort the list by:
   (a,b)->Long.compare(  //   Using a builtin Long-comparator with:
     s(a+""),s(b+"")));} //   The correctly formatted values as described in the challenge

long s(String s){        // Separated method with String parameter and long return-type
  var r="";              //  Temp-String, starting empty
  for(int l=s.length(),  //  The length of the input-String
      i=l%2;i<l;)        //   If the length is even:
                         //    Loop `i` in the range [0,`l`) (in steps of 2)
                         //   Else (the length is odd):
                         //    Loop `i` in the range [1,`l`) (in steps of 2) instead
    r+=                  //   Append the result-String with:
      s.split("")[++i].  //    The digit at index `i+1`
      .repeat(s.charAt(i++-1)-48);
                         //    Repeated the digit at index `i` amount of times
  return r.isEmpty()?    //  If the temp-String is empty:
          0              //   Return 0
         :               //  Else:
          new Long(r);}  //   Convert the temp-String to a long and return it

こんにちは、チャレンジは文字列の入力を明示的に禁止します、ごめんなさい!(私はJavaでそれを許可したいのですが、他の回答では公平ではないでしょう。)
スンダ-モニカーの復活

@sundar Ah、その要件を逃しました。私の悪い..幸いなことに、2x +""を追加するだけで簡単に数値を文字列に変換できます。今すぐ修正する必要があります。:)
ケビンクルーイッセン

1
いいね 私はJavaからそれを期待していませんでした。:)
スンダ-復活モニカ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.