내 파스타 소스에 무엇입니까?


37

배경

프랑스에서, 그리고 아마도 유럽 연합 (EU), 판매 가능한 음식의 나머지 있어야 에, 포장에 그것을 구성하는 성분 목록 무게 비율 내림차순를 . 그러나 성분이 표지의 텍스트 나 이미지로 강조 표시 되지 않는 한 정확한 백분율을 표시 할 필요는 없습니다 .

예를 들어 포장에 큰 빨간 토마토와 아름다운 바질 잎만을 보여주는 바질 토마토 소스에는 다음과 같은 표시가 있습니다.

성분 : 토마토 80 %, 양파 조각, 바질 1.4 %, 바다 소금, 으깬 마늘, 생 지팡이 설탕, 엑스트라 버진 올리브 오일, 후추.

사치스러운 소리로 들리지만… 얼마나 많은 양파를 먹을 까요?

도전

내림차순으로 가중치 백분율 목록이 주어지면 결국 불완전한 경우 레시피에서 찾을 수있는 최소최대 가중치 백분율 의 전체 목록을 출력합니다 .

  • 함수 또는 전체 프로그램을 작성할 수 있습니다.
  • 입력은 임의의 적절한 형식 (예를 들면, 숫자 나 문자열리스트 어레이) 일 수있다. 분수 값은 소수점 이하 1 자리까지 지원해야합니다. 누락 된 중량 백분율은 일관되고 모호하지 않은 방식으로 표시 될 수 있습니다 (예 0: '?'또는 null). 당신은 입력이 항상 올바른 조리법에 연결됩니다 (가정 수 [70][∅, ∅, 50]예를 들어, 무효).
  • 출력은 어떤 적당한 형태 (예를 들면, 최소 및 최대 무게 백분율 또는 이중선의 단일리스트 모두 하나 개의 어레이) 일 수있다. 최소 및 최대 비율은 어떤 순서로 (가능 [min, max]하고 [max, min]모두 허용). 정확한 중량 백분율은 다른 백분율과 다르게 처리 될 필요가 없으며 최소값과 최대 값이 동일하게 표시 될 수 있습니다.

대한 표준 규칙이 적용됩니다. 코드를 입력하는 동안 파스타 접시가 식고 있으므로 가장 짧은 제출이 승리합니다.

이 문제는 언뜻보기에는 어렵 기 때문에 다음은 몇 가지 경우에 대한 단계별 해결 방법입니다.

[40, ∅, ∅]

각각 xy두 개의 누락 백분율을 호출합시다 .

  • 그것은 첫 번째 성분의 40 %에서 나오기 때문에 40 % x보다 높을 수 없습니다.
    [40, [?, 40], [?, ?]]
  • 누락 된 두 백분율의 합은 항상 60 %입니다. 결과적으로 :
    • 경우 x그 소요 최대 값 다음 y의 필요 최소한 = 20 % 40 % - 60 % 따라서 값.
      [40, [?, 40], [20, ?]]
    • 경우 x는 필요 최소한의 값을, 다음 y의 소요 최대 값입니다. 그러나 x보다 작을 수 없으므로이 y경우 x= y= 60 % / 2 = 30 %입니다.
      [40, [30, 40], [20, 30]]

[70, ∅, ∅, 5, ∅]

의 각각 부르 자 x, y그리고 z세없는 비율.

  • 에 대한 최소 및 최대 백분율 z은 반드시 0 %에서 5 % 사이입니다. z잠시 동안 = 0 %로 가정하자 . 누락 된 두 백분율의 합은 항상 25 %입니다. 결과적으로 :
    [70, [?, ?], [?, ?], 5, [0, 5]]
    • 경우 y그 걸리는 최소 값 5 %, 다음 x의 필요 최대 = 20 % 5 % - 25 % 따라서 값.
      [70, [?, 20], [5, ?], 5, [0, 5]]
    • 경우 y의 소요 최대 값을, 다음 x의 필요 최소한의 값입니다. 그러나 x보다 작을 수 없으므로이 y경우 x= y= 25 % / 2 = 12.5 %입니다.
      [70, [12.5, 20], [5, 12.5], 5, [0, 5]]
  • z= 5 % 라고 가정하면 모든 것이 정상인지 확인합시다 . 누락 된 두 백분율의 합은 항상 20 %입니다. 결과적으로 :
    • 경우 y그 걸리는 최소 값 5 %, 다음 x의 필요 최대 = 15 % 5 % - 20 % 따라서 값. 이 사례는 이미 이전에 계산 된 범위에 포함되어 있습니다.
    • 경우 y의 소요 최대 값을, 다음 x의 필요 최소한의 값입니다. 그러나 x보다 작을 수 없으므로이 y경우 x= y= 20 % / 2 = 10 %입니다. 이 사례는에 대해 이전에 계산 된 범위에 이미 포함되어 y있지만에 대해서는 포함되어 있지 않습니다 x.
      [70, [10, 20], [5, 12.5], 5, [0, 5]]

테스트 사례

Input:  [∅]
Output: [100]

Input:  [70, 30]
Output: [70, 30]

Input:  [70, ∅, ∅]
Output: [70, [15, 30], [0, 15]]

Input:  [40, ∅, ∅]
Output: [40, [30, 40], [20, 30]]

Input:  [∅, ∅, 10]
Output: [[45, 80], [10, 45], 10]

Input:  [70, ∅, ∅, ∅]
Output: [70, [10, 30], [0, 15], [0, 10]]

Input:  [70, ∅, ∅, 5, ∅]
Output: [70, [10, 20], [5, 12.5], 5, [0, 5]]

Input:  [30, ∅, ∅, ∅, 10, ∅, ∅, 5, ∅, ∅]
Output: [30, [10, 25], [10, 17.5], [10, 15], 10, [5, 10], [5, 10], 5, [0, 5], [0, 5]]


3
나는에 대한 입력 대 출력의 단계별 설명을 추가 [40, ∅, ∅]하고 [70, ∅, ∅, 5, ∅]좀 더 명확하게 메이크업 것들에. 테스트 사례를 보지 않고 당면한 과제는 분명하지만, 지금은 그렇지 않습니다. 내가 그것을 올바르게 이해한다면 [40, ∅, ∅]: 100 %에는 60 개가 더 필요 하며이 두 개로 나뉩니다 . 첫 번째 는 30 이상이어야합니다 (그렇지 않으면 두 번째 는 위에있을 것이므로 순서가 맞지 않아야합니다). 또한 위에있을 수 없으므로 40첫 번째 [30,40]이고 두 번째가가됩니다 [(100-40-40=)20, (100-40-30=)30].
Kevin Cruijssen

일관되게 [min,max]/ [max,min]또는 혼합 허용됩니까?
l4m2

@ l4m2 믹싱 [min,max]하고 [max,min]경계선이 허용되지만 모호한 결과로 이어질 수 없으므로 괜찮습니다.
Blackhole

어쩌면 내가 뭔가를 잃어 버렸지 만 [70, 12, 11, 5, 2]두 번째 예에서 왜 효과가 없습니까? 작동하는 경우 최소값은 x보다 작습니다 12.5.
DLosc

답변:


11

자바 스크립트 (ES6), 252 바이트

0누락 된 백분율이 예상 됩니다. 모든 항목에 대한 최소값과 최대 값 쌍을 반환합니다.

a=>(g=a=>(h=(M,I,J=I^1)=>a.some((x,i)=>a.map((y,j)=>s-=j-i?M(j,i)-i?y[I]:M(w=y[I],z=x[J])-z||w==z?w:++k&&z:y[J],s=100,k=1,X=x)&&(I?-s:s)<0)?X[J]=M(X[I],X[J]+s/k):0)(Math.max,0)+h(Math.min,1)?g(a):a)(a.map((n,i)=>[n?p=n:a.find(n=>i--<0&&n)||0,p],p=100))

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

어떻게?

초기화

먼저 입력 배열 a [] 의 각 값을 가능한 가장 큰 범위로 바꿉니다.

a.map((n, i) =>       // for each value n at position i in a[]:
  [                   //   generate a [min, max] array:
    n ?               //     if n is not 0:
      p = n           //       use n as the minimum and save it in p
    :                 //     else:
      a.find(n =>     //       find the first value n
        i-- < 0 &&    //         which is beyond the current value
        n             //         and is not equal to 0
      ) || 0,         //       or use 0 as a default value
    p                 //     use p as the maximum
  ],                  //   end of array declaration
  p = 100             //   start with p = 100
)                     // end of map()

예 :

[ 0 ] --> [ [ 0, 100 ] ]
[ 30, 0, 5, 0 ] --> [ [ 30, 30 ], [ 5, 30 ], [ 5, 5 ], [ 0, 5 ] ]

주요 기능

주요 함수는 h () 입니다. 최소화하거나 최대화하려고 할 때 일치하지 않는 첫 번째 항목을 찾습니다. 하나를 찾으면 다른 범위를 고려할 때 적어도 일시적으로 허용되는 값으로 업데이트합니다.

입력하거나 그것이 얻어 M = Math.max은 / I = 0 또는 M = Math.min은 / I = 1 과 정의 J를 같이 I XOR 1 .

h () 는 최소화 및 최대화 패스를 모두 지원하도록 작성 되었으므로 코드를 주석 처리하기가 약간 까다 롭습니다. 그렇기 때문에 M = Math.max , I = 0J = 1 인 최대화 패스에만 중점을 둘 것 입니다. 이러한 매개 변수를 사용하면 코드는 다음과 같이 읽습니다.

a.some((x, i) =>              // for each range x at position i in a[] (tested range):
  a.map((y, j) =>             //   for each range y at position j in a[] (reference range):
    s -=                      //     update s:
      j - i ?                 //       if i is not equal to j:
        Math.max(j, i) - i ?  //         if j > i:
          y[0]                //           the reference range is beyond the tested range
                              //           so we just use the minimum value of the y range
        :                     //         else:
          Math.max(           //           take the maximum of:
            w = y[0],         //             w = minimum value of the y range
            z = x[1]          //             z = maximum value of the x range
          ) - z ||            //           if it's not equal to z
          w == z ?            //           or they are equal (i.e. if w <= z):
            w                 //             use w
          :                   //           else:
            ++k && z          //             increment the counter k and use z
      :                       //       else:
        y[1],                 //         use the maximum value of the y range
    s = 100,                  //     start with s = 100
    k = 1,                    //     start with k = 1
    X = x                     //     save the range x in X
  ) &&                        //   end of map()
  (0 ? -s : s) < 0            //   abort if s < 0 (i.e. if we've subtracted more than 100)
) ?                           // end of some(); if truthy:
  X[1] = Math.max(            //   update the maximum value of the faulty range to:
    X[0],                     //     either the minimum value
    X[1] + s / k              //     or the maximum value, less the correction
  )                           //   whichever is greater
:                             // else:
  0                           //   do nothing

재귀

재귀 함수 g () 는 최소화 또는 최대화 패스가 새로운 수정으로 이어질 때까지 h ()를 계속 호출 하여 최종 결과를 반환합니다.

g = a => h(Math.max, 0) + h(Math.min, 1) ? g(a) : a

잘했다 :-)!
Blackhole

4
@Blackhole 감사합니다! 그리고 BTW : 내 파스타 소스가 읽습니다 [38,0,10,0,0,0,0,0,0,0].
Arnauld 19
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.