MATLAB Answers

the cyclist

Independence Day weekend puzzler

Asked by the cyclist
on 3 Jul 2011

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

the cyclist
on 4 Jul 2011

I only intended it to be for "smallish" vectors of numbers, but feel free to create whatever conditions you want, for maximum enjoyment.

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.

Fangjun Jiang
on 4 Jul 2011

Sure. +1

Tags

Products

No products are associated with this question.

9 Answers

Answer by Fangjun Jiang
on 3 Jul 2011
 Accepted answer

I like this Golf challenge. Inspired by Paulo's entry.

num2str(str2num(sprintf('%d',x))+1)-'0'

is shorter.

  0 Comments


Answer by Jan Simon
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
on 4 Jul 2011

This works for long vectors (thousands of elements).


bym
Answer by bym
on 3 Jul 2011

kind of a hybrid:

sprintf('%d',sum(x.*10.^(numel(x)-1:-1:0))+1)-'0'

  5 Comments

David Young
on 4 Jul 2011

Jan: my earlier answer uses only built-in functions.

Jan Simon
on 4 Jul 2011

@David: Which one is your earlier answer?

David Young
on 4 Jul 2011

@Jan: The one that starts with a call to diff


Answer by 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
on 4 Jul 2011

+1 vote for the 'z' solution; compact & elegant

Andrei Bobrov
on 4 Jul 2011

@proecsm, thanks!


Answer by 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

David Young
on 4 Jul 2011

This fails if there are more than about 16 elements in the vector, because you only get about 16 significant figures in a double.

Jan Simon
on 4 Jul 2011

+1: A one-liner without calls to other M-files and therefore even no hidden semicolons.

David Young
on 4 Jul 2011

Thanks Jan!


Answer by 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]

  0 Comments


Answer by 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?!

  0 Comments


Answer by 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
on 4 Jul 2011

This one works for long vectors with thousdands of elements (my arithmetic-based solution doesn't).


Answer by 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))))]

  0 Comments


Discover what MATLAB® can do for your career.

Opportunities for recent engineering grads.

Apply today