Independence Day weekend puzzler

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

Fangjun Jiang
Fangjun Jiang 2011년 7월 3일
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
the cyclist 2011년 7월 3일
You can assume the elements in the input array are single digits, 0-9.
David Young
David Young 2011년 7월 4일
How big can the array be? For example, should the answer work correctly for x=repmat(9, 1, 100)?
David Young
David Young 2011년 7월 4일
Sorry, the example isn't stringent enough: I mean x=repmat(9,1,1000).
the cyclist
the cyclist 2011년 7월 4일
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
Paulo Silva 2011년 7월 4일
+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
Fangjun Jiang 2011년 7월 4일
Sure. +1

댓글을 달려면 로그인하십시오.

 채택된 답변

Fangjun Jiang
Fangjun Jiang 2011년 7월 3일

3 개 추천

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

추가 답변 (8개)

Jan
Jan 2011년 7월 3일

2 개 추천

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

David Young
David Young 2011년 7월 4일
This works for long vectors (thousands of elements).

댓글을 달려면 로그인하십시오.

bym
bym 2011년 7월 3일

2 개 추천

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

댓글 수: 5

Jan
Jan 2011년 7월 3일
+1: This does not call other M-functions, therefore it is the one-linest one-liner yet.
Andrei Bobrov
Andrei Bobrov 2011년 7월 4일
num2str(10.^(numel(x)-1:-1:0)*x'+1)-'0'
David Young
David Young 2011년 7월 4일
Jan: my earlier answer uses only built-in functions.
Jan
Jan 2011년 7월 4일
@David: Which one is your earlier answer?
David Young
David Young 2011년 7월 4일
@Jan: The one that starts with a call to diff

댓글을 달려면 로그인하십시오.

Andrei Bobrov
Andrei Bobrov 2011년 7월 3일

1 개 추천

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

bym
bym 2011년 7월 4일
+1 vote for the 'z' solution; compact & elegant
Andrei Bobrov
Andrei Bobrov 2011년 7월 4일
@proecsm, thanks!

댓글을 달려면 로그인하십시오.

David Young
David Young 2011년 7월 3일

1 개 추천

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

David Young
David Young 2011년 7월 4일
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
Jan 2011년 7월 4일
+1: A one-liner without calls to other M-files and therefore even no hidden semicolons.
David Young
David Young 2011년 7월 4일
Thanks Jan!

댓글을 달려면 로그인하십시오.

Paulo Silva
Paulo Silva 2011년 7월 3일

0 개 추천

x=[1 2 3]; %example input
xr=num2str(str2num(strrep(num2str(x),' ',''))+1)-'0'
%xr =[1 2 3 4]
the cyclist
the cyclist 2011년 7월 3일

0 개 추천

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 2011년 7월 4일

0 개 추천

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

David Young
David Young 2011년 7월 4일
This one works for long vectors with thousdands of elements (my arithmetic-based solution doesn't).

댓글을 달려면 로그인하십시오.

David Young
David Young 2011년 7월 4일

0 개 추천

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

카테고리

도움말 센터File Exchange에서 Dates and Time에 대해 자세히 알아보기

태그

Community Treasure Hunt

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

Start Hunting!

Translated by