히드라 슬레이어의 귀환


13

그 히드라를 죽인 지 얼마되지 않아 오랜 세월 영광을 누리지 만 지금은 사람들이 당신을 씻고 있다고합니다. 글쎄, 당신이 그들을 잘못 증명할 때, 당신은 다른 히드라의 행방을 들었습니다. 단순히 그것을 죽이면 당신은 당신이받을만한 모든 영광을 얻게 될 것입니다.

당신은 당신의 검을 받기 위해 병기고에 도착하지만, 그들이 남겨둔 모든 것은 일반 검에서 모두 섹터입니다. n- 섹터는 Hydra의 헤드 수를 n으로 나누지 만 헤드 수를 n으로 나눌 수있는 경우에만 사용할 수 있습니다.

다시 한 번 히드라를 죽이는 데 도움이되는 코드를 작성하려고합니다. 코드는 히드라 수두를 입력하고, 싸움을 시작하며, 매 차례마다 수두가 자라는 헤드 수와 사용할 수있는 n 섹터 목록을 입력으로 사용합니다. 코드는 가능한 한 빨리 히드라를 없애기위한 최적의 움직임 패턴을 출력합니다.

한 번의 전투에서 당신은 하나의 칼을 선택할 수 있습니다. 슬라이스 후에 히드라에 머리가 하나만 있다면, 머리가 자라지 않는다면 말입니다. 당신은 결코 움직이지 않을 수 있으며, 가능한 움직임이 없으면 잃게됩니다.

해결책이 없으면 빈 목록, 아무것도 없음, 숫자 0 등과 같은 해결책 이외의 것을 출력 할 수 있습니다.

이것은 이므로 응답은 바이트 수로 점수가 매겨지며 덜 나아집니다.

테스트 사례

다음은 몇 가지 기본 테스트 사례입니다. 요청시 추가 테스트 사례가 추가됩니다.

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]

히드라는 머리를 1 개만 시작할 수 있습니까?
ETHproductions

@ETHproductions이 경우를 처리 할 필요가 없습니다.
Ad Hoc Garf Hunter 20

목록이 정렬되었다고 가정 할 수 있습니까?
ETHproductions

@ETHproductions 그렇습니다. 왜 그런지 모르겠습니다.
Ad Hoc Garf Hunter

1 섹터는 기본적으로 "건너 뛰기"검입니까?
Neil

답변:


5

자바 스크립트 (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

자바 스크립트, 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

파이썬 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]

온라인으로 사용해보십시오!


일반적으로 재개 가능한 비트는 전역 변수를 생성, 수정 및 다음 번에 원래 값으로 되돌릴 수 없음을 의미합니다. 여기에 오류가있는 정책이 무엇인지 모르겠습니다. 전체 프로그램은 빈 출력으로 인해 오류가 발생할 수 있습니다.
Stephen



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그것이 존재하는 경우 마지막이어야한다는 것입니다. 그렇지 않으면, 매번 1섹터를 사용하고 다른 시도를 할 수 없기 때문에 히드라는 한계없이 자랄 것 입니다.

나는 사용하고 싶을 때마다 6 바이트를 줄여서 N표현할 상수 를 선언했다 .NothingNothing

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.