解决Kotlin的约瑟夫斯问题

我最近偶然发现了一个帖子讲述的约瑟夫问题 ,并试图解决它在不同的脚本语言。 为了简洁起见,这是问题所在(摘自引用的帖子):

Flavius Josephus是犹太裔的罗马历史学家。 在公元一世纪的犹太罗马战争中,他与同伴士兵(共40名士兵)一起被困在一个山洞里,周围被敌军罗马军队包围。 他们决定自杀,方法是环戴戒指,指望每三个男人自杀。 每个这样指定的人都会自杀...约瑟夫斯不想死,设法将自己置于最后一个幸存者的位置。 在问题的一般版本中,有n个士兵,编号从1到n ,每第k个士兵将被淘汰。 计数从第一个士兵开始。 最后一个幸存者是多少?

测试我的建筑Kotlin技能似乎是一个很大的挑战。 这是我想出的解决方案。 首先,使用TestNG和数据提供程序的测试类-完美的用例:

classJosephusTest{

    @DataProvider
    fundata():Array<Array<Int>>{
        returnarrayOf(
                arrayOf(2,1,0),
                arrayOf(3,1,0),
                arrayOf(10,1,0),
                arrayOf(3,2,0),
                arrayOf(4,2,1)
        )
    }

    @Test(dataProvider="data")
    funcircle_of_size_and_step_should_survive_position(size:Int,step:Int,expectedPosition:Int){
        valcircle=Circle(size,step)
        valsurvivor=circle.findSurvivor()
        assertEquals(survivor.position,expectedPosition)
    }
}

现在,代码:

classSoldier(valposition:Int){

    varstate=State.Living

    lateinitvarnext:Soldier

    funsuicide(){
        state=State.Dead
    }

    funisDead()=state==State.Dead
}

enumclassState{
    Living,Dead
}

classCircle(privatevalsize:Int,privatevalstep:Int){

    privatevalfirst=Soldier(0)

    init{
        varperson=first
        while(person.position<size-1){
            person=createNext(person)
        }
        vallast=person
        last.next=first
    }

    privatefuncreateNext(soldier:Soldier):Soldier{
        valnew=Soldier(soldier.position+1)
        soldier.next=new
        returnnew

    }

    funfindSurvivor():Soldier{
        varsoldier:Soldier=first
        varnumberOfDead=0
        while(numberOfDead<size-1){
            varcount:Int=0
            while(count<step){
                soldier=nextLivingSoldier(soldier)
                count++
            }
            soldier.suicide()
            numberOfDead++
        }
        returnnextLivingSoldier(soldier)

    }

    privatefunnextLivingSoldier(soldier:Soldier):Soldier{
        varcurrentSoldier=soldier.next
        while(currentSoldier.isDead()){
            currentSoldier=currentSoldier.next
        }
        returncurrentSoldier
    }
}

该代码可以正常工作,并且测试成功。

但是,在尝试编写解决方案的代码时,我意识到在Java和Kotlin中都没有实现循环链​​表的数据结构。 因此,我必须实现自己的循环数据结构,但无需实现通用的收集功能。

现在,上述代码的问题在于,虽然我觉得Soldier类很好,但Circle类却没有。 Circle var太多,感觉太像命令式编程了。 缺乏for(;;)在Kotlin力量我使用while与外部变量-两次: countnumberOfDead

我一直认为我可以通过更改数据结构来改善这种情况。 我只是不知道如何...现在,Kotlin和FP专家,您有什么建议吗?

翻译自: https://blog.frankel.ch/solving-the-josephus-problem-in-kotlin/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值