n까지의 최단 경로 수를 센다


21

이 코드 챌린지는 ( 는 음이 아닌 정수)의 맵을 사용 하여 최소 단계 수로 에서 시작 하여 에 도달하는 방법의 수를 계산하게 합니다.2엑스엑스+엑스jj

(이는 OEIS 시퀀스 A307092 와 관련이 있습니다.)

예를 들어, 세 개의 맵이 필요하기 때문에 이고 에서 을 보내는 세 개의 맵으로 구성된 두 개의 고유 한 시퀀스가 ​​있습니다 .에프(13)=2213

엑스엑스+엑스0엑스엑스+엑스2엑스엑스+엑스0또는엑스엑스+엑스2엑스엑스+엑스1엑스엑스+엑스0

결과적으로 또는 입니다.21213261213

예제 값

f(2)   = 1 (via [])
f(3)   = 1 (via [0])
f(4)   = 1 (via [1])
f(5)   = 1 (via [1,0])
f(12)  = 2 (via [0,2] or [2,1])
f(13)  = 2 (via [0,2,0] or [2,1,0], shown above)
f(19)  = 1 (via [4,0])
f(20)  = 2 (via [1,2] or [3,1])
f(226) = 3 (via [2,0,2,1,0,1], [3,2,0,0,0,1], or [2,3,0,0,0,0])
f(372) = 4 (via [3,0,1,0,1,1,0,1,1], [1,1,0,2,0,0,0,1,1], [0,2,0,2,0,0,0,0,1], or [2,1,0,2,0,0,0,0,1])

도전

문제는 정수 를 입력으로 사용하고 형식의 최소 개수의 맵을 통해 에서 까지의 고유 경로 수를 출력 하는 프로그램을 생성하는 것 입니다 .22엑스엑스+엑스j

이것은 이므로 가장 적은 바이트가 이깁니다.


1
나는 ^상징이 지수를 나타낸다 는 것을 명시 적으로 언급해야한다고 생각합니다 . XOR 일 수도 있습니다 (예 : C는 ^비트 XOR에 사용).
Ramillies

1
@Ramillies 아마도 MathJax로 변경해야 할 것입니다. 즉 대신 입니다 . 엑스=엑스+엑스jx -> x + x^j
케빈 크루이 센

@ KevinCruijssen : 좋은 지적, 그것은 확실히 도움이 될 것입니다.
Ramillies

나는 이것을 OEIS에 A309997 으로 추가했다 . ( 승인 될 때까지는 초안이 될 것입니다 .)
Peter Kagey

답변:



5

자바 스크립트 (ES6),  111 ... 84  80 바이트

1=2

f=(n,j)=>(g=(i,x,e=1)=>i?e>n?g(i-1,x):g(i-1,x+e)+g(i,x,e*x):x==n)(j,2)||f(n,-~j)

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

댓글

f = (                     // f is the main recursive function taking:
  n,                      //   n = input
  j                       //   j = maximum number of steps
) => (                    //
  g = (                   // g is another recursive function taking:
    i,                    //   i = number of remaining steps
    x,                    //   x = current sum
    e = 1                 //   e = current exponentiated part
  ) =>                    //
    i ?                   // if there's still at least one step to go:
      e > n ?             //   if e is greater than n:
                          //     add the result of a recursive call with:
        g(i - 1, x)       //       i - 1, x unchanged and e = 1
      :                   //   else:
                          //     add the sum of recursive calls with:
        g(i - 1, x + e) + //       i - 1, x + e and e = 1
        g(i, x, e * x)    //       i unchanged, x unchanged and e = e * x
    :                     // else:
      x == n              //   stop recursion; return 1 if x = n
)(j, 2)                   // initial call to g with i = j and x = 2
|| f(n, -~j)              // if it fails, try again with j + 1

4

하스켈 , 78 75 바이트

이 구현은 반복적으로 필요한 모든 매핑의 "트리"에서 호흡 우선 탐색을 사용합니다 x -> x + x^j.

j#x=x+x^j
f n=[sum[1|x<-l,x==n]|l<-iterate((#)<$>[0..n]<*>)[2],n`elem`l]!!0

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

설명

-- computes the mapping x -> x + x^j
j#x=x+x^j                          
--iteratively apply this function for all exponents [0,1,...,n] (for all previous values, starting with the only value [2])
                            iterate((#)<$>[0..n]<*>)[2] 
-- find each iteration where our target number occurs
    [                   |l<-...........................,n`elem`l] 
-- find how many times it occurs
     sum   [1|x<-l,x==n] 
-- pick the first entry
f n=.............................................................!!0



1

펄 5 ( -lp), 79 바이트

$e=$_;@,=(2);@,=map{$x=$_;map$x+$x**$_,0..log($e)/log$x}@,until$_=grep$_==$e,@,

TIO


1

CJam (27 바이트)

qi2a{{_W$,f#f+~2}%_W$&!}ge=

온라인 데모

경고 : 메모리를 많이 사용하면 매우 빠릅니다.

해부:

qi            e# Read input and parse to int n (accessed from the bottom of the stack as W$)
2a            e# Start with [2]
{             e# Loop
  {           e#   Map each integer x in the current list
    _W$,f#f+~ e#     to x+x^i for 0 <= i < n
    2         e#   and add a bonus 2 for the special case
  }%          e#   Gather these in the new list
  _W$&!       e#   Until the list contains an n
}g
e=            e# Count occurrences

보너스는 2( 루프가 루프보다 비싸기 2때문에 특별한 입력 사례를 처리하기 위해 ) 목록의 크기가 매우 빠르게 커지고 지수를 사용 하면 목록에서 더 큰 숫자의 값이 커짐 을 의미합니다 매우 빠릅니다.whiledo-whilen-1



1

R , 78 77 바이트

function(n,x=2){while(!{a=sum(x==n)})x=rep(D<-x[x<n],n+1)+outer(D,0:n,'^')
a}

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

간단한 너비 우선 검색 사용

설명과 함께 풀린 코드 :

function(n){                              # function taking the target value n

  x=2                                     # initialize vector of x's with 2

  while(!(a<-sum(x==n))) {                # count how many x's are equal to n and store in a
                                          # loop while a == 0

    x=rep(D<-x[x<n],n+1)+outer(D,0:n,'^') # recreate the vector of x's 
                                          # with the next values: x + x^0:n
  }
a                                         # return a
}   

메모리 할당량이 많은 짧은 버전 (더 큰 경우 실패) :

R , 70 69 바이트

function(n,x=2){while(!{a=sum(x==n)})x=rep(x,n+1)+outer(x,0:n,'^')
a}

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

@RobinRyder 덕분에 -1 바이트


!(a<-sum(x==n))!{a=sum(x==n)}두 경우 모두 -1 바이트 가 될 수 있습니다 .
로빈 라이더

0

Pyth , 24 바이트

VQIJ/mu+G^GHd2^U.lQ2NQJB

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

이것은 올바른 출력을 생성해야하지만 매우 느립니다 (TIO에서 372 테스트 케이스가 시간 초과 됨). 로 교체 .lQ2하여 더 짧게 만들 수는 Q있지만 런타임이 끔찍합니다.

참고 : 도달 할 수없는 숫자 대한 출력을 생성하지 않습니다.(1)

설명

VQ                        # for N in range(Q (=input)):
   J                      #   J =
     m                    #     map(lambda d:
      u                   #       reduce(lambda G,H:
       +G^GH              #         G + G^H,
            d2            #         d (list), 2 (starting value) ),
              ^U.lQ2N     #       cartesian_product(range(log(Q, 2)), N)
    /                Q    #     .count(Q)
  IJ                  JB  #   if J: print(J); break
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.