How to draw three-dimensional image: Plot3D NDSolve - wolfram-mathematica

m = 10; c = 2; k = 5; F = 12;
NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] == F*Sin[2*Pi*f*t],
x[0] == 0, x'[0] == 0}, x[t], {t, 0, 30}]
{f, 0, 5} ( 0=< f <= 5 )
How to draw three-dimensional image:
x = u(t,f)
............
If f = 0.1,0.2,... 5,
We can solve the equation:
NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] == F*Sin[2*Pi*f*t],
x[0] == 0, x'[0] == 0}, x[t], {t, 0, 30}]
x is a function of t and f
...............
m = 10; c = 2; k = 5; F = 12;
f = 0.1
s = NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] == F*Sin[2*Pi*f*t],
x[0] == 0, x'[0] == 0}, x[t], {t, 0, 30}]
Plot[Evaluate[x[t] /. s], {t, 0, 30}, PlotRange -> All]
f = 0.1
f = 0.2
f = 0.3
f = 5
How to draw three-dimensional image:
x = u(t,f)

Here goes a solution.
m = 10; c = 2; k = 5; F = 12;
NumberOfDiscrit$f = 20;(* Number of points you want to divide 0<=f<=5*)
NumberOfDiscrit$t = 100;(* Number of points you want to divide 0<=t<=30 *)
fValues = Range[0., 5., 5./(NumberOfDiscrit$f - 1)];
tValues = Range[0., 30., 30./(NumberOfDiscrit$t - 1)];
res = Map[(x /.
First#First#
NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*#*t])*x[t] ==
F*Sin[2*Pi*#*t], x[0] == 0, x'[0] == 0}, x, {t, 0, 30}]) &,
fValues];
AllDat = Map[(##tValues) &, res];
InterpolationDat =
Flatten[Table[
Transpose#{tValues,
Table[fValues[[j]], {i, 1, NumberOfDiscrit$t}],
AllDat[[j]]}, {j, 1, NumberOfDiscrit$f}], 1];
Final3DFunction = Interpolation[InterpolationDat];
Plot3D[Final3DFunction[t, f], {t, 0, 30}, {f, 0, 5}, PlotRange -> All,
PlotPoints -> 60, MaxRecursion -> 3, Mesh -> None]
You can use Manipulate to dynamically change some of the parameters. By the way the above 3D picture may be misleading if one takes f as a continuous variable in u(t,f). You should note that the numerical solution seems to blow up for asymptotic values of t>>30. See the picture below.
Hope this helps you out.

You could also do something like this
Clear[f]
m = 10; c = 2; k = 5; F = 12;
s = NDSolve[{m*Derivative[2, 0][x][t, f] +
c*Derivative[1, 0][x][t, f] + (k*Sin[2*Pi*f*t])*x[t, f] == F*Sin[2*Pi*f*t],
x[0, f] == 0,
Derivative[1, 0][x][0, f] == 0}, x, {t, 0, 30}, {f, 0, .2}]
Plot3D[Evaluate[x[t, f] /. s[[1]]], {t, 0, 30}, {f, 0, .2}, PlotRange -> All]

This should do it.
m = 10; c = 2; k = 5; F = 12;
fun[f_?NumericQ] :=
Module[
{x, t},
First[x /.
NDSolve[
{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] == F*Sin[2*Pi*f*t],
x[0] == 0, x'[0] == 0},
x, {t, 0, 30}
]
]
]
ContourPlot[fun[f][t], {f, 0, 5}, {t, 0, 30}]
Important points:
The pattern _?NumericQ prevents fun from being evaluated for symbolc arguments (think fun[a]), and causing NDSolve::nlnum errors.
Since NDSolve doesn't appear to localize its function variable (t), we needed to do this manually using Module to prevent conflict between the t used in NDSolve and the one used in ContourPlot. (You could use a differently named variable in ContourPlot, but I think it was important to point out this caveat.)
For a significant speedup in plotting, you can use memoization, as pointed out by Mr. Wizard.
Clear[funMemo] (* very important!! *)
funMemo[f_?NumericQ] :=
funMemo[f] = Module[{x, t},
First[x /.
NDSolve[{m*x''[t] + c*x'[t] + (k*Sin[2*Pi*f*t])*x[t] ==
F*Sin[2*Pi*f*t], x[0] == 0, x'[0] == 0}, x, {t, 0, 30}]]]
ContourPlot[funMemo[f][t], {f, 0, 5}, {t, 0, 30}] (* much faster than with fun *)
If you're feeling adventurous, and willing to explore Mathematica a bit more deeply, you can further improve this by limiting the amount of memory the cached definitions are allowed to use, as I described here.
Let's define a helper function for enabling memoization:
SetAttributes[memo, HoldAll]
SetAttributes[memoStore, HoldFirst]
SetAttributes[memoVals, HoldFirst]
memoVals[_] = {};
memoStore[f_, x_] :=
With[{vals = memoVals[f]},
If[Length[vals] > 100, f /: memoStore[f, First[vals]] =.;
memoVals[f] ^= Append[Rest[memoVals[f]], x],
memoVals[f] ^= Append[memoVals[f], x]];
f /: memoStore[f, x] = f[x]]
memo[f_Symbol][x_?NumericQ] := memoStore[f, x]
Then using the original, non-memoized fun function, plot as
ContourPlot[memo[fun][f][t], {f, 0, 5}, {t, 0, 30}]

Related

Working with implicit functions in Mathematica returned from other functions

I have a equation
inv = (x + f) (y + g) == z;
But for some reason I cannot CountourPlot it, even though copy-pasting output, for example {(2 + x) (2 + y)} == {11} into CountourPlot works. I've tried both Hold and Defer to no luck.
What's happening and how I can fix this problem?
Actual code:
inv00 = (x + 1) (y + 1) == z
inv01 = inv00 /. {z -> 2}
ContourPlot[inv01, {x, 0, 1}, {y, 0, 1}]
ContourPlot[(1 + x) (1 + y) == 2, {x, 0, 1}, {y, 0, 1}]

How to solve flow game using Google OR tools?

I tried to make solver for flow game using google-OR tools.
I made a few rules for the corner to only contains corner pipes, but other than that, i can not figure out how to make the pipe connected to each other nor how to tell the model to make a pipe that is connecting to each other.
A few snippet
pipe_types = {
0: " ",
1: "-",
2: "|",
3: "┗" ,
4: "┛" ,
5: "┓",
6: "┏",
7: "●"
}
model = cp_model.CpModel()
filled_map = [[0,0,0,0],
[0,0,7,0],
[0,0,0,0],
[0,7,0,0]]
mesh_size = int(np.sqrt(len(np.array(filled_map).flatten())))
target_map = [[model.NewIntVar(1, 6, 'column: %i' % i) for i in range(mesh_size)] for j in range(mesh_size)]
flow_map = init_map(model, target_map, filled_map)
for i in range(len(flow_map)):
for j in range(len(flow_map[0])):
# check if top or bottom side
if (i == 0) or (i == len(flow_map)-1):
model.Add(flow_map[i][j] != 2)
# check if left or right side
if (j == 0) or (j == len(flow_map[0])-1):
model.Add(flow_map[i][j] != 1)
# left up corner
if (i == 0) & (j == 0):
model.Add(flow_map[i][j] != 3)
model.Add(flow_map[i][j] != 4)
model.Add(flow_map[i][j] != 5)
# right up corner
if (i == 0) & (j == len(flow_map[0])-1):
model.Add(flow_map[i][j] != 3)
model.Add(flow_map[i][j] != 4)
model.Add(flow_map[i][j] != 6)
# left bottom corner
if (i == len(flow_map)-1) & (j == 0):
model.Add(flow_map[i][j] != 4)
model.Add(flow_map[i][j] != 5)
model.Add(flow_map[i][j] != 6)
# right bottom corner
if (i == len(flow_map)-1) & (j == len(flow_map[0])-1):
model.Add(flow_map[i][j] != 3)
model.Add(flow_map[i][j] != 5)
model.Add(flow_map[i][j] != 6)
# Solving
status = solver.Solve(model)
res = []
if status == cp_model.OPTIMAL or status == cp_model.FEASIBLE:
for i in range(len(flow_map)):
for j in range(len(flow_map[0])):
res.append(solver.Value(flow_map[i][j]))
print(solver.Value(flow_map[i][j]), end=" ")
print()
This would results horizontal pipes on the center of the mesh. Later on, i would have to figure out how to add color and such on this too.
Is there any pointer on how to make this on OR tools?
Edit 1:
Based on David Eisenstat's answer, I can find solution. Visualizing this solution based on JohanC's answer, I get this result.
Can I get the pathing made from google-OR tools?
Edit 2:
Using hamilton path from "Hamiltonian" path using Python
I could generate somewhat correct pathing.
But it feels so weird since OR tools already calculate the pathing, and I have to recalculate the path. The path generated from "Hamiltonian" path using Python doesn't show all possible combinations. If I can take the path from OR tools, I think that would be my best interest.
As I don't have experience with OR-tools, here is an approach with Z3.
The initial board is represented by numbers for the end points, one number for each color. The idea is a bit similar to how Sudoku is represented.
Each other cell on the board will get either a value for zero, or a number. This number should be equal to exactly two of its neighbors.
The initial endpoints should have exactly one neighbor with its color.
from z3 import Solver, Sum, Int, If, And, Or, sat
def plot_solution(S):
import matplotlib.pyplot as plt
ax = plt.gca()
colors = plt.cm.tab10.colors
for i in range(M):
for j in range(N):
if board[i][j] != 0:
ax.scatter(j, i, s=500, color=colors[board[i][j]])
if S[i][j] != 0:
for k in range(M):
for l in range(N):
if abs(k - i) + abs(l - j) == 1 and S[i][j] == S[k][l]:
ax.plot([j, l], [i, k], color=colors[S[i][j]], lw=15)
ax.set_ylim(M - 0.5, -0.5)
ax.set_xlim(-0.5, N - 0.5)
ax.set_aspect('equal')
ax.set_facecolor('black')
ax.set_yticks([i + 0.5 for i in range(M - 1)], minor=True)
ax.set_xticks([j + 0.5 for j in range(N - 1)], minor=True)
ax.grid(b=True, which='minor', color='white')
ax.set_xticks([])
ax.set_yticks([])
ax.tick_params(axis='both', which='both', length=0)
plt.show()
board = [[1, 0, 0, 2, 3],
[0, 0, 0, 4, 0],
[0, 0, 4, 0, 0],
[0, 2, 3, 0, 5],
[0, 1, 5, 0, 0]]
M = len(board)
N = len(board[0])
B = [[Int(f'B_{i}_{j}') for j in range(N)] for i in range(M)]
s = Solver()
s.add(([If(board[i][j] != 0, B[i][j] == board[i][j], And(B[i][j] >= 0, B[i][j] < 10))
for j in range(N) for i in range(M)]))
for i in range(M):
for j in range(N):
same_neighs_ij = Sum([If(B[i][j] == B[k][l], 1, 0)
for k in range(M) for l in range(N) if abs(k - i) + abs(l - j) == 1])
if board[i][j] != 0:
s.add(same_neighs_ij == 1)
else:
s.add(Or(same_neighs_ij == 2, B[i][j] == 0))
if s.check() == sat:
m = s.model()
S = [[m[B[i][j]].as_long() for j in range(N)] for i in range(M)]
print(S)
plot_solution(S)
Solution:
[[1, 2, 2, 2, 3],
[1, 2, 4, 4, 3],
[1, 2, 4, 3, 3],
[1, 2, 3, 3, 5],
[1, 1, 5, 5, 5]]
As mentioned in the comments, a possible requirement is that all cells would need to be colored. This would need a more complicated approach. Here is an example of such a configuration for which the above code could create a solution that connects all end points without touching all cells:
board = [[0, 1, 2, 0, 0, 0, 0],
[1, 3, 4, 0, 3, 5, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 2, 0, 4, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0],
[0, 5, 0, 0, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 0]]
The best way is probably with AddCircuit. This constraint takes a directed graph where each arc is labeled with a literal and requires that the arcs labeled true form a subgraph where each node has in- and out-degree 1, and further that there is at most one cycle that is not a self-loop. By forcing an arc from the end to the beginning, we can use this constraint type to require that there is a single path from the beginning to the end.
The documentation is somewhat poor, so here's a working code sample. I'll leave the drawing part to you.
import collections
from ortools.sat.python import cp_model
def validate_board_and_count_colors(board):
assert isinstance(board, list)
assert all(isinstance(row, list) for row in board)
assert len(set(map(len, board))) == 1
colors = collections.Counter(square for row in board for square in row)
del colors[0]
assert all(count == 2 for count in colors.values())
num_colors = len(colors)
assert set(colors.keys()) == set(range(1, num_colors + 1))
return num_colors
def main(board):
num_colors = validate_board_and_count_colors(board)
model = cp_model.CpModel()
solution = [
[square or model.NewIntVar(1, num_colors, "") for (j, square) in enumerate(row)]
for (i, row) in enumerate(board)
]
true = model.NewBoolVar("")
model.AddBoolOr([true])
for color in range(1, num_colors + 1):
endpoints = []
arcs = []
for i, row in enumerate(board):
for j, square in enumerate(row):
if square == color:
endpoints.append((i, j))
else:
arcs.append(((i, j), (i, j)))
if i < len(board) - 1:
arcs.append(((i, j), (i + 1, j)))
if j < len(row) - 1:
arcs.append(((i, j), (i, j + 1)))
(i1, j1), (i2, j2) = endpoints
k1 = i1 * len(row) + j1
k2 = i2 * len(row) + j2
arc_variables = [(k2, k1, true)]
for (i1, j1), (i2, j2) in arcs:
k1 = i1 * len(row) + j1
k2 = i2 * len(row) + j2
edge = model.NewBoolVar("")
if k1 == k2:
model.Add(solution[i1][j1] != color).OnlyEnforceIf(edge)
arc_variables.append((k1, k1, edge))
else:
model.Add(solution[i1][j1] == color).OnlyEnforceIf(edge)
model.Add(solution[i2][j2] == color).OnlyEnforceIf(edge)
forward = model.NewBoolVar("")
backward = model.NewBoolVar("")
model.AddBoolOr([edge, forward.Not()])
model.AddBoolOr([edge, backward.Not()])
model.AddBoolOr([edge.Not(), forward, backward])
model.AddBoolOr([forward.Not(), backward.Not()])
arc_variables.append((k1, k2, forward))
arc_variables.append((k2, k1, backward))
model.AddCircuit(arc_variables)
solver = cp_model.CpSolver()
status = solver.Solve(model)
if status == cp_model.OPTIMAL:
for row in solution:
print("".join(str(solver.Value(x)) for x in row))
if __name__ == "__main__":
main(
[
[1, 0, 0, 2, 3],
[0, 0, 0, 4, 0],
[0, 0, 4, 0, 0],
[0, 2, 3, 0, 5],
[0, 1, 5, 0, 0],
]
)

how can I change value of array in a loop in mathematica?

I wrote a code in matlab as below:
T= ((1-(-1)) * rand([4,4],'double') + (-1) * ones(4,4));
for i=1:4
for j=1:i
T(j,i)=TT(i,j);
end
T(i,i)=0;
end
Now, I want to write this code in mathematica as below:
T = RandomReal[{-1, 1}, {4, 4}];
For[i = 1, i < 5, i++,
For[ j = 1, j < i, j++,
T[[j, i]] = T[[i, j]]]
T[[i, i]] = 0];
But it doesn't work!
Could you tell me about my mistakes?
Thank you.
SeedRandom[1234];
t = u = RandomReal[{-1, 1}, {4, 4}];
t // MatrixForm
If must use For
For[i = 1, i < 5, i++,
For[j = 1, j < i, j++, t[[j, i]] = t[[i, j]]]; t[[i, i]] = 0];
It mutates t
t // MatrixForm
One way to do this functionally
(l = LowerTriangularize[u, -1]) + Transpose[l]

Random "Path" Generation Code

I am currently working on generating a random path for a game I am recreating. It is based off of the "Thin Ice" game in Club Penguin where you play as a fire character, walk across a path of ice, and get to the exit, melting as many ice blocks as possible along the way. (Link to play: http://justdoodiecp.weebly.com/play-thin-ice.html)
This game has preset boards. The game I am making will have random board generation. I have run into many issues with this.
I am currently coding in Mathematica, but would appreciate any input.
So far, I have been creating a "random walk" in a square grid. The grid is a two dimensional list of {},{0},{1},{2},{3}. The walk moves either up, down, left or right, never diagonally and never staying in the same place. It also cannot walk back on itself.The walk replaces {} with {0} at the positions it goes to and cannot go to any spot with 0,1,2, or 3 currently in place. It starts at 2. The goal is to get it to eventually stop at 3, but I'm thinking I may do away with the value of three until the walk is complete. It can travel adjacent to another section of the path, with no wall in between them. This walk continues on until it traps itself OR the amount of {0} is equal to the dimensions minus the amount of obstacles that should be placed. The amount of obstacles is inputted when calling the function. However, I do not want the function to trap itself but instead fill up the board with {0} until the amount of {0} is equal to the dimensions minus the amount of obstacles that should be placed. Once the path is generated, all obstacles will be placed in any blank spots, replacing them with {1}.
Here is my code so far:
gameboard2[dim_, obs_] :=
(*0 = blank, 1= obstacles, 2 = start, 3 = exit, 4 = water*)
Module[{i, j, board = {}, boardPts = {}, x = 1, y = 1, endx = 1,
endy = 1, prevx = 1, prevy = 1, possibleValues = {}, pt = {},
blankspc = dim^2 - 2 - obs},
board = Table[{}, {i, 1, dim + 2}, {j, 1, dim + 2}];
(*Generation of border*)
Table[board[[1, i]] = {1}, {i, 1, dim + 2}];
Table[board[[dim + 2, i]] = {1}, {i, 1, dim + 2}];
For[i = 1, i <= Length[board], i++,
board[[i, 1]] = {1};
board[[i, dim + 2]] = {1};
];
(*Random start point placement*)
While[Count[board, {2}, 2] != 1,
x = RandomChoice[Table[i, {i, 1, dim + 2}]];
y = RandomChoice[Table[i, {i, 1, dim + 2}]];
If[board[[x, y]] != {1}, board[[x, y]] = {2}];
];
(*Random exit point placement*)
While[Count[board, {3}, 2] != 1,
endx = RandomChoice[Table[i, {i, 1, dim + 2}]];
endy = RandomChoice[Table[i, {i, 1, dim + 2}]];
If[board[[endx, endy]] != {1}, board[[endx, endy]] = {3}];
];
(*Random path generation*)
(*x needs to be between 2 and dim+1 and y needs to be between 2 and dim+1*)
For[i = 1, i <= blankspc, i++,
prevx = x; prevy = y;
possibleValues = {};
(*Testing position of x and y, making sure they are not on the side or the corner of the board*)
If[x == 2,
If[y == 2, (*bottom left*) possibleValues = {{x, y + 1}, {x + 1, y}},
If[y == dim + 1, (*top left*)
possibleValues = {{x, y - 1}, {x + 1, y}},
(*left side*) possibleValues = {{x, y + 1}, {x, y - 1}, {x + 1, y}}]],
If[x == dim + 1,
If[y == 2, (*bottom right*) possibleValues = {{x, y + 1}, {x - 1, y}},
If[y == dim + 1, (*top right*)
possibleValues = {{x, y - 1}, {x - 1, y}},
(*right side*)
possibleValues = {{x, y + 1}, {x, y - 1}, {x - 1, y}}]],
If[y == 2, (*bottom*)
possibleValues = {{x, y - 1}, {x - 1, y}, {x + 1, y}},
If[y == dim + 1,(*top*)
possibleValues = {{x, y + 1}, {x - 1, y}, {x + 1,
y}},(*Not on any side or corner*)
If[x > 2 && x < dim + 1 && y > 2 && y < dim + 1,
possibleValues = {{x, y + 1}, {x, y - 1}, {x + 1, y}, {x - 1,
y}}, possibleValues = {{x, y}}]
]
]
]
];
(*Ensure every position in possibleValues is equal to {} on the board*)
For[j = 1, j <= Length[possibleValues], j++,
If[board[[possibleValues[[j, 1]], possibleValues[[j, 2]]]] != {},
possibleValues[[j]] = {}];
];
possibleValues =
Delete[possibleValues, Position[possibleValues, {}]];
(*Random choosing of a point to move to*)
pt = RandomChoice[possibleValues];
x = pt[[1]];
y = pt[[2]];
If[board[[x, y]] == {}, board[[x, y]] = {0}];
];
(*Prints amount of {} and the length of the path to see if it became the right length*)
Print[blankspc];
Print[Count[board, {0}, 2]];
Return[TableForm[board]]
]
Output:
In[30]:= gameboard2[10, 30]
(*Note how many errors there are. This occurs when the path gets trapped and cannot move to any squares around it*)
During evaluation of In[30]:= RandomChoice::lrwl: The items for choice {} should be a list or a rule weights -> choices. >>
During evaluation of In[30]:= Part::partw: Part 2 of RandomChoice[{}] does not exist. >>
During evaluation of In[30]:= Part::pkspec1: The expression RandomChoice[{}][[2]] cannot be used as a part specification. >>
During evaluation of In[30]:= RandomChoice::argt: RandomChoice called with 0 arguments; 1 or 2 arguments are expected. >>
During evaluation of In[30]:= Part::partw: Part 1 of RandomChoice[] does not exist. >>
During evaluation of In[30]:= Part::partw: Part 2 of RandomChoice[] does not exist. >>
During evaluation of In[30]:= General::stop: Further output of Part::partw will be suppressed during this calculation. >>
During evaluation of In[30]:= Part::pkspec1: The expression RandomChoice[][[1]] cannot be used as a part specification. >>
During evaluation of In[30]:= RandomChoice::argt: RandomChoice called with 0 arguments; 1 or 2 arguments are expected. >>
During evaluation of In[30]:= Part::pkspec1: The expression RandomChoice[][[1]] cannot be used as a part specification. >>
During evaluation of In[30]:= General::stop: Further output of Part::pkspec1 will be suppressed during this calculation. >>
During evaluation of In[30]:= RandomChoice::argt: RandomChoice called with 0 arguments; 1 or 2 arguments are expected. >>
During evaluation of In[30]:= General::stop: Further output of RandomChoice::argt will be suppressed during this calculation. >>
During evaluation of In[30]:= 68
(*This is how many {0} there should be*)
During evaluation of In[30]:= 45
(*This is how many there are*)
{{{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}},
{{1}, {}, {}, {}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {1}},
{{1}, {}, {}, {}, {0}, {0}, {0}, {0}, {}, {}, {0}, {1}},
{{1}, {}, {}, {}, {0}, {0}, {0}, {0}, {}, {}, {0}, {1}},
{{1}, {}, {}, {}, {0}, {0}, {0}, {0}, {}, {}, {0}, {1}},
{{1}, {}, {}, {}, {0}, {0}, {0}, {0}, {}, {}, {0}, {1}},
{{1}, {}, {}, {}, {0}, {0}, {}, {}, {}, {}, {0}, {1}},
{{1}, {}, {}, {}, {}, {3}, {}, {0}, {0}, {}, {0}, {1}},
{{1}, {}, {}, {}, {}, {0}, {0}, {0}, {0}, {0}, {0}, {1}},
{{1}, {}, {}, {}, {}, {0}, {}, {2}, {0}, {}, {}, {1}},
{{1}, {}, {}, {}, {}, {0}, {0}, {0}, {0}, {}, {}, {1}},
{{1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}, {1}}}]
I've looked all over the internet for various path generation tips and tricks, but none have been what I am looking for. Most allow the path to go back on itself, or move diagonally, or generate a maze. These will not work.
Can anyone help me uncover the correct logic? If I was not clear, please ask questions! :)
Thanks!

Can i return list in Mathematica function?

In my code I'm trying to return list of numbers from my function but it gives me just null.
sifra[zprava_, klic_] := Module[
{c, n, e, m, i, z, pocCyklu, slovo},
pocCyklu = Ceiling[Divide[StringLength[zprava], 5]];
c = Array[{}, pocCyklu];
z = Partition[Characters[zprava], 5, 5, 1, {}];
For[i = 1, i < pocCyklu + 1, i++,
slovo = StringJoin # z[[i]];
m = StringToInteger[slovo];
n = klic[[1]];
e = klic[[2]];
c[[i]] = PowerMod[m, e, n];
]
Return[c]
];
sif = sifra[m, verejny]
After the cycles are done there should be 2 numbers in c.
Print[c] works OK it prints list with 2 elements in it but sif is null.
Return[c] gives me:
Null Return[{28589400926821874625642026431141504822, 2219822858062194181357669868096}]
You could write the function like this:
sifra[zprava_, klic_] := Module[{c, n, e, m, i, z, pocCyklu, slovo},
pocCyklu = Ceiling[Divide[StringLength[zprava], 5]];
c = ConstantArray[{}, pocCyklu];
z = Partition[Characters[zprava], 5, 5, 1, {}];
For[i = 1, i < pocCyklu + 1, i++,
slovo = StringJoin#z[[i]];
m = ToExpression[slovo];
{n, e} = klic;
c[[i]] = PowerMod[m, e, n]];
c]
Demonstrating use with example data:
sifra["9385637605763057836503784603456", {124, 2}]
{20, 97, 41, 9, 4, 113, 36}
You could also write the function like this:
sifra[zprava_, {n_, e_}] := Module[{z},
z = Partition[Characters[zprava], 5, 5, 1, {}];
Map[PowerMod[ToExpression[StringJoin[#]], e, n] &, z]]

Resources