从古至今,关于运势和未来的计算都是王公贵族的爱好,我们可以从零开始, 以双向链表实现 运势计算(周易)。


运势计算:以双向链表实现: 实现链表_双向链表


0.0 需要获得每天的运势吗?

本文实现算法 主要参考 熊逸大师的说明,《当你的邻居为九五之尊》,这里做一个简单的汇总,如果有需要参考原文的请自行搜索。

占卜算卦是一个古老的方法,人们无法把握未来时,经常通过这个方法获得一些确定性的心理效应。

其社会影响深远而广泛,虽然它并不是一种完全准确的科学,但我们可以通过go实现 一个简易的占卜程序,用以了解我们的古人如何处理不确定性的。 并尝试了解其中的变化规则。


运势计算:以双向链表实现: 实现链表_整除_02



0.1 计算步骤初略

步骤

1, 产生49个数,为大衍之数为 54,实际参与计算的为 七七四十九

2, 随机 分成 两组(随机的方法非常重要,可以影响甚至决定结果), 为了可以产生正常的 三变 运算,最小12 也就是说范围是:天 12 ~ 37, 地 37 ~ 12

3, 从 天,地 随机选择一侧 取出一个 作为 人(一般在实际操作时,可以让寻求运势的人操作,以加强参与感)

4, 一变 把象征天的那组棋子数数有多少颗,数清楚之后把这个数字除以4(4象征一年四季),余数是几。

任何数字除以4,余数都只有四种可能:1、2、3、整除。如果遇到整除的情况,我们就当做余数是4。好了,现在把余数拿开。

把象征地的那组棋子照猫画虎,和“3”的做法一致。

把“2”里用来象征人的那一颗棋子,加上“3”中作为余数被拿掉的棋子,还有“4”里同样作为余数被拿掉的棋子归在一起。

得出的数字只有两种可能:不是9就是5。如果错了,你就从头再来吧。     好了,从1-5完成动作,叫做“一变”。

5, 二变,重复 2~4 步 6, 三变,重复 2~4 步,最后剩下的卡 除以 4 得出 第一爻

7, 重复 1~6 步,6次,产生 6个爻 即为 一卦 8, 解卦象

0.2 双向链表的实现

我们可以通过双向链表 存储卦象的6个爻,这样我们可以知道前后顺序,并且可以在每个节点存储变爻的值,为此实现其结构体 和 链表

//定义链表结构体
type node struct {
        number  int    //爻值
        yaobian [][]int   //三次爻变的 具体算子
        prev    *node   //前一个爻 节点
        next    *node   //后一个爻 节点
    }

//定义双向链表
type dlist struct {
        lens int
        head *node
        tail *node
    }

//链表构造函数
func makeDlist() *dlist {
        return &dlist{}
    }

//判断是否空链表 
func (this *dlist) newNodeList(n *node) bool { 

    if this.lens == 0 {
        this.head = n
        this.tail = n
        n.prev = nil
        n.next = nil
        this.lens += 1
        return true
    } else {
        Logg.Panic("not empty node list.")
    }
    return false
}


// 头部添加 节点
func (this *dlist) pushHead(n *node) bool {

    if this.lens == 0 {
        return this.newNodeList(n)
    } else {
        this.head.prev = n
        n.prev = nil
        n.next = this.head
        this.head = n
        this.lens += 1
        return true
    }
}


//  添加尾部节点,我们主要使用此方法,用以保持爻的相对位置
func (this *dlist) append(n *node) bool {

    if this.lens == 0 {
        return this.newNodeList(n)
    } else {
        this.tail.next = n
        n.prev = this.tail
        n.next = nil
        this.tail = n
        this.lens += 1
        return true
    }
}


/// 显示并返回链表的值
func (this *dlist) display() []int {
    
    numbs := []int{}
    node := this.head
    t := 0 
    for node != nil {

        Logg.Println(node.number, node.yaobian)
        numbs = append(numbs, node.number)
        t += 1
        if t >= this.lens {
            break
        }

        node = node.next
    }

    fmt.Println("length:", this.lens)
    return numbs
}

结语

本小节我们实现了 一个简单的双向链表,

包括其链表节点 和 链表管理,添加和查询操作,

这将在第三节运势解读中得到运用。