Il ritorno di Hydra Slayer


13

È passato un po 'di tempo da quando hai ucciso quell'idra , ti sei crogiolato nella gloria per anni, ma ora la gente ti sta chiamando lavato, a è stato. Bene, è ora che tu dimostri di aver sbagliato, hai sentito dove si trova un'altra idra. Basta ucciderlo e ti verrà assegnata tutta la gloria che meriti.

Arrivi all'armeria per ricevere le tue spade ma sono tutte fuori dalle spade normali, tutto ciò che rimane è Settori. Un settore n dividerà il numero di teste su un'Idra per n, ma può essere usato solo se il numero di teste è divisibile per n.

Ancora una volta scriverai del codice per aiutarti a uccidere l'idra. Il tuo codice prenderà come input il numero di teste con cui l'idra inizia il combattimento, il numero di teste con cui l'idra cresce ogni turno e un elenco di n-settori che puoi usare. Il tuo codice produrrà un modello ottimale di mosse per uccidere l'idra il più rapidamente possibile

Ad ogni turno di combattimento puoi selezionare una singola spada da usare, se dopo una fetta l'idra ha una sola testa, vinci, se non le fa crescere le teste. Non puoi mai fare alcuna mossa e se non ci sono possibili mosse disponibili perdi.

Se non è possibile alcuna soluzione, è possibile che venga visualizzato qualcosa di diverso da una soluzione, ad esempio un elenco vuoto, nulla, il numero zero, ecc.

Si tratta di quindi le risposte verranno assegnate in base al numero di byte, con meno valore.

Casi test

Ecco alcuni casi di test super di base, altri casi di test verranno aggiunti su richiesta.

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'idra può avere solo 1 testa per iniziare?
ETHproductions

@ETHproductions Non è necessario gestire tale caso.
Post Rock Garf Hunter,

Possiamo presumere che l'elenco sia ordinato?
ETHproductions

@ETHproductions Sì, puoi. Non vedo perché no.
Post Rock Garf Hunter,

Un 1 settore è fondamentalmente una spada "skip turn"?
Neil,

Risposte:


5

JavaScript (ES6), 111 105 byte

Salvato 4 byte grazie a @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}}

Ho abbandonato la prima ricorsione profonda che stavo tentando di usare per i loop molto più sicuri. Emette la soluzione come un array se esiste, funziona per sempre in caso contrario. Se ciò non è consentito, eccone uno che alla fine si interrompe (nella maggior parte dei casi, comunque):

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

Salvataggio di un byte grazie a 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 byte

+26 byte per gestire correttamente la rigenerazione ciclica della testa su scelte di armi sbagliate. (Grazie a @ThePirateBay per averlo sottolineato)

+27 byte per correggere alcuni casi limite che causano errori.

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]

Provalo online!


Di solito il bit resuable significa che non è possibile creare var globali, modificarli e presumere che la prossima volta tornino al valore originale. Non so quale sia la politica di errore qui - i programmi completi sarebbero sicuramente autorizzati a errori per output vuoto.
Stephen,


Possibili 208 byte .
Jonathan Frech,

1

VB.NET (.NET 4.5), 439 + 35 (importazioni) = 474 byte

Richiede 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 funzione Zaccetta due Int64(numero di teste e frequenza di ricrescita della testa) e una List(Of Int64)(Settori), e restituisce un List(Of Int64) (the ordered choice of Sectors). ReturnsNulla` se non c'è soluzione.

Suppone che i settori siano presentati in ordine crescente dal più grande al più piccolo.

I Optionalparametri sono per le chiamate ricorsive per salvare lo stato. Seguono l'ordine attuale dei settori in uso, l'ordine più breve di settori in assoluto e il numero di capi mai incontrati. Se incontriamo di nuovo lo stesso numero di teste, ci deve essere stato un modo più breve per raggiungerlo.

L'unico ordinamento dei settori che conta è che devo 1essere l'ultimo se esiste. Altrimenti, l'idra potrebbe crescere senza limiti perché potrei ad ogni turno semplicemente usare il 1Settore e non provarne mai un altro.

Ho dichiarato una costante Nda rappresentare Nothing, radendo 6 byte ogni volta che volevo usare Nothing.

And/Or non sono in corto circuito, quindi uso l'operatore condizionale null ( ?.) per evitare errori null dell'oggetto. Nel codice reale, userei AndAlso/ OrElseche fanno corto circuito.

Provalo online!


Z non golfato per leggibilità

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
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.