반올림 만족


16

반올림 만족

당신은 과학 수업 시간에 알고 있고 2 시그마 무화과로 반올림하도록 요청했지만 당신의 대답은 5.2501...? 로 반올림해야 5.3하지만 너무 만족스럽지 않습니다! 으로 반올림 5.3하면 전체 0.05만큼 줄어 듭니다. 0.1 (반올림 한 자리 값)에 비해 많은 양입니다! 만족스러운 방식으로 반올림하도록 도와주세요.

만족스러운 방식으로 반올림하려면 반올림 할 때 발생할 수있는 최대 오류의 절반보다 작은 오류가 발생하는 첫 번째 숫자를 반올림해야합니다. 기본적으로 0, 1, 8 또는 9가 발생할 때마다 반올림해야합니다. 이러한 상황이 발생하지 않으면 입력을 그대로 반환하십시오. 선행 0 또는 1을 반올림하지 마십시오. 만족스럽지 않습니다.

입력

음수가 아닌 10 진수를 나타내는 문자열 또는 부동 소수점 값.

산출

문자열 또는 부동 형식의 동일한 10 진수가 만족스럽게 반올림됩니다.

Input -> Output
0 -> 0
0.5 -> 0.5
0.19 -> 0
0.8 -> 1
5.64511 -> 5.645
18.913 -> 20
88.913 -> 100
36.38299 -> 36.4
621 -> 620
803.22 -> 1000
547.4726 -> 547.4726

이것은 도전이므로 가장 짧은 코드가 승리합니다!



같은 문자열 036.40000이 유효한 출력 으로 간주됩니까?
Arnauld

1
.0정수가 주어진 다고 가정 할 수 있습니까 ? 또한 0긍정적이지 않습니다.
Outgolfer Erik

@EriktheOutgolfer 아니요, 감사합니다. 음수가 아닌 것으로 변경 될 수도 있습니다.
Quintec

1
그래서 19에 라운드 200.19에 라운드 0? 왜?
Neil

답변:


2

자바 스크립트 (ES6),  100 99 98  78 바이트

입력을 문자열로받습니다. float를 반환합니다.

s=>+(0+s).replace(/\d/g,(d,i)=>j&&+d+((n=s[i+!++s[i]])<2&&i?--j:n>7&&j--),j=1)

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

어떻게?

먼저 입력 문자열 앞에 선행 0 을 추가하여 가능한 선행 8 또는 9 앞에 숫자를 보장 하여 반올림을 즉시 트리거해야합니다.

플래그 j 는 만족스러운 반올림을 수행 할 수있는 숫자를 찾고있는 동안 1 로 설정되고 그 후에 0 설정됩니다 .

우리가 걷는 문자열에 선행 0 이 추가되었지만 s 는 변경되지 않았 으므로 d 는 현재 문자를 포함하고 s[i]다음 문자를 가리 킵니다 .

다음 코드를 사용하여 가능한 소수 구분 기호를 건너 뛰고 n 의 다음 숫자를로드합니다 .

n = s[i + !++s[i]]

문자열은 JavaScript에서 변경할 수 없지만 s [ i ] 가 실제로 증가하지 않더라도 숫자 값이 포함 된 경우 표현식 ++s[i]s[i]+1 반환합니다 . 따라서, 발현 을 평가 f를 L S E (강제적으로 0 (포함하는 모든 자리 용) 0 )과 행 t R U E (강제로 1 ) 십진수 분리기 .s[i]!++s[i]false00true1"."

반올림이 발생 d + --j하면 다음 숫자 n0 또는 1 이고 원래 입력의 선행 숫자가 아니고 n8 또는 9 인d + j-- 경우 결과를 n . 따라서 j 는 두 경우 모두 0 으로 설정 되지만 첫 번째 경우에는 0d 를, 두 번째 경우에는 1 을 더합니다 (반올림).89j00d1


1
그리고 핀볼 / 고무 공은 도랑에 빠진다! :)
Quintec

2

루비 , 79 77 69 67 65 바이트

->n,z=n+".0"{z[i=z=~/\./]='';n.to_f.round (z=~/(?!^)[01]|8|9/)-i}

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

설명

  • ->n 문자열로 입력하십시오
  • z=n+".0"z점과 관련 숫자가 포함 된 임시 문자열 을 만듭니다 .
  • i=z=~/\./소수점 위치를 결정 z하고에 할당합니다 i.
  • z[i]='' 더 이상 들어 가지 않도록 점을 떨어 뜨립니다.
  • z=~/(?!^)[01]|8|9/비 시작 0-1또는 임의 의 위치 8-9중 먼저 오는 위치를 결정하십시오 .
  • (...)-i 이 차이는 유지할 소수점 이하 자릿수이며, 왼쪽에서 반올림하면 음수입니다.
  • n.to_f.round ... float로 변환하고 반올림을 수행하십시오.

1

젤리 , 34 바이트

;”.ḟ$µ»"”2e€⁽¡XṾ¤;1i1_i”.$_>¥0ɓVær

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

Jonathan Allan 에게 -1 감사합니다 .


ŒV? 나도 효과가 있다고 생각 V합니다.
Jonathan Allan

@JonathanAllan Nope. (기본적으로 은행가의 반올림)
아웃 골퍼 Erik

오, 입력에 작용하지 않기 때문에? _>¥0ɓVær내 것처럼처럼 보십시오 (나는 너무 빨리 dyadic의 사용법을 그리워했습니다!)
Jonathan Allan

@JonathanAllan Ah, 체인의 영리한 사용법, 감사합니다.
Outgolfer Erik

1

젤리 ,  30  29 바이트

Outgolfer Erik 덕분에 -1 ( ¥답변에서 이색적인 단어 사용 )

O;0µ_8H1¦%8ỊTḢ_<48TḢƊ_>¥0ɓVær

부동 소수점을 생성하는 문자 목록을 허용하는 모나드 링크.

온라인으로 사용해보십시오! 또는 테스트 스위트를 참조하십시오.

어떻게

입력 문자열이 문자에서 독점적으로 이루어지는 것이 첫째 주 0123456789.서수이 [48,49,50,51,52,53,54,55,56,57,46]여덟으로 나누었을 때 나머지를 가지고 [0,1,2,3,4,5,6,7,0,1,6]. 사이 유일한 문자 -11포괄적는 0, 1, 8, 및 9.

또한 서수 ( [40,41,42,43,44,45,46,47,48,49,38]) 에서 8을 빼면 동일하게 (상당히) 보유합니다. 우리는이 (절반 경우 [20,20.5,21,21.5,22,22.5,23,23.5,24,24.5,19]사이에 여덟 나누었을 때 나머지가) 유일한 문자 -11이 포함됩니다 89.

O;0µ_8H1¦%8ỊTḢ_<48TḢƊ_>¥0ɓVær - Link: list of characters, S
O                             - ordinal (vectorises across S)
 ;0                           - concatenate a zero
                              - (to cater BOTH for no '0', '1', '8', or '9' AND for no '.')
   µ                          - start a new monadic link (call that X)
    _8                        - subtract eight (vectorises across X)
        ¦                     - sparse application...
       1                      - ...to: indices: one
      H                       - ...do: halve (i.e. halve first ordinal)
         %8                   - modulo by eight (vectorises)
           Ị                  - insignificant (abs(v)<=1?) (vectorises)
            T                 - truthy indices
             Ḣ                - head
                    Ɗ         - last three links as a monad (i.e. f(X)):
               <48            -   less than 48? (i.e. was it a '.' in S or the added 0?)
                  T           -   truthy indices
                   Ḣ          -   head
              _               - subtract
                       ¥      - last two links as a dyad
                      < 0     -   less than zero? (1 if so 0 otherwise)
                     _        -   subtract
                         ɓ    - start a new dyadic chain (i.e. f(S,X))
                          V   - evaluate S as Jelly code (i.e. get S as a float)
                           ær - round to the nearest multiple of 10^(-X)

1

레티 나 0.8.2 , 75 바이트

^[89]
10
T`d`0`(?<=.)[01].*|(?<=8|9).*
T`89d`0d`.\.?[89]
(\.|(\..+?))0+$
$2

온라인으로 사용해보십시오! 링크에는 테스트 사례가 포함됩니다. 설명:

^[89]
10

선행 8또는 의 경우를 처리하십시오 9.

T`d`0`(?<=.)[01].*|(?<=8|9).*

비 선두가 있다면 0또는 1다음과 문자열 밖으로의 나머지 부분을 제로. 거기있어 경우에도, 8또는 9, 다음 문자열의 나머지 부분에서 제로를두고 있지만. 그러나 두 경우 모두 소수점을 변경하지 마십시오.

T`89d`0d`.\.?[89]

여전히있을 경우 8또는를 9이 시점에서, 다음을 제로로하고, (아마도 소수점 전) 앞의 숫자를 증가.

(\.|(\..+?))0+$
$2

소수점 뒤에 오는 경우 0을 삭제하지만 그 사이에 다른 숫자가없는 경우에만 소수점을 삭제하십시오.


1

C (gcc) , 111102 바이트

g(_,i,j,k)char*_;{for(i=*_<56?*_++:48,j=3;j;j&=k%8>1|(i=*_++)/48*2)putchar(j&1?i+(k=_[*_<48])/56:48);}

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

//_: input, as string
//i: current digit, rounded if applicable
//j: tracks whether number is rounded, and whether \0 or '.' has been encountered
//k: digit to test rounding (round if k is one of 0,1,8,9)
//'0'==48, '8'==56
g(_,i,j,k)char*_;{
    for(i=*_<56?*_++:48,j=3;                //special case: if first digit is 8 or 9, use a
                                            //placeholder digit with value 0. initialize j.
        j;                                  //only stop execution when number is rounded and
                                            //'.' or \0 has been encountered.
        j&=k%8>1|(i=*_++)/48*2)             //check if execution should stop.
        putchar(j&1?i+(k=_[*_<48])/56:48);  //print '0' if rounding had already been done;
                                            //otherwise, print digit. round up as needed.
}

0

C # (Visual C # 대화식 컴파일러) 280 바이트

c=>{int d=c.IndexOf('.');int t=c.IndexOfAny(new char[]{'8','9','0','1'},1);var m=c[0]=='8'||c[0]=='9'?1>0:0>1;var z=decimal.Parse(c);Func<decimal>q=()=>(decimal)Math.Pow(10,m?d<0?c.Length:d:d<0?c.Length-t:d>t?d-t:d-t+1);return m?Math.Round(z/q())*q():t<0?z:Math.Round(z/q())*q();}

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

소수점 대신 double을 사용하면 짧을 수 있지만 정확도를 유지하기 위해 소수점을 사용하거나 547.4726과 같은 숫자는 547.472595214844입니다.

C # (Visual C # 대화식 컴파일러) 268 바이트

c=>{int d=c.IndexOf('.');int t=c.IndexOfAny(new char[]{'8','9','0','1'},1);var m=c[0]=='8'||c[0]=='9'?1>0:0>1;var z=float.Parse(c);Func<double>q=()=>Math.Pow(10,m?d<0?c.Length:d:d<0?c.Length-t:d>t?d-t:d-t+1);return m?Math.Round(z/q())*q():t<0?z:Math.Round(z/q())*q();}

온라인으로 사용해보십시오! (정확한 버전이 적음)

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