7
\$\begingroup\$

Input:

A decimal

Output:

The input truncated

How to truncate them?

The integer part of the input will remain the same. The decimal part of the input will be truncated based on the lowest digit in consecutive order. The two step-by-step examples below should clarify what I mean by that:

Example 1: Input: 17.46940822

Step 1: Leave the integer part unchanged: 17
Step 2: Look at the first decimal digit, and truncate it to that many decimal digits: 4.4694
Step 3: Look at the next decimal digit. If it's lower, adjust the truncation accordingly. If not, continue to the next decimal digit: 6 → remains .4694
Step 3 again: 9 → remains .4694
Step 3 again: 4 → remains .4694

So the output will be: 17.4694.

Example 2: Input: 10.4521084

Step 1: Leave the integer part unchanged: 10
Step 2: Look at the first decimal digit, and truncate it to that many decimal digits: 4.4521
Step 3: Look at the next decimal digit. If it's lower, adjust the truncation accordingly. If not, continue to the next decimal digit: 5 → remains .4521
Step 3 again: 2 → truncation adjusted to: .45

So the output will be: 10.45

Challenge rules:

  • You are allowed to take the input as decimal, string, list/array/stream of characters, etc. (Same applies to the output, although I doubt there are a lot of languages that have the proper truncation while remain working with decimal values.)
    You are also allowed to use a comma , instead of a dot . (perhaps useful for regex-based solution/languages).
  • If the decimal part is not long enough for the truncation, you are optionally allowed to add trailing zeros. I.e. 123.4 can be both 123.4 or 123.4000
  • If you have to truncate to 0 decimal digits we omit the decimal digits. The dot/comma may remain optionally if you use strings. I.e. 847.3072847 (or 847.)
  • You can assume the input will always contain at least one decimal digit, so 123 won't be an input, but 123.0 can be an input.

General rules:

  • This is , so shortest answer in bytes wins.
    Don't let code-golf languages discourage you from posting answers with non-codegolfing languages. Try to come up with an as short as possible answer for 'any' programming language.
  • Standard rules apply for your answer with default I/O rules, so you are allowed to use STDIN/STDOUT, functions/method with the proper parameters and return-type, full programs. Your call.
  • Default Loopholes are forbidden.
  • If possible, please add a link with a test for your code (i.e. TIO).
  • Also, adding an explanation for your answer is highly recommended.

Test cases:

Input:          Output:

17.46940822     17.4694
10.4521084      10.45
123.4           123.4000 (or 123.4)
-847.3072       -847 (or -847.)
123.0           123 (or 123.)
98.76543210     98.7654
0.3165          0.3
-0.1365         -0.1
82937.82937     82937.82
-0.1010101      -0.1
-1.0101010      -1 (or -1.)
28.684297       28.68
13.35           13.350 (or 13.35)
0.99999999999   0.999999999
28.321          28.32
0.56462         0.5646
\$\endgroup\$
7
  • \$\begingroup\$ Need we output string? \$\endgroup\$
    – l4m2
    Commented Oct 30, 2018 at 9:05
  • \$\begingroup\$ @l4m2 No, you are also allowed to output it as a decimal, or list of characters. Although I don't know a lot of languages that can do the proper truncation without converting to string format. \$\endgroup\$ Commented Oct 30, 2018 at 9:06
  • \$\begingroup\$ So it's fine to remove ending zero if outputing float? \$\endgroup\$
    – l4m2
    Commented Oct 30, 2018 at 9:07
  • \$\begingroup\$ @l4m2 Sure. I've updated the rules to also allow no additional trailing zeros. \$\endgroup\$ Commented Oct 30, 2018 at 9:09
  • 1
    \$\begingroup\$ Suggested test case 0.56462 (This Jelly code passes all other given test cases :() \$\endgroup\$ Commented Oct 30, 2018 at 21:40

12 Answers 12

4
\$\begingroup\$

05AB1E, 18 bytes

2 bytes extra due to a bug with £ not handling 0 correctly.

'.¡`DvÐgsNè-F¨]'.ý

Try it online! or as a Test Suite

Explanation

    '.¡                 # split input on "."
       `                # push int and decimals separately to stack
        D               # duplicate decimal digits
         v              # for each
          Ð             # triplicate the current decimal digits
           g            # get the length
            sNè         # get the Nth digit
               -        # subtract from the total length
                F¨]     # drop that many digits from the end
                        # end loop
                   '.ý  # join on "."
\$\endgroup\$
0
4
\$\begingroup\$

Python 2, 103 101 98 94 93 87 bytes

a,b=input().split('.');i,w=0,len(b)
while w>i:w=min(int(b[i]),w);i+=1
print a+'.'+b[:w]

Try it online!


Saved:

  • -2 bytes, thanks to Kevin Cruijssen
  • -3 bytes, thanks to Vedant Kandoi
  • -4 bytes, thanks to Lynn
\$\endgroup\$
5
  • \$\begingroup\$ a+w+1 can be a-~w. Nice answer though, +1 from me. \$\endgroup\$ Commented Oct 30, 2018 at 9:21
  • 2
    \$\begingroup\$ Oh, and return can be print as well. And here you are golfing Python for years. Tsk tsk tsk. ;p (It's the simplest things we usually forgot to golf I guess.) \$\endgroup\$ Commented Oct 30, 2018 at 9:32
  • \$\begingroup\$ Instead of a function, use n=input() and remove the spaces and print as mentioned by @KevinCruijssen to save a few bytes. \$\endgroup\$ Commented Oct 30, 2018 at 10:06
  • \$\begingroup\$ I think while w>=i<a+i<len(n): is okay, as the . is never at the start of the string, so a>0. \$\endgroup\$
    – lynn
    Commented Oct 30, 2018 at 11:43
  • 1
    \$\begingroup\$ @KevinCruijssen Thanks :) Ye have little faith :( . I didn't really have time to golf it, I just submitted a working solution, and left for a couple of hours. \$\endgroup\$
    – TFeld
    Commented Oct 30, 2018 at 12:53
3
\$\begingroup\$

JavaScript (Node.js), 58 bytes

f=(s,p=1/0,q=1,c=s[q])=>c?f(s.slice(0,p-~c),++c?p:q,q+1):s

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ Ridiculously & unnecessarily complicated and for the same score as my boring, straightforward solution?! +1 \$\endgroup\$
    – Shaggy
    Commented Nov 2, 2018 at 23:08
  • \$\begingroup\$ @Shaggy Actually, they are similar enough. s.slice(0,p-~c) -> d.slice(0,-~d[n]), q+1 -> ++n, both recursive. Only difference is how to handle digits before the dot. \$\endgroup\$
    – tsh
    Commented Nov 3, 2018 at 7:22
2
\$\begingroup\$

Charcoal, 28 bytes

≔⪪S.θW⊟EθΦκ‹ΣμLκ⊞θ…⊟θI§ι⁰⪫θ.

Try it online! Link is to verbose version of code. Explanation:

≔⪪S.θ

Split the input on ..

W⊟EθΦκ‹ΣμLκ

Filter each part on those digits that are less than the string's length. Then take the last result. (This saves 1 byte over filtering on just the decimals.) Loop until that is empty.

⊞θ…⊟θI§ι⁰

Take the first filtered digit and truncate the decimals to that length.

⪫θ.

Join the parts back together and implicitly print.

\$\endgroup\$
2
  • \$\begingroup\$ Seems to give an incorrect result for the negative input-cases (although it is possible I don't know how to input negative values in Charcoal, I tried with a leading - or _, but both failed). Everything else works fine. \$\endgroup\$ Commented Oct 30, 2018 at 10:45
  • 1
    \$\begingroup\$ @KevinCruijssen Ah, my final golf broke because it tried to cast - to integer. Fortunately I can use Sum instead. \$\endgroup\$
    – Neil
    Commented Oct 30, 2018 at 12:15
2
\$\begingroup\$

Ruby -pl, 48 bytes

c=i=j=$_=~/,/;$_=$_[0,c.to_i-~j]while c=$_[i+=1]

Try it online!

Uses a decimal comma instead of a dot.

\$\endgroup\$
2
\$\begingroup\$

C (gcc), 84, 78 bytes

Takes input as a pointer to a string buffer, outputs by modification. Note that providing a pointer to a buffer that is too small (intPartLen + 1 + 9 > bufSize) can cause SEGFAULT.

If assuming the size of the buffer to be sufficient is not allowed, +7 to the score.

l,M;f(char*F){F=strchr(F,46);for(l=47,M=57;*++F&&++l<M;*F<M?M=*F:0);F[M-l]=0;}

Try it online!

Degolf

l,M;f(char*F){
    F=strchr(F,46); // Find the pointer to the period.
    for(l=47,M=57;  // Initialize variables (48='0', 57='9')
            *++F&&++l<M;  // Check for null terminator, and that we're not
                          // going through too many decimals
            *F<M?M=*F:0); // Keep smaller of M and the char pointed to by F.
        F[M-l]=0; // Explained below.
}

At the end of the loop, F is a pointer to the nth decimal after the decimal point (ptr). M is the smallest digit observed as its ASCII value. l is '0'+n-1 (or 47+n). Thus:

F[M-l] == *(F + M - l)
F[M-l] == *(ptr + n + M - '0' - n + 1)
F[M-l] == *(ptr + M - '0' + 1)

Which gives us a pointer to the first character to truncate; replacing this character with a \0 results in the truncation of the remaining digits for most intents and purposes. This is also where the SEGFAULT happens; for example, if the input is 123.4, the smallest digit is 4, and the pointer will point to the character * in 123.4\0??*.

\$\endgroup\$
2
\$\begingroup\$

PHP, 92 bytes

several solutions, same length:

# any PHP:
for($n=$argn,$t=9;~$d=$n[$i+++$p=1+strpos($n,46)];$n=substr($n,0,$p+$t))$t<$d||$t=$d;echo$n;
for($t=9;$i<$t&&~$d=$n[$i+++$p=1+strpos($n=$argn,46)];)$t<$d||$t=$d;echo substr($n,0,$p+$t);
for($t=9;$i<$t&&~$d=$n[++$i+$p=strpos($n=$argn,46)];)$t<$d||$t=$d;echo substr($n,0,$p+$t+1);

# PHP 7:
for($t=9;~$d=($n=&$argn)[$i+++$p=1+strpos($n,46)];$n=substr($n,0,$p+$t))$t<$d||$t=$d;echo$n;
for($n=$argn;~$d=$n[$i+++$p=1+strpos($n,46)];$n=substr($n,0,$p+$t))($t??9)<$d||$t=$d;echo$n;

Run as pipe with -nR or try (most of) them online.

\$\endgroup\$
2
  • \$\begingroup\$ I was like, wow, that's a long PHP answer. But then I saw the byte-count and realized they are four separated programs. ;) Btw, in what order does PHP execute $i+++$p=1+strpos($n,46)? \$\endgroup\$ Commented Oct 30, 2018 at 13:59
  • \$\begingroup\$ @KevinCruijssen $i++, then $p=.... ++$p=... would throw a parse error. \$\endgroup\$
    – Titus
    Commented Oct 30, 2018 at 14:05
2
\$\begingroup\$

JavaScript, 58 bytes

Input and output as a string, using a comma as the decimal separator.

s=>s.replace(/,.+/,g=d=>d[++n]?g(d.slice(0,-~d[n])):d,n=0)

Try it online

\$\endgroup\$
0
1
\$\begingroup\$

Perl 6 -p, 57 41 bytes

$!=m/\./.to;.=substr(0,$!+$/)while m:c/./

Try it online!

Explanation

$!=m/\./.to;       # Store position of decimal point in $!
.=substr(0,$!+$/)  # Truncate string to length $!+$/
while m:c/./       # while there's a match for the next digit
\$\endgroup\$
1
\$\begingroup\$

Python 3, 77 bytes

g,h=input().split(".")
for i in h:h=h[:int(i)]if i in h else h
print(g+"."+h)

Try it online!

Somehow, despite slicing past the end of a string and modifying while iterating on that same string, the interpreter doesn't complain.

This answer has a similar structure to the other Python one, but uses a different method to find where to truncate and works in newer versions of Python.

\$\endgroup\$
1
\$\begingroup\$

JavaScript (Node.js), 78 68 bytes

-10 bytes from @tsh

a=>eval('for([x,y]=a.split`.`,i=0;c=y[i++];y=y.slice(0,c));x+`.`+y')

Try it online!

\$\endgroup\$
2
  • \$\begingroup\$ A quick saving using comma as the decimal separator. \$\endgroup\$
    – Shaggy
    Commented Oct 30, 2018 at 21:22
  • \$\begingroup\$ 68 bytes \$\endgroup\$
    – tsh
    Commented Oct 31, 2018 at 9:02
1
\$\begingroup\$

Clean, 115 bytes

import StdEnv,Text
$s#[i,d:_]=split['.']s
=i++['.':iter 9(\p=hd([take n\\n<-map digitToInt p|n<length p]++[id])p)d]

Try it online!

Defines the function $ :: [Char] -> [Char]. Link includes test suite.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.