0010 嘿嘿

-----

For instance, if you are older, you have less time to recover from any major losses and you may well wish to boost your pension income.
So preserving your capital and generating extra income are your main priorities.
In this case, you'd probably construct a portfolio with some shares (but not high risk ones), along with gilts, cash deposits
and perhaps convertibles or income shares of split capital investment trusts.
If you are younger and in a solid financials position, you might take an aggressive approach. 
But only if you are blessed with a sanguine disposition and won't suffer sleepless nights over share prices.
If you recognize yourself in this description, you might include a couple of heady growth stocks in your portfolio, alongside your more pedestrian investments.
Once you have
decided on your investment aims you can then decide where to put your money. 
The golden rule here is spread your risk, if you put all of your money into Periwigs International, you're setting up yourself as a hostage to fortune.

-----

M.Hiroi 的下一章内容是有关bit操作的。今天看了land of lisp开始的部分,里面第一个除了 defparameter defvar defun 的函数竟然是 ash ,也是bit操作之一。
之前有想过,lisp给我的印象是大多是处理符号,估计bit操作有点麻烦吧。事实证明我太太太太太天真了。

[问题]本章里面用开关灯的问题来熟悉bit操作。
这个问题是说:有排成一个5x5方阵的25盏灯,给出一个这25盏灯的开关状态,问能不能把这所有的灯都关了(或开了)。
按开关的要求是必须同时也按下上下左右四个方向的开关。
这个是以前文曲星上也有的游戏,一直不知道怎么玩的,这次顺便把玩法也学会了。
xxxxx         ooooo                                                                            1    2    3    4    5
xxxxx         ooooo                                                                            6    7    8    9   10
xxxxx  =>   ooooo            为了方便标记位置,用右边的记法        11  12  13  14   15
xxxxx         ooooo                                                                          16  17  18  19   20
xxxxx         ooooo                                                                          21  22  23  24   25
大致就是上图的这个印象。

[流程]我先照搬介绍章节里面的解法,然后需要代码的地方自己编了看看。

[想法]首先考虑到的状况是这样子的,总共有25个按钮,那么所有按钮的开关情况共有 2^25 种情况,如果都验证一遍的话,计算量有点大。
为此,一行一行从上往下考虑情况,比如第一行只按了2,4位置的开关。那么第二行中,为了按灭3位置的灯,就必须按下8位置的开关。
所以其实第一行的定了下来的话,那么余下四行就都定下来了。因此,只需要考虑第一行的 2^5 种情况就可以了。

[按开关的表示方法]用一位来表示一个开关的状态,那么,可以用一个 16进制的 0x1ffffff 来表示开关的全开,0x000000 来表示开关的全关。
按开关就可以表示称当前状态和一个16进制数 0xXXXXXXX 的xor的计算结果。把按下 25 个位置开关的操作所对应的 0xXXXXXXX表示为如下的变量。

(defvar *pattern* #(#x0000023 #x0000047 #x000008e #x000011c #x0000218
                    #x0000461 #x00008e2 #x00011c4 #x0002388 #x0004310
                    #x0008c20 #x0011c40 #x0023880 #x0047100 #x0086200
                    #x0118400 #x0238800 #x0471000 #x08e2000 #x10c4000
                    #x0308000 #x0710000 #x0e20000 #x1c40000 #x1880000))

解法如下:

(defun solve-lamp (board)
  (dotimes (i 32)
    (let ((new-board board) 
	  operation)
      (dotimes (j 5)
	(when (logbitp j i)
	  (setf new-board (logxor new-board (aref *pattern* j)))
	  (push j operation)))
;      (format t "~X ~%" new-board)
      (dotimes (k 4)
	(dotimes (j 5)
	  (when (logbitp (+ j (* k 5)) new-board)
	    (setf new-board (logxor new-board (aref *pattern* (+ j 5 (* k 5)))))
	    (push (+ j 5 (* k 5)) operation)))
	)
      (when (zerop new-board)
	(print-lamp operation))
)))
 
(defun print-lamp (ope)
  (format t "~%")
  (dotimes (k 5)
    (dotimes (j 5)
      (if (member (+ j (* k 5)) ope)
	  (format t "P")
	  (format t "-")))
    (format t "~%")))
因为事先大致看了一下M.Hiroi的解法,所以大致都是一样的。
这里是M.Hiroi的解法:
(defun solve (board)
  (dotimes (i 32)
    (let ((new-board board) pushed-button)
      ; 1 行目のボタンを押す
      (dotimes (j 5)
        (when (logbitp j i)
          (push j pushed-button)
          (setq new-board (logxor new-board (aref *pattern* j)))))
      ; 1 行ずつライトを消していく
      (dotimes (j 20)
        (when (logbitp j new-board)
          (push (+ j 5) pushed-button)
          (setq new-board (logxor new-board (aref *pattern* (+ j 5))))))
      ; ライトが全部消えたか
      (if (zerop new-board)
          (print-answer (reverse pushed-button))))))
区别在于:

1)dotimes 关于 k 和 j 的二重循环,可以省略一层
2)换行不用 format 用 (terpri)
3)打印结果的想法不同

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值