골프 무료 점심


26

환율 표에서 최대 수익을 창출 할 수있는 교환 순서를 찾으십시오.


예를 들어, 통화 거래가 부과 후의 통화 A riary (가정 통화), B aht, C edi 및 D enar를 고려하십시오. 아래 환율 표 :

                       TO
       A          B          C          D

   A   0.9999     1.719828   4.509549   0.709929

F  B   0.579942   0.9999     2.619738   0.409959
R
O  C   0.219978   0.379962   0.9999     0.149985
M
   D   1.39986    2.429757   6.409359   0.9999

AAA 로 교환 하는 것은 좋은 생각이 아닙니다.

덜 분명하지만,이 표에서는 다른 통화로 A 를 교환 다음 다시 교환하는 것이 손실 요인입니다.

via B: 1.719828 × 0.579942 = 0.997400489976
via C: 4.509549 × 0.219978 = 0.992001569922
via D: 0.709929 × 1.39986  = 0.99380120994

그러나, 교환 DD를B 것은 다음 B에 다시 A는 않습니다 (반올림에 굴복하지 주어진 충분한 자본) 이익 :

0.709929 × 2.429757 × 0.579942 = 1.0003738278192194

기회가 존재하는 동안이 "무료 점심"을 반복적으로 섭취 할 수 있습니다.

그러나 훨씬 더 매혹적인 체인이 있습니다. 즉 A 에서 D 로, D 에서 C 로, C 에서 B로 , 마지막으로 B가 다시 A로 돌아옵니다 .

0.709929 × 6.409359 × 0.379962 × 0.579942 = 1.0026612752037345

도전 세부 사항

가정 통화의 의미를 고정시키는 임의의 합리적인 형식의 환율 표 (예 : 1 번째 행 및 1 번째 열은 항상 가정 통화 임)
(또는 이러한 테이블 및 가정 통화 지수가 주어짐)를
찾으십시오. * 교환 사용을 반복하지 않고 통화 목록에 색인으로 자국 통화시작하고 끝나는 교환의 최대 차익 거래 순서 (예 : Y-> X 교환은 X-> Y 교환을 따를 수 있지만 X-> Y는 그렇지 않을 수 있음) X-> Y를 따르십시오).

그러한 수익성있는 기회가 존재하지 않으면 빈 목록이 생성되거나 식별 된 기회와 혼동되지 않는 다른 결과가 생성됩니다.
-예를 들어 위의 예 ( A-> D, D-> C, C-> B, B-> A ) :

  • 0 인덱싱을 사용하면 1을 반환 [[0,3],[3,2],[2,1],[1,0]]하거나[0,3,2,1,0]
  • 1 인덱싱을 사용하면 1을 반환 [[1,4],[4,3],[3,2],[2,1]]하거나[1,4,3,2,1]

모호성이 없으면 다른 형식도 좋습니다.
주의해야 할 점은 최고의 기회가 가정-> 가정 (어리석은 책상)에서 단일 거래가 될 수 있다는 것입니다. 위의 고정 옵션의 양쪽 끝 (예 : [3,2,1]또는 [4,3,2]) 에서 홈 통화 인덱스를 제외하고 "기회 없음"에 대한 빈 목록을 제외하기로 결정한 경우 홈-> 홈도 빈 목록이 아닌지 확인하십시오.

* 똑같이 수익성있는 유효한 기회가 여러 개 존재하는 경우, 기회 중 일부 또는 전부를 반환하십시오.

Bellman-Ford 알고리즘 은 이에 접근하는 한 가지 방법이지만 골프에 가장 적합하지는 않습니다.

테스트 사례

표시된 입력은 예제에서 사용 된 배열에 있으며 표시된 결과는 0- 인덱싱을 사용하여 통화-통화 표시를 나열합니다 (기회가 존재하는 경우 자국 통화는 후행에만 있고 빈 기회는 없습니다).

[[0.999900, 1.719828, 4.509549, 0.709929],
 [0.579942, 0.999900, 2.619738, 0.409959],
 [0.219978, 0.379962, 0.999900, 0.149985],
 [1.399860, 2.429757, 6.409359, 0.999900]]  ->  [3, 2, 1, 0]

[[0.9999, 1.5645, 0.9048, 1.0929],
 [0.6382, 0.9999, 0.5790, 0.6998],
 [1.1051, 1.7269, 0.9999, 1.2087],
 [0.9131, 1.4288, 0.8262, 0.9999]]  ->  [1, 2, 0]

[[0.9999, 1.4288, 0.8262, 0.9131],
 [0.6998, 0.9999, 0.5790, 0.6382],
 [1.2087, 1.7269, 0.9999, 1.1051],
 [1.0929, 1.5645, 0.9048, 0.9999]]  ->  [1, 2, 3, 1, 0]

[[1.002662, 1.719828, 4.509549, 0.709929],
 [0.579942, 0.999900, 2.619738, 0.409959],
 [0.219978, 0.379962, 0.999900, 0.149985],
 [1.399860, 2.429757, 6.409359, 0.999900]]  ->  [3, 2, 1, 0, 0]

[[1.002662, 1.719828, 4.509549, 0.709929],
 [0.579942, 1.002604, 2.619738, 0.409959],
 [0.219978, 0.379962, 1.003000, 0.149985],
 [1.399860, 2.429757, 6.409359, 1.002244]]  ->  [3, 3, 2, 2, 1, 1, 0, 0]

[[0.9999, 1.4288, 0.8262, 0.9131],
 [0.6998, 0.9999, 0.5790, 0.6382],
 [1.2087, 1.7269, 1.0001, 1.1051],
 [1.0929, 1.4974, 0.9048, 0.9999]]  ->  [1, 2, 2, 0]

[[0.9999, 1.3262, 0.7262, 0.9131],
 [0.6998, 0.9999, 0.5490, 0.6382],
 [1.2087, 1.7269, 0.9999, 1.2051],
 [1.0929, 1.5645, 0.9048, 0.9999]]  ->  [3, 2, 3, 1, 0]

[[0.9999, 1.5645, 0.9048, 0.5790],
 [0.6382, 0.9999, 0.5790, 0.3585],
 [1.1051, 1.7269, 0.9999, 0.6391],
 [1.7271, 2.6992, 1.5645, 0.9999]]  ->  [1, 2, 0]  and/or  [3, 2, 0]

[[0.9999, 1.2645, 0.7048, 0.3790],
 [0.4382, 0.9999, 0.3790, 0.1585],
 [1.0001, 1.5269, 1.0001, 0.4391],
 [1.5271, 2.4992, 1.3645, 0.9999]]  ->  []

[[0.9999, 1.2645, 0.7048, 0.3790],
 [0.4382, 0.9999, 0.3790, 0.1585],
 [0.9999, 1.5269, 1.4190, 0.4391],
 [1.5271, 2.4992, 1.3645, 0.9999]]  ->  [2, 2, 0]

이것은 이므로 바이트 단위의 가장 짧은 솔루션이 승리하지만 경쟁도 언어 내에서 이루어져야하므로 코드 골프 언어로 인해 좋아하는 언어로 제출하지 못하게하십시오!

답변:


8

자바 스크립트 (ES6), 122 (113) 103 바이트

챌린지에 설명 된 형식과 관련하여 입력 값을 조옮김 행렬로 가져옵니다. 교환을 (from,to)형식으로 설명하는 문자열을 리턴 합니다.

a=>(g=(s,x=b=0,h='')=>a.map((r,y)=>~h.search(k=`(${x},${y})`)||g(s*r[x],y,h+k),x|s<b||(b=s,p=h)))(1)&&p

첫 번째 테스트 사례 : 온라인으로 사용해보십시오!

더 많은 테스트 사례 : 온라인으로 사용해보십시오!

댓글

a => (                  // given the exchange rate matrix a[][]
  g = (                 // g = recursive function taking:
    s,                  //   s = current amount of money
    x = b = 0,          //   x = ID of current currency, b = best result so far
    h = ''              //   h = exchange history, as a string
  ) =>                  //  
  a.map((r, y) =>       // for each row at position y in a[]:
    ~h.search(          //   if we can't find in h ...
      k = `(${x},${y})` //     ... the exchange key k from currency x to currency y
    ) ||                //   then:
    g(                  //   do a recursive call to g() with:
      s * r[x],         //     s = new amount obtained by applying the exchange rate
      y,                //     x = y
      h + k             //     h = h + k
    ),                  //   end of recursive call
    x | s < b ||        //   if x is our home currency and s is greater than or equal to b
    (b = s, p = h)      //   then set b to s and set p to h
  )                     // end of map()
)(1)                    // initial call to g() with s = 1
&& p                    // return p

4

파이썬 (2) , 143 (125) 124 바이트

lambda M:g(M)[1]
g=lambda M,s=[],p=1,x=0:max([(p,s)]*-~-x+[g(M,s+[(x,y)],p*M[x][y],y)for y in range(len(M))if(x,y)not in s])

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

0 기반 인덱싱을 사용합니다 (0은 자국 통화). 최대 지불금을 산출하는 교환 튜플 목록을 리턴합니다.

접근 방식은 무차별 적입니다. 재귀를 통해 우리는 시작하는 모든 비 가장자리 반복 경로를 방문하게됩니다 0( n통화 수이기 때문에 최대 깊이 를 제공합니다 n^2). 이 경로의 하위 집합도 '0'으로 끝나는 경우 그 대가를 극대화합니다.


1

하스켈, 175 바이트

e?l|e`elem`l=0|2>1=1
w[]=[]
w l=[maximum l];0!q=[q]
n!c@(v,i,(h,l))=do{j<-[0..3];c:((n-1)!(v*l!!i!!j*(i,j)?h,j,((i,j):h,l)))}
z l=w$filter(\(v,e,_)->v>1&&e==0)$12!(1,0,([],l))

여기 사용해보십시오

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