Consider a "goto" array, in which each element tells you the next input to jump to:
a=. 1 3 3 6 10 7 10 9 15 12
So if we start at index 0, the value is 1, which means "go to index 1". When we do that, the value is 3, which means "go to index 3". The value there is 6, so we jump to index 6, where the value is 10. At this point we stop, because index 10 is out of bounds. If we were to collect our results, we'd get:
0 1 3 6 10
And indeed we can do this using ^: and an array power:
a {~^:(i.5) 0 NB. returns 0 1 3 6 10
The problem is that I had to know in advance how many iterations I'd need.
Instead I'd like to use the u^:v y form with a boolean returning v (it could check if the list length had been exceeded) -- but I'd also like to collect results.
Is this possible?
Things get verbose quickly if you are doing that collection manually with ,, although a slick manually collection solution will suffice if there is no built-in way to do what I want.
Completely different approaches that achieve the same goal are also welcome.
As suggested above you can use a: to return the results from the intermediate iterations. It will continue to iterate until it gets the same result twice in a row. The code below will cause the verb to halt the first time an invalid index is encountered. This is done by using the conjunction adverse :: to catch an error, then returning the same right argument again.
a {~ ::]^:a: 0
0 1 3 6 10
The standard idiom is
a {~^:a: 0
which is handled by special code. You have to make sure that there is an extra entry at the end of the array, usually _1, to stop the loop, and that the chain ends there. See
http://code.jsoftware.com/wiki/Vocabulary/Idioms#Variable-Length_Records
Related
I have just undertaken learning python. Thus, I constantly experience confusion.
Let me illustrate my question with an example. I want to carry out a coin flipping simulation
I start out by defining head and tail
c=random.randint(0,1)
for i in range(10):
print(c)
In this case the program returns identical outputs. It returns ten 1 values or ten 1 values. However if a add some adjustment by shifting the variable into the loop like this
for i in range(10):
c=random.randint(0,1)
print(c)
Then I receive what I expect.The program generates either 1 or 0 value 10 times randomly. I haven't understood why it acts like this. Can you walk me through please?
I desired to have 10 random values of integers 1 or 0. I ended up either having either 10 0 values or 1 values.
I have recently started learning python and am currently on fundamentals so please accept my excuse if this question sounds silly. I am a little confused with the indexing behavior of the list while I was learning the bubble sort algorithm.
For example:
code
my_list = [8,10,6,2,4]
for i in range(len(my_list)):
print(my_list[i])
for i in range(len(my_list)):
print(i)
Result:
8
10
6
2
4
0
1
2
3
4
The former for loop gave elements of the list (using indexing) while the latter provided its position, which is understandable. But when I'm experimenting with adding (-1) i.e. print (my_list[i-1]) and print(i-1) in both the for loops, I expect -1 to behave like a simple negative number and subtract a value from the indexed element in the first for loop i.e. 8-1=7
Rather, it's acting like a positional indicator of the list of elements and giving the last index value 4.
I was expecting this result from the 2nd loop. Can someone please explain to me why the print(my_list[i-1]) is actually changing the list elements selection but not actually subtracting value 1 from the list elements itself i.e. [8(-1), 10(-1), 6(-1)...
Thank you in advance.
The list index in the expression my_list[i-1] is the part between the brackets, i.e. i-1. So by subtracting in there, you are indeed modifying the index. If instead you want to modify the value in the list, that is, what the index is pointing at, you would use my_list[i] - 1. Now, the subtraction comes after the retrieval of the list value.
Here when you are trying to run the first for loop -
my_list = [8,10,6,2,4]
for i in range(len(my_list)):
print(my_list[i-1])
Here in the for loop you are subtracting the index not the Integer at that index number. So for doing that do the subtraction like -
for i in range(len(my_list)):
print(my_list[i]-1)
and you were getting the last index of the list because the loop starts with 0 and you subtracted 1 from it and made it -1 and list[-1] always returns the last index of the list.
Note: Here it is not good practice to iterate a list through for loop like you did above. You can do this by simply by -
for i in my_list:
print(i-1)
The result will remain the same with some conciseness in the code
I have a dataframe in which one of the columns is a binary column with 1s and 0s. I want to identify the first cluster of 1s of size 5 in that column(i.e., the first time 5 continuous 1s occur), and then delete all subsequent rows after the first 1 in that cluster.
I tried writing a loop that would count the 1s, and "continue" (i.e., break and start again) when it encountered a zero. However, I have not been able to write it correctly, because I'm unsure of the syntax. I'm new to Python, apologies if the following is completely wrong -
for i in randomstring["random"]:
i = i+1
if i%5 == 0:
i.remove(i)
elif i == 0:
continue
The loop above ran without error but I'm not sure what it achieved, there was no output.
This is roughly what the dataframe looks like (without the other columns) :
1
0
1
0
1
1
1
1
1
I want this -
1
0
1
0
1
If i rephrase your problem. It seems like you want to find an index.
I will propose you a way with numpy (just for personal reason).
#Just for the purpose of test
X=np.random.randint(0,2,100)
#TO have the index
Z=np.arange(len(X))
#Under it works only cause you have 0 and 1.
M=np.diff(X.cumsum())==0
U=X.cumsum()[1:][M]
Z=Z[1:][M]
COUNT=np.zeros(len(U))
COUNT[1:]=np.diff(U)
COUNT[0]=U[0]
#In COUNT there is the COUNT of consecutive 1
Z=Z-COUNT
#It gives you all the first index where the number of consecutive zero is 5
ANSWER=np.array(Z[COUNT==5],dtype=np.int32)
This is way too long :D . I try to find a better solution and will edit when i do.
First Edit : Change to use numpy diff.
(1:)`(3:)#.(1&=)"0 i.2
1 3
(1:,2:)`(3:)#.(1&=)"0 i.2
1 2
3 0
I want to get
1 2 3
Without new dimensions. Without zeros.
The shape changes dramatically between (1:) and (1:,2:).
$ 1: 'a'
$ 1 $ 1: 'a'
1
$ (1:,2:) 'a'
2
(1&$ 1:)`(1&$ 3:)#.(1&=)"0 i.2
1
3
There's probably a better way, but to my way of thinking, you're generating arrays of unequal length, which should be boxed, and then you want to turn them into a single list.
Thus:
; ((1:,2:)`(3:))#.(1&=)"0&.> i.2
1 2 3
Which can be refactored and improved a bit:
;#:((1:,2:)`(3:)#.(1&=)each) i.2
1 2 3
You could have used (1:,2:,3:) 'ignored argument' to form the list, but that doesn't address why you were using #.
Dane's comment about boxing intermediate results and then razing the resulting list is relevant if you want to merge irregularly shaped results. (Which might be what you were trying for, here.)
I've been working on this programming challenge: http://www.codeabbey.com/index/task_view/summing-up
Which basically states:
Input data has two values A and B in the single line.
Output should have the sum A+B printed into it.
Additionally after the stop the program should have values A, B, A+B in the cells 0, 1 and 2 respectively.
So for example input would look like this:
9 26
Now, I think I be misunderstanding either the problem or the solution because I believe the solution is supposed to be 9 26 35 where 9, 26, and 35 are all in their own cells.
My solution returns 9 26 35 and I believe in the correct cells (0,1, and 2 respectfully) but I am getting the answer wrong. Can anyone please look at the problem and my code and tell me where I am going wrong?
Code:
;:>;:><[-<+>]<:
I tried plugging this into a couple of online brainfuck interpreters. There is one here:
http://copy.sh/brainfuck/
and another here:
http://esoteric.sange.fi/brainfuck/impl/interp/i.html
In both cases, I needed to change your character set slightly --> : becomes . and ; becomes ,
The output from both was
9 Y
Notice that 35 - 9 = 24, and Y is the 24th letter of the alphabet. I think you are outputting the number "35" and having it interpretted as a letter.
I would try changing the program so that your output is literally single digits of the answer -- ie, output a 3, then output a 5, instead of outputting a numerical "35" (but leave the numerical value in cell 2 at the end). In other words, your text output should be a formatted version of the values in memory, rather than just outputting the numerical values directly.
It sounds like the output should only have A+B printed, not A, B, and A+B, as you're doing with :.
And your result seems like it'll have A+B in cell 0, and 0 in cell 1 (essentially the same as the example code).
>< is just cancelling itself out.