2010年08月06日_林老师_新浪博客

LOGO编程题 挑战100个随机数(答案)★★★★★

    在LOGO作图窗口显示100个数字并不是太困难的事。难的是要随机地完整地填入1~100这些数字。如果随意地填写这100个数字的话,就有100!种填写方法。要知道,100!——也就是100的阶乘,是一个长达158位数的“天文数字”。就算计算机每秒钟能够填写1000000种方案的话,也需要许多亿亿亿亿年!所以就必须找到科学的计算方法,而{jd1}不是盲目地填写这些数据。

 

关于100阶乘的计算方法

请参考林老师编写的《LOGO语言竞赛习题集》P251

用LOGO语言计算出100阶乘的158位xx值是:

JIECHENG 100
100! =93326215443944152681699238856266700490715968264381621468592963895217
5999932299156089414639761565182862536979208272237582511852109168640000000000
00000000000000
这是一个158位数

 

 把题目和答案分开的好处是有利于练习时独立思考

 

    现在提供这个问题的两个不同的解决方法。

    纵观各种不同的编程方式,最为合理的思维方式必定包含以下内容:

    一、{zh0}预先准备好1~100这些数字,在这些预先准备好的数字中进行随机移位操作,可以避免“重复”、“缺漏”的现象;

    二、在正确地产生了100个随机数后,合理的方式应该是按某种规律填写到位,否则显示输出的工作量将会很大。

 

    {dy}个方法:林老师编写的LOGO程序

 

关于使用程序换行转接号“\”的技巧请参考:

 


    上面的程序是按照这样的思路来解决填写100个随机数字的:

    ①先建立:A和:B两个数组,这两个数组都有1~100个有效存储空间。

    ②:A数组先全部清零,用来存放{zh1}填写的结果。:B数组预先按从小到大的顺序填入1~100这些数值。

   附带说一句:各种计算机程序设计语言所输出的“随机数”其实全部都是“伪随机数”,看似无序,其实这些数值既然是计算出来的,仍然有一定的规律,所以并非{jd1}“随机”。为了保证输出结果的“随机”性,用ITEM命令剪取当前时间的“分”、“秒”值作为随机数的“种子”。因为你在什么时间开始运行这个程序是随意的,所以这个“种子”也可以看成是“随意”的。所以这个程序输出的答案可以说是相当的“随机”的。从概率上来看,绝无两次输出相同的表格的可能。

    白璧微瑕:林老师偶然发现,作为“官方”xx《说明书》的LOGO语言自带的Help系统也有多处错误。例如RERAMDOMHelp说明中建议使用

    RERANDOM ((ITEM 1 TIME)*3600+(ITEM 2 TIME)*60+ITEM 3 TIME)

其实是错误的。因为每天{zd0}的秒数是86400,假如“种子”值不对,LOGO系统将提示:The procedure RERANDOM needs a number between -32768 and 32767 as its first input. 要求种子数值在-32768~32767之间。所以不能用小时数作为“种子”!

    ④FOR "I 1 100[SJ :I]命令调用SJ :I子程序100次,给这100个格子填充数据。

    ⑤每次“检取”数据的对象是:B数组。在每次“检取”时,:B数组中有:N个数据(刚开始时:N=100)。被“检取”数据的序号(或位置):J是随机产生的。

    ASET :A :I AGET :B :J命令把:B数组中第:J号空间中的数值填充到:A数组第:I号空间里去。

    简单地说,每次是随意地从:B数组中“抓”一个数据填写到:A数组中。:A数组中的数据是从1号空间开始填写,下一次接着填2号、3号、……100号。

   现在这一步就显得十分重要了:从:B数组中,每“抓”走一个数据后,后面的数据就要全部逐个地朝前移位(移位的同时就把已经“抓”走的数据覆盖掉了,产生出来的是新的数据链),同时还要把:B数组中的数据的有效个数:N减少1。这样就能保证下一次再“抓”的数据中{jd1}不会有已经被“抓”过的。

    这样执行100次后。:A数组中就已经储存好100个随机“检取”的1~100号数据。

    ⑦表格是按照规律画出来的。之所以留出30×30的空格,是考虑到一个字符横向要占用7个点,显示100要占用3个数位,其余的空间留些间隔好看些。

    输出的例子如下:

 

 

    第二个方法:“LOGO语言爱好者”编写的程序:

    林老师7月22日在博客中发表了题目后,8月4日“LOGO语言爱好者”就给林老师发来了如下的程序。
    这是一个十分成功、且思路巧妙的程序。程序仅用1个数组,十分简练。程序中的方格不是整体画好的,而是待到所有随机数产生好之后,按规律画一个格子、随即顺带显示输出这个格子中的数据。其中产生100个不重复的从1~100的随机数的核心部分注解如下:

    先定义:B[0]~:B[99]数组空间,并预存1~100这些数字。因为只有预存了1~100这些数据,再随机从中“抓取”才能有效保证数据绝不重复。

    先预设:Z=100,即MAKE "Z 100。在整个处理循环中:Z的值从100逐步递减到1。

    以下是FOR "I -1 98[ ]循环中5个步骤操作的功能:

    MAKE "X (RANDOM :Z)+:I  ;产生一个随机抓取:B数组的位置
    MAKE "T AGET :B :X      ;把这个位置原来数组中的值暂存:T
    ASET :B :X AGET :B :I+1 ;当前数组(第:I+1空间)存储的值放到抓取的位置
    ASET :B :I+1 :T         ;把暂存值:T返回存入当前数组空间中

                             实质上是:B数组两个空间中数据的互换
    MAKE "Z :Z-1            ;产生随机数的范围缩小1  :Z值的范围100~1

    操作的最终结果是:B数组中1~100数据重新随机排序

     

    其实这两个程序中最为优美之处是:{zh1}所有数据都按规律自动准确地找到自己的位置显示出来。

    林老师编写的程序命令是:

    FOR "I 1 100[PU SETXY SE (REMAINDER :I-1 10)*30-150 \
           150-(INT((:I-1)/10))*30 PD TT AGET :A :I]

 

    “LOGO语言爱好者”编写的程序命令是:

FOR "I 0 9[FOR "J 0 9[PU SETXY SE -150+30*:I 30*:J-150 \
FG AGET :B :Z MAKE "Z :Z+1]]

 

 

我们向热心参与讨论研究的“LOGO语言爱好者”表示敬意!

你说这个LOGO命题是不是显得十分有趣?

我们还能找到其它不同类型的编程方式吗?

……

 

 

林老师博客首页的链接:

       

 

林正山老师邮箱: 

 

需要LOGO系统文件的可以发邮件给林老师

文件包中还包括学习LOGO语言常用表格工具程序文件

 

声明:
    林正山老师发表的文章,媒体、网站或出版物未经本人许可谢绝进行任何形式的删节、改编、重组及转载。

    允许个人博客按原文(含图片及附注)进行完整转载,转载时敬请注明本博作者姓名、文章原始出处,并以链接形式标明来源。

 

   LOGO语言竞赛教程》国际标准书号书号ISBN978-7-5335-3424-034.1万字、414页,定价22.00元,《LOGO语言竞赛习题集》国际标准书号ISBN978-7-5335-3425-7,39.6万字、481页,定价26.00元。两本书均大32开本,封面采用250克铜版纸,四色全彩印刷,内文采用60克胶版纸,黑白印刷,福建省科技出版社出版。

    凡查询购买以上两本书的,林老师不再一一回函,敬请见谅。

    希望购买正版书的,请自己和福州市安泰图书城一楼源泉书店0591-87547909联系。为保证书款安全,建议外地读者使用“支付宝”等第三方转交担保付款,避免直接汇款购买。

 

已投稿到:
  • 评论加载中,请稍候...

验证码:

郑重声明:资讯 【2010年08月06日_林老师_新浪博客】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——