Independence Day weekend puzzler
Mostrar comentarios más antiguos
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 comentarios
Fangjun Jiang
el 3 de Jul. de 2011
I need a little clarification. As if the output is 124=123+1, 1920=1919+1 and 1000=999+1? What if your input is [1 2 34], should the output be [1 2 35] or [1 2 3 5]?
the cyclist
el 3 de Jul. de 2011
David Young
el 4 de Jul. de 2011
How big can the array be? For example, should the answer work correctly for x=repmat(9, 1, 100)?
David Young
el 4 de Jul. de 2011
Sorry, the example isn't stringent enough: I mean x=repmat(9,1,1000).
the cyclist
el 4 de Jul. de 2011
Paulo Silva
el 4 de Jul. de 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
el 4 de Jul. de 2011
Sure. +1
Respuesta aceptada
Más respuestas (8)
Jan
el 3 de Jul. de 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 comentario
David Young
el 4 de Jul. de 2011
This works for long vectors (thousands of elements).
bym
el 3 de Jul. de 2011
kind of a hybrid:
sprintf('%d',sum(x.*10.^(numel(x)-1:-1:0))+1)-'0'
5 comentarios
Jan
el 3 de Jul. de 2011
+1: This does not call other M-functions, therefore it is the one-linest one-liner yet.
Andrei Bobrov
el 4 de Jul. de 2011
num2str(10.^(numel(x)-1:-1:0)*x'+1)-'0'
David Young
el 4 de Jul. de 2011
Jan: my earlier answer uses only built-in functions.
Jan
el 4 de Jul. de 2011
@David: Which one is your earlier answer?
David Young
el 4 de Jul. de 2011
@Jan: The one that starts with a call to diff
Andrei Bobrov
el 3 de Jul. de 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 comentarios
bym
el 4 de Jul. de 2011
+1 vote for the 'z' solution; compact & elegant
Andrei Bobrov
el 4 de Jul. de 2011
@proecsm, thanks!
David Young
el 3 de Jul. de 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 comentarios
David Young
el 4 de Jul. de 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
el 4 de Jul. de 2011
+1: A one-liner without calls to other M-files and therefore even no hidden semicolons.
David Young
el 4 de Jul. de 2011
Thanks Jan!
Paulo Silva
el 3 de Jul. de 2011
x=[1 2 3]; %example input
xr=num2str(str2num(strrep(num2str(x),' ',''))+1)-'0'
%xr =[1 2 3 4]
the cyclist
el 3 de Jul. de 2011
David Young
el 4 de Jul. de 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 comentario
David Young
el 4 de Jul. de 2011
This one works for long vectors with thousdands of elements (my arithmetic-based solution doesn't).
David Young
el 4 de Jul. de 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))))]
Categorías
Más información sobre Dates and Time en Centro de ayuda y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!