【问题标题】:Code-Golf: Friendly Number AbbreviatorCode-Golf:友好号码缩写
【发布时间】:2011-02-11 03:34:15
【问题描述】:

基于这个问题:Is there a way to round numbers into a friendly format?

挑战 - 更新! (从规范中删除了数百个缩写)

按字符计数的最短代码,将缩写一个整数(无小数)。

代码应包含完整的程序。

相关范围为0 - 9,223,372,036,854,775,807(有符号64位整数的上限)。

缩写的小数位数为正数。 您不需要计算以下内容:920535 abbreviated -1 place(类似于0.920535M)。

十位和百位 (0-999) 的数字应永远缩写(数字 571+ 小数位的缩写为 5.7dk - 这是不必要的,并且不友好)。

记得从零取整一半(23.5 取整为 24)。银行家的四舍五入是禁止的。

以下是相关的数字缩写:

h = hundred (102)
k = thousand (103)
@987654335 @6)
G = billion (109)
T = trillion (1012@ 987654343@
P = quadrillion (1015)
E = quintillion (1018)

SAMPLE INPUTS/OUTPUTS(输入可以作为单独的参数传递):

第一个参数将是要缩写的整数。第二个是小数位数。

12 1                  => 12 // tens and hundreds places are never rounded
1500 2                => 1.5k
1500 0                => 2k // look, ma! I round UP at .5
0 2                   => 0
1234 0                => 1k
34567 2               => 34.57k
918395 1              => 918.4k
2134124 2             => 2.13M
47475782130 2         => 47.48G
9223372036854775807 3 => 9.223E
// ect...

相关问题的原始答案(JavaScript,不遵循规范):

function abbrNum(number, decPlaces) {
    // 2 decimal places => 100, 3 => 1000, etc
    decPlaces = Math.pow(10,decPlaces);

    // Enumerate number abbreviations
    var abbrev = [ "k", "m", "b", "t" ];

    // Go through the array backwards, so we do the largest first
    for (var i=abbrev.length-1; i>=0; i--) {

        // Convert array index to "1000", "1000000", etc
        var size = Math.pow(10,(i+1)*3);

        // If the number is bigger or equal do the abbreviation
        if(size <= number) {
             // Here, we multiply by decPlaces, round, and then divide by decPlaces.
             // This gives us nice rounding to a particular decimal place.
             number = Math.round(number*decPlaces/size)/decPlaces;

             // Add the letter for the abbreviation
             number += abbrev[i];

             // We are done... stop
             break;
        }
    }

    return number;
}

【问题讨论】:

  • (1) 由于您的“相关缩写”是 k、M、G、T 等,因此您的示例输出应更改以匹配。 (2) 代码是否应该包含完整的程序?
  • 如果构建一个完整的(而不是代码高尔夫)实现需要考虑两个问题:1)在某些情况下,2^10 比 10^3 作为基础更有意义,2)应该 xxx5 舍入甚至(更好的统计数据)而不是总是向上(简单规则)。我正在为实现其中一个(或两个)的答案投票。
  • @dmckee:我很难按原样制定规则。因此,我投票支持最简单的实现,以使其尽可能保持 Code-Golfy。
  • 如果你想要二进制,请使用44.22Gi :p
  • 我会投票删除数百个作为缩写的可能性。我在实践中从未见过这样做,而且它使代码复杂化,因为它不是 10 的 3 倍。

标签: language-agnostic code-golf rosetta-stone number-formatting human-readable


【解决方案1】:

Python 2.x,78 个字符

a=input()
i=0
while a>=1e3:a/=1e3;i+=1
print"%g"%round(a,input())+" kMGTPE"[i]

此版本(75 个字符)使用 printf 打印额外的零并遵循四舍五入规则。

a=input()
i=0
while a>=1e3:a/=1e3;i+=1
print"%%.%df"%input()%a+" kMGTPE"[i]

【讨论】:

  • 有人用一些测试用例验证过吗?
【解决方案2】:

Javascript 114 个字符

function m(n,d){p=M.pow
d=p(10,d)
i=7
while(i)(s=p(10,i--*3))<=n&&(n=M.round(n*d/s)/d+"kMGTPE"[i])
return n}

还有 114 - 使用 spidermonkey - 在 STDIN 上输入

[n,d]=readline().split(' '),x=n.length,p=Math.pow,d=p(10,d)
x-=x%3
print(Math.round(n*d/p(10,x))/d+" kMGTPE"[x/3])

104 - 功能

function(a,b,c,d){
    c=(''+a).length;
    d=Math.pow;
    b=d(10,b);
    return((a*b/d(10,c-=c%3))+.5|0)/b+' kMGTPE'[c/3]
}

如果您将 (''+a) 替换为 a 并承诺只传递字符串,则它也会变为 99 :)

【讨论】:

  • 我知道 someone 有一些巧妙的方法来缩短它!也许有一些 1.6+ 的功能或 1.8 的 [].reduce
【解决方案3】:

Perl 114 111 104 个字符

我第一次参加代码高尔夫比赛!

标准输入提供的参数:perl fna.pl 918395 1

($n,$d)=@ARGV;
@n=$n=~/./g;
@s=' kMGTPE'=~/./g;
printf"%.".(@n>3?$d:0)."f%s",$n/(10**($#n-$#n%3)),$s[@n/3];

输出:

918.4k


脱高尔夫球版本(附说明):

( $number, $dp ) = @ARGV;      # Read in arguments from standard input

@digits = split //, $number;   # Populate array of digits, use this to count
                               # how many digits are present

@suffix = split //, ' kMGTPE'; # Generate suffix array

$number/(10**($#n-$#n%3));     # Divide number by highest multiple of 3

$precision = @n>3 ? $dp : 0;   # Determine number of decimal points to print

sprintf "%.".$precision."f%s", # "%.2f" prints to 2 dp, "%.0f" prints integer
        $number, $suffix[@n/3];# Select appropriate suffix

【讨论】:

    【解决方案4】:

    J,61 个 63 65 个字符

    ((j.&(1&{)":({.%&1e3{:));{&' kMGTPE'@{.)(([:<.1e3^.{.),{:,{.)
    

    输出:

    ((j.&(1&{)":({.%&1e3{:));{&' kMGTPE'@{.)(([:<.1e3^.{.),{:,{.) 1500 0
    ┌─┬─┐
    │2│k│
    └─┴─┘
    
    ((j.&(1&{)":({.%&1e3{:));{&' kMGTPE'@{.)(([:<.1e3^.{.),{:,{.) 987654321987654321 4
    ┌────────┬─┐
    │987.6543│P│
    └────────┴─┘
    

    (输出是这样“装箱”的原因是因为 J 不支持由不同类型组成的列表)

    解释(从右到左):

    (([:&lt;.1000^.{.),{:,{.)

    我们创建一个新的三元素列表,使用, 加入([:&lt;.1000^.{.)(第一个参数{. 的底数&lt;. base 1000 log ^.。我们与第二个参数@987654329 一起加入它@ 然后是第一个参数{.

    所以在第一个位之后,我们将 12345 2 转换为 1 2 12345

    ((j.&amp;(1&amp;{)":({.%&amp;1000{:));{&amp;' kMGTPE'@{.) 使用; 将表达式的两半连接到一个框中以生成最终输出。

    前半部分是((j.&amp;(1&amp;{)":({.%&amp;1000{:)),它将 (%) 最后一个输入数字 ({:) 除以 1000,即第一个次数。然后它使用输入列表中的第二个数字 (1&amp;{) 设置精度 ":

    后半部分 {&amp;' kMGTPE'@{. - 这使用第一个数字从 0 索引的缩写列表中选择 ({) 适当的字符。

    【讨论】:

    • 987654321987654321 4 的输出应该是 987.6543P1234567 2 的输出应该是 1.23M
    • @David:我知道,我在发布后发现了这一点。刚刚花了最后半个小时来修复它,代价​​是 2 个字符。 :)
    • 此外,它支持高达 999,999,999,999,999,999,999 - 比要求高 100 倍以上。
    • 好吧,看了你的代码我想说你家人很担心你
    • @M28:我会把它当作一种恭维:)
    【解决方案5】:

    dc - 75 个字符

    A7 1:U77 2:U71 3:U84 4:U80 5:U69 6:U[3+r1-r]sJ?sddZd3~d0=Jrsp-Ar^ldk/nlp;UP
    

    使用Z(位数)%3 查找单位。大部分代码用于设置单位字符数组,实际代码为 39 个字符。当%3 等于0 时,J 宏会进行调整,以避免在第 7 次打印0.918M。测试用例。它不能正确地四舍五入。

    如果您说dc,请随时改进。

    【讨论】:

      【解决方案6】:

      Ruby - 79 77 75 83 个字符

      n,d=ARGV
      l=n.to_s.length
      printf"%.#{l>3?d:0}f%s",n.to_f/10**(l-l%3)," kMGTPE"[l/3]
      

      从命令行参数读取。

      74 72 80 个字符,在双引号内打印输出

      n,d=ARGV
      l=n.to_s.length
      p"%.#{l>3?d:0}f%s"%[n.to_f/10**(l-l%3)," kMGTPE"[l/3]]
      

      66 74 个字符,打印额外的零

      n,d=ARGV
      l=n.to_s.length
      p"%.#{d}f%s"%[n.to_f/10**(l-l%3)," kMGTPE"[l/3]]
      

      基于this 解决方案和示例代码。

      【讨论】:

        【解决方案7】:

        Perl 94 个字符

        ($_,$d)=@ARGV;$l=length;@u=' kMGTPE'=~/./g;printf"%.".($l>3?$d:0)."f$u[$l/3]",$_/10**($l-$l%3)
        

        用法:

        perl abbreviator.pl 47475782130 2
        

        输出:

        47.48G
        

        【讨论】:

          【解决方案8】:

          PHP 57 个字符

          for($a=num+1;$a>=1;$a=$a/26)$c=chr(--$a%26+65).$c;echo$c;
          

          【讨论】:

            【解决方案9】:

            Haskell,126(没有导入,它是一个带有两个参数的函数):

            f n p|l>3=showFFloat (Just p) (c n/c 10^(l-w)) [" kMGTPE"!!f]|True=show n where(f,w)=divMod l 3;c=fromIntegral;l=length$show n
            

            扩展:

            import Numeric
            
            doit :: Integer -> Int -> String
            doit n p
                | l > 3 = showFFloat (Just p) d [" kMGTPE" !! f]
                | otherwise = show n
                where
                d = (fromIntegral n) / fromIntegral (10^(l-w))
                (f,w) = divMod l 3
                l = length $ show n
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 2011-03-01
              • 1970-01-01
              • 1970-01-01
              • 2011-06-02
              • 1970-01-01
              • 1970-01-01
              • 2011-01-22
              相关资源
              最近更新 更多