I would like to know if it is possible to calculate the sum of 1+2+3+...+k in brainfuck just with the number k at the beginning of the code?
For example is it possible to do 1+2+3 like this:
+++> (here the code creates a two add it with the three, create the one and add it)
Because I can do this : +++>++>+[<<+>>-]<[<+>-]< but if k=10000 how can I do this ?
Here is a simple version. Assume we name the first three cells y, temp0 and x. Then we can simply use this algorithm within a decrementing loop:
+++ # Input number (in fisrt cell)
[ # loop while first cell is not 0
>[-] # if second cell is null
<[>>+<+<-] # copy first cell in second and third and decrease it to 0
>[<+>-] # move second cell in first cell
<- # decrement input
] # go to begin of while loop
>> # the current cell now has the result
Note that this only works up to k = 22 due to the 8-bit limit. To output the number or deal with larger numbers, you'll have to use extra effort.
,[[>+>+<<-]>-[<+>-]<]>>.
A more concise and efficient algorithm than Ingo's. Uses three "slots"
|num|: original number; decremented each loop.
|temp|: copied back into |1| each loop
|total|: accumulates values each loop
+++ input |num|
[ while |num| is non-zero
[>+>+<<-] copy |num| to |temp| and |results|
>-[<+>-] copy |temp-1| back to |num|
< reset pointer
]
>>. output |total|
same explanation, but in more detail
+++ input |num|
[ while |num| is non-zero
[ until |num| is zero
>+>+ increment |temp| and |total|
<< return to |num|
- decrement |num|
]
>- goto |temp|, decrement
[<+>-] until |temp| is zero; decrement |temp|; increment |num|
< goto |num|
]
>>. goto |total|, output it
Related
I can find / identify all digits in a number using a recursive function.
My issue is trying to sum the number through each recursion.
I had to initialize sum = 0 at the top of my function statement, and when I return through recursion, I'm always resetting sum back to zero. I do not know how to save a variable without first initalizing it.
Code is below;
function output= digit_sum(input)
sum=0
if input < 10
output = input
else
y=rem(input,10);
sum=sum+y
z=floor(input/10);
digit_sum(z)
end
output=sum
end
My aim was to build a prime number generator in Forth. Not a Sieve of Eratosthenes but two nested loops who are bruteforcing all combinations of number A and number B. In the sourcecode, I have a word for the loop, for testing if a condition is true and also some attempt in doing the nested loop. But after executing the code with gforth a stack-underflow error is shown. Maybe some kind of dup is missing somewhere, but it's also possible that the i and j index in the loops is wrong. The problem is, that if i change something in the code, the stack is different. That means, after putting out the index number of the for loop to the screen, it's no longer possible to get access to this number. Also i find it's difficult to get access to variables, because Forth doesn't seem to have variables at all. So I created a helper variable, but it's unclear how to use it.
I know, the code looks a bit confusing, can anybody help?
variable temp
: numbers
10 0 do i . loop
;
: cond
0 dup
0 = if ." equal 0" endif
;
: plain
10 2 mod .
10 3 mod .
10 4 mod .
10 5 mod .
10 6 mod .
10 7 mod .
10 8 mod .
10 9 mod .
;
: plain2
10 temp !
\ 10 0 do temp # i mod . loop
\ 10 0 do temp # . i . loop
10 2 do temp # i mod . cond loop
;
: cond2 ( n - n )
10 2 do i
10 2 do i
mod .
loop cr loop
;
: main
\ numbers
cond2
\ plain
\ plain2
;
main
CR bye
There are several bugs and repetitions in your code. For example in your cond word you put 0 on the data stack then dup it and compare stack top value (which is 0) with 0. Of course, you will get true every time.
It seems that you try to write many words definitions at once and use them in your program without debugging carefully every single word. With Forth programming it is better to make (and debug) a few short words and then compose more complicated code with them. I would recommend you to read Starting Forth book which describes this approach very well.
Regarding your code -- it is better to rewrite it completely. Here it is:
: is-not-divided-by mod 0= INVERT ;
: check-prime-number true SWAP DUP 2 DO DUP I is-not-divided-by ROT AND SWAP loop DROP ;
: is-prime-number DUP 2 > IF check-prime-number ELSE DROP true THEN ;
: prime-numbers 1 DO I is-prime-number IF I . THEN LOOP ;
and now 10 prime-numbers will print you prime numbers from 1 to 9.
I want to use structure in matlab but in first iteration it's run correctly and in other iteration give that message .
1x2 struct array with fields:
my code is :
for i=1:lenfd
currow=rees(i,:)
maxcn=max(currow)
if maxcn~=0
maxin=find(currow==maxcn)
ress(i).x =maxin
end
end
thank you.
That message is not a warning or error. That's just MATLAB printing the output of an operation. And it does that by default, unless you suppress it by appending a semicolon to the command:
for ii = 1:lenfd
currow = rees(ii,:); % <=== NOTE: semicolons at the end
maxcn = max(currow);
if maxcn ~= 0
ress(ii).x = find(currow==maxcn);
end
end
Note that max() may have 2 outputs, the second output being the first index into the array where the maximum occurred. If you know beforehand that any maximum will occur only once, you can skip the call to find() and use the second output of max().
I was trying to make a simple statement with Matlab as follows:
if TF==1
disp('One'), break
else continue
end
... ... ...
... ... ...
But even if TF is not 1, when I run the command, it doesn't CONTINUE to the rest of the script!! Any help would be appreciated-- Thanks
The continue statement has a very different meaning. Within a loop, like a for or while loop, continue instructs to skip the current round and continue with the next iteration in the loop. So if you remove continue, you will see the behavior that you are expecting. Here is an example:
for k = 1 : 10
if k == 4
% skip the calculation in the case where k is 4
continue
end
area = k * k;
disp(area);
end
When the loop iterates at k == 4, the block calculating the area of the corresponding square is skipped. This particular example is not very practical.
However, imagine you have a list of ten file names, and you want to process each file in this loop "for k = 1 : 10". You will have to try and open each file, but then if you find out the file does not exist, an appropriate way to handle it would be to print a little warning and then continue to the next file.
I want to remove a (*) asterisk from my matrix and write out that matrix to a text file and the remaining elements will be concatenated to each other without a space or any kind of delimiters. I wrote this code
for b = 1 : length(out7num_r7_nt_back)
if ~(out7num_r7_nt_back(b) == '*')
out7num_r7_back(b) = '';
end
end
disp(out7num_r7_nt_back);
dlmwrite('my_data.txt',out7num_r7_nt_back, '');
I got this error message:
??? Index of element to remove exceeds matrix dimensions.
You can use a vectorized boolean index, replacing the loop as follows:
out7num_r7_nt_back = out7num_r7_nt_back(out7num_r7_nt_back(b) ~= '*');
That should be much faster as well.
Value of upper bound of for loop (length(out7num_r7_nt_back)) gets evaluated only once!
Say you have '*ab' in a variable. Loop will count to 3 (length of variable). Inside the loop when program erases '*', you'll get 'ab' which is of length 2. Since loop is iterating to 3, program will try to access out7num_r7_nt_back(3) which is out of bounds.
You could remove characters while going backwards:
...
for b = length(out7num_r7_nt_back) : -1 : 1
...
But you should prefer vectorized approach because it's faster and cleaner to write.