39
\$\begingroup\$

When I was a kid, and wanted to count the dollar bills in my life savings, I would count out loud:

one, two, three, four, five, six, seven, eight, nine, ten;
eleven, twelve, thirteen, fourteen, fifteen, sixteen, seventeen, eighteen, nineteen, twenty;
twenty-one, twenty-two, twenty-three, twenty-four, twenty-five...

Eventually I got tired of pronouncing each of these multi-syllable numbers. Being mathematically minded, I created a much more efficient method of counting:

one, two, three, four, five, six, seven, eight, nine, ten;
one, two, three, four, five, six, seven, eight, nine, twenty;
one, two, three, four, five, six, seven, eight, nine, thirty...

As you can see, I would only pronounce the digit(s) that have changed from the previous number. This has the added advantage that it's considerably more repetitive than the English names for numbers, and therefore requires less brainpower to compute.

Challenge

Write a program/function which takes in a positive integer and outputs/returns how I would count it: that is, the right-most non-zero digit and all trailing zeroes.

Examples

   1    1
   2    2
  10   10
  11    1
  29    9
  30   30
  99    9
 100  100
 119    9
 120   20
 200  200
 409    9
1020   20

A full list of test-cases shouldn't be necessary. This is A274206 on OEIS.

Rules

  • Your entry must theoretically work for all positive integers, ignoring precision and memory issues.
  • Input and output must be in decimal.
  • You may choose to take input and/or output as a number, a string, or an array of digits.
  • Input is guaranteed to be a positive integer. Your entry can do anything for invalid input.

This is , so the shortest code in bytes wins.

\$\endgroup\$
6
  • \$\begingroup\$ So does "in decimal" include a list of decimal digits, like [1,0,2,0] -> [2,0] for the last test case? (I'm unclear on the phrase "single-item array"). \$\endgroup\$ Commented Feb 21, 2017 at 23:26
  • 1
    \$\begingroup\$ @JonathanAllan By "single-item array" I meant an array that contains a single number or string which represents the integer. I didn't think allowing arrays of digits was a good idea, but now it kind of seems like an arbitrary restriction since strings are allowed (and strings are very similar to arrays in many languages). So I'll allow an array of digits unless there's a good reason not to. \$\endgroup\$ Commented Feb 21, 2017 at 23:38
  • 5
    \$\begingroup\$ Dang it, you stole my secret :P \$\endgroup\$ Commented Feb 22, 2017 at 2:07
  • 2
    \$\begingroup\$ I think almost everyone counted like this as a kid. ;) At least I did as well. :) \$\endgroup\$ Commented Feb 22, 2017 at 8:35
  • 9
    \$\begingroup\$ @KevinCruijssen "as a kid"? \$\endgroup\$ Commented Feb 22, 2017 at 8:55

39 Answers 39

20
\$\begingroup\$

Python 2, 28 bytes

f=lambda n:n%10or 10*f(n/10)

Try it online!

A recursive formula works out very cleanly. If the last digit is nonzero, output it. Otherwise, remove the final zero, compute the output for that, and multiply it by 10.

\$\endgroup\$
11
\$\begingroup\$

Jelly, 6 3 bytes

-3 bytes by having I/O as a decimal list of digits.

ṫTṪ

Test suite at Try it online!

How?

ṫTṪ - Main link: listOfDigits  e.g.  [1,    0,    2,    0]  or [1,      1,    9  ]
 T  - truthy indexes                 [1,          3      ]     [1,      2,    3  ]
ṫ   - tail (vectorises)              [[1,0,2,0],  [2,0]  ]     [[1,1,9],[1,9],[9]]
  Ṫ - tail pop                                    [2,0]                       [9]

If we could not take decimal lists a 6 byter is:

DµṫTṪḌ

Which you can see here.

This does the same thing, but converts an integer to a decimal list beforehand and converts back to an integer afterwards.

\$\endgroup\$
1
  • \$\begingroup\$ As I was scrolling past the first few answers, I said to myself, "I bet there's a 3-byte Jelly solution..." \$\endgroup\$
    – DLosc
    Commented Feb 23, 2017 at 7:29
9
\$\begingroup\$

C, 30 29 27 bytes

Proud of this as I abuse two C exploits to golf this up (described at end of post); This is specifically for C (GCC)


3) b=10;f(a){a=a%b?:b*f(a/b);}//27 bytes

2) b;f(a){b=a=a%10?:10*f(a/10);} //29 bytes

1) f(i){return i%10?:10*f(i/10);} //30 bytes

Try it online (27 byte version)


First attempt (30 bytes): Abuses the fact that in GCC if no value is declared in ternary, the conditional value will be returned. Hence why my ternary operator is blank for the truth return value.

Second attempt (29 bytes): Abuses memory bug in GCC where, as far as I understand, if a function has no return value, when more than two variables have been meaningfully utilized in the function, the last set value of the first argument variable will be returned.
   (Edit: but this "set value" must set in certain ways, for example setting a variable with = or += works but setting it with %= does not work; weird)

Third attempt (27 bytes): Since I must meaningfully utilize the second variable (b) anyways to properly abuse the memory bug mentioned above, I may as well use it as an actual variable for "10" for substitution.
   (Note: I should be able to swap a=a%b with a%=b to save another byte but unfortunately this causes the memory bug exploit above to stop "working", so I can't)

\$\endgroup\$
2
  • \$\begingroup\$ You might want to add "GCC" to the title of your answer since it's GCC-specific (it doesn't work on clang). Also, the "memory bug" is probably just undefined behavior that happens to work due to the specific stack frame layout that GCC uses. It probably doesn't work on other platforms, even with GCC. \$\endgroup\$
    – simon
    Commented Feb 23, 2017 at 13:34
  • \$\begingroup\$ @gurka Done, thanks \$\endgroup\$ Commented Feb 23, 2017 at 18:36
7
\$\begingroup\$

Retina, 7 6 bytes

!`.0*$

Try it online (all test cases)

Output matches of a digit followed by any zeros at the end of the input string. Though not required, this also happens to work for 0.

\$\endgroup\$
6
  • \$\begingroup\$ Huh, I had figured [1-9] (or [^0]) would be necessary instead of \d. I guess the greediness of * ensures the correct output every time. \$\endgroup\$ Commented Feb 21, 2017 at 21:37
  • \$\begingroup\$ @ETHproductions This has nothing to do with the greediness of * but with the fact that matches are searched for from left to right. \d0*?$ would also work. \$\endgroup\$ Commented Feb 21, 2017 at 22:11
  • \$\begingroup\$ using the regex .0*$ should work \$\endgroup\$
    – 12Me21
    Commented Feb 21, 2017 at 22:14
  • \$\begingroup\$ If there's a (short enough) way to output only the last match, you could use .0* \$\endgroup\$
    – 12Me21
    Commented Feb 21, 2017 at 22:22
  • \$\begingroup\$ @12Me21 The only way to do that is to only match the last occurrence, or to use a replace or something. It won't be shorter. \$\endgroup\$
    – mbomb007
    Commented Feb 21, 2017 at 22:28
7
\$\begingroup\$

Cubix, 18 32 bytes

I think I'll have to spend sometime on this later and see if I can compress it a bit. But for the moment here it is.
Turns out I was thinking about this totally the wrong way. Now the process incrementally applies a mod (1,10,100,1000,...) to the input integer and prints out the first one which isn't zero. Bit more boring, but shorter.

!N%*I1^\.u;u@O\;;r

Try it here

    ! N
    % *
I 1 ^ \ . u ; u
@ O \ ; ; r . .
    . .
    . .
\$\endgroup\$
2
  • \$\begingroup\$ Always nice to see a Cubix answer :) \$\endgroup\$
    – Oliver
    Commented Feb 22, 2017 at 1:00
  • \$\begingroup\$ @obarakon Got an improved one to put up soon. Really did this one the wrong way \$\endgroup\$
    – MickyT
    Commented Feb 22, 2017 at 1:19
5
\$\begingroup\$

JavaScript, 21 bytes

f=n=>n%10||10*f(n/10)

Test cases

f=n=>n%10||10*f(n/10)

console.log(f(1   )); //  1
console.log(f(2   )); //  2
console.log(f(10  )); //  10
console.log(f(29  )); //  9
console.log(f(99  )); //  9
console.log(f(1020)); //  20

\$\endgroup\$
5
\$\begingroup\$

Javascript 19 18 bytes

Thanks to ETHproductions for golfing off one byte and Patrick Roberts for golfing off two bytes

x=>x.match`.0*$`

Returns an array of strings that match the regex of being at the end of the input string with any character followed by the largest possible number of zeroes.

Try it Online

\$\endgroup\$
2
  • 5
    \$\begingroup\$ I don't think you need the g, as there's only ever one match to find. \$\endgroup\$ Commented Feb 21, 2017 at 23:15
  • \$\begingroup\$ Save 2 bytes by using x=>x.match`.0*$` \$\endgroup\$ Commented Feb 25, 2017 at 16:30
5
\$\begingroup\$

Brachylog, 2 bytes

a₁

Try it online!

The suffix builtin a₁, for integers, is implemented as:

brachylog_adfix('integer':1, 'integer':0, 'integer':0).
brachylog_adfix('integer':1, 'integer':I, 'integer':P) :-
    H #\= 0,
    H2 #\= 0,
    abs(P) #=< abs(I),
    integer_value('integer':Sign:[H|T], I),
    integer_value('integer':Sign:[H2|T2], P),
    brachylog_adfix('integer':1, [H|T], [H2|T2]).

Brachylog likes to be able to treat integers as lists of digits, and for that it uses the custom utility predicate integer_value/2. The interesting thing about integer_value/2 here is that since it has to be able to correctly translate a digit list with leading zeros, it ends up also being able to translate an integer to a digit list with leading zeros, so predicates that don't want that to happen (most of them, especially the nondet ones like a) forbid the heads of their digit lists from being 0. So, while a₁ generates suffixes shortest first for lists and strings, it skips over any suffix of an integer with a leading 0, which in addition to removing duplicates, also means that the first suffix generated is the rightmost non-zero digit with all trailing zeroes.

\$\endgroup\$
3
\$\begingroup\$

Bash + coreutils, 12

grep -o .0*$

Try it online.

\$\endgroup\$
3
\$\begingroup\$

Grime, 5 bytes

d\0*e

Try it online!

Explanation

       Find the longest substring of the input matching this pattern:
d      a digit, then
 \0*   zero or more 0s, then
    e  edge of input (which is handled as an Nx1 rectangle of characters).
\$\endgroup\$
2
\$\begingroup\$

Brain-Flak, 74 bytes

{({}<>)<>}(()){{}<>(({}<>)[((((()()()){}){}){}){}]<(())>){((<{}{}>))}{}}{}

Try it online!

Only prints the last non-0 and all trailing 0s.

Explanation:

{({}<>)<>}                    # Move everything to the other stack (reverse the input)
(())                          # Push a 1 to get started
{                             # do...
  {}<>                        #   pop the result of the equals check (or initial 1)
  (                           #   push...
    ({}<>)                    #     the top value from the other stack (also put this on the stack)
    [((((()()()){}){}){}){}]  #     minus the ASCII value of 0
    <(())>                    #     on top of a 1
  )                           #   close the push   
  {                           #   if not zero (ie. if not equal)
    ((<{}{}>))                #     replace the 1 from 3 lines back with a 0
  }{}                         #   end if and pop the extra 0
}                             # while the copied value != "0"
{}                            # pop the result of the equals check
\$\endgroup\$
2
\$\begingroup\$

Vim, 19 bytes

Two versions, both 19 bytes:

:s/\v.*([^0]0*)/\1
:s/.*\([^0]0*\)/\1

Plus a trailing carriage return on each.

Verify all test-cases online! (One byte added to test on multiple lines)

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

TI-Basic, 18 bytes

If fPart(.1Ans
Return
Ans.1
prgmA
10Ans
\$\endgroup\$
2
\$\begingroup\$

R, 33 bytes

Implemented as an unnamed function

function(x)rle(x%%10^(0:99))$v[2]

This applies a mod of 10^0 through 10^99. rle is used to reduce the results down so that the second item is always the result we want.
Try it online!

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

Zsh, 18 16 bytes

<<<${(M)1%[^0]*}

Try it online! Try it online!

Bash, 25 20 bytes

-5 bytes by @roblogic

echo ${1#${1%[^0]*}}

Try it online! Try it online!

--- Shells need to call external programs to use regex, so we have to make do with globbing.

The ${1%[^0]*} expansion matches the shortest suffix beginning with a nonzero character, and removes it.

  • In Zsh, adding the (M) flag causes the matched suffix to be kept instead of removed.
  • In Bash, the ${1% } expansion removes as a prefix whatever is left.
\$\endgroup\$
1
  • \$\begingroup\$ 20 bytes in bash: echo ${1#${1%[^0]*}} \$\endgroup\$
    – roblogic
    Commented Aug 17, 2023 at 8:39
1
\$\begingroup\$

GNU sed, 17 14 + 1(r flag) = 15 bytes

Edit: 2 bytes less thanks to Riley

s:.*([^0]):\1:

It works by deleting everything until the right-most nonzero digit, which is then printed along with any existing trailing zeros. The script can handle multiple tests in one run, each on a separate line.

Try it online! (all test examples)

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

Mathematica, 26 bytes

Pure function which takes a list of digits and outputs a list of digits:

#/.{___,x_,y:0...}:>{x,y}&

Explanation

#                           First argument
 /.                           Replace
   {                              start of list followed by
    ___,                          zero or more elements followed by
        x_,                       an element (referred to later as x) followed by
           y:0...                 a sequence of zero or more 0s (referred to later as y) followed by
                 }                end of list
                  :>            with
                    {x,y}         {x,y}
                         &   End of function.

This works since it finds the leftmost match for x, which must be the rightmost nonzero element of the list since it is followed by a sequence of zero of more 0s and then the end of the list.

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

Java 8, 47 bytes

this is a lambda expression assignable to a IntUnaryOperator:

x->{int m=1;for(;x%m<1;m*=10);return x%m*m/10;}

explanation: multiply m by 10 until x%m is not 0. return x%m*m/10 requires the division because m is an order of magnitude more than the desired result.

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

Perl 6, 10 bytes

{+m/.0*$/}

Trivial regex solution. Inputs and outputs a number.

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

MATL, 10 7 bytes

3 bytes saved thanks to @B. Mehta!

tfX>Jh)

Input and output are an array of digits.

Try it online!

Or verify all test cases.

Explanation

t     % Input string implicitly. Duplicate
f     % Push indices of non-zero digits
X>    % Keep maximum, say k
Jh    % Attach 1j to give [k, 1j]. This is interpreted as an index "k:end"
)     % Index into original string. Display implcitly
\$\endgroup\$
1
  • \$\begingroup\$ Since we're allowed to take input and output as a vector of integers, you can remove the 48- entirely, saving 3 bytes: Try it online! \$\endgroup\$
    – B. Mehta
    Commented Feb 22, 2017 at 2:41
1
\$\begingroup\$

C#, 30 28 bytes

Based on this JavaScript answer, so I suppose all the credits kinda go to him.

Golfed

i=a=>a%10<1?10*i(a/10):a%10;
  • -2 bytes by removing () around a thanks to Emigna
\$\endgroup\$
6
  • 1
    \$\begingroup\$ I think you need to explicitly name the function i for this to work as you're using recursion. \$\endgroup\$
    – Emigna
    Commented Feb 22, 2017 at 10:50
  • \$\begingroup\$ @Emigna you're right! I totally missed that :( \$\endgroup\$
    – Metoniem
    Commented Feb 22, 2017 at 11:47
  • \$\begingroup\$ Updated it but I'm not 100% sure if it's correct this way \$\endgroup\$
    – Metoniem
    Commented Feb 22, 2017 at 11:48
  • 1
    \$\begingroup\$ I don't know the consensus on this in C#. That syntax is valid, but will only work if the delegate has already been declared (otherwise i will be undeclared for the recursive call). \$\endgroup\$
    – Emigna
    Commented Feb 22, 2017 at 12:26
  • 1
    \$\begingroup\$ The parenthesis around a is not required either way though. \$\endgroup\$
    – Emigna
    Commented Feb 22, 2017 at 12:27
1
\$\begingroup\$

J, 27 bytes

10&|`(10*(p%&10))@.(0=10&|)

It's based off of xnor's formula, so credits to him.

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

Kotlin, 49 bytes

lambda, assignable to (List<Int>) -> List<Int>

{a->a.slice(a.indexOfLast{it in 1..9}..a.size-1)}
  • implicit parameter name it in indexOfLast
  • .. for building ranges
\$\endgroup\$
1
\$\begingroup\$

Perl 5, 12 bytes

11, plus 1 for -nE instead of -e

say/(.0*$)/
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 9 bytes

RD0Ê1k>£R

Try it online! or as a Test suite

Explanation

R          # reverse input
 D         # duplicate
  0Ê       # check each for inequality with 0
    1k     # get the index of the first 1
      >    # increment
       £   # take that many digits from the input
        R  # reverse
\$\endgroup\$
3
  • \$\begingroup\$ Try it online! - 6 bytes \$\endgroup\$ Commented Apr 11, 2018 at 22:26
  • \$\begingroup\$ Or 5 - Try it online! \$\endgroup\$ Commented Apr 11, 2018 at 22:27
  • \$\begingroup\$ @MagicOctopusUrn: That's only checking the last digit. It should be the last non-zero digit and all after. \$\endgroup\$
    – Emigna
    Commented Apr 12, 2018 at 5:51
1
\$\begingroup\$

Japt, 6 bytes

f".0*$

Try it online!

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

Stax, 5 bytes

æΩ$3╚

Run and debug it

Procedure:

  1. Calculate "multiplicity" by 10. (That's the number of times 10 evenly divides the input)
  2. Add 1.
  3. Keep that many characters from the right of (the input as a string).
\$\endgroup\$
1
\$\begingroup\$

05AB1E, 4 bytes

ĀÅ¡θ

I/O as a list of digits.

Try it online or verify all test cases (test suite contains a join for better readability).

Explanation:

Ā     # Python-style truthify each digit in the (implicit) input-list (0 if 0; 1 if [1-9])
      #  i.e. [9,0,4,0,3,0,0] → [1,0,1,0,1,0,0]
 Å¡   # Split the (implicit) input-list on truthy values (1s)
      #  i.e. [9,0,4,0,3,0,0] and [1,0,1,0,1,0,0] → [[],[9,0],[4,0],[3,0,0]]
   θ  # And only leave the last inner list
      #  i.e. [[],[9,0],[4,0],[3,0,0]] → [3,0,0]
      # (after which it is output implicitly as result)
\$\endgroup\$
1
\$\begingroup\$

Thunno 2 t, 3 bytes

V€ỵ

Try it online!

Port of Jonathan Allan's Jelly answer.

Explanation

V€ỵ  # Implicit input
V    # Truthy indices
 €ỵ  # Head remove over each
     # Take the last item
     # Implicit output
\$\endgroup\$
1
\$\begingroup\$

Desmos, 62 bytes

Input (variable A) and output (variable B) are both arrays of digits. Run the ticker to start the program.

Ticker:

B->join(A[n],B),n->\left\{A[n]=0:n-1,0\right\}

Expression List:

B=[]
n=A.length

Try it on Desmos!

Scans A from right to left until a nonzero digit is encountered. Afterwards, set n=0 to invalidate the action and halt the program.

\$\endgroup\$
8
  • 1
    \$\begingroup\$ 34 bytes \$\endgroup\$
    – Aiden Chow
    Commented Aug 17, 2023 at 3:18
  • \$\begingroup\$ BTW welcome to Code Golf! I don't see Desmos answers often from people other than me, so it's always exciting to see other people golfing in Desmos! \$\endgroup\$
    – Aiden Chow
    Commented Aug 17, 2023 at 3:26
  • \$\begingroup\$ That being said, if you would like to learn more about various Desmos golfing tips, please check out the Tips for Golfing in Desmos page, or check out some of my Desmos answers to see some of the tricks I use. I hope you will do more Desmos golfing in the future! \$\endgroup\$
    – Aiden Chow
    Commented Aug 17, 2023 at 3:28
  • \$\begingroup\$ @AidenChow Thanks! I started writing programs in Desmos last summer and eventually I realized that I could try golfing in Desmos after looking for something new to keep myself busy on. I just finished turning my brainfuck interpreter to plaintext so now I'll have to read those tips and optimize it again haha \$\endgroup\$
    – fwoosh
    Commented Aug 17, 2023 at 3:44
  • \$\begingroup\$ Sounds cool! If you don't mind, could I take a look at your brainfuck interpreter (and the plaintext you have)? Maybe I can try helping you golf it. \$\endgroup\$
    – Aiden Chow
    Commented Aug 17, 2023 at 3:58

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.