language-agnostic code-golf

language agnostic - Código Golf: Rangos Numéricos



language-agnostic code-golf (8)

Reto

Compactar una larga lista de números mediante la sustitución de carreras consecutivas con rangos.

Ejemplo

Entrada

1, 2, 3, 4, 7, 8, 10, 12, 13, 14, 15
Se garantiza que la entrada está en orden ascendente y no contendrá duplicados.

Salida

1 - 4, 7, 8, 10, 12 - 15
Tenga en cuenta que los rangos de dos números deben dejarse como están. ( 7, 8 ; no 7 - 8 )

Reglas

Puede aceptar una lista ordenada de enteros (o tipo de datos equivalente) como un parámetro del método, desde la línea de comandos o desde la entrada estándar (elija la opción que resulte en un código más corto)
Puede generar una lista de cadenas imprimiéndolas o devolviendo una sola cadena o un conjunto de cadenas.

Implementación de referencia

(DO#)

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


PHP 95 caracteres

(en realidad es el segundo idioma después de python)

Dado $a=array(numbers);

Algos

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


Ruby: 123 caracteres

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

Más legible

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

Y ejecutar como

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


C ++, 166 caracteres

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

¿No todos aman abusar del operador?: ;)

Versión más legible:

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


Common Lisp, 442/206 caracteres

(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)))

La función "d" reescribe la lista de entrada en una forma canónica. Por diversión lo hice completamente recursivamente. La función "p" formatea la salida al equivalente de la implementación de referencia.


F #, 188 caracteres

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

Más legible:

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


Python, 83 caracteres

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

Manifestación:

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


Python, 98 caracteres

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 caracteres

Este no incluye un extra '','' al final

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


Ruby, 165 caracteres

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)