九头蛇杀手的归来


13

自从您杀死那只九头蛇以来已经有一段时间了,您沉浸在荣耀中已有好几年了,但是现在人们都在呼唤您,被洗净了。好了,现在您可以证明它们是错误的,您已经听说了另一只蛇蝎的下落。杀死它,您将获得应有的所有荣耀。

您到达军械库时会收到您的剑,但它们全都是普通剑,只剩下部门。一个n扇区将九头蛇的头数除以n,但仅当头数可被n整除时才能使用。

再一次,您将要编写一些代码来帮助您杀死hydra。您的代码将输入九头蛇的头数,开始战斗,九头蛇每回合增加的头数,以及可以使用的n个扇区的列表。您的代码将输出最佳移动方式,以尽快消灭水蛇

战斗的每一回合,您都可以选择一把剑来使用,如果在一片水after之后只有一个头赢得了您,如果没有,您会长出头。您可能永远不会采取任何行动,如果没有可能采取的行动,您将会输掉。

如果没有解决方案,您可能会输出除解决方案以外的任何内容,例如,空列表,无内容,数字零等。

这是因此答案将按字节数计分,少者更好。

测试用例

这是一些超级基本的测试用例,如果需要,可以添加更多的测试用例。

24 heads, 1  heads per turn, [2,3] -> [3,3,2,3]
25 heads, 2  heads per turn, [2,3] -> No solutions
4  heads, 2  heads per turn, [2]   -> No solutions
4  heads, 3  heads per turn, [2,5] -> [2,5]
10 heads, 17 heads per turn, [2, 3, 7, 19] -> No solutions
10 heads, 6  heads per turn, [1,16] -> [1,16]
6  heads, 2  heads per turn, [2, 3, 5] -> [2, 5]
125 heads, 1  head per turn, [1, 2, 3, 127] -> [1, 1, 127]

九头蛇可以只有一个头开始吗?
ETHproductions'Aug

@ETHproductions您不必处理这种情况。
Ad Hoc Garf Hunter

我们可以假定列表已排序吗?
ETHproductions'Aug

@ETHproductions是的,您可以。我不明白为什么不这样。
Ad Hoc Garf Hunter

1扇区基本上是“跳过转身”剑吗?
尼尔

Answers:


5

的JavaScript(ES6),111个 105字节

由于@ThePirateBay,节省了4个字节

(h,p,a)=>{for(b={[h]:[]};c=b,b=[];)for(d in c)for(e of a){d%e?0:q=b[d/e+p]=[...c[d],e];if(d==e)return q}}

我放弃了试图用于更安全的广度优先循环的深度优先递归。将解决方案输出为数组(如果存在),如果不存在则永远运行。如果这是不允许的,那么这最终会停止(无论如何在大多数情况下):

(h,p,a)=>{for(b={[h]:[]};c=b,b=[],c+c;)for(d in c){for(e of a){a[[,d]]||d%e?0:q=b[d/e+p]=[...c[d],e];if(d==e)return q}a[[,d]]=1}}

3

JavaScript,191190字节

感谢Step Hen,节省了一个字节

(h,t,s)=>eval(`r=[],d=0,q=[],s.map(a=>q.push([],h));while(q.length){p=q.shift(),h=q.shift(),s.map(w=>(a=h/w)==1?d=w:!(a%1)&!r[a+=t]?r[q.push([...p,w],a),a]=1:0);d?(q=[],p).push(d):0}d?p:[]`)

f=(h,t,s)=>eval(`r=[],d=0,q=[],s.map(a=>q.push([],h));while(q.length){p=q.shift(),h=q.shift(),s.map(w=>(a=h/w)==1?d=w:!(a%1)&!r[a+=t]?r[q.push([...p,w],a),a]=1:0);d?(q=[],p).push(d):0}d?p:[]`)

console.log(`[${f(24, 1, [2,3])}]`);
console.log(`[${f(25, 2, [2,3])}]`);
console.log(`[${f(4, 2, [2])}]`);
console.log(`[${f(4, 3, [2,5])}]`);
console.log(`[${f(10, 17, [2, 3, 7, 19])}]`);
console.log(`[${f(10, 6, [1,16])}]`);
console.log(`[${f(125, 1, [1, 16])}]`);
console.log(`[${f(1024, 3, [1, 2, 137])}]`);



2

Python 2中169个 195 222字节

+26个字节可正确处理不良武器选择时的循环头部再生。(感谢@ThePirateBay指出来)

+27个字节可修复某些导致错误的极端情况。

lambda n,p,w:g(n,n,p,w[::-1])[:-1]
def g(n,b,p,w,a=[]):
 if b<2:return[1]
 for x in w:
	if n%x<1and n/x+p!=n and n not in a:
	 try:
		l=[x]+g(n/x+p,n/x,p,w,[n]+a)
	 	if l and l[-1]!=0:return l
	 except:return[0]
 return[0]

在线尝试!


通常,可恢复位表示您无法创建全局变量,对其进行修改,并假设它们下次将恢复为原始值。邓诺这里错误的政策是什么-绝对可以将完整程序错误输出为空。
斯蒂芬



1

VB.NET(.NET 4.5),439 + 35(导入)= 474字节

需要 Imports System.Collections.Generic

Const N=Nothing
Function Z(h,r,a,Optional c=N,Optional p=N,Optional ByRef s=N)
If c Is N Then
c=New List(Of Long)
p=New List(Of Long)
End If
If s IsNot N And s?.Count<c.Count Then Return N
If p.Contains(h)Then Return N
p.Add(h)
For i=0To a.Count-1
Dim w=a(i)
If h Mod w=0Then
c.Add(w)
If h\w=1And(s Is N Or s?.Count>c.Count)Then
s=New List(Of Long)
s.AddRange(c)
End If
Z(h\w+r,r,a,c,p,s)
c.RemoveAt(c.Count-1)
End If
Next
Z=s
End Function

该函数Z采用两个Int64(头数和头长率)和一个List(Of Int64)List(Of Int64) (the ordered choice of Sectors). Returns扇形),如果没有解决方案,则返回Nothing`。

假设部门按从大到小的顺序排列。

Optional参数用于递归调用以保存状态。它们跟踪正在使用的扇区的当前顺序,有史以来最短的扇区以及遇到的磁头数量。如果我们再次遇到相同数量的正面,则必须有一种更短的方式达到它。

唯一重要的部门排序是,1如果存在的话,我需要排在最后。否则,hydra可能会无限增长,因为我可以随时使用1Sector而从不尝试任何其他方法。

我声明了一个常量N来表示Nothing,每次我想使用时减少6个字节Nothing

And/ Or不会短路,因此我使用null条件运算符(?.)来避免对象null错误。在实际代码中,我将使用AndAlso/ OrElse进行短路。

在线尝试!


Z 出于可读性而取消

Public Function Z(currentHeads As Long, regrowRate As Integer, weapons As ISet(Of Long), Optional currentWeapons As List(Of Long) = Nothing, Optional previousHeads As List(Of Long) = Nothing, Optional shortestWeapons As List(Of Long) = Nothing) As List(Of Long)

    ' initial call
    If currentWeapons Is Nothing Then
        currentWeapons = New List(Of Long)
        previousHeads = New List(Of Long)
    End If

    ' we've made more moves than our best so far
    If shortestWeapons IsNot Nothing AndAlso shortestWeapons.Count <= currentWeapons.Count Then
        Return Nothing
    End If

    ' exit, we've been here before
    If previousHeads.Contains(currentHeads) Then
        Return Nothing
    End If

    ' keep track of previous state to prevent duplicate paths
    previousHeads.Add(currentHeads)

    For Each w In weapons

        ' save 1 for last
        If w = 1 Then Continue For

        If currentHeads Mod w = 0 Then
            currentWeapons.Add(w)

            If currentHeads \ w = 1 Then
                If shortestWeapons Is Nothing OrElse shortestWeapons.Count > currentWeapons.Count Then
                    shortestWeapons = New List(Of Long)(currentWeapons)
                End If
            End If

            Dim answer = A(currentHeads \ w + regrowRate, regrowRate, weapons, currentWeapons, previousHeads, shortestWeapons)
            If answer IsNot Nothing Then
                If shortestWeapons Is Nothing OrElse shortestWeapons.Count > answer.Count Then
                    shortestWeapons = New List(Of Long)(answer)
                End If
            End If

            currentWeapons.RemoveAt(currentWeapons.Count - 1)
        End If
    Next

    If weapons.Contains(1) Then
        currentWeapons.Add(1)

        Dim answer = A(currentHeads \ 1 + regrowRate, regrowRate, weapons, currentWeapons, previousHeads, shortestWeapons)
        If answer IsNot Nothing Then
            If shortestWeapons Is Nothing OrElse shortestWeapons.Count > answer.Count Then
                shortestWeapons = New List(Of Long)(answer)
            End If
        End If

        currentWeapons.RemoveAt(currentWeapons.Count - 1)
    End If

    Return shortestWeapons
End Function
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.