35
\$\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\$
  • \$\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\$ – Jonathan Allan Feb 21 '17 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\$ – ETHproductions Feb 21 '17 at 23:38
  • 5
    \$\begingroup\$ Dang it, you stole my secret :P \$\endgroup\$ – LegionMammal978 Feb 22 '17 at 2:07
  • 1
    \$\begingroup\$ I think almost everyone counted like this as a kid. ;) At least I did as well. :) \$\endgroup\$ – Kevin Cruijssen Feb 22 '17 at 8:35
  • 7
    \$\begingroup\$ @KevinCruijssen "as a kid"? \$\endgroup\$ – Martin Ender Feb 22 '17 at 8:55

34 Answers 34

19
\$\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\$
  • \$\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 Feb 23 '17 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\$
  • \$\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 Feb 23 '17 at 13:34
  • \$\begingroup\$ @gurka Done, thanks \$\endgroup\$ – Albert Renshaw Feb 23 '17 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\$
  • \$\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\$ – ETHproductions Feb 21 '17 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\$ – Martin Ender Feb 21 '17 at 22:11
  • \$\begingroup\$ using the regex .0*$ should work \$\endgroup\$ – 12Me21 Feb 21 '17 at 22:14
  • \$\begingroup\$ If there's a (short enough) way to output only the last match, you could use .0* \$\endgroup\$ – 12Me21 Feb 21 '17 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 Feb 21 '17 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\$
  • \$\begingroup\$ Always nice to see a Cubix answer :) \$\endgroup\$ – Oliver Feb 22 '17 at 1:00
  • \$\begingroup\$ @obarakon Got an improved one to put up soon. Really did this one the wrong way \$\endgroup\$ – MickyT Feb 22 '17 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\$
  • 5
    \$\begingroup\$ I don't think you need the g, as there's only ever one match to find. \$\endgroup\$ – ETHproductions Feb 21 '17 at 23:15
  • \$\begingroup\$ Save 2 bytes by using x=>x.match`.0*$` \$\endgroup\$ – Patrick Roberts Feb 25 '17 at 16:30
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\$
3
\$\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\$
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 bytes

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

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\$

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\$
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\$
  • \$\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 Feb 22 '17 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\$
  • 1
    \$\begingroup\$ I think you need to explicitly name the function i for this to work as you're using recursion. \$\endgroup\$ – Emigna Feb 22 '17 at 10:50
  • \$\begingroup\$ @Emigna you're right! I totally missed that :( \$\endgroup\$ – Metoniem Feb 22 '17 at 11:47
  • \$\begingroup\$ Updated it but I'm not 100% sure if it's correct this way \$\endgroup\$ – Metoniem Feb 22 '17 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 Feb 22 '17 at 12:26
  • 1
    \$\begingroup\$ The parenthesis around a is not required either way though. \$\endgroup\$ – Emigna Feb 22 '17 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\$
  • \$\begingroup\$ Try it online! - 6 bytes \$\endgroup\$ – Magic Octopus Urn Apr 11 '18 at 22:26
  • \$\begingroup\$ Or 5 - Try it online! \$\endgroup\$ – Magic Octopus Urn Apr 11 '18 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 Apr 12 '18 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\$
0
\$\begingroup\$

Pyke, 13 11 10 bytes

`1QY0mN%e>

Try it here!

  QY       -     digits(input)
    0mN    -    map(^, i != 0)
 1     %   -   indecies(^, i == 1)
        e  -  ^[-1]
`        > - str(input)[^:]

11 bytes:

`D\0mN1R%e>

Try it here!

13 bytes:

`D\0mN_1R@_t>

Try it here!

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

Haskell 57 Bytes

f(x:s)a|x=='0'=f s$'0':a|1>0=x:a
t x=f(reverse.show$x)[]

Input    -> Output
t 120    -> "20"
t 30200  -> "200"
\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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