소수 자르기 및 계산


11

이 과제에서는 입력 문자열 에 소수점 이하 자릿수를 출력 하고 필요한 경우 입력을 자르는 프로그램을 작성 합니다.

-12.32
2

32
0

3231.432
3

-34.0
0 -34

023
0 23

00324.230
2 324.23

10
0

00.3
1 0.3

0
0

-04.8330
3 -4.833

규칙

  • 입력은 STDIN, 함수 인수 또는 가장 가까운 해당 문자열을 통해 가져올 수있는 문자열입니다.
  • 출력은 함수 리턴, STDOUT 또는 가장 가까운 해당 항목을 통해 이루어질 수 있습니다.
  • 언어의 최대 문자열 길이를 제외하고 입력 정수의 크기에는 제한이 없습니다 .
  • 입력에 불필요한 (행간 또는 후행) 0이있는 경우 :
    1. 당신은 그들을 꺼내야합니다
    2. 새 숫자의 소수점 이하 자릿수를 출력합니다
    3. 구분 기호로 구분 된 새 숫자를 출력합니다 (예 : 공백, 줄 바꿈, 쉼표)
  • 입력은 항상이 RegEx :와 일치 -?\d+(\.\d+)?하거나 RegEx를 말하지 않는 경우 :
    • -음의 번호를 의미 시작 부분에. 그런 다음에있을 것입니다 적어도 하나의 숫자. 그러면 ... 그리고 더 많은 숫자 가있을 있습니다 ..
    • 입력이 유효한지 확인하려면 여기를 확인하십시오.
  • 정규식 없음

이것은 이므로 바이트 단위의 가장 짧은 코드가 승리합니다.


빼기 부호와 앞에 0이있는 테스트 사례를 추가 할 수 있습니까?
Luis Mendo

트리밍 여부에 관계없이 최종 번호를 출력 할 수 있습니까?
insertusername 여기

1
@insertusername 여기서 두 번째 숫자가 잘린 경우에만 출력 할 수 있습니다
Downgoat

1
단일 테스트 사례 / 예제를 추가 할 수 있습니다 0.
insertusername 여기

3
무의미한 정규 표현식 제한의 경우 -1입니다.
코너 오브라이언

답변:


0

PHP 7, 142 바이트

어떻게 든 모든 것을 하나의 인쇄 진술로 짜낼 수있었습니다.

<?=strlen((explode('.',$t=trim('-'==($_=$argv[1])[0]?$n=$_=trim($_,'-'):$_,0)))[1]).($t!==$_?($n?' -':' ').('.'==$t[0]?0:'').trim($t,'.'):'');

다음과 같이 명령 행에서 실행합니다.

$ php trimandcount.php "-04833.010"

데모

작동하는 매우 긴 문자 (62 자)를 포함한 모든 테스트 사례를 확인하십시오.

구매하기 전에 시도 1

1 모든 결과를 보려면 " 7.0.0 출력 "아래의 상자 위로 마우스를 가져갑니다 .


4

파이썬 2, 165180 바이트

처음에 나는 첫 번째 Pyth 프로그램을 작성하려고 생각하고 잠재적 쉼표 뒤에 숫자를 세도록했습니다. 그러나 나는 매우 화가 났으며, 당신이 그 언어를 어떻게 즐길지 모르겠습니다. 단지 승리의 목적이라고 생각합니다. 어쨌든 여기 내 솔루션이 있습니다 (많은 수가 작동하지 않기 때문에 편집).

def t(i):
 o,a='',i
 while a[-1]=='0':
  a=a[:-1]
 while a[0]=='0':
  a=a[1:]
 if a[-1]=='.':a=a[:-1]
 if'.'in a:o=str(len(a)-a.index('.')-1)
 else:o='0'
 if a!=i:o+=" "+a
 print o

누군가가 Pyth에서 내 작품을 만들고 싶다면 : ~b@+cz"."" "1Wq@b_1"0"~b<b_1)plrb6당신이 어디에 있는지 보려면, 사이에 ap를 삽입 할 수 있습니다 @+.


2

05AB1E , 23 바이트 (비경쟁)

젠장, 나는 너무 가까웠다. 파이썬은 과학적 표기법을 사용하여 매우 큰 수레를 구문 분석하므로 인터프리터 에서이 버그를 수정했습니다. 그러나 이것은 도전 후에 이루어 졌으므로 제출은 비 경쟁적입니다.

암호:

DÞ'.¡0Üg,\DÞ0Ü'.ÜDrQ_i,

설명:

D                       # Duplicate top of the stack, or input when empty
 Þ                      # Convert to float
  '.¡                   # Split on '.' (decimal point)
     0Ü                 # Remove trailing zeroes
       g                # Get the length
        ,               # Output top of the stack (the length)
         \              # Discard the top item
          D             # Duplicate top of the stack
           Þ            # Convert to float
            0Ü          # Remove trailing zeroes
              '.Ü       # Remove trailing dots
                 D      # Duplicate top of the stack
                  r     # Reverse the stack
                   Q_i, # If not equal, print top of the stack

ISO 8859-1 인코딩을 사용합니다 .


2

자바 스크립트 (ES6) 156 162

편집 에 대한 버그 수정 '-0'- 들으 @Fez Vrasta 편집이 6 바이트 저장 들으 @Neil

엉망이지만 100 % 문자열 기반-숫자 유형으로 인한 제한 없음

s=>(l=k=p=t=0,[...s].map(c=>++t&&c=='.'?p=t:+c&&(l=t,k=k||t)),m=p>l?p-1:p?l:t,k=k>p&&p?p-2:k-1,r=(s<'0'?'-':'')+s.slice(k,m),(p&&m>p?m-p:0)+(r!=s?' '+r:''))

덜 골프

f=s=>
(
  // All values are position base 1, so that 0 means 'missing'
  // k position of first nonzero digit
  // l position of last non zero digit
  // p position of decimal point
  // t string length
  l=k=p=t=0,
  // Analyze input string
  [...s].map((c,i)=>c=>++t&&c=='.'?p=t:+c&&(l=t,k=k||t)),
  // m position of last digits in output
  // if the point is after the last nz digit, must keep the digits up to before the point
  // else if point found, keep  up to l, else it's a integer: keep all
  m=p>l?p-1:p?l:t,
  // the start is the first nonzero digit for an integer
  // but if there is a point must be at least 1 char before the point
  k=k>p&&p?p-2:k-1,
  // almost found result : original string from k to m
  r=(s<'0'?'-':'')+s.slice(k,m), // but eventually prepend a minus
  (p&&m>p?m-p:0) // number of decimal digits
  +(r!=s?' '+r:'') // append the result if it's different from input
)

테스트

F=s=>(l=k=p=t=0,[...s].map(c=>++t&&c=='.'?p=t:+c&&(l=t,k=k||t)),m=p>l?p-1:p?l:t,k=k>p&&p?p-2:k-1,r=(s<'0'?'-':'')+s.slice(k,m),(p&&m>p?m-p:0)+(r!=s?' '+r:''))

console.log=x=>O.textContent+=x+'\n';
// Test cases  
;[['-12.32','2'],['32','0'],['3231.432','3'],['-34.0','0 -34']
 ,['023','0 23'],['00324.230','2 324.23'],['10','0'],['00.3','1 0.3']
 ,['0','0'],['-0','0'],['-04.8330','3 -4.833']]
.forEach(t=>{
  var i=t[0],k=t[1],r=F(i);
  console.log((k==r?'OK ':'KO ')+i+' -> '+r)})

function test(){var i=I.value,r=F(i);R.textContent=r;}
test()
input { width:90% }
input,span { font-family: sans-serif; font-size:14px }
Input: <input id=I oninput='test()' value='-000000098765432112345.67898765432100000'>
Output: <span id=R></span><br>
Test cases<br>
<pre id=O></pre>


내 답변과 답변 모두 -0입력으로 문제가있는 것 같습니다 . 우리는 출력해야합니다0 하지 않아야합니다.0 0
Fez Vrasta

예, 지적 해 주셔서 감사합니다
edc65

@FezVrasta 고정
edc65

않습니다 c=='.'?p=t:+c&&(l=t,k=k||t)작업은 당신에게 바이트를 저장하려면?

나는 당신이 사용하여 더 많은 것을 절약 할 수 있다고 생각합니다 t=l=k=p=0++t&&c=='.'

1

ES6, 102 (180) 177 바이트

s=>(t=s.replace(/(-?)0*(\d+(.\d*[1-9])?).*/,"$1$2"),d=t.length,d-=1+t.indexOf('.')||d,t!=s?d+' '+t:d)

s=>{t=[...s];for(m=t[0]<'0';t[+m]==0&&t[m+1]>'.';)t[m++]='';r=l=t.length;for(r-=1+t.indexOf('.')||l;t[--l]<1&&r;r--)t[l]='';t[l]<'0'?t[l]='':0;t=t.join``;return t!=s?r+' '+t:r}

편집 : @ edc65 덕분에 3 바이트가 절약되었습니다. insertusername 덕분에 1 바이트가 절약되었습니다.


분할 대신 스프레드 시도t=[...s]
edc65

@ edc65 나는 그것을 다시 쓴 후 다시 골프를하려고 나이를 보내고 당신은 가서 플래시에 3 바이트 절약을 찾을 수 있습니다 ...
Neil

1 바이트를 절약 할 수 있다고 생각합니다 : Replace t[--l]==0with t[--l]<1.
insertusername 여기

@insertusername 여기 감사합니다!
Neil

0

C ++, 180 바이트

int f(char*s,char*&p){int m=*s=='-',n=0;for(p=s+m;*p=='0';++p);for(;*++s-'.'&&*s;);p-=p==s;if(*s){for(;*++s;)++n;for(;*--s=='0';--n)*s=0;*s*=n>0;}if(m&&*p-'0'|n)*--p='-';return n;}

이것은 이식 가능한 C ++로, 문자 인코딩을 가정하지 않으며 라이브러리도 포함하지 않습니다 (표준 라이브러리도 포함하지 않음).

입력이 전달됩니다 s . 소수점 이하 자릿수가 반환됩니다. 문자열이 내부에서 수정되고 새 시작이에 반환됩니다 p.

권리에 의해, 나는 size_t 하지만 대신 문자열 크기를의 범위의 절반으로 제한하는 OS에 대해 컴파일해야한다고 주장합니다 int. 나는 그것이 합리적이라고 생각한다. 32 비트 아키텍처에서 소수점 이하 20 억 이상을 계산합니다.

설명

int f(char*s, char*&p){
    int m=*s=='-', n=0;
    for(p=s+m;*p=='0';++p);     // trim leading zeros
    for(;*++s-'.'&&*s;);        // advance to decimal point
    p-=p==s;                    // back up if all zeros before point
    if(*s){
        for(;*++s;)++n;          // count decimal places
        for(;*--s=='0';--n)*s=0; // back up and null out trailing zeros
        *s*=n>0;                 // don't end with a decimal point
    }
    if(m&&*p-'0'|n)*--p='-';    // reinstate negative sign
    return n;
}

테스트 프로그램

#include <cstring>
#include <cstdio>
int main(int argc, char **argv)
{
    for (int i = 1;  i < argc;  ++i) {
        char buf[200];
        strcpy(buf, argv[i]);
        char *s;
        int n = f(buf, s);
        printf("%10s ==> %-10s (%d dp)\n", argv[i], s, n);
    }
}

테스트 출력

    -12.32 ==> -12.32     (2 dp)
        32 ==> 32         (0 dp)
  3231.432 ==> 3231.432   (3 dp)
     -34.0 ==> -34        (0 dp)
       023 ==> 23         (0 dp)
 00324.230 ==> 324.23     (2 dp)
        10 ==> 10         (0 dp)
      00.3 ==> 0.3        (1 dp)
  -04.8330 ==> -4.833     (3 dp)
    -00.00 ==> 0          (0 dp)
       -00 ==> 0          (0 dp)
       000 ==> 0          (0 dp)
      0.00 ==> 0          (0 dp)
      -0.3 ==> -0.3       (1 dp)
         5 ==> 5          (0 dp)
        -5 ==> -5         (0 dp)
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.