Board logo

标题: 【练习-070】批处理最简代码实现1至100的连加 [打印本页]

作者: batman    时间: 2012-12-18 10:07     标题: 【练习-070】批处理最简代码实现1至100的连加

出题目的:
  展示技术,拓展思路
加分原则:
  满分20分,成功完成连加计算5分,不用循环语句10分,最简代码5分
  思路奇妙的再追加10分
题目如下:
  在脚本之家看到vbs计算1到100连加的骨灰级代码并简化如下:
  Dim a(101):Execute(Join(a,"s=s+i:i=i+1:")):MsgBox s
  就请大家用批处理写出自己认为的最简代码吧!
作者: Demon    时间: 2012-12-18 10:46

垃圾脚本之家

http://demon.tw/programming/no-loop-calculate-1-100-sum.html
作者: ml4516730    时间: 2012-12-18 12:28

  1. @echo off
  2. set i=0
  3. for /l  %%a in  (1,1,100) do set /a i=i+%%a
  4. echo %i%
  5. pause
复制代码

作者: batman    时间: 2012-12-18 12:41

楼上请检查自己的代码。。。
作者: cutebe    时间: 2012-12-18 12:55

这个批处理名字有要求:"C.BAT"
  1. @SET/aA+=1,B+=A
  2. @IF %A%==100 ECHO,%B%&PAUSE>NUL&EXIT
  3. @C
复制代码
  1. (FOR /L %%C IN (0,1,99)DO @SET/aA+=1,B+=A)&SET B&PAUSE
复制代码
  1. @SET/aB=(1+100)*100/2&@SET B&PAUSE>NUL
复制代码
  1. @CMD/VON/C"(FOR /L %%C IN (0,1,99)DO SET/aA+=1,B+=A)>NUL&ECHO,!B!&PAUSE"
复制代码

作者: ml4516730    时间: 2012-12-18 13:13

回复 4# batman


    我自己运行过啊,有错吗
作者: cutebe    时间: 2012-12-18 13:26

参考了 Seter 的
http://bbs.bathome.net/redirect. ... d=465&pid=37670
  1. @SET/aA+=1,B+=A
  2. @%0%A:~2% 2>NUL
  3. @ECHO,%B%&PAUSE>NUL
复制代码
发现第二三行代码用&串起来还有递归效果
  1. @SET/aA+=1,B+=A
  2. @%0%A:~2% 2>NUL&@ECHO,%B%&PAUSE>NUL
复制代码

作者: terse    时间: 2012-12-18 13:46

等差数列求和公式 不可吗
作者: cyy998    时间: 2012-12-18 14:21

回复 7# cutebe

很不可思议的代码,看得我一头雾水,能解释解释么?
作者: batman    时间: 2012-12-18 14:52

回复 8# terse


    直接心算然后@echo 5050
   
    ps:是不是只有题才能把你勾出来?
作者: batman    时间: 2012-12-18 14:52

回复 6# ml4516730


    是我老花眼了,不好意思。。。
作者: cutebe    时间: 2012-12-18 15:09

回复 9# cyy998


  1. @SET/aA+=1,B+=A
  2. @%0%A:~2% 2>NUL
  3. @ECHO,%B%&PAUSE>NUL
复制代码

因为没有使用 @ECHO OFF 关闭回显,所以代之使用每句前加 @ ,这个好理解

再有就是 一、三 句仔细拆分看也好理解
第一句相当于:
SET /a A+=1  //是 SET /a A=A+1 的简化写法,即累加或递加;下同
SET /a B+=1
第三句相当于:
ECHO %B%  //这个显示变量 B 的值,如果这个觉得难下面不用看了
PAUSE    //原句中 >NUL 把命令输出屏蔽了,下同(标记①

难一点的是第二句
去掉 @ 2>NUL 后剩下
%0%A:~2%
由红蓝两部分组成,红色 %0 表示批处理本身,蓝色 %A:~2% 取变量 A 的第3个及之后的字符
实际作用中 %0 没有变化。%A:~2% 因为之前第一句代码是在做累加运算,因此变量 A 处于变化之中;
当 A 在 1 到 99 之间,%A:~2% 是空值  //%0%A:~2% 相当于 %0,就是调用自身
当 A 等于 100 时,%A:~2% 值为 0  //%0%A:~2% 相当于 %00,实际上找不到这个程序因此出现错误(转而运行下一句,即第三句)。
                 //代码运行时看不到错误信息是因为(参看标记①)2>NUL
作者: apang    时间: 2012-12-18 15:37

  1. @set /a i+=1,s+=i,1/(i/101) 2>nul&&(echo,%s%&pause)||%0
复制代码

作者: 一马平川_陈    时间: 2012-12-18 20:26

回复 12# cutebe


    新手,请教下,第一句为啥不只执行一次呢?
作者: cutebe    时间: 2012-12-18 21:39

本帖最后由 cutebe 于 2012-12-18 21:41 编辑

回复 14# 一马平川_陈


    参看第二句注释。因为第二句 %0 调用了自身(就是这个批处理本身)。相当于重复执行第一句。
  1. @SET/aA+=1,B+=A
  2. @ECHO,%B%
  3. @PAUSE>NUL
  4. @%0
复制代码
看以上代码,忽略 @ 符号,一二三行是顺序执行;执行到第四行时因为调用自身因此又执行第一行了。
把每行的 @ 删除再运行就看得出来了。
作者: terse    时间: 2012-12-19 01:08

本帖最后由 terse 于 2012-12-19 01:48 编辑
  1. 看来只能和谐55
复制代码

作者: batman    时间: 2012-12-19 01:25

回复 16# terse


    连加,题意有木有?
作者: Demon    时间: 2012-12-19 11:44

二楼被忽略了么
作者: batman    时间: 2012-12-19 14:32

回复 18# Demon


    兄弟,我真不知道为此说上些什么,你是想让我严厉谴责脚本之家吗?
作者: tezman    时间: 2012-12-19 16:02

向各位学习!!
作者: batman    时间: 2012-12-19 16:28

回复 20# tezman


    楼上是来刷分的?请不要用这种有刷分嫌疑的内容来回复。。。
作者: m891319    时间: 2012-12-20 08:49

本帖最后由 m891319 于 2012-12-20 08:58 编辑
  1. @echo off
  2. set n=100
  3. set /a a=(%n%+1)*%n%/2
  4. echo %a%
  5. pause
复制代码

作者: Demon    时间: 2012-12-20 11:25

回复  Demon


    兄弟,我真不知道为此说上些什么,你是想让我严厉谴责脚本之家吗?
batman 发表于 2012-12-19 14:32



求加分,你懂的。
作者: batman    时间: 2012-12-20 12:14

回复 23# Demon


    求bat代码,你也懂的。。。
作者: Demon    时间: 2012-12-20 18:31

回复  Demon


    求bat代码,你也懂的。。。
batman 发表于 2012-12-20 12:14


真小气
作者: 523066680    时间: 2012-12-20 19:17

虽不明,但觉厉。
作者: m891319    时间: 2012-12-21 00:33

不能单纯用公式 要用累加的话
goto算不算循环?
  1. @echo off
  2. set n=100
  3. :r
  4. set /a i=%i%+1
  5. set /a a=%a%+%i%
  6. if not %i%==%n% goto :r
  7. echo %a%
  8. pause
复制代码

作者: CrLf    时间: 2012-12-21 09:32

本帖最后由 CrLf 于 2012-12-21 17:28 编辑

最简很难看……保存为 0.bat
  1. @set/a m+=n+=1,1/(n-100) 2>nul&&0
  2. @echo %m%&pause
复制代码

作者: 极品小猫    时间: 2012-12-23 00:29

  1. @set sum=0
  2. :count
  3. @echo %sum%
  4. @if %sum% lss 100 set /a sum+=1 && goto :count
  5. pause
复制代码
凑个热闹, 膜拜13, 28楼的方法.
还以为没有人用goto法, 发个比27楼更简单的. -.-
作者: cutebe    时间: 2012-12-23 00:41

其实我7楼的代码字节数还是很少的
不过到这里也学到了个新知识
作者: CrLf    时间: 2012-12-23 01:40

回复 28# CrLf


    唔,还是保存为0.bat,再省几个字节,不过看着更蛋疼了...
  1. @set/am+=n+=1,1/(n-101)2>nul&&0&echo %m%&pause
复制代码

作者: qzwqzw    时间: 2012-12-23 11:49

楼上几种方案的微调
如果再精简的话
可以把nul改为#
不过那和%0改0一样具有限制
  1. @set/az+=i+=1,1/(100-i)2>nul&&%0&set,z&pause
复制代码
  1. @set/az+=i+=1
  2. @if %i% leq 99 %0
  3. @set,z&pause
复制代码
  1. @set/az+=i+=1
  2. @%0%i:~2%=2>nul||(set,z&pause)
复制代码

作者: CrLf    时间: 2012-12-23 15:00

回复 32# qzwqzw


    如此,貌似可再精简一下:
  1. @set/a.+=n+=1,1/(n-100)2>#&&0&set.&pause
复制代码

作者: qzwqzw    时间: 2012-12-23 17:13

本帖最后由 qzwqzw 于 2012-12-23 17:54 编辑

如果不考虑任何隐含的限制条件
那么set.&pause也可以省略了
反正也没有限定一定要输出结果
而2>的使用也完全可以省略了
也因为题目没有限定要屏蔽错误
@在未限定屏蔽命令时也无必要
最后精简得到的代码结果如下:
  1. set/as+=i+=1,1/(i/100)||0
复制代码
还是给一个稍微正常点的精简
  1. @set/as+=i+=1,1/(i-101)2>nul&&%0||set/p=%s%
复制代码
上段代码会递减输出从0~100到0~0的累加结果
另外给一个递增输出从0~100到0~...的代码
  1. @set/as+=i+=1,1/(i/101)2>nul&&set/p=%s%||%0
复制代码
从代码的执行结果来看
&&与||联用的执行逻辑与我想象的还有些不同
它的执行条件受到了set/p的影响
如果set/p=%s%改成echo %s%结果会有不同
因为Echo会置%errorlevel%为0而set/p会置1
作者: CrLf    时间: 2012-12-23 18:31

本帖最后由 CrLf 于 2012-12-23 23:00 编辑

回复 34# qzwqzw


    set/p好办法,似乎调整次序可以再简化一个字节:
  1. @set/as+=i+=1/!!(i-100)2>nul||set/p=%s%&%0
复制代码

作者: m891319    时间: 2012-12-23 19:30

本帖最后由 m891319 于 2012-12-23 19:32 编辑

回复 28# CrLf


    学习了m+=n+=1的方法

看了前面几位大大的思路
稍微总结了下简化代码的思考方向:
1. 利用%0等方式递规呼叫
2. 利用 && 或 || 简化判断流程
3. 目前看到递规的最简化 set/am+=n+=1 ,实在经典
4. 由于题目没有限定输出,后面的讨论都在于不拘泥于正式输出,
    以求更加精简代码

这是小弟领悟后的答案
  1. @set/%~n0%0
复制代码
得将档案储存为"am+=n+=1&setlocal enabledelayedexpansion&if !n!==100 (echo !m!&pause) else endlocal&"
不包含双引号,输出相当正式,也不会有递规产生
不过由于档名有字元限制,"set/" 实在是无法省略
算是有些投机取巧的方法...
作者: CrLf    时间: 2012-12-23 22:54

回复 36# m891319


    申明下,批处理中的此类写法首见于:http://bbs.bathome.net/viewthread.php?tid=12689




欢迎光临 批处理之家 (http://www.bathome.net/) Powered by Discuz! 7.2