거절하기 좋은시기


16

설정

당신이 제공하는 가정 N 1, 퓨즈 ≤ N ≤ 5 미터가 긴 각각, 각 퓨즈의 연관된 연소율 갖는 경우 N의 당 m D의 시간.

퓨즈는 한쪽 또는 양쪽 끝에서 켜진 후 퓨즈가 완전히 소비 될 때까지 필요한만큼 여러 번 한쪽 끝 또는 양쪽 끝에서 꺼 지거나, 다시 켜거나 꺼질 수 있습니다. 퓨즈를 즉시 켜고 끌 수 있으며, 퓨즈가 완전히 소비 된 (즉 번인) 순간을 정확히 관찰 할 수 있습니다.

퓨즈 절단 할 수 없으며 끝을 제외하고 어디에서나 불을 켤 수 없습니다 .

이러한 설정은 두 개의 퓨즈 조명 / 소비 이벤트 사이의 시간을 측정하여 무한정 정확한 타이밍 시스템을 허용합니다. 예를 들어, 시간당 1 미터의 연소율을 가진 두 개의 퓨즈가 제공된 경우 정확히 45 분 (3/4 시간)을 측정 할 수 있습니다.

  1. 동시에 : 양쪽 끝에 첫 번째 퓨즈 조명, 한쪽 끝에 두 번째 퓨즈 조명, 시간 간격의 시작 표시
  2. 첫 번째 퓨즈가 소비되는 순간에 두 번째 퓨즈의 두 번째 끝 조명 (30 분 후)
  3. 두 번째 퓨즈가 소비되는 순간 시간 간격의 끝 표시 (15 분 후)

도전

소수의 시간 tn 개의 퓨즈 의 정확한 연소율을 나타내는 n 개의 분수가 주어지면, 퓨즈의 체계적인 연소를 통해 t 시간을 정확하게 측정 할 수 있다면 진실한 값을 출력 / 반환하는 프로그램 또는 기능을 작성하십시오 . 그렇지 않으면 허위 가치.

프로그램에 대한 입력은 다음 중 하나 일 수 있습니다.

  • 양식의 명령 행 인수 TN/TD N1/D1 N2/D2 N3/D3 ...
  • TN/TD N1/D1 N2/D2 N3/D3 ...stdin거나 동등한 형식의 문자열
  • TN/TD N1/D1 N2/D2 N3/D3 ...함수 인수 로 전달 된 형식의 문자열
  • ["TN/TD", "N1/D1", "N2/D2", "N3/D3", ...]함수 인수로 전달 된 문자열 배열

모든 경우에 t = TN/ TD, 여기서 TN, TD∈ [1,10000].

마찬가지로, 모든 경우 : 퓨즈 연소율 = N을 I / D I = N<i>/ D<i>여기서 N<i>, D<i>∈ [1,10] ∀ I .

항상 1 ~ 5 개의 퓨즈 (포함)가 있고 모든 입력이 유효하고 범위 내에 있다고 가정 할 수 있습니다. 또한 모든 입력 비율이 가장 낮은 용어로 주어진다고 가정 할 수 있습니다.

이 문제에 대해 소수 구성 요소와 함께 부동 소수점 숫자를 사용할 수 없습니다. 즉, 응용 프로그램의 어느 곳에서나 부동 소수점 숫자를 사용하면 소수 성분이 0이 아닌 정수 값만 사용할 수 있습니다.

채점

이것은 챌린지이므로 바이트 단위의 가장 짧은 준수 제출이 승리합니다.


입력 / 출력 예

input:  29/6 3/2 2/3 3/5 3/7 7/5
output: true

One solution:
  - light both ends of fuse 1, mark start of interval
  - on fuse 1 consumption: light both ends of fuse 2, light one end of fuse 5
  - on fuse 5 consumption: extinguish one end of fuse 2, light both ends of fuse 3,
    light both ends of fuse 4
  - on fuse 2 consumption: extinguish one end of fuse 3, extinguish both ends of
    fuse 4
  - on fuse 3 consumption: relight one end of fuse 4
  - on consumption of fuse 4: mark end of interval (29/6 hours)

input:  2/1 3/1 5/1 7/1
output: false

input:  5/1 6/1 1/6 9/1 1/9
output: true

One solution:
  - light fuse 1 at one end, light fuse 2 at both ends, light fuse 4 at both ends
  - on fuse 1 consumption: extinguish one end of fuse 2, mark start of interval
  - on fuse 4 consumption: relight one end of fuse 2
  - on fuse 2 consumption: mark end of interval (5 hours)

행복한 융합! :)


@ MartinBüttner 부동 소수점 숫자 제한이라고 생각합니다.
hmatt1

2
@ MartinBüttner 소스 코드에 제한이 없다는 데 동의합니다. [restricted-source]가 현재이 질문에 적합하지 않다고 생각합니다.
hmatt1

@ chilemagic : 부동 소수점 논리를 사용할 수 없다는 사실에주의를 기울이고 싶었지만 태그를 올바르게 사용하지 않는다는 합의가 있다면 제거하겠습니다.
COTO

테스트 케이스가 너무 큼 :)
feersum

5
롤, 골프 목적으로 O ((n!) ^ 3) 알고리즘을 사용하고 있습니다.
feersum

답변:


8

파이썬 2, 305

이것은 골프 버전입니다. 시간 (및 공간) 복잡도가 3 n 2 와 같기 때문에 실제로는 시간에 비해 너무 낮을 수 있으므로 n> 3 에서는 실제로 사용할 수 없습니다 . 어쨌든 함수는 문자열 목록을 허용합니다.

def f(i):
 Z=range;r=map(__import__('fractions').Fraction,i);R=r[1:];n=len(R);L=[[[1]*n,[0]]];g=0
 for m,p in L: 
  for d in([v/3**i%3for i in Z(n)]for v in Z(3**n)):
    try:x=min(m[i]/R[i]/d[i]for i in Z(n)if m[i]*d[i]>0);L+=[[[m[i]-x*R[i]*d[i]for i in Z(n)],[p[0]+x]+p]]
    except:g|=p[0]-r[0]in p
 return g

약간 최적화 된 버전은 몇 분 안에 테스트 사례를 완료 할 수 있습니다. 불가능한 n = 5 경우에는 여전히 느릴 수 있습니다 .

def fLessslow(i):
 Z=range
 r=map(__import__('fractions').Fraction,i)
 R=r[1:]
 n=len(R)
 L=[((1,)*n,(0,))]
 ls = set(L)
 for m,p in L: 
  if p[0]-r[0]in p: return 1
  for d in([v/3**i%3 for i in Z(n)]for v in Z(3**n)):
   if any(d[i] and m[i]<=0 for i in Z(n)):continue
   try:
    x=min(m[i]/R[i]/d[i]for i in Z(n)if m[i]*d[i]>0)
    thing = (tuple(m[i]-x*R[i]*d[i]for i in Z(n)),(p[0]+x,)+p)
    if thing not in ls:L+=[thing];ls.add(thing)
   except:5
 return 0

print fLessslow('5/1 6/1 1/6 9/1 1/9'.split())
print fLessslow('29/6 3/2 2/3 3/5 3/7 7/5'.split())

1
버그가있는 코드에 대한 좋은 8 가지 찬성 : 설명에서 예제를 사용하여 함수 호출 : print f ( '3/4 1/1 1 / 1'.split ())는 설명에서 알 수 있듯이 0을 반환합니다. .
Jakube

@Jakube 테스트 해 주셔서 감사합니다 ...이 사이트에서는 매우 드 rare니다! 이제 수정되었습니다. 나는 밧줄의 끝이 얼마나 많은지에 따라 한곳에서 1 또는 2의 요소로 나눌 것을 잊었습니다.
feersum

3

파이썬 2, 331

그것은 feersum의 버전보다 약간 길지만 훨씬 빠릅니다. 모든 테스트 케이스는 랩톱에서 약 3 초가 걸립니다. n = 5를 완전히 검색하려면 10 분이 걸립니다. 일부 코드는 feersum의 버전과 비슷하지만 의도적으로 코드를 복사하지 않았습니다.

from fractions import*
f=Fraction
r=range
g=lambda x:h(f(x[0]),[1/f(i)for i in x[1:]],[])
def h(t,x,y):
 for i in r(1,3**len(x)):
  c=[[],[],[]]
  for j in r(len(x)):c[i/3**j%3]+=[x[j]]
  n,b,w=c
  m=min(b+[i/2 for i in w])
  if h(t,[i for i in n+[j-m for j in b]+[j-2*m for j in w]if i],[i+m for i in y]+[m]):return True
 return t in y

용법:

print g('3/4 1/1 1/1'.split())
print g('29/6 3/2 2/3 3/5 3/7 7/5'.split())
print g('2/1 3/1 5/1 7/1'.split())
print g('5/1 6/1 1/6 9/1 1/9'.split())

설명:

람다 식 g는 문자열을 분수로 변환하고 목표 시간을 연소율과 분리하고 연소 시간 (= 1 / 연소율)을 계산하는 것과 같이 입력의 일부 전처리를 수행합니다.

h 함수는 모든 레코딩 시간 x를 3 세트 n, b 및 w로 나눕니다 (n은 비 연소, b는 one_end_burning, w는 both_ends_burning). 모든 배치를 반복하고 (배열 n = x, b = [], w = [] 제외) 가장 짧은 레코딩 속도 (저장 시간 (m))로 퓨즈를 결정하고 업데이트 된 레코딩 시간으로 h를 재귀 적으로 호출합니다. y에서는 누군가 퓨즈를 사용하여 측정 할 수있는 모든 시간을 절약합니다. 재귀 호출에서 이러한 값도 업데이트됩니다.

값을 찾 자마자 True를 사용하여 모든 통화를 종료합니다.


4
젊은 파이썬 프로그래머에게는 모든 내장 분수와 큰 정수가 손상됩니다. 나는 young'un이 때 뒤로, 우리가 가진 모든했다 1's와 0우리가 모니터없이 콘솔에서 한 번에 하나씩에 입력 한의. 때때로 우리는 1s 가 없었습니다 .
COTO
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.