按数字对描述的内容排序


17

给定一个正整数,我们可以形成一个新的数字,该数字由成对的数字描述(对于带有奇数数字的数字,添加前导0)。

例如:

  • 1234可以读为1 2、3 4s-因此,1234的输出为2444。

  • 643的位数为奇数,因此添加前导零使其成为偶数。然后,将0643读取为:零6s,四个3s,因此输出为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,因此可以对它们进行排序。任意顺序。)

(相关:说出您所看到的一1,二1,一2一1

感谢Kevin Cruijssen在沙盒中阐明问题的帮助。


2
我们可以将数字列表作为输入吗?我们可以输出数字列表吗?
Xcoder先生18年

@ Mr.Xcoder输入应为整数列表,而不是数字列表。但是,输出可以是数字列表,如果这样更方便的话。
sundar-恢复莫妮卡

正如@mnel指出的那样,我的答案不适用于10位以上的数字。保持原样是合法的,还是我应该以32字节为代价对其进行修改。
JayCe

@JayCe如果我理解正确,那么限制是因为那是R中整数类型的限制-因为strtoi返回了整数-正确吗?如果是这样,那很好,它是合法的。
sundar-恢复莫妮卡

你是对的!会保持原样。
JayCe

Answers:


5

APL(Dyalog),26字节

感谢ngn保存1个字节:)

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

在线尝试!

来自dzaima&ngn的灵感


100⊥⍣¯1⊢⍵-> ⍵⊤⍨⍵/100适用于
26。– jslip

我真的不希望在给定的测试用例上使用
WSFULLs

图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

呵呵,我真的很嫉妒我的单字母变量名称!不,是认真的...每当我发布一个“类似的”替代方案时,它都来自StackOverflow,感觉就像是在偷东西;)
digEmAll

strtoi将返回NA为整数上述10个数字,(as.numeric不会)
MNEL

@mnel感谢您指出!我用sundar进行了检查,由于它是整数类型的限制,我可以将其保留为:)
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))))]

在线尝试!

  • -11个字节感谢@sundar的“算术”建议!

没有说明的代码:

# 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字节的版本:TIO
sundar – Reinstate Monica,

@sundar:我没想到算术方法...我节省了11个字节,谢谢!
digEmAll

2

Pyth,14个字节

oir9c.[Z2jNT2T

在这里尝试!| 测试套件!| 12个字节,带数字I / O列表

怎么运行的?

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提升到其数字数组并反转。| [5,2,7]
 ẋƝ对于x,y的每两个连续数字,重复xy次。| [[5,5],[2、2、2、2、2、2、2]]
   m2模块化2。采用此数组的所有其他元素。| [[5,5]]
     Ṛ反转。| [[5,5]]
      F展平。| [5、5]
       from从十进制转换为整数。| 55

绝对是巧合:2537并且3725不代表相同的数字。
暴民埃里克(Erik the Outgolfer)'18年

您能给我一个测试用例来解决这个问题,我将其添加到问题中吗?
sundar-恢复莫妮卡

@sundar如Erik所说,[2537, 3725]。我从不怀疑这是一个巧合,因此我在回答中
加上了

@ Mr.Xcoder测试用例已添加,谢谢。
sundar-恢复莫妮卡

2

Perl 6、53字节

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

在线尝试!

匿名的lambda,它接受值列表并按数字对的描述对其进行排序。

在这种情况下,我将数字反转,然后rotor将列表加2以获取每对数字。对于奇数长度的数字,这将排除第一位数字,但是由于这可以转换0为该数字的倍数,因此可以。另外,它会排列值以[x]正确使用。



2

Haskell89 88字节

多亏了OVS,节省了一个字节

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]

核心功能由infix运算符提供,该运算符(?)跟踪乘数m以及其余的RLE输入n(?)连续从中减去10,n同时还有一个十进制数字要从中减去,这样做,它将最后一个数字的另一个副本推到输出的前面(通过乘数m,每次增加10)。当十位数用完时,最后两位数字将被丢弃,并且过程将重复进行直到数字减少为0。最后,我们将运算符(初始乘数为1)用作排序键。


1
m?n|n<1=0|n%100<10=m?div n 100|w<-n-10=m*10?w+m*n%10短一个字节。
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由于奶牛嘎嘎
-4(加上-4为基础转换想法)由于NGN
-2感谢这么H.PWiz


⊃,/可以成为
Kritixi Lithos

@Cowsquack我知道我忘记了内置的:p
dzaima

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

@ngn当然,我永远都不记得所有的
记号

这里的另一个伎俩-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是该数组的长度。

第二个测试用例给出错误的结果,因为转换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()由于字符串和与之相关的函数,您的函数之所以长,您可以通过读取最后两位数字并像这样构建输出来节省许多字节: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);}您还将通过避免声明和初始化chars来节省字节。
安约

好主意-我认为处理整数值使此方法完全不同,因此您应该考虑发布答案?:)
Felix Palmen '18

建议b-~sprintf(b+1,"%d",x)%2不要使用b+!(sprintf(b+1,"%d",x)&1)
ceilingcat '18

@Annyo建议x/10%10而不是x%100/10
ceilingcat '18


1

Brachylog,18个字节

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

在线尝试!

说明

需要考虑三种不同情况的小东西负载:奇数个数字,零个数字对和正常对。

{               }ᵒ     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不必要,实际上使它排序有误:等效于用1而不是0进行填充,因此给定[125,26,1],将其排序为[1、26、125]而不是[1] ,125,26]。
sundar-恢复莫妮卡

1

Perl 5 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个字节。说明:

%)`

分别在每行上应用前两个阶段。

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

匹配并复制偶数个尾数。

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

将每个数字对替换为其描述值。将\G\d导致在空间的匹配停止。

N`

按数字排序。

.+ 

删除排序键。


按键排序是一个聪明的窍门。好一个
sundar-恢复莫妮卡

1

05AB1E20 19 字节

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

错误修正为1字节,然后通过golfed -2字节由于@sundar

在线尝试验证所有测试用例

绝对可以打高尔夫球..对此不太高兴。

说明:

Σ                    # 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);}

将一个Longs列表作为参数并对该输入列表进行排序(不返回新列表)。

在线尝试(注意:String.repeat(int)仿真是repeat(String,int)因为Java 11尚未在TIO上。字节数保持不变。)

说明:

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-恢复莫妮卡(Monica)

@sundar Ah,错过了该要求;我的不好。幸运的是+"",将其添加到2x 即可将数字转换为String,这是一个简单的解决方法。现在应该修复。:)
Kevin Cruijssen

1
真好 我没想到Java会那样。:)
sundar-恢复莫妮卡
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.