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)