I have a grid of randomly generated numbers of size gameSize (user input) which is contained within a vector of vectors. The user can enter two co-ordinates (x, y) so that it changes a number within the grid to a predefined value, which is "0".
So for example the user enters, X:0 Y:0 and:
{9, 7, 9}
{9, 6, 8}
{5, 1, 4}
becomes:
{0, 7, 9} <-- Changes position 0,0 to 0 (the predefined value)
{9, 6, 8}
{5, 1, 4}
I'm trying to figure out how to add an "undo" feature in which the user is prompted if they want to undo their selection or not, and if Yes then reverse the selection so that position 0,0 changes back to the original value (which is the value 9 in this example). How can I implement this? I understand I need to somehow record a previous grid state but have no clue how.
If you only want to be able to "undo" the last change, then you could simply make a copy, a backup of sorts, of the state before doing the change. Then if the user wants to "undo" the change then copy from the backup into the actual data.
For more levels of undo you could have a stack of copies.
If the data is large, then instead of copying the data for every change just store a copy of the actual change instead. Then when the user wants to "undo" you do the opposite of the change.
Example: If the user want to modify coordinates X,Y by Z, then store X, Y and Z. Then when doing undo you modify X,Y with -Z.
In object oriented languages you often find that people will use the command pattern to implement undo systems. Some people might say it's overkill but it is really quite flexible and doesn't take much boiler plate to get started.
The general idea is that you create an interface, with the methods execute() and undo(). You then you can create a whole slew of other classes that implement that interface and that know how do specific actions (e.g., in your example change position) and how to undo them. You then just need to keep track of commands that you have executed by putting them on a stack, and when you need to undo just pop them from the stack and call undo().
Here is a good resource for learning about the command pattern and design patterns in general.
Related
I need to create a timeline. For this I need cards repeating.
I already created and manage to show the template of the card I want.
But now I need to make this repeat... I do not have a BD right now, so first I'm creating the frontend of the application, so for now I only need to create a simple array that will repeat my template x times.
This is my HTML:
<ion-list>
<enviouTemplate [cardEnviou]="enviouCard" *ngIf="buttonClicked1"></enviouTemplate>
<recebeuTemplate [cardRecebeu]="recebeuCard" *ngIf="buttonClicked2"></recebeuTemplate>
</ion-list>
The father TS don't have any code right now, this is working purely by using the children TS directly to HTML.
How can I make the cards repeat?
The ngIf is there because there'll be two kind of cards, so don't mind that.
Thanks a lot!
I manage to make it work, right now its like this:
HTML:
<ion-list *ngFor="let card of cards">
<enviouTemplate [cardEnviou]="card" *ngIf="buttonClicked1"></enviouTemplate>
<recebeuTemplate [cardRecebeu]="card" *ngIf="buttonClicked2"></recebeuTemplate>
</ion-list>
Parent TS(only for test):
cards : any = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
But my question now is about something that I read, that its not a good practice to use ngFor inside ion-list.
So how should I build the html?
One thing to point, I need to use the ngIf, because I have two timelines that will show up only when a button is selected, and I see that the application don't accept ngFor and ngIf in the same element...
I'm working with Mathematica,
I begin by importing the data from some CSV files, and I store them under some variable names.
For the moment let's assume we use:
sample1 = Sort[RandomReal[{0, 10}, {10, 2}]];
sample2 = Sort[RandomReal[{0, 10}, {10, 2}]];
sample3 = Sort[RandomReal[{0, 10}, {10, 2}]];
So, I want to do some calculations on the data individually,
I was thinking of using a PopupMenu by "recalling" the defined variables and then I could do a linear fit and display both the data and the linear fit, and also find the highest value:
variables = Names["Global`*"];
PopupMenu[Dynamic[x], variables]
data=Dynamic[x];
lm = LinearModelFit[data, x, x];
Show[ListLinePlot[data, PlotRange-> All],
Plot[lm[x], {x, 0, data[[Length[data], 1]]}]]
Peak = Max[data[[All, 2]]]
But the problem is that when i recall the variables, Mathematica only brings them as names and not the actual data list.
For the moment I'm trying also to store different calculations on a bigger list that would go on storing the values for the calculations:
Data = {};
(This bit would be outside, with the data importing probably, just to define the list)
AppendTo[Data, {Normal[lm], Peak}]
I'm also trying to store the name of the set that's selected, so that's another challenge... Would anyone know how could I solve this issue?
I do realize that it's a pretty specific question (sorry!), but it could be used for other things too! I think...
Thanks!
I have a fairly simple board game i've been building in C++. Currently, players are assigned a player number (1, 2, 3...N) depending on the number of players in the game. Pretty standard. The players and their stats are kept in a file which include their name and their number. I then process turns via reading a directory with turn files. The turns are submitted by the players and contain only their player name and their task/turn. In the future, I plan to have player numbers change so to mix up the order of the game.
(if you're a board gamer, think Caylus or Agricola)
Players are read in at the start of the application. I then give a command and turns are processed. Basically, I simply read the directory of turns, 1 by 1, and match that turn to a player name. As it stands, there is no order in turn processing. Player 3 can go before player 2.
I figured this wasn't a great design so I came up with the following solution:
As I'm comparing which turn goes with which player, insert that turn into a std::map<int, Turn>, the key being the player number.
After I gather all the turns, search for player N, starting with 1, within the map and process his turn.
I'm iterating through the list of players again here because I need to match the player with the player number in order to process the turn.
Do this until I've processed all players.
Is there a better way to do this? This seems kludgey and a lot of overhead.
Thanks!
Note: My turn processing method takes in a Player class (which represents the player stats file) and a struct representing the turn read from the turn file.
So as I understand it, your problem is you have thee bits of linked data: Turns, PlayerIDs and PlayerTurnPositions (OK the latter 2 are ints but I'll assume you've typedef-ed them to something like that to avoid confusion). And you want to maintain a lookup from the PlayerID and PlayerTurnPosition values to the corresponding Turn, and also maintain a bidirectional relation between the Player info.
This is just screaming out to use a boost::bimap with some extra info attached to each pair relation; something like
boost::bimaps::bimap<
boost::bimaps::vector_of<PlayerID>,
boost::bimaps::vector_of<PlayerTurnPosition>,
boost::bimaps::with_info<boost::shared_ptr<Turn> >
>
should do the job nicely (although there are other options for the left/right view container types; set_of probably makes more sense given playerIDs and positions are presumably unique).
Example of this sort of with_info usage in the docs.
You might think of defining an Action class for a player acting in his turn, which is defined by a player number and a turn number, and define a comparison on this class. Read all Actions from the files, insert them into an ordered list, and then process these actions.
I've been trying to solve this problem for quite sometime but I am having trouble with it.
Let's say on a trigger, you receive values.
First trigger: You get 1
Second trigger: You get 1, 2
Third trigger: You get 1, 2, 3
So, I store 1.
For 2nd trigger, I store 2 since 1 already exist.
For 3rd trigger, I store 3 since 1,2 already exist
so in total I have stored 1,2,3
As you can see, we can easily check for new values, if old != new.
Here's come the problem:
Fourth trigger: You get 1, 2, 4
For 4th trigger, I store 1, 2 because it exists
but how do I check against 3 and remove 3 from store and check if 4 is new?
If you are having problems understanding this, feel free to clarify. Thanks!
Use a std::set<int> container. When a trigger arrives, clear it an insert all the values from trigger. This should be ok if you work with just a few numbers (about ten or so). With more, a little bit more sophisticated approach might be required.
Hard to tell what you're asking exactly, but see std::set data structure if your main problem is trying to maintain a set of unique numbers and efficiently check for existence in the set.
Your logic changed between 1,2,3 and 1,2,4
(only stored 3 on former, but stored 1,2,4 on latter)
In that case, ignore data recv'd that already exists, only storing new data, unless some old data was not sent in which case you'll create a new set of data to store.
But, I'm guessing that's not what you had in mind at all :)
edit
I see it's been edited now, so my answer is invalid
edit-2
the fastest way is to drop all stored data on each iteration as comparisons will take as long (if not longer) than a complete save of sent data.
Your approach sounds like it is better served by using some basic set theory. A couple of answers already point you to STL sets for that matter. With that, you'll need to iterate through the reported values to test for membership in the set.
However, is there an opportunity to affect what is reported with each "trigger"? For example, if this is something like a select poll, you could just put whatever it is that you're polling into a different state so that it is not reported as ready in subsequent triggers.
In Mathematica I have a list of point coordinates
size = 50;
points = Table[{RandomInteger[{0, size}], RandomInteger[{0, size}]}, {i, 1, n}];
and a list of cluster indices these points belong to
clusterIndices = {1, 1, 1, 1, 1, 1, 1, 2, 2, 1, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1};
what is the easiest way to split the points into two separate lists based on the clusterIndices values?
EDIT:
The solution I came up with:
pointIndices =
Map[#[[2]] &,
GatherBy[MapIndexed[{#1, #2[[1]]} &, clusterIndices], First],
{2}];
pointsByCluster = Map[Part[points, #] &, pointIndices];
It there a better way to do this?
As #High Performance Mark and #Nicholas Wilson said, I'd start with combining the two lists together via Transpose or Thread. In this case,
In[1]:= Transpose[{clusterIndices, points}]==Thread[{clusterIndices, points}]
Out[1]:= True
At one point, I looked at which was faster, and I think Thread is marginally faster. But, it only really matters when you are using very long lists.
#High Performance Mark makes a good point in suggesting Select. But, it would only allow you to pull a single cluster out at a time. The code for selecting cluster 1 is as follows:
Select[Transpose[{clusterIndices, points}], #[[1]]==1& ][[All, All, 2]]
Since you seem to want to generate all clusters, I'd suggest doing the following:
GatherBy[Transpose[{clusterIndices, points}], #[[1]]& ][[All, All, 2]]
which has the advantage of being a one liner and the only tricky part was in selecting the correct Part of the resulting list. The trick in determining how many All terms are necessary is to note that
Transpose[{clusterIndices, points}][[All,2]]
is required to get the points back out of the transposed list. But, the "clustered" list has one additional level, hence the second All.
It should be noted that the second parameter in GatherBy is a function that accepts one parameter, and it can be interchanged with any function you wish to use. As such, it is very useful. However, if you'd like to transform your data as your gathering it, I'd look at Reap and Sow.
Edit: Reap and Sow are somewhat under used, and fairly powerful. They're somewhat confusing to use, but I suspect GatherBy is implemented using them internally. For instance,
Reap[ Sow[#[[2]], #[[1]] ]& /# Transpose[{clusterIndices, points}], _, #2& ]
does the same thing as my previous code without the hassle of stripping off the indices from the points. Essentially, Sow tags each point with its index, then Reap gathers all of the tags (_ for the 2nd parameter) and outputs only the points. Personally, I use this instead of GatherBy, and I've encoded it into a function which I load, as follows:
SelectEquivalents[x_List,f_:Identity, g_:Identity, h_:(#2&)]:=
Reap[Sow[g[#],{f[#]}]&/#x, _, h][[2]];
Note: this code is a modified form of what was in the help files in 5.x. But, the 6.0 and 7.0 help files removed a lot of the useful examples, and this was one of them.
Here's a succinct way to do this using the new SplitBy function in version 7.0 that should be pretty fast:
SplitBy[Transpose[{points, clusterIndices}], Last][[All, All, 1]]
If you aren't using 7.0, you can implement this as:
Split[Transpose[{points, clusterIndices}], Last[#]==Last[#2]& ][[All, All, 1]]
Update
Sorry, I didn't see that you only wanted two groups, which I think of as clustering, not splitting. Here's some code for that:
FindClusters[Thread[Rule[clusterIndices, points]]]
How about this?
points[[
Flatten[Position[clusterIndices, #]]
]] & /#
Union[clusterIndices]
I don't know about 'better', but the more usual way in functional languages would not be to add indices to label each element (your MapIndexed) but instead to just run along each list:
Map[#1[[2]] &,
Sort[GatherBy[
Thread[ {#1, #2} &[clusterIndices, points]],
#1[[1]] &], #1[[1]][[1]] < #2[[1]][[1]] &], {2}]
Most people brought up in Lisp/ML/etc will write the Thread function out instantly is the way to implement the zip ideas from those languages.
I added in the Sort because it looks like your implementation will run into trouble if clusterIndices = {2[...,2],1,...}. On the other hand, I would still need to add in a line to fix the problem that if clusterIndices has a 3 but no 2, the output indices will be wrong. It is not clear from your fragment how you are intending to retrieve things though.
I reckon you will find list processing much easier if you refresh yourself with a hobby project like building a simple CAS in a language like Haskell where the syntax is so much more suited to functional list processing than Mathematica.
If I think of something simpler I will add to the post.
Map[#[[1]] &, GatherBy[Thread[{points, clusterIndices}], #[[2]] &], {2}]
My first step would be to execute
Transpose[{clusterIndices, points}]
and my next step would depend on what you want to do with that; Select comes to mind.