for algorithm code-golf rosetta-stone

algorithm - for - meta tags generator



Code Golf-Genera números de página cercanos basados en la página actual (14)

C # 278 caracteres

Programa

void Pages(int c,int t,int w){ int p=(w/2)+1; int b=c-p; int f=c+(w-p); if(b<0){ f+=b*-1; }else if(f>t){ b-=f-t; f=t; } for(int i=1;i<=t;i++){ if(t<=w||(i==1||i==t)||(i>b&&i<=f)) Console.Write(i==c?"[X]":"[{0}]",i); else if(t>w&&(i==b||i==f+1)) Console.Write("..."); } }

Prueba

for(int i=1;i<=5;i++) { Pages(i,5,5); Console.WriteLine(); } for(int i=1;i<=15;i++) { Pages(i,15,5); Console.WriteLine(); }

Salida

[X][2][3][4][5] [1][X][3][4][5] [1][2][X][4][5] [1][2][3][X][5] [1][2][3][4][X] [X][2][3][4][5]...[15] [1][X][3][4][5]...[15] [1][2][X][4][5]...[15] [1][2][3][X][5][6]...[15] [1]...[3][4][X][6][7]...[15] [1]...[4][5][X][7][8]...[15] [1]...[5][6][X][8][9]...[15] [1]...[6][7][X][9][10]...[15] [1]...[7][8][X][10][11]...[15] [1]...[8][9][X][11][12]...[15] [1]...[9][10][X][12][13]...[15] [1]...[10][11][X][13][14][15] [1]...[11][12][X][14][15] [1]...[11][12][13][X][15] [1]...[11][12][13][14][X]

El desafío es crear un algoritmo para generar un subconjunto de números de tamaño específico en una secuencia basada en la posición actual en esa secuencia.

Mientras navega por las muchas páginas de contenido en un sitio ocupado como Stack Overflow o Digg, a menudo es conveniente dar al usuario una forma de saltar rápidamente a la primera página, la última página o una página específica que se encuentra cerca de la página actual. visita.

Requerimientos

  • Los números de la primera y última página siempre se muestran
  • El subconjunto de números de página contendrá el número de página actual así como los números de página anteriores y / o posteriores (según la página actual)
  • El subconjunto de números de página siempre será un número fijo de páginas y nunca podrá exceder o no alcanzar ese número fijo a menos que:
    • totalPages < fixedWidth
  • La posición del número de página actual en el subconjunto es fija a menos que:
    • 1 <= currentPage < (fixedWidth - defaultPostion) o
    • (totalPages - currentPage) < (fixedWidth - defaultPostion)
  • La salida debe indicar cuándo hay una diferencia mayor que 0 entre la primera página de datos y la primera página del subconjunto, así como entre la última página del subconjunto y la última página de datos. Este indicador debería aparecer como máximo una vez en cualquier posición.

Si aún no puede visualizar esto, eche un vistazo a su perfil de Desbordamiento de pila en las preguntas / respuestas. Si tiene más de 10 de cualquiera de los dos, debería ver enlaces de paginación en la parte inferior que se generan exactamente de esta manera. Eso, o desplácese hasta la parte inferior de http://digg.com y observe su control de paginación.

Ejemplos

Todos los ejemplos asumen un tamaño de subconjunto de 5 y la página actual en la posición 3, pero estos deben ser configurables en su solución. ... indica el espacio entre los números de página, [x] indica la página actual.

Página actual: 1 de 30

Salida: [x][2][3][4][5]...[30]

Página actual: 2 de 30

Salida: [1][x][3][4][5]...[30]

Página actual: 13 de 30

Salida: [1]...[11][12][x][14][15]...[30]

Página actual: 27 de 30

Salida: [1]...[25][26][x][28][29][30]

Página actual: 30 de 30

Salida: [1]...[26][27][28][29][x]

Página actual: 3 de 6

Salida: [1][2][x][4][5][6]

Página actual: 4 de 7

Salida: [1][2][3][x][5][6][7]

Aclaraciones adicionales

  • La primera y la última página no cuentan para numberOfPages menos que sean secuencialmente parte de numberOfPages como en [1][x][3][4][5]...[30] o [1]...[26][27][28][x][30] , pero no en [1]...[8][9][x][11][12]...[30]
  • No debe incluirse ningún indicador de espacio si la distancia entre uno de los extremos del subconjunto y la primera o la última página es menor que 1. Por lo tanto, es posible tener una secuencia de páginas sin fixedWidth + 2 hasta fixedWidth + 2 como en [1][2][3][x][5][6]...[15] o [1][2][3][x][5][6][7]

Soluciones en cualquiera y todos los idiomas son bienvenidas.

¡Buena suerte!


C #, 240/195 184 caracteres

Similar a la otra respuesta de C #, pero con algún efecto secundario desagradable lleno de LINQ. Me imagino que esto podría ser algo más corto.

void Pages(int p,int t,int s) { int h=s/2,l=0; foreach(var c in Enumerable.Range(1,t).Where(x=>x==1||x==t||(p+h<s&&x<=s)||(p-h>t-s&&x>t-s)||(x>=p-h&&x<=p+h)).Select(x=>{Console.Write((x-l>1?"...":"")+(x==p?"[X]":"["+x+"]"));l=x;return x;})); }

Editar:

Resulta que la versión imperativa es más corta por un buen margen ( 195 184 caracteres):

void Pages(int p,int t,int s){ int h=s/2,l=0,i=1; for(;i<=t;i++) if(i==1||i==t||p+h<s&&i<=s||p-h>t-s&&i>t-s||i>=p-h&&i<=p+h){ Console.Write((i-l>1?"...":"")+(i==p?"[X]":"["+i+"]")); l=i; } }


GolfScript - 89 80 78 caracteres

~:&;/:C;:T,{-1%[T&-T)C-:C&2/-(]$0=:|1>{.1</|>}*}2*]${{)]`[C]`/''[x]''*}%}%''...''*

Muestra I / O:

$ echo "27 30 5"|golfscript page_numbers.gs [1]...[25][26][x][28][29][30]

La salida para todos los números de página requiere 83 caracteres (modificaciones menores en el cuerpo principal).

~:&;:T,{:C;T,{-1%[T&-T(C-:C&2/-]$0=:|1>{.1</|>}*}2*]${{)]`[C)]`/''[x]''*}%}%''...''*n}

Muestra I / O:

$ echo "7 5"|golfscript page_numbers.gs [x][2][3][4][5]...[7] [1][x][3][4][5]...[7] [1][2][x][4][5]...[7] [1][2][3][x][5][6][7] [1]...[3][4][x][6][7] [1]...[3][4][5][x][7] [1]...[3][4][5][6][x] $ echo "7 3"|golfscript page_numbers.gs [x][2][3]...[7] [1][x][3]...[7] [1][2][x][4]...[7] [1]...[3][x][5]...[7] [1]...[4][x][6][7] [1]...[5][x][7] [1]...[5][6][x]


Javascript - 398 393 caracteres


Funcion de trabajo

v(j, o, l) , donde:

  • j es el numero de pagina
  • o es el número total de páginas
  • l es el número de páginas para mostrar (tamaño de subconjunto)

v(10, 30, 5) devuelve: [1]...[8][9][x][11][12]…[30]

function v(j,o,l){function k(q){return q.length}function y(n,m){t=[];while(n<=m){t.push(n);n++}return t}r=y(1,j-1);g=y(j+1,o);b=k(r);a=k(g);c=l/2;(b>l/2&&a>=c)?r=r.splice(-l/2):((a<=c)?r=r.splice(-l+a+1):0);b=k(r);g=g.slice(0,l-1-b);a=k(g);r.push("x");g[a-1]==o-1?g.push(o):0;r[0]==2?r.unshift(1):0;r=r.concat(g);return(r[0]>2?"[1]...":"")+"["+r.join("][")+"]"+(g[k(g)-1]<o-1?"...["+o+"]":"")}


Versión sin comprimir

function run(cp, tp, l) { function y(n,m){t=[];while(n<=m){t.push(n);n++}return t}; var before=y(1, cp-1); var after=y(cp+1, tp); var b=before.length; var a=after.length; var c=Math.floor(l/2); if (b>l/2 && a>=c) { before=before.splice(-l/2); } else if (a<=c) { before=before.splice(-(l-a)+1); } b=before.length; after=after.slice(0, l-1-b); a=after.length before.push("x"); if (after[a-1]==tp-1) after.push(tp); if (before[0]==2) before.unshift(1); before=before.concat(after); // Add bounds to either side var pre=["",""]; if (before[0]>2) pre[0]="[1]..."; if (after[after.length-1]<tp-1) pre[1]="...["+tp+"]"; return pre[0]+"["+before.join("][")+"]"+pre[1]; }


Una simple función de prueba.

function testValues() { var ts=[1, 30, "[x][2][3][4][5]...[30]", 2, 30, "[1][x][3][4][5]...[30]", 13, 30, "[1]...[11][12][x][14][15]...[30]", 27, 30, "[1]...[25][26][x][28][29][30]", 30, 30, "[1]...[26][27][28][29][x]", 3, 6, "[1][2][x][4][5][6]", 4, 7, "[1][2][3][x][5][6][7]"]; for (var i=0; i<ts.length; i+=3) { var rr=v(ts[i], ts[i+1], 5); document.write(ts[i]+" of "+ts[i+1]+": "+rr+" |Correct-> "+ts[i+2]+"<br>"); ts[i+2]==rr ? document.write("<span style=''color:green''>Check!</span>") : document.write("<span style=''color:red''>Fail</span>"); document.write("<br><br>"); } }


PHP, 234 caracteres

function pages($t,$c,$s=5){$m=ceil($s/2);$p=range(1,$t);$p[$c-1]=''x'';$a=array();return preg_replace(''~(/[(''.implode(''|'',array_merge($c-$m<2?$a:range(2,$c-$m),$t-1<$c+$m?$a:range($c+$m,$t-1))).'')/])+~'',''...'',''[''.implode('']['',$p).'']'');}

(Más o menos)

function pages($max, $current, $subset=5) { $m = ceil($subset / 2); // amount to go in each direction $arr = range(1, $max); // array(1, 2, 3, 4, 5, 6, 7, 8, 9, 10) $arr[$current-1] = ''x''; // array(1, 2, 3, 4, x, 6, 7, 8, 9, 10) // replace ~(/[(2|8|9)/])+~ with ... $pattern = ''~(/[('' . implode(''|'', array_merge($current-$m >= 2 ? range(2, $current-$m) : array(), $max-1 >= $current+$m ? range($current+$m, $max-1): array())) . '')/])+~''; return preg_replace($pattern, ''...'', ''[''.implode('']['',$arr).'']''); }

Esto no sigue exactamente la especificación ( [1][x][3][4]...[30] lugar de [1][x][3][4][5]...[30] ), pero se volvería mucho menos elegante teniendo en cuenta eso.


Python - 321 caracteres

Supongo que está escribiendo en la página actual y en el total de páginas en la línea de comandos (estándar):

import sys p=sys.stdout.write c,t=raw_input().split() c,t=int(c),int(t) r=range(1,t+1) l=len(r) p("[1]") if c>7: p("...") for n in r[c-3:c+2]: if n==1:continue if n-t==-5 and l>7:continue if c==n:n="X" p("[%s]"%n) if l<7: for n in range(2,6): if c==n:n="X" p("[%s]"%n) if r[c+2]<t and l>6: p("...") p("[%d]"%t)

Realmente no jugaba al golf (solo nombres cortos), así que espero que la mejor solución sea al menos la mitad de esta longitud.

Ejemplo

python pag.py 3 30 [1][2][X][4][5]...[30]

Edit: Me doy cuenta de que esto falla para cosas como "2 4" o "2 2" - asume que tienen al menos 6 páginas. encogimiento de hombros


Common Lisp: 262 personajes significativos.

(defun [(n) (formato t "[~ a]" n)) (defun p (cm y tecla (s 5) (p 2)) (let ((l (max (min (- cp)) - - ms - 1)) 1)) (r (min (max (+ c (- p) s -1) s) m))) (cuando (> l 1) ([1)) (cuando (> l 2) (princ "...")) (bucle para n de l a r do ([(if (= nc) # / xn))) (when (<r (1- m)) (princ "...")) (cuando (<rm) ([m))))

Sin comprimir

(defun print[] (n) (format t "[~a]" n)) (defun page-bar (current max &key (subset-size 5) (current-position 2)) (let ((left (max (min (- current current-position) (- max subset-size -1)) 1)) (right (min (max (+ current (- current-position) subset-size -1) subset-size) max))) (when (> left 1) (print[] 1)) (when (> left 2) (princ "...")) (loop for p from left upto right do (print[] (if (= p current) #/x p))) (when (< right (1- max)) (princ "...")) (when (< right max) (print[] max))))

Pruebas:

CL-USER> (mapc (lambda (n) (p n 7) (format t "~%")) ''(1 2 3 4 5 6 7)) [x][2][3][4][5]...[7] [1][x][3][4][5]...[7] [1][2][x][4][5]...[7] [1][2][3][x][5][6][7] [1]...[3][4][x][6][7] [1]...[3][4][5][x][7] [1]...[3][4][5][6][x] (1 2 3 4 5 6 7) CL-USER> (p 1 1) [x] NIL CL-USER> (p 1 2) [x][2] NIL CL-USER> (p 0 0) NIL CL-USER> (p 0 1) [1] NIL CL-USER> (p 0 30) [1][2][3][4][5]...[30] NIL CL-USER> (p 31 30) [1]...[26][27][28][29][30] NIL

El tamaño del subconjunto y la posición de la página actual en ese subconjunto se pueden dar en parámetros opcionales ( :current-position se basa en cero dentro del subconjunto, naturalmente):

CL-USER> (page-bar 8 15 :subset-size 6 :current-position 5) [1]...[3][4][5][6][7][x]...[15] NIL

EDITAR: La llamada en la versión comprimida sería:

CL-USER> (p 8 15 :s 6 :p 5)


Perl, 92 caracteres

$_=join'''',map{$_==1||$_==$n||abs($_-$x)<=$a?$_==$x?''[x]'':"[$_]":''_''}(1..$n);s/_+/.../g;print

Prueba completa:

@i=( [1,30,2], [2,30,2], [13,30,2], [27,30,2], [30,30,2], [3,6,2], [4,7,2] ); for$r(@i) { ($x,$n,$a)=@$r; $_=join'''',map{$_==1||$_==$n||abs($_-$x)<=$a?$_==$x?''[x]'':"[$_]":''_''}(1..$n);s/_+/.../g;print ;print"/n"; }


Python - 334 caracteres - funcionalidad completa

Me doy cuenta de que ya se ha publicado una respuesta más corta, pero esa no admite el ancho y la posición configurables en el subconjunto de páginas. La mía lo hace.

def paginator(c, n, w, o): b = range(c-w/2+o,c+w/2+1+o) b = [e+abs(b[0])+1 for e in b]if b[0]<=0 else[e-abs(n-b[w-1])for e in b]if b[w-1]>n else b p = ([]if 1 in b else[1])+b+([]if n in b else[n]) return ''''.join((''...''if p[i]-p[i-1]!=1 and i>0 and i<len(p)else'''')+''[%d]''%p[i]if p[i]!=c else''[x]''for i in range(len(p)))

Y aquí están las pruebas que todos pasan.

if __name__ == ''__main__'': for current, n, width, offset, expect in ( (1, 30, 5, 0, "[x][2][3][4][5]...[30]"), (2, 30, 5, 0, "[1][x][3][4][5]...[30]"), (13, 30, 5, 0, "[1]...[11][12][x][14][15]...[30]"), (13, 30, 5, 1, "[1]...[12][x][14][15][16]...[30]"), (13, 30, 5, -1, "[1]...[10][11][12][x][14]...[30]"), (27, 30, 5, 0, "[1]...[25][26][x][28][29][30]"), (30, 30, 5, 0, "[1]...[26][27][28][29][x]"), (30, 30, 5, 1, "[1]...[26][27][28][29][x]"), (3, 6, 5, 0, "[1][2][x][4][5][6]"), (3, 6, 5, -1, "[1][2][x][4][5][6]"), (3, 6, 5, 1, "[1][2][x][4][5][6]"), (4, 7, 5, 0, "[1][2][3][x][5][6][7]"), ): output = paginator(current, n, width, offset) print "%3d %3d %3d %3d %-40s : %s" % (current, n, width, offset, output, output == expect) print ''''

Este es mi primer código de golf, cosas increíbles, voy a hacer mucho más de ahora en adelante: P


Python - 156 182 140 caracteres

f=lambda c,m,n:''...''.join(''''.join(('' '',''[%s]''%(p,''x'')[p==c])[min(m-n,c-1-n/2)<p<max(n+1,c+1+n/2)or p in(1,m)]for p in range(1,m+1)).split())

Y probando contra ejemplos en OP:

for c, m, expect in ( (1, 30, "[x][2][3][4][5]...[30]"), (2, 30, "[1][x][3][4][5]...[30]"), (13, 30, "[1]...[11][12][x][14][15]...[30]"), (27, 30, "[1]...[25][26][x][28][29][30]"), (30, 30, "[1]...[26][27][28][29][x]"), (3, 6, "[1][2][x][4][5][6]"), (4, 7, "[1][2][3][x][5][6][7]"), ): output = f(c, m, 5) print "%3d %3d %-40s : %s" % (c, m, output, output == expect)

Gracias por los comentarios. :)

PD. muy editado para disminuir el número de caracteres y agregar n = número de páginas alrededor del actual ( m es el número máximo de páginas y c es el número de la página actual)


Ruby 1.9 - 197 caracteres

p,s,t=$*.map &:to_i a=p-s/2 e=a+s-1 a<1&&(e+=1-a;a=1) e>t&&(a-=e-t;e=t) s>=t&&(a=1;e=t) m=(a..e).map{|n|"[#{n==p ??x:n}]"}.join a>2&&m=''...''+m a>1&&m=''[1]''+m e<t-1&&m<<''...'' e<t&&m<<"[#{t}]" puts m

Uso: ruby pager.rb [position] [sampleSize] [totalWidth]


Ruby 1.9.1 - 114

for x,n,w in [[1,30,5],[2,30,5],[13,30,5],[27,30,5],[30,30,5],[3,6,5],[4,7,5]] puts (1..n).map{|i|i>[-w/2+x,n-w].min&&i<=[x+w/2,w].max||i==1||i==n ?"[#{i==x ?''x'':i}]":''-''}.join.gsub(/-+/,''...'') end


F #! - 233 personajes significativos.

Todas las opciones soportadas y dentro de las especificaciones.

Programa:

let P c b n f m s = let p = b/2 let u = max 1 (if n-b <= c-p then n-b+1 else max 1 (c-p)) let v = min n (if b >= c+p-1 then b else min n (c+p)) let P = printf let C c a n = if c then P a n C (u > 1) f 1 C (u = 3) f 2 C (u > 3) "%s" s let I = Seq.iter (P f) I {u .. c-1} P "%s" m I {c+1 .. v} C (n - 2 > v) "%s" s C (v = n - 2) f (n-1) C (n > v) f n

Prueba:

for p in 1..6 do P p 5 30 "[%d]" "[x]" "..." printfn "" for p in 25..30 do P p 5 30 "[%d]" "[x]" "..." printfn ""

Salida:

[x][2][3][4][5]...[30] [1][x][3][4][5]...[30] [1][2][x][4][5]...[30] [1][2][3][x][5]...[30] [1][2][3][4][x][6][7]...[30] [1]...[4][5][x][7][8]...[30] [1]...[23][24][x][26][27]...[30] [1]...[24][25][x][27][28][29][30] [1]...[26][x][28][29][30] [1]...[26][27][x][29][30] [1]...[26][27][28][x][30] [1]...[26][27][28][29][x]


Groovy: 242 232 caracteres , soporta longitud de grupo configurable

Sintaxis de llamadas: Paging(currentOffset, totalWidth, groupSize)

def(c,t,g)=args.collect{it.toInteger()};def p,s=Math.max(c-(g/2).toInteger(),1);p=''[''+((c==1?''x'':1)+(s>2?'']...'':'']''));(s..Math.min(s+g-1,t)).each{if(it>1&&it<t)p+=''[''+(c==it?''x'':it)+'']''};print p+(t>s+g?''...['':''['')+(t==c?''x'':t)+'']'';

Versión legible:

def (c,t,g) = args.collect{it.toInteger()}; def p,s = Math.max(c - (g/2).toInteger(), 1); p = ''[''+((c==1?''x'':1)+(s>2?'']...'':'']'')); (s .. Math.min(s+g-1,t)).each{ if(it > 1 && it < t) p += ''['' + (c == it ? ''x'' : it) + '']'' }; print p + (t > s + g ? ''...['' : ''['') + (t==c ? ''x'' : t) + '']'';

Llamándolo así:

Paging ([1, 20, 5]) println ''''; Paging ([10, 20, 5]) println ''''; Paging ([20, 20, 5]) println ''''; Paging ([7, 17, 3]) println ''''; Paging ([2, 228, 3]) println ''''; Paging ([2, 5, 3]) println ''''; Paging ([1, 5, 5])

produce estos resultados:

[x][2][3][4][5]...[20] [1]...[8][9][x][11][12]...[20] [1]...[18][19][x] [1]...[6][x][8]...[17] [1][x][3]...[228] [1][x][3]...[5] [x][2][3][4][5]