Iterate over an array and fill empty adjacent spots in array - arrays

I have created an multi dimensional array of empty strings with some row/columns being filled with a letter. Goal is to to fill the adjacent empty slots where the letters are found with that letter. I have most of array filling but I also want to count how many times loops occur to fill array.
This is in python 3 using numpy module only.
It keeps going out of range of index or I get infinite loops.
import numpy as np
letter_spots=[[3,0],[3,4],[1,3]]
A_array= np.zeros([5,5],str)
for lists in letter_spots:
A_array[lists[0]][lists[1]]='A'
for row in range(A_array.shape[0]):
for column in range(A_array.shape[1]):
if A_array[row][column]=='A':
if column+1 < A_array.shape[0]:
if A_array[row][column+1]=='':
A_array[row][column+1]='A'
if column>0:
if A_array[row][column - 1] == '':
A_array[row][column - 1] = 'A'
if row + 1 < A_array.shape[0]:
if A_array[row + 1][column] == '':
A_array[row + 1][column] = 'A'
if row > 0:
if A_array[row - 1][column] == '':
A_array[row - 1][column] = 'A'
Start array:
[['' '' '' '' '']
['' '' '' 'A' '']
['' '' '' '' '']
['A' '' '' '' 'A']
['' '' '' '' '']]
Current End Array:
[['' '' '' 'A' 'A']
['' '' 'A' 'A' 'A']
['A' 'A' 'A' 'A' 'A']
['A' 'A' 'A' 'A' 'A']
['A' 'A' 'A' 'A' 'A']]
Expected End Array:
[['A' 'A' 'A' 'A' 'A']
['A' 'A' 'A' 'A' 'A']
['A' 'A' 'A' 'A' 'A']
['A' 'A' 'A' 'A' 'A']
['A' 'A' 'A' 'A' 'A']]

You could just use where
import numpy as np
array1 = np.array([2, 2, 2, 0, 2, 0, 2])
print np.where(array1==0, 1, array1)

Related

create list of data time from an array

I have a weird format of date time information which is saved as a separate string. Such as,
print(time)
print(time[0])
print(type(time[0]))
print(type(time[0][0]))
[['2' '0' '2' ... '3' '2' '3']
['2' '0' '2' ... '4' '2' '3']
['2' '0' '2' ... '5' '2' '4']
...
['2' '0' '2' ... '5' '2' '7']
['2' '0' '2' ... '6' '2' '6']
['2' '0' '2' ... '7' '2' '0']]
['2' '0' '2' '2' '0' '5' '2' '1' '0' '7' '1' '3' '2' '3']
<class 'numpy.ma.core.MaskedArray'>
<class 'numpy.str_'>
The goal is to convert each row of the array into a proper DateTime format.
The outcome can be both list or an array.
For example,
['2' '0' '2' '2' '0' '5' '2' '1' '0' '7' '1' '3' '2' '3']
into
DateTime format 20220521-07:13:23
As the original data has multiple rows, I need to loop through the array.
suppose your list is:
l = ['2','0','2','2','0','5','2','1','0','7','1','3','2','3']
you can use:
time = [l[8+2*i]+l[9+2*i] for i in range(3)]
date = ''.join(l[:8]) + '- ' + ':'.join(time)
print(date)
>>> 20220521- 07:13:23

Check if a string contains a specific number of given values

I am trying to decode a message provided as a morse code via command line argument. If the provided string contains 7 spaces it means that I need to print a space to the decoded string.
This is the way I am trying to check if string contains 7 spaces via for loop:
if ((str[i] == ' ' && str[i + 1] == ' ' &&
str[i + 2] == ' ' && str[i + 3] == ' ' &&
str[i + 4] == ' ' && str[i + 5] == ' ' &&
str[i + 6] == ' ')) {
mx_printchar(' ');
}
Please let me know if any efficient way could be used for this purpose.
Currently, I cannot use linked lists or structs, but maybe there is any other way, please advise
You could use substr() instead as shown below :
if (str.substr(i,7) == " ") {
//do your task here
}
This will check for the substring from i to i+7(this index included) and if this substring is equal to 7 spaces, then it will do the required task.

Count elements in an array

I have an array that contains string elements:
farm = np.array(garden)
leads to this:
[['F' 'F' 'W' 'W']
['F' '_' '_' 'W']
['G' '_' '_' 'J']
['G' 'G' 'J' 'J']]
I want to count how many times lets say 'F' appears, is there a simple way to do this? This is a small version of the bigger array that I will be working on
EDIT:
Lists have a count method. So your new and improved pythonic code is
D= sum([i.count("F") for i in listX])
Well you can make a function, that
Checks if the parameter passed to it is in the array. You can even use list comprehensions. For example
F = sum([sum([1 for i in j if i=="f"]) for j in listX])
Michael's solution is the most "pythonic", but I wanted to offer an alternative solution using simpler constructs, in case you're just learning:
lst = []
lst.append(['F', 'F', 'W', 'W'])
lst.append(['F', '_', '_', 'W'])
lst.append(['G', '_', '_', 'J'])
lst.append(['G', 'G', 'J', 'J'])
numFs = 0
# Look at each sublist
for sublist in lst:
# Look at each element within the sublist
for s in sublist:
# If the element is an 'F', add 1 to the number of Fs
if s == 'F':
numFs += 1
print(numFs)
You could also try to reduce and join the elements of the arrays into a string and then count, like so:
from functools import reduce
a = [['F' 'F' 'W' 'W'], ['F' '_' '_' 'W'], ['G' '_' '_' 'J'], ['G' 'G' 'J' 'J']]
c = ''.join(reduce(list.__add__, a)).count('F')
print(c)
When executed, this code prints:
3

Depth First Search in C

If I have to iterate through a table of hexagonal cells checking for text inside them by conducting a recursive depth first search, arranged as shown: [Typing it out on StackOverflow apparently doesn't keep the formatting.]
Example 1:
Example 2:
What would be the best way to identifying them as "cells?" In other words, besides removing the textual diagonal lines and converting them into a 2D array with just numbers in it, what would be the best way to tell the computer in code to recognize x certain number of y characters resembles a "cell?"
Thanks in advance.
Easiest way to represent a hexagonal grid would be plain 2-d array with special rule about neighborhood of the cells. Take your second case for example, in matrix form it would be:
char M[][] =
{
{ 'b', 'g', 'g', 'b', ' ' },
{ 'g', ' ', 'B', 'B', 'B' },
{ 'g', 'B', ' ', 'b', 'g' },
{ 'B', ' ', 'g', 'g', 'g' }
}
Element in column m in row n is neighbor with:
elements in columns m and m + 1 in row n - 1
elements in columns m - 1 and m + 1 in row n
elements in columns m - 1 and m in row n + 1

How to print a value as a variable from a cell in Matlab?

For
A=[1;3;5]
and
B=cell(7,1)
I have the following results stored in a cell
[1]
[3]
[5]
[1;3]
[1;5]
[3;5]
[1;3;5]
I would like to print the results in a way that a=1, b=3, and c=5. -- Basically assign each value in A to a variable.
How would I do this in Matlab ?
I am looking for a result which can be something like this :
" you can have a "
" you can have b "
" you can have c "
" you can have a or b "
.
.
etc
Let C be the array of letters you want to assign to the numbers in A. Then
A = [1 3 5];
B = {[1]; [3]; [5]; [1;3]; [1;5]; [3;5]; [1;3;5]};
C = ['a', 'b', 'c']
k = 6; % indicates current line of B
str = ['you can have ' strrep(strrep(sprintf('_%c_', ...
C(ismember(A, B{k}))'), '__', ' or '), '_', '')];
results in
str =
you can have a or b or c
If you want to create the responses to all fields in B at once, you can use
allStr = arrayfun(#(x) ['you can have ' strrep(strrep(sprintf('_%c_', ...
C(ismember(A, B{x}))'), '__', ' or '), '_', '')], ...
(1:length(B))', 'uniformoutput', false)
This results in
allStr =
'you can have a'
'you can have b'
'you can have c'
'you can have a or b'
'you can have a or c'
'you can have b or c'
'you can have a or b or c'
A step by step explanation of this code is as follows:
% which contents of A can be found in B?
idx = ismember(A, B{k})';
% to which letters do these indices correspond?
letters = C(idx);
% group the letters in a string embedded in '_' as place holders for later use
% by this, the places between letters will be marked with '__' and the places
% at the beginning and the end of the string will be marked with '_'
stringRaw = sprintf('_%c_', letters);
% replace each occurrence of '__' by ' or '
stringOr = strrep(stringRaw, '__', ' or ');
% replace each occurrence of '_' by ''
stringClean = strrep(stringOr, '_', '');
% add first half of sentence
stringComplete = ['you can have ' stringClean];
To get this working with complete words (as requested in the comments), you need to transform C into a cell array of strings and update the formula accordingly:
A = [1 3 5];
B = {[1]; [3]; [5]; [1;3]; [1;5]; [3;5]; [1;3;5]};
C = {'first', 'second', 'third'}
k = 7; % indicates current line of B
str = ['you can have ' strrep(strrep(sprintf('_%s_', ...
C{ismember(A, B{k})}), '__', ' or '), '_', '')];
This results in:
str =
you can have first or second or third
If I have understood properly, you want something like this:
numToLetter = [ 'a', ' ', 'b', ' ', 'c' ];
B = { 1, 3, 5, [ 1; 3 ], [ 1; 5 ], [ 3; 5 ], [ 1; 3; 5 ] };
% Loop though each entry in our cell array
for i = 1 : length(B)
fprintf(' you can have '); % Print initial message
% Loop though each vector element inside the B{i}
for j = 1 : length(B{i})
fprintf('%c', numToLetter(B{i}(j) ) ) % Use our numToLetter lookup table
% to convert the number to a letter,
% and print it out.
if j ~= length(B{i})
fprintf(' or '); % Print 'or' if there are more to come
end
end
fprintf('\n'); % New line
end
The main bit of your question was how to assign each number to a letter (note: I know you asked to assign each one to a variable, but I don't think that's quite what you want.). This is done using a lookup table, called numToLetter, which has a stored at 1, b stored at 3, and c stored at 5. This way you simply use your input numbers as indices into this table. You could use this lookup table with a vector; for example:
myNumbers = [ 1 3 3 1 5 ];
myLetters = numToLetter(myNumbers)
Gives the output:
myLetters =
abbac

Resources