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 code-golf, so the shortest code in bytes wins.
39 Answers 39
Python 2, 28 bytes
f=lambda n:n%10or 10*f(n/10)
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.
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.
-
\$\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– DLosc2017年02月23日 07:29:54 +00:00Commented Feb 23, 2017 at 7:29
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) (削除) //29 bytesb;f(a){b=a=a%10?:10*f(a/10);} (削除ここまで)
1) (削除) //30 bytesf(i){return i%10?:10*f(i/10);} (削除ここまで)
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)
-
\$\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– simon2017年02月23日 13:34:02 +00:00Commented Feb 23, 2017 at 13:34
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.
-
\$\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– ETHproductions2017年02月21日 21:37:14 +00:00Commented 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\$Martin Ender– Martin Ender2017年02月21日 22:11:09 +00:00Commented Feb 21, 2017 at 22:11 -
\$\begingroup\$ using the regex
.0*$should work \$\endgroup\$12Me21– 12Me212017年02月21日 22:14:05 +00:00Commented 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– 12Me212017年02月21日 22:22:24 +00:00Commented 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– mbomb0072017年02月21日 22:28:06 +00:00Commented Feb 21, 2017 at 22:28
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
! N
% *
I 1 ^ \ . u ; u
@ O \ ; ; r . .
. .
. .
-
\$\begingroup\$ Always nice to see a Cubix answer :) \$\endgroup\$Oliver– Oliver2017年02月22日 01:00:45 +00:00Commented 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– MickyT2017年02月22日 01:19:56 +00:00Commented Feb 22, 2017 at 1:19
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
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.
-
5\$\begingroup\$ I don't think you need the
g, as there's only ever one match to find. \$\endgroup\$ETHproductions– ETHproductions2017年02月21日 23:15:27 +00:00Commented Feb 21, 2017 at 23:15 -
\$\begingroup\$ Save 2 bytes by using
x=>x.match`.0*$`\$\endgroup\$Patrick Roberts– Patrick Roberts2017年02月25日 16:30:59 +00:00Commented Feb 25, 2017 at 16:30
Brachylog, 2 bytes
a1
The suffix builtin a1, 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 a1 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.
Grime, 5 bytes
d0円*e
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).
Brain-Flak, 74 bytes
{({}<>)<>}(()){{}<>(({}<>)[((((()()()){}){}){}){}]<(())>){((<{}{}>))}{}}{}
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
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)
TI-Basic, 18 bytes
If fPart(.1Ans
Return
Ans.1
prgmA
10Ans
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!
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.
-
\$\begingroup\$ 20 bytes in bash:
echo ${1#${1%[^0]*}}\$\endgroup\$roblogic– roblogic2023年08月17日 08:39:54 +00:00Commented Aug 17, 2023 at 8:39
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)
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.
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.
MATL, (削除) 10 (削除ここまで) 7 bytes
3 bytes saved thanks to @B. Mehta!
tfX>Jh)
Input and output are an array of digits.
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
-
\$\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– B. Mehta2017年02月22日 02:41:03 +00:00Commented Feb 22, 2017 at 2:41
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
()aroundathanks to Emigna
-
1\$\begingroup\$ I think you need to explicitly name the function
ifor this to work as you're using recursion. \$\endgroup\$Emigna– Emigna2017年02月22日 10:50:06 +00:00Commented Feb 22, 2017 at 10:50 -
\$\begingroup\$ @Emigna you're right! I totally missed that :( \$\endgroup\$Mika– Mika2017年02月22日 11:47:26 +00:00Commented Feb 22, 2017 at 11:47
-
\$\begingroup\$ Updated it but I'm not 100% sure if it's correct this way \$\endgroup\$Mika– Mika2017年02月22日 11:48:34 +00:00Commented 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
iwill be undeclared for the recursive call). \$\endgroup\$Emigna– Emigna2017年02月22日 12:26:58 +00:00Commented Feb 22, 2017 at 12:26 -
1\$\begingroup\$ The parenthesis around
ais not required either way though. \$\endgroup\$Emigna– Emigna2017年02月22日 12:27:47 +00:00Commented Feb 22, 2017 at 12:27
J, 27 bytes
10&|`(10*(p%&10))@.(0=10&|)
It's based off of xnor's formula, so credits to him.
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
itinindexOfLast ..for building ranges
Perl 5, 12 bytes
11, plus 1 for -nE instead of -e
say/(.0*$)/
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
-
\$\begingroup\$ Try it online! - 6 bytes \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2018年04月11日 22:26:16 +00:00Commented Apr 11, 2018 at 22:26
-
\$\begingroup\$ Or 5 - Try it online! \$\endgroup\$Magic Octopus Urn– Magic Octopus Urn2018年04月11日 22:27:55 +00:00Commented 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– Emigna2018年04月12日 05:51:47 +00:00Commented Apr 12, 2018 at 5:51
Stax, 5 bytes
æΩ3ドル╚
Procedure:
- Calculate "multiplicity" by 10. (That's the number of times 10 evenly divides the input)
- Add 1.
- Keep that many characters from the right of (the input as a string).
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)
Thunno 2 t, 3 bytes
V€ỵ
Port of Jonathan Allan's Jelly answer.
Explanation
V€ỵ # Implicit input
V # Truthy indices
€ỵ # Head remove over each
# Take the last item
# Implicit output
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
Scans A from right to left until a nonzero digit is encountered. Afterwards, set n=0 to invalidate the action and halt the program.
-
1\$\begingroup\$ 34 bytes \$\endgroup\$Aiden Chow– Aiden Chow2023年08月17日 03:18:26 +00:00Commented 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– Aiden Chow2023年08月17日 03:26:18 +00:00Commented 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– Aiden Chow2023年08月17日 03:28:35 +00:00Commented 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– fwoosh2023年08月17日 03:44:57 +00:00Commented 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– Aiden Chow2023年08月17日 03:58:35 +00:00Commented Aug 17, 2023 at 3:58
[1,0,2,0]->[2,0]for the last test case? (I'm unclear on the phrase "single-item array"). \$\endgroup\$