Independence Day weekend puzzler

11 views (last 30 days)
Inspired by an assignment in my son's Java programming class:
Write a one-liner that takes as input an array of numbers (e.g. x = [1 2 3]) and which outputs an array of integers that is "incremented" properly, (in this case, y = [1 2 4]).
Examples of proper input/output:
x = [1 9 1 9] ----> y = [1 9 2 0]
and
x = [9 9 9] ----> y = [1 0 0 0]
No semicolons allowed in your one line!
  7 Comments
Paulo Silva
Paulo Silva on 4 Jul 2011
+1 vote for the interesting puzzler, it's the first vote!
Please vote on it if you found it interesting and you want more of them.

Sign in to comment.

Accepted Answer

Fangjun Jiang
Fangjun Jiang on 3 Jul 2011
I like this Golf challenge. Inspired by Paulo's entry.
num2str(str2num(sprintf('%d',x))+1)-'0'
is shorter.

More Answers (8)

Jan
Jan on 3 Jul 2011
My submission is neither a one-liner nor free of semicolons. But the total number of lines and semicolons is less than in STR2NUM and NUM2STR, which have 86 and 217 lines and call INT2STR in addtion.
n = length(x);
q = find(x ~= 9, 1, 'last');
if isempty(q) % [9, 9, 9, ...]
x = 1;
x(n + 1) = 0; % or x = [1, zeros(1, n)]
else % Any non-9 is found
x = [x(1:q - 1), x(q) + 1, zeros(1, n - q)];
end
  1 Comment
David Young
David Young on 4 Jul 2011
This works for long vectors (thousands of elements).

Sign in to comment.


bym
bym on 3 Jul 2011
kind of a hybrid:
sprintf('%d',sum(x.*10.^(numel(x)-1:-1:0))+1)-'0'
  5 Comments
Jan
Jan on 4 Jul 2011
@David: Which one is your earlier answer?
David Young
David Young on 4 Jul 2011
@Jan: The one that starts with a call to diff

Sign in to comment.


Andrei Bobrov
Andrei Bobrov on 3 Jul 2011
str2num(num2str(10.^(length(x)-1:-1:0)*x'+1)')'
ADD
z = 10.^(numel(x)-1:-1:0)*x'+1
y = round(rem(fix(z.*10.^-(fix(log10(z)):-1:0))*.1,1)*10)
  2 Comments
bym
bym on 4 Jul 2011
+1 vote for the 'z' solution; compact & elegant

Sign in to comment.


David Young
David Young on 3 Jul 2011
One-liner, avoiding string operations:
diff([0 (floor((sum(x.*10.^(length(x)-1:-1:0))+1) ./ 10.^(floor(log10(sum(x.*10.^(length(x)-1:-1:0))+1)):-1:0))) .* 10.^(floor(log10(sum(x.*10.^(length(x)-1:-1:0))+1)):-1:0)]) ./ 10.^(floor(log10(sum(x.*10.^(length(x)-1:-1:0))+1)):-1:0)
EDIT: This is only one line of code, even though formatting on the Answers web page makes it look like 4 lines.
  3 Comments
Jan
Jan on 4 Jul 2011
+1: A one-liner without calls to other M-files and therefore even no hidden semicolons.

Sign in to comment.


Paulo Silva
Paulo Silva on 3 Jul 2011
x=[1 2 3]; %example input
xr=num2str(str2num(strrep(num2str(x),' ',''))+1)-'0'
%xr =[1 2 3 4]

the cyclist
the cyclist on 3 Jul 2011
Here's one just a bit shorter than andrei bobrov's [using numel() to trim one character from length()]:
str2num(num2str(10.^(numel(x)-1:-1:0)*x'+1)')'
Anything shorter?!

David Young
David Young on 4 Jul 2011
Also one line of code (formatting for the web page will display it over more than one line of text):
double(regexprep(char(x), {['([' char(0:8) ']?)(' char(9) '*)$'] ['^(' char(0) '+)$']}, {'${char($1+1)}${regexprep($2,char(9),char(0))}' [char(1) '$1']}))
  1 Comment
David Young
David Young on 4 Jul 2011
This one works for long vectors with thousdands of elements (my arithmetic-based solution doesn't).

Sign in to comment.


David Young
David Young on 4 Jul 2011
I'm sorry about this one - it's somewhat over the top, and I promise I won't do any more. However, since I think it's a different approach to the others (arithmetic operations but no powers of 10!), here it is:
[ones(1, sum(x)==9*length(x)) x(1:length(x)-sum(cumsum(fliplr(x)) == 9*(1:length(x)))-1) repmat(x(max(1, length(x)-sum(cumsum(fliplr(x)) == 9*(1:length(x)))))+1, 1, sum(x)~=9*length(x)) zeros(1, sum(cumsum(fliplr(x)) == 9*(1:length(x))))]

Categories

Find more on Shifting and Sorting Matrices in Help Center and File Exchange

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!