Algorithm 代码高尔夫-根据当前页面生成附近的页码
挑战在于创建一种算法,根据序列中的当前位置生成序列中特定大小的数字子集 当浏览繁忙站点(如Stack Overflow或Digg)上的许多内容页面时,通常需要为用户提供一种快速跳转到第一页、最后一页或当前页面附近的特定页面的方法 要求Algorithm 代码高尔夫-根据当前页面生成附近的页码,algorithm,code-golf,rosetta-stone,Algorithm,Code Golf,Rosetta Stone,挑战在于创建一种算法,根据序列中的当前位置生成序列中特定大小的数字子集 当浏览繁忙站点(如Stack Overflow或Digg)上的许多内容页面时,通常需要为用户提供一种快速跳转到第一页、最后一页或当前页面附近的特定页面的方法 要求 始终显示第一页和最后一页的页码 将显示页码的子集 包含当前页码 以及之前和/或之前的页码 之后(取决于当前页面) 将显示页码的子集 始终保持固定的页数和 不能超过或低于 除非: totalpage l 1)([1])(当(>l 2)(原理…)(n从l到r do
- 始终显示第一页和最后一页的页码
- 将显示页码的子集 包含当前页码 以及之前和/或之前的页码 之后(取决于当前页面)
- 将显示页码的子集
始终保持固定的页数和
不能超过或低于
除非:
totalpage
- 当前页面的位置
子集中的数字是固定的
除非:
1 Python-321个字符 我假设您在命令行(stdin)上键入当前页面和总页面: 编辑:我意识到这对于“24”或“22”之类的东西是失败的——它假设至少有6页。耸肩Groovy:242 232个字符,支持可配置的组长度 调用语法:
产生以下结果:分页(currentOffset、totalWidth、groupSize)
公共Lisp:262个有效字符 (格式t“[~a]”n))(格式t“[~a]”n))(格式p(c m&key(s 5)(p 2))(let((l)(max(min(-c p)-s-1))(r(min(max(+c(-p)s-1)s)m))(当(>l 1)([1])(当(>l 2)(原理…)(n从l到r do的循环([(if(=n c)#\x n))(当([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]
未压缩:
子集大小和当前页面在该子集中的位置可以在可选参数中给出((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))))
在子集内自然为零): 编辑:压缩版本中的调用将是::当前位置
F#!-233个有效字符。 支持的所有选项,且在规格范围内 节目:CL-USER> (p 8 15 :s 6 :p 5)
输出: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
Python-156 182 140个字符 谢谢你的评论。:) PS.大量编辑以减少字符数并在当前页面周围添加[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]
=页数(n
为最大页数,m
为当前页码)Ruby 1.9-197个字符c
p,s,t=$*.map&:to\u i a=p-s/2 e=a+s-1 at&(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 ePHP,234个字符 这并不完全符合规范(
而不是[1][x][3][4]…[30]
),但考虑到这一点,它将变得不那么优雅。C#278个字符[1][x][3][4][5]…[30]
节目 C#,240/195 184个字符 与另一个C#答案类似,但有一些令人讨厌的副作用充满了LINQ。我想这可能会短一些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;})); }
编辑: 结果是命令式版本短了很多(195184个字符):void页面(int p、int t、int s){ int h=s/2,l=0; foreach(可枚举范围(1,t)中的变量c),其中(x=>x==1 | | x==t | |(p+ht-s)| |(x>=p-h&&x{Console.Write((x-l>1?…)+(x==p?[x]:“[“+x+”)”);l=x;返回x;); }
GolfScript-89 80 78个字符 所有页码的输出占用83个字符(对主体进行轻微修改) Python-334个字符-完整功能 我意识到已经发布了一个简短的答案,但该答案不支持页面子集中可配置的宽度和位置。我的答案是void页面(int p、int t、int s){ int h=s/2,l=0,i=1; 对于(;i=p-h&&i1?“…:”)+(i==p?[X]:“[”+i+”]); l=i; } }
这是我的第一个高尔夫代码,很棒的东西,从现在开始我将做更多的事情:pJavascript-398393个字符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)))
工作功能
,其中:v(j,o,l)
是页码j
是总页数o
是要显示的页数(子集大小)l
返回:v(10,30,5)
[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+"]":"")}
函数v(j,o,l){function k(q){return q.length}函数y(n,m){t=[];而(nl/2&&a>=c)?r=r.splice(-l/2):((a2?[1]…:)+“[”+r.join([])+(g[k(g)-1]=c){ 接头前=接头前(-1/2); }如果(a2)pre[0]=“[1]…”; if(在[after.length-1]之后)Ruby 1.9.1-114 [1,30,5],[2,30,5],[13,30,5],[27,30,5],[30,30,5],[3,6,5],[4,7,5]中x,n,w的
puts(1..n).map{i | i>[-w/2+x,n-w].min&&iPerl,92个字符
$\=join'',映射{$\==1 | |$$\==n | | abs($\-$x)找出你自己的SEO代码。在这个例子中,分页与SEO有什么关系?@Yuriy,我昨天不得不解决这个问题;我做到了。@AvatarKava:我帮助做了一些与SEO类似的事情。虽然我不是100%确定,但想法是在页面上有一个确切的链接数。第2页(共30页)是否应该是
或[1][x][3][4][5]。。。[30]
?您没有说得很清楚。我认为在(2 30)的情况下,输出是不正确的。此外,子集大小和当前页面在子集中的位置是不可配置的。30个中的2个应该是[1][x][3][4]…[30]
那将是6页,不是吗?、1、x、3、4、5和30问题中的示例清楚地表明,应该始终有5个周围的页面,如果还没有显示,则应加上端点。积极编辑以减少字符数,并在当前页面周围添加n=页面数人们实际使用LISP?我认为这只是一个神话tale![1][x][3][4][5]…[30]
输出ruby pager.rb 1 5 7
。我有ruby 1.8.7(2010-01-10 patchlevel 249)[i686 linux]。它只在ruby 1.9中正常运行,因为最长的行中有字符文字([120][2][3][4][5]…[7]
)并发症是?x
CL-USER> (page-bar 8 15 :subset-size 6 :current-position 5) [1]...[3][4][5][6][7][x]...[15] NIL
CL-USER> (p 8 15 :s 6 :p 5)
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
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 ""
[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]
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())
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)
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
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).']');}
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).']'); }
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("..."); } }
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(); }
[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]
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;})); }
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; } }
~:&;\:C;:T,{-1%[T&-T)C-:C&2/-(]$0=:|1>{.1<\|>}*}2*]${{)]`[C]`/'[x]'*}%}%'...'*
$ echo "27 30 5"|golfscript page_numbers.gs [1]...[25][26][x][28][29][30]
~:&;:T,{:C;T,{-1%[T&-T(C-:C&2/-]$0=:|1>{.1<\|>}*}2*]${{)]`[C)]`/'[x]'*}%}%'...'*n}
$ 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]
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)))
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 ''
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+"]":"")}
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]; }
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>"); } }
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
$_=join'',map{$_==1||$_==$n||abs($_-$x)<=$a?$_==$x?'[x]':"[$_]":'_'}(1..$n);s/_+/.../g;print
@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"; }