Can this matrix be generated in a less manual way? It's okay for 4 x 4, but I need something larger. Thanks
--> L : matrix([L11,L12,L13,L14],[L21,L22,L23,L24],[L31,L32,L33,L34],[L41,L42,L43,L44]);
(L) matrix(
[L11, L12, L13, L14],
[L21, L22, L23, L24],
[L31, L32, L33, L34],
[L41, L42, L43, L44]
)
Answer to the question and note the noun form for L in the concat function ('L)
L:genmatrix(lambda([i,j], concat('L,i,j)), 3, 3);
(L) matrix(
[L11, L12, L13],
[L21, L22, L23],
[L31, L32, L33]
)
For a diagonal matrix
R:genmatrix(lambda([i,j], if i=j then concat('R,i) else 0), 3, 3);
(R) matrix(
[R1, 0, 0],
[0, R2, 0],
[0, 0, R3]
)
Related
The idea is simple, but the execution is bothering me.
I've created a small random dungeon generator that create a grid like this:
000001
000111
000111
001101
011101
011111
This is a sample 6x6 dungeon where 0 is a wall and 1 is an open path.
The conversion from this to some sort of tile id map is simple, and trivial, but creating the image itself is the hard part.
I want to know if there's a lib, or method to achieve that. If not, then what would you do?
This is not part of a game, and only a dungeon generator for DND. Any language is OK, but the generator was made in Go.
You can use OpenCV for this task. Probably PIL can do the same, don't have exp with it.
import cv2
import numpy as np
data_list = [
[0, 0, 0, 0, 0, 1],
[0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1],
[0, 0, 1, 1, 0, 1],
[0, 1, 1, 1, 0, 1],
[0, 1, 1, 1, 1, 1]
]
arr = np.array(data_list, dtype=np.uint8) * 255
arr = cv2.resize(arr, (0, 0), fx=50, fy=50, interpolation=cv2.INTER_NEAREST)
cv2.imshow("img", arr)
cv2.waitKey()
# or you can save on disk
cv2.imwrite("img.png", arr)
use np.block()
# a bunch of sprites/images, all the same size
# load them however you like
tiles = [...]
data_list = [
[0, 0, 0, 0, 0, 1],
[0, 0, 0, 1, 1, 1],
[0, 0, 0, 1, 1, 1],
[0, 0, 1, 1, 0, 1],
[0, 1, 1, 1, 0, 1],
[0, 1, 1, 1, 1, 1]
]
picture = np.block([
[tiles[k] for k in row]
for row in data_list
])
Or, if you use any kind of game engine, or something even more trivial, like SDL/PyGame, simply "blit" each tile.
PIL, as you found out, is perfectly capable of blitting one image (tile) onto another (whole map).
I kind of managed to get a solution, but it will be a Python only.
Using PIL I can make a mosaic with tile images and create the map. It's not a solid solution made from scratch but it can do the Job.
I'm still open for another approach.
My solution is this method here:
matrix = np.loadtxt(input_file, usecols=range(matrix_square), dtype=int)
tiles = []
for file in glob.glob("./tiles/*"):
im = Image.open(file)
tiles.append(im)
output = Image.new('RGB', (image_width,image_height))
for i in range(matrix_width):
for j in range(matrix_height):
x,y = i*tile_size,j*tile_size
index = matrix[j][i]
output.paste(tiles[index],(x,y))
output.save(output_file)
The matrix_square is the matrix dimensions (as a square). I'm still working on a better solution, but this is working fine for me.
You need to change the tile_size to match the tile resolution that you're using.
This is a generated dungeon with this method
The tiles are bad, but the grid is fine enough.
Find the minimum sum of elements with one element from each row. I think the answer is
-214, but z3py returns unsat. What is wrong?
from z3 import Solver, Int, ForAll, Or
ARR = [
[36, 12, 90, 88, 82],
[-92, 50, 40, 31, 43],
[81, 28, -26, 8, -59],
[18, -99, -70, -33, 58],
[44, -33, 24, -92, -68],
]
s = Solver()
xs = [Int(f"x_{i}") for i, row in enumerate(ARR)]
ys = [Int(f"y_{i}") for i, row in enumerate(ARR)]
for x, y, row in zip(xs, ys, ARR):
s.add(Or(*[x == val for val in row]))
s.add(Or(*[y == val for val in row]))
s.add(ForAll(ys, sum(xs) <= sum(ys)))
print(s.check()) # unsat
Your encoding isn't quite correct. If you stick the following line in your program:
print(s.sexpr())
You'll see that it prints, amongst other things:
(assert (forall ((y_0 Int) (y_1 Int) (y_2 Int) (y_3 Int) (y_4 Int))
(<= (+ 0 x_0 x_1 x_2 x_3 x_4) (+ 0 y_0 y_1 y_2 y_3 y_4))))
And this is the reason why it is unsat. This is a quantified formula, and thus it says it is only satisfiable if the formula is true for all values y_0 .. y_4. This is obviously not true, and hence the unsat result.
Instead of this formulation, you should use z3's optimization engine. Pick one variable from each row, add them, and minimize that result. Something like this:
from z3 import *
ARR = [
[36, 12, 90, 88, 82],
[-92, 50, 40, 31, 43],
[81, 28, -26, 8, -59],
[18, -99, -70, -33, 58],
[44, -33, 24, -92, -68],
]
o = Optimize()
es = [Int(f"e_{i}") for i, row in enumerate(ARR)]
for e, row in zip (es, ARR):
o.add(Or(*[e == val for val in row]))
minTotal = Int("minTotal")
o.add(minTotal == sum(es))
o.minimize(minTotal)
print(o.check())
print(o.model())
When I run this, I get:
sat
[e_0 = 12,
e_3 = -99,
e_2 = -59,
e_1 = -92,
e_4 = -92,
minTotal = -330]
That is, solver picks 12 from the first row, -92 from the second, -59 from the third, -99 from the fourth, and -92 from the last row; for a minimum sum of -330.
It's easy to see that this is the correct solution since the solver picks minimum element from each row, and thus their sum will be minimal as well. (I'm not sure why you were expecting -214 to be the answer.)
I'm learning Erlang and have come across/trying to understand list comprehension. I've discovered that you can make Cartesian products quite easily using it.
Basically I though of a deck of cards and that if you multiply the unique values by the number of suits, you will result will every possible combination - creating a full deck of cards. However, what if I wish to add the 2 jokers to the deck - but jokers do not belong to a suit. How do we solve that issue?
The code below is what I have so far and will output the possible combinations without the jokers.
CardValues = [ace, king, queen, jack, 10, 9, 8, 7, 6, 5, 4, 3, 2],
CardSuits = [spades,hearts,clubs,diamonds],
CartesianList = [{X, Y} || X <- CardValues, Y <- CardSuits ],
io:format("\nCartesianList:~p\n",[CartesianList]).
Would there be a better way of achieving/how would you achieve this?
I expect the output for the jokers would be something like {joker, nosuit}
Thanks,
Snelly.
If you really want to get it directly from a list comprehension, you may use filters:
CardValues = [joker,joker,ace, king, queen, jack, 10, 9, 8, 7, 6, 5, 4, 3, 2],
CardSuits = [spades,hearts,clubs,diamonds,nosuit],
CartesianList = [{X, Y} || X <- CardValues, Y <- CardSuits, ((X == joker)andalso(Y==nosuit))orelse((X =/= joker)andalso(Y=/=nosuit)) ],
io:format("\nCartesianList:~p\n",[CartesianList]).
But it is really weird, artificial and inefficient, I would add them manually:
CardValues = [ace, king, queen, jack, 10, 9, 8, 7, 6, 5, 4, 3, 2],
CardSuits = [spades,hearts,clubs,diamonds],
CartesianList = [{joker,nosuit},{joker,nosuit}|[{X, Y} || X <- CardValues, Y <- CardSuits ]]],
io:format("\nCartesianList:~p\n",[CartesianList]).
When I use Maxima to calculate the Taylor series:
f(x,y) := taylor((x+y)^3, [x, y], [2, 3], 2);
f(2,3); /* error: wrong number of arguments */
Basically I want to define a function as a expansion of (x+y)^3, which takes in x,y as parameter. How can I achieve this?
Try
(%i1) f(x,y) := ''(ratdisrep(taylor(('x+'y)^3, ['x, 'y], [2, 3], 2))) $
(%i2) f(2, 3);
(%o2) 125
or
(%i1) define(f(x, y), ratdisrep(taylor(('x+'y)^3, ['x, 'y], [2, 3], 2)))$
(%i2) f(2, 3);
(%o2) 125
i try to plot the result of this code as vertical line each one in the position of the solution of the FindRoot routine (something like that: http://www.astrobio.net/albums/xsolar/ach.sized.jpg ).
omega[a_] := 2 \[Pi] /a^(3/2);
Do[
Print[FindRoot[omega[a]/omega[5.2]==j/i+1, {a, 1}]],
{j,1,7,1},{i,1,7,1}]
Can someone help me please?
I'm part guessing, because your question isn't clear enough:
omega[a_] := 2 Pi/a^(3/2);
ListPlot[Flatten[
Table[{a /. FindRoot[omega[a]/omega[5.2] == j/i + 1, {a, 1}], i + j},
{j, 1, 7, 1}, {i, 1, 7, 1}], 1],
Filling -> Axis, PlotRange -> {{0, 6}, {0, 15}}]