【问题标题】:Code Golf: Numeric Ranges代码高尔夫:数字范围
【发布时间】:2011-01-11 15:50:27
【问题描述】:

挑战

通过用范围替换连续运行来压缩一长串数字。

示例

输入

1, 2, 3, 4, 7, 8, 10, 12, 13, 14, 15
输入保证是升序的,不会包含重复的。

输出

1 - 4, 7, 8, 10, 12 - 15
请注意,两个数字的范围应保持原样。 (7, 8;不是7 - 8

规则

您可以从命令行或标准输入中接受整数(或等效数据类型)的排序列表作为方法参数。(选择导致更短代码的任何选项)
您可以通过打印字符串或返回单个字符串或一组字符串来输出字符串列表。

参考实现

(C#)

IEnumerable<string> Sample(IList<int> input) {
    for (int i = 0; i < input.Count; ) {
        var start = input[i];
        int size = 1;
        while (++i < input.Count && input[i] == start + size)
            size++;

        if (size == 1)
            yield return start.ToString();
        else if (size == 2) {
            yield return start.ToString();
            yield return (start + 1).ToString();
        } else if (size > 2)
            yield return start + " - " + (start + size - 1);
    }
}

【问题讨论】:

  • 问题的CW是removed a while ago。我也相信程序员应该是代码高尔夫应该去的地方(至少根据常见问题解答和 Jeffs 的帖子)。
  • @Oded,@SLaks,到目前为止,这里是打码高尔夫的合适场所。
  • CW 请求应该通过标志来完成,而不是通过问题中的上述提示来完成。我已经为你做了。
  • 喜欢这些 Code Golf 和其他谜题吗?提交到Code Golf & Programming Puzzles area51 proposal
  • 重复问题和剧透 - 已在 codegolf.com/home-on-the-range 中发布。请不要在此处发布解决方案,以免解决方案被用来夸大 codegolf.com 上的排名

标签: language-agnostic code-golf


【解决方案1】:

Python,98 个字符

def f(a):
 for x in a:
  if x-1not in a or x+1not in a:print x,"-"if x+1in a and x+2in a else",",

Python - 86 个字符

这个结尾不包含额外的“,”

f=lambda a:''.join(`x`+",-"[(x+1in a)&x+2in a]for x in a if(x-1in a)&(x+1in a)^1)[:-1]

【讨论】:

  • if x-1not in a or x+1not in a:print x,",-"[x+1in a and x+2in a], 更短
  • 我对python不是很了解,但是这最后不是多打印一个“,”吗?
【解决方案2】:

Python,83 个字符

def f(l,a=2):
 for x in l:
  b,a=a,(x+1in l)*(x-1in l)
  if a<1:print',- '[b],`x`,

演示:

>>> l=[1, 2, 3, 4, 7, 8, 10, 12, 13, 14, 15]
>>> f(l)
  1 - 4 , 7 , 8 , 10 , 12 - 15

【讨论】:

  • 复制并粘贴您的第一个 sn-p 实际超过 83 个字符
  • @yes:您将换行符计为两个字符。
  • 非常好,但为什么 x 周围有反引号?
  • @TomaszGandor:老实说,我不确定(这已经很老了!)。没有反引号似乎可以正常工作,是的......
【解决方案3】:

Ruby,165 个字符

a=[]
def o(a)print "#{@s}#{a[0]}#{"#{a.size<3?',':' -'} #{a[-1]}"if a.size>1}";@s=', 'end
ARGV[0].split(', ').each{|n|if a[0]&&a[-1].succ!=n;o(a);a=[]end;a<<n;};o(a)

【讨论】:

    【解决方案4】:

    C++,166 个字符

    #define o std::cout
    void f(std::vector<int> v){for(int i=0,b=0,z=v.size();i<z;)i==z-1||v[i+1]>v[i]+1?b?o<<", ":o,(i-b?o<<v[b]<<(i-b>1?" - ":", "):o)<<v[i],b=++i:++i;}
    

    你们不都喜欢滥用?: 运算符吗? ;)

    更易读的版本:

    #define o std::cout
    void f(std::vector<int> v){
        for(int i=0,b=0,z=v.size();i<z;)
            i==z-1||v[i+1]>v[i]+1 ?
                b?o<<", ":o,
                (i-b?o<<v[b]<<(i-b>1?" - ":", "):o)<<v[i],
                b=++i
            :++i;
    }
    

    【讨论】:

      【解决方案5】:

      普通 Lisp,442/206 个字符

      (defun d (l)
        (if l
            (let ((f (car l))
              (r (d (cdr l))))
            (if r
                (if (= (+ f 1) (caar r))
                (push `(,f ,(cadar r)) (cdr r))
                (push `(,f ,f) r))
                `((,f ,f))
                ))
            nil))
      
      (defun p (l)
        (mapc #'(lambda (x)
                (if (= (car x) (cadr x))
                (format t "~a " (car x))
                (if (= (+ 1 (car x)) (cadr x))
                    (format t "~a ~a " (car x) (cadr x))
                    (format t "~a-~a " (car x) (cadr x)))))
            (d l)))
      

      “d”函数将输入列表重写为规范形式。为了好玩,我完全递归地做到了这一点。 “p”函数将输出格式化为等效的参考实现。

      【讨论】:

        【解决方案6】:

        F#,188 个字符

        let r(x::s)=
         let f=printf
         let p x=function|1->f"%A "x|2->f"%A %A "x (x+1)|n->f"%A-%A "x (x+n-1)
         let rec l x n=function|y::s when y=x+n->l x (n+1)s|y::s->p x n;l y 1 s|[]->p x n
         l x 1 s
        

        更具可读性:

        let range (x::xs) =
          let f = printf
          let print x = function
            | 1 -> f "%A " x
            | 2 -> f "%A %A " x (x+1)
            | n -> f "%A-%A " x (x+n-1)
          let rec loop x n = function
            | y::ys when y=x+n ->
                loop x (n+1) ys
            | y::ys ->
                print x n
                loop y 1 ys
            | [] ->
                print x n
          loop x 1 xs
        

        【讨论】:

          【解决方案7】:

          Ruby:123 个字符

          def y(n) t=[];r=[];n.each_with_index do |x,i| t<<x;if(x.succ!=n[i+1]);r=((t.size>2)?r<<t[0]<<-t[-1]:r+t);t=[];end;end;r;end
          

          更具可读性

          def y(n) 
          t=[];r=[];
          n.each_with_index do |x,i|
           t << x
           if (x.succ != n[i+1])
              r = ((t.size > 2) ? r << t[0] << -t[-1] : r+t)  
              t=[]
           end
           end
           r
          end
          

          然后像这样执行

           > n=[1, 2, 3, 4, 7, 8, 10, 12, 13, 14, 15]
           > y n
           => [1, -4, 7, 8, 10, 12, -15]
          

          【讨论】:

            【解决方案8】:

            PHP 95 个字符

            (其实是python之后的第二语言

            给定$a=array(numbers);

            算法:

            for($i=0;$i<count($a);$i++){$c=$i;while($a[$i+2]==$a[$i]+2)$i++;echo $a[$c],$i-$c>1?'-':',';}
            

            【讨论】:

            • 实际上这会引发关于未定义偏移的通知......但是,嘿,规则并没有说 stderr 必须是干净的......但是输出格式不太正确。编辑:它也没有说明输入的来源,所以你的 95 个字符不是有效的恕我直言
            • @luxifer:我不太记得这个问题,我会再试一次我的脚本,我会更新
            猜你喜欢
            • 2010-11-28
            • 2010-09-23
            • 2010-12-17
            • 2011-01-15
            • 1970-01-01
            • 1970-01-01
            • 2010-12-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多