Le retour de l'Hydra Slayer


13

Ça fait un moment que tu as tué cette hydreCela , vous avez baigné dans la gloire pendant des années, mais maintenant les gens vous appellent lavé, a a été. Eh bien, il est temps de leur prouver le contraire, vous avez entendu le sort d'une autre hydre. Tuez-le simplement et vous obtiendrez toute la gloire que vous méritez.

Vous arrivez à l'armurerie pour recevoir vos épées, mais elles ne sont plus des épées normales, il ne leur reste que des secteurs. Un n-secteur divisera le nombre de têtes sur une Hydra par n, mais ne peut être utilisé que si le nombre de têtes est divisible par n.

Encore une fois, vous allez écrire du code pour vous aider à tuer l'hydre. Votre code prendra en entrée le nombre de têtes de l'hydre, commence le combat avec, le nombre de têtes avec lesquelles l'hydre grandit à chaque tour, et une liste de n secteurs que vous pouvez utiliser. Votre code affichera un schéma optimal de mouvements pour tuer l'hydre le plus rapidement possible

À chaque tour du combat, vous pouvez sélectionner une seule épée à utiliser, si après une tranche, l'hydre n'a qu'une seule tête que vous gagnez, sinon elle fait pousser des têtes. Vous ne pouvez jamais faire aucun mouvement, et s'il n'y a pas de mouvements possibles disponibles, vous perdez.

Si aucune solution n'est possible, vous pouvez sortir autre chose qu'une solution, par exemple une liste vide, rien, le nombre zéro, etc.

Il s'agit de donc les réponses seront notées en fonction de leur nombre d'octets, moins étant mieux.

Cas de test

Voici quelques cas de test super basiques, plus de cas de test seront ajoutés sur demande.

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]

L'hydre ne peut-elle avoir qu'une seule tête pour commencer?
ETHproductions

@ETHproductions Vous n'avez pas à gérer ce cas.
Post Rock Garf Hunter

Peut-on supposer que la liste est triée?
ETHproductions

@ETHproductions Oui, vous le pouvez. Je ne vois pas pourquoi pas.
Post Rock Garf Hunter

Un 1-secteur est essentiellement une épée "skip turn"?
Neil

Réponses:


5

JavaScript (ES6), 111 105 octets

4 octets enregistrés grâce à @ThePirateBay

(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}}

J'ai abandonné la récursion en profondeur d'abord que j'essayais d'utiliser pour les boucles en largeur d'abord beaucoup plus sûres. Produit la solution sous forme de tableau s'il existe, s'exécute indéfiniment s'il ne l'est pas. Si ce n'est pas autorisé, en voici un qui finit par s'arrêter (dans la plupart des cas, de toute façon):

(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, 191 190 octets

Un octet enregistré grâce à 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 octets

+26 octets pour gérer correctement la régénération cyclique de la tête sur les mauvais choix d'armes. (Merci à @ThePirateBay de l'avoir signalé)

+27 octets pour corriger certains cas marginaux provoquant des erreurs.

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]

Essayez-le en ligne!


Habituellement, le bit resuable signifie que vous ne pouvez pas créer de variables globales, les modifier et supposer qu'elles reviendront à la valeur d'origine la prochaine fois. Je ne sais pas quelle est la politique sur les erreurs ici - les programmes complets seraient certainement autorisés à sortir pour une sortie vide.
Stephen



1

VB.NET (.NET 4.5), 439 + 35 (importations) = 474 octets

A besoin 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

La fonction Zprend deux Int64(nombre de têtes et taux de repousse des têtes), et un List(Of Int64)(secteurs), et renvoie un List(Of Int64) (the ordered choice of Sectors). Returnsrien s'il n'y a pas de solution.

Suppose que les secteurs sont présentés dans un ordre trié du plus grand au plus petit.

le Optional paramètres sont pour les appels récursifs pour sauvegarder l'état. Ils suivent l'ordre actuel des secteurs en cours d'utilisation, l'ordre des secteurs le plus court jamais créé et le nombre de têtes rencontrées. Si nous rencontrons à nouveau le même nombre de têtes, il doit y avoir eu un moyen plus court pour l'atteindre.

Le seul ordre des secteurs qui compte est que je dois 1être le dernier s'il existe. Sinon, l'hydre pourrait croître sans limites car je pourrais à chaque tour utiliser le 1secteur et ne jamais en essayer d'autre.

J'ai déclaré une constante Nà représenter Nothing, en rasant 6 octets chaque fois que je voulais l'utiliser Nothing.

And/ Orne court-circuite pas, donc j'utilise l'opérateur conditionnel nul ( ?.) pour éviter les erreurs nulles de l'objet. En vrai code, j'utiliserais AndAlso/ OrElsequi font des courts-circuits.

Essayez-le en ligne!


Z sans golf pour la lisibilité

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
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.