C++ if/else grid system - c++

I am trying to create a C++ program that will move an X on a 4x4 grid and display each move. We are not allowed to use arrays because we haven't learned how yet. I know that I am supposed to use 16 if/else statements, but I am not sure what to do from there. I know there is an easier way than mapping out each possible option because that would take forever!!! What do I do???
EDIT: It is only allowed to move up/down/left/right. And what I mean by display each move it is first supposed to display the user's starting point (which I've already set up) and then it is supposed to print grids with successive moves on them including all of the previous moves until it reaches the end point.

Note: I originally wrote this answer based on assumptions about the task that turned out to be wrong. However, I'll leave the answer up as I believe it might still contain useful information for the OP.
When you have x different possible situations, you don't always need an if/else with x branches. The trick is to find a way to use the same computation (typically one or more mathematical expressions, and possibly loops) to handle all or most of the situations.
In this case, there are indeed 16 different positions on a 4x4 grid, and one way to represent a position is to store its row and column number (each a value between 0 and 3). By using two loops, one inside the other (nested loops), you can generate all 16 combinations of row and column position. I'll assume now that you're supposed to print e.g. . on the empty cells of the grid. Inside the inner loop, you need to figure out whether you should print a . or an X. What question should you ask in order to figure that out? Simply "is the row and column number that the nested loops are currently at the same row and column number as the location of the X?"
Edit after seeing your update: Even when working with a grid, arrays are only needed when you have to store information about every cell, so one can sometimes get away without an array if you can generate the grid information from fewer pieces of information (such as the position of the X). However, if you need to keep track of the previous positions, you need an array (either one- or two-dimensional) in order to do it elegantly. I would say that the "no arrays" restriction of this task is not educational, as it forces an unnatural and very cumbersome way to solve this task. :-( (However, if your instructor subsequently gives the same task and allows you to use loops, it will be a good demonstration of why loops are useful.)
What you could do is to use 16 bool variables (all set to false initially) with names such as grid00, grid01, grid02, grid03, grid10, ..., grid33. Then make two methods, bool isOccupied(int row, int column) and void occupy(int row, int column) that use 16-way if/else statements to allow you to easily read and change the variable that corresponds to a given position.

I know that I am supposed to use 16 if/else statements, but I am not
sure what to do from there.
If this is a constraint on your solution given to your by your instructor, that means that you will need to handle each of the 16 possible grid locations in a separate {} block. You'll have to have an enum representing each of the pairs. like:
e_1_1, e_1_2, e_1_3, e_1_4,
e_2_1, e_2_2, e_2_3, e_2_4,
e_3_1, e_3_2, e_3_3, e_3_4,
e_4_1, e_4_2, e_4_3, e_4_4,
and you'll have to manually update the current position to a new one in the switch statement. Keep track of your current position in a variable called something like 'position'.
I know there is an easier way than mapping out each possible option
because that would take forever!!!
Welcome to programming. ;-)
Copy and paste is your friend and this problem of having to write a lot of similar but slightly different code is fairly common to many programming tasks. Becoming a good programmer means learning how to avoid largely duplicate code when possible. You are not there yet, or you wouldn't have to ask. So this first step will be an important lesson for you. A bit of pain will help you appreciate how much better the approach you will use the next time will be.
But this isn't that much work. An experienced C++ programmer could knock this out in less than 5 to 10 minutes. Moderately experienced, perhaps 20 to 30. It might take a learning programmer a few hours or more.
There are more concise ways to handle this problem without requiring 16 separate blocks, however, none of them are easier to understand. If this a requirement for a class learning project, then you will find it beneficial to do it first this way, then as a next step, try to do it with more complex logic.
Suggestions
An experienced programmer would define the move possibilities as an enum. Then the moves would be handled inside the {} blocks for the if statements using a switch statement that handled each of the four enums corresponding to the four moves. If you don't know the switch statement yet you can use an if ... else if ... else if ... that checks for each of the four moves.
Start with handling just the first upper left corner position moves for a smaller 2 x 2 grid. Then add each of the other three positions for the 2 x 2 grid. Once you have that working you should be able to understand easily how to extend the solution to a 4 x 4 and arbitrarily larger grid.
You'll want to have a function that prints the position array that gets called after every move. For now, you'll have to check the value of the enum and print manually. Something like:
Is position == e_1_1? print '* else print '_'
Is position == e_1_2? print '* else print '_'
Is position == e_1_3? print '* else print '_'
Is position == e_1_4? print '* else print '_'
print a newline
Is position == e_2_1? print '* else print '_'
Is position == e_2_2? print '* else print '_'
Is position == e_2_3? print '* else print '_'
Is position == e_2_4? print '* else print '_'
etc.
Some pointers for easy debugging:
Set the values for an enum for up, down, left, and right to something you can print out and follow easily, i.e. e_up = 'u' and e_down = 'd'. That will make it easier to debug if you don't have an IDE that will let you easily see the enum values, and you can print out the moves directly in the beginning.
Make your changes to the code in small increments. Run the code and once you know that the part you added works, move on. If you add too much at once it is much harder to figure out where things are broken, especially when you are new.
Future Solution with Arrays
Some hints: You'll want to use a two-dimensional array.
Try this on a 2 x 2 array first to make your life simpler. Then when the logic works, change the array size. To make this process easier use a const integer to define a value that you use to define the arrays and the printing using a for loop so that when you change the constant from:
const int array_size = 2
to
const int array_size = 4
the rest of the code will just work. For extra credit, support arrays of differing height and width by using separate constants for array_height and array_width. Learn to do it well and the way a pro would do it and you'll develop pro habits and earn pro wages much more quickly.
Remember to use a for loop for printing the rows and columns that uses the constants you defined.
You'll want to have the code running a loop looking for input, then processing the move, then printing out the new grid.

Related

Maxima: creating a function that acts on parts of a string

Context: I'm using Maxima on a platform that also uses KaTeX. For various reasons related to content management, this means that we are regularly using Maxima functions to generate the necessary KaTeX commands.
I'm currently trying to develop a group of functions that will facilitate generating different sets of strings corresponding to KaTeX commands for various symbols related to vectors.
Problem
I have written the following function makeKatexVector(x), which takes a string, list or list-of-lists and returns the same type of object, with each string wrapped in \vec{} (i.e. makeKatexVector(string) returns \vec{string} and makeKatexVector(["a","b"]) returns ["\vec{a}", "\vec{b}"] etc).
/* Flexible Make KaTeX Vector Version of List Items */
makeKatexVector(x):= block([ placeHolderList : x ],
if stringp(x) /* Special Handling if x is Just a String */
then placeHolderList : concat("\vec{", x, "}")
else if listp(x[1]) /* check to see if it is a list of lists */
then for j:1 thru length(x)
do placeHolderList[j] : makelist(concat("\vec{", k ,"}"), k, x[j] )
else if listp(x) /* check to see if it is just a list */
then placeHolderList : makelist(concat("\vec{", k, "}"), k, x)
else placeHolderList : "makeKatexVector error: not a list-of-lists, a list or a string",
return(placeHolderList));
Although I have my doubts about the efficiency or elegance of the above code, it seems to return the desired expressions; however, I would like to modify this function so that it can distinguish between single- and multi-character strings.
In particular, I'd like multi-character strings like x_1 to be returned as \vec{x}_1 and not \vec{x_1}.
In fact, I'd simply like to modify the above code so that \vec{} is wrapped around the first character of the string, regardless of how many characters there may be.
My Attempt
I was ready to tackle this with brute force (e.g. transcribing each character of a string into a list and then reassembling); however, the real programmer on the project suggested I look into "Regular Expressions". After exploring that endless rabbit hole, I found the command regex_subst; however, I can't find any Maxima documentation for it, and am struggling to reproduce the examples in the related documentation here.
Once I can work out the appropriate regex to use, I intend to implement this in the above code using an if statement, such as:
if slength(x) >1
then {regex command}
else {regular treatment}
If anyone knows of helpful resources on any of these fronts, I'd greatly appreciate any pointers at all.
Looks like you got the regex approach working, that's great. My advice about handling subscripted expressions in TeX, however, is to avoid working with names which contain underscores in Maxima, and instead work with Maxima expressions with indices, e.g. foo[k] instead of foo_k. While writing foo_k is a minor convenience in Maxima, you'll run into problems pretty quickly, and in order to straighten it out you might end up piling one complication on another.
E.g. Maxima doesn't know there's any relation between foo, foo_1, and foo_k -- those have no more in common than foo, abc, and xyz. What if there are 2 indices? foo_j_k will become something like foo_{j_k} by the preceding approach -- what if you want foo_{j, k} instead? (Incidentally the two are foo[j[k]] and foo[j, k] when represented by subscripts.) Another problematic expression is something like foo_bar_baz. Does that mean foo_bar[baz], foo[bar_baz] or foo_bar_baz?
The code for tex(x_y) yielding x_y in TeX is pretty old, so it's unlikely to go away, but over the years I've come to increasing feel like it should be avoided. However, the last time it came up and I proposed disabling that, there were enough people who supported it that we ended up keeping it.
Something that might be helpful, there is a function texput which allows you to specify how a symbol should appear in TeX output. For example:
(%i1) texput (v, "\\vec{v}");
(%o1) "\vec{v}"
(%i2) tex ([v, v[1], v[k], v[j[k]], v[j, k]]);
$$\left[ \vec{v} , \vec{v}_{1} , \vec{v}_{k} , \vec{v}_{j_{k}} ,
\vec{v}_{j,k} \right] $$
(%o2) false
texput can modify various aspects of TeX output; you can take a look at the documentation (see ? texput).
While I didn't expect that I'd work this out on my own, after several hours, I made some progress, so figured I'd share here, in case anyone else may benefit from the time I put in.
to load the regex in wxMaxima, at least on the MacOS version, simply type load("sregex");. I didn't have this loaded, and was trying to work through our custom platform, which cost me several hours.
take note that many of the arguments in the linked documentation by Dorai Sitaram occur in the reverse, or a different order than they do in their corresponding Maxima versions.
not all the "pregexp" functions exist in Maxima;
In addition to this, escaping special characters varied in important ways between wxMaxima, the inline Maxima compiler (running within Ace editor) and the actual rendered version on our platform; in particular, the inline compiler often returned false for expressions that compiled properly in wxMaxima and on the platform. Because I didn't have sregex loaded on wxMaxima from the beginning, I lost a lot of time to this.
Finally, the regex expression that achieved the desired substitution, in my case, was:
regex_subst("\vec{\\1}", "([[:alpha:]])", "v_1");
which returns vec{v}_1 in wxMaxima (N.B. none of my attempts to get wxMaxima to return \vec{v}_1 were successful; escaping the backslash just does not seem to work; fortunately, the usual escaped version \\vec{\\1} does return the desired form).
I have yet to adjust the code for the rest of the function, but I doubt that will be of use to anyone else, and wanted to be sure to post an update here, before anyone else took time to assist me.
Always interested in better methods / practices or any other pointers / feedback.

If... else condition in LUA language

I'm new to coding and I recently started to take my baby steps in LUA. I have a small problem so it would be very helpful if you can help me. In my code, I need to code that
If x ~= 1 and x~=2 and x~=3 and x~=4 then (do something) end
is there a faster way not to hardcode that part, not to type the whole thing from x~=1 to x~=4?
Thank you!
If you need something like if x ~= 1 and x~=2 and x~=3 and x~=4 then (do something) end x is usually an integer.
Then
if x < 1 or x > 4 then
-- do your stuff here
end
Is what you are looking for. If you want to explicitly check wether x is unquald 1,2,3,4 you can simply do something like Egor suggested.
But as you see unless you can describe your conditions in a shorter mathematical way you still have separate unique conditions and you won't come around writing them down.
If you have to check those conditions repeatedly you can use a truth table like in Egor's example or you write a function that returns if that condition is met for its argument.

Replace all occurrences based on map

This question might have already been answered but I haven't found it yet.
Let's say I have a std::map<string,string> which contains string pairs of <replace_all_this, to_this>.
I checked Boost's format library, which is close but not perfect:
std::map<string,string> m;
m['$search1'] = 'replace1';
m['$search2'] = 'replace2';
format fmter1("let's try to %1% and %2%.");
fmter % 36; fmter % 77;
for(auto r : m) {
fmter % r.second;
}
// would print "let's try to replace1 and replace2
This would work, but I lose control of what.
Actually I'd like to have this as result:
format fmter1("let's try to $search2 and $search1 even if their order is different in the map.");
...
//print: "let's try to replace2 and replace1 even if their order is different in the map".
Please note: map can contain more items, and items can occur multiple times in the formatter.
What is the way to go for this in 2020, I'd like it to be effective and fast, so I'd avoid iterating over the map multiple times.
There may be new libraries but there is no new algorithm to do that faster than what we have so far.
Assuming your format implies a $<name> for your variables, you can search for the first '$', read the <name> search for that in the map, then do the replace. This allows you to either skip the replacement or process it too (i.e. make it recursive where a variable can reference another).
I don't think that doing it the other way around would be any faster: i.e. go through the map and search for the names in the string means you'd be parsing the strings many times and if you have many variables, it will be a huge waste if most are not likely part of your string. Also if you want to prevent some level of recursivity, it's very complicated.
Where you can eventually optimize is in calculating the size of the resulting string and allocate that buffer once instead of using += which is not unlikely going to be slower.
I have such an implementation in my snaplogger. The variable has to be between brackets and it can include multiple parameters to further tweak the data. There is documentation here about what is supported by that function and as written, you can easily extend the class to add more features. It's probably not a one to one match to what you're looking for, but it shows you that there is not 20 ways of implementing that function.

Simple spell checking algorithm

I've been tasked with creating a simple spell checker for an assignment but have given next to no guidance so was wondering if anyone could help me out. I'm not after someone to do the assignment for me, but any direction or help with the algorithm would be awesome! If what I'm asking is not within the guildlines of the site then I'm sorry and I'll look elsewhere. :)
The project loads correctly spelled lower case words and then needs to make spelling suggestions based on two criteria:
One letter difference (either added or subtracted to get the word the same as a word in the dictionary). For example 'stack' would be a suggestion for 'staick' and 'cool' would be a suggestion for 'coo'.
One letter substitution. So for example, 'bad' would be a suggestion for 'bod'.
So, just to make sure I've explained properly.. I might load in the words [hello, goodbye, fantastic, good, god] and then the suggestions for the (incorrectly spelled) word 'godd' would be [good, god].
Speed is my main consideration here so while I think I know a way to get this work, I'm really not too sure about how efficient it'll be. The way I'm thinking of doing it is to create a map<string, vector<string>> and then for each correctly spelled word that's loaded in, add the correctly spelled work in as a key in the map and the populate the vector to be all the possible 'wrong' permutations of that word.
Then, when I want to look up a word, I'll look through every vector in the map to see if that word is a permutation of one of the correctly spelled word. If it is, I'll add the key as a spelling suggestion.
This seems like it would take up HEAPS of memory though, cause there would surely be thousands of permutations for each word? It also seems like it'd be very very slow if my initial dictionary of correctly spelled words was large?
I was thinking that maybe I could cut down time a bit by only looking in the keys that are similar to the word I'm looking at. But then again, if they're similar in some way then it probably means that the key will be a suggestion meaning I don't need all those permutations!
So yeah, I'm a bit stumped about which direction I should look in. I'd really appreciate any help as I really am not sure how to estimate the speed of the different ways of doing things (we haven't been taught this at all in class).
The simpler way to solve the problem is indeed a precomputed map [bad word] -> [suggestions].
The problem is that while the removal of a letter creates few "bad words", for the addition or substitution you have many candidates.
So I would suggest another solution ;)
Note: the edit distance you are describing is called the Levenshtein Distance
The solution is described in incremental step, normally the search speed should continuously improve at each idea and I have tried to organize them with the simpler ideas (in term of implementation) first. Feel free to stop whenever you're comfortable with the results.
0. Preliminary
Implement the Levenshtein Distance algorithm
Store the dictionnary in a sorted sequence (std::set for example, though a sorted std::deque or std::vector would be better performance wise)
Keys Points:
The Levenshtein Distance compututation uses an array, at each step the next row is computed solely with the previous row
The minimum distance in a row is always superior (or equal) to the minimum in the previous row
The latter property allow a short-circuit implementation: if you want to limit yourself to 2 errors (treshold), then whenever the minimum of the current row is superior to 2, you can abandon the computation. A simple strategy is to return the treshold + 1 as the distance.
1. First Tentative
Let's begin simple.
We'll implement a linear scan: for each word we compute the distance (short-circuited) and we list those words which achieved the smaller distance so far.
It works very well on smallish dictionaries.
2. Improving the data structure
The levenshtein distance is at least equal to the difference of length.
By using as a key the couple (length, word) instead of just word, you can restrict your search to the range of length [length - edit, length + edit] and greatly reduce the search space.
3. Prefixes and pruning
To improve on this, we can remark than when we build the distance matrix, row by row, one world is entirely scanned (the word we look for) but the other (the referent) is not: we only use one letter for each row.
This very important property means that for two referents that share the same initial sequence (prefix), then the first rows of the matrix will be identical.
Remember that I ask you to store the dictionnary sorted ? It means that words that share the same prefix are adjacent.
Suppose that you are checking your word against cartoon and at car you realize it does not work (the distance is already too long), then any word beginning by car won't work either, you can skip words as long as they begin by car.
The skip itself can be done either linearly or with a search (find the first word that has a higher prefix than car):
linear works best if the prefix is long (few words to skip)
binary search works best for short prefix (many words to skip)
How long is "long" depends on your dictionary and you'll have to measure. I would go with the binary search to begin with.
Note: the length partitioning works against the prefix partitioning, but it prunes much more of the search space
4. Prefixes and re-use
Now, we'll also try to re-use the computation as much as possible (and not just the "it does not work" result)
Suppose that you have two words:
cartoon
carwash
You first compute the matrix, row by row, for cartoon. Then when reading carwash you need to determine the length of the common prefix (here car) and you can keep the first 4 rows of the matrix (corresponding to void, c, a, r).
Therefore, when begin to computing carwash, you in fact begin iterating at w.
To do this, simply use an array allocated straight at the beginning of your search, and make it large enough to accommodate the larger reference (you should know what is the largest length in your dictionary).
5. Using a "better" data structure
To have an easier time working with prefixes, you could use a Trie or a Patricia Tree to store the dictionary. However it's not a STL data structure and you would need to augment it to store in each subtree the range of words length that are stored so you'll have to make your own implementation. It's not as easy as it seems because there are memory explosion issues which can kill locality.
This is a last resort option. It's costly to implement.
You should have a look at this explanation of Peter Norvig on how to write a spelling corrector .
How to write a spelling corrector
EveryThing is well explain in this article, as an example the python code for the spell checker looks like this :
import re, collections
def words(text): return re.findall('[a-z]+', text.lower())
def train(features):
model = collections.defaultdict(lambda: 1)
for f in features:
model[f] += 1
return model
NWORDS = train(words(file('big.txt').read()))
alphabet = 'abcdefghijklmnopqrstuvwxyz'
def edits1(word):
splits = [(word[:i], word[i:]) for i in range(len(word) + 1)]
deletes = [a + b[1:] for a, b in splits if b]
transposes = [a + b[1] + b[0] + b[2:] for a, b in splits if len(b)>1]
replaces = [a + c + b[1:] for a, b in splits for c in alphabet if b]
inserts = [a + c + b for a, b in splits for c in alphabet]
return set(deletes + transposes + replaces + inserts)
def known_edits2(word):
return set(e2 for e1 in edits1(word) for e2 in edits1(e1) if e2 in NWORDS)
def known(words): return set(w for w in words if w in NWORDS)
def correct(word):
candidates = known([word]) or known(edits1(word)) or known_edits2(word) or [word]
return max(candidates, key=NWORDS.get)
Hope you can find what you need on Peter Norvig website.
for spell checker many data structures would be useful for example BK-Tree. Check Damn Cool Algorithms, Part 1: BK-Trees I have done implementation for the same here
My Earlier code link may be misleading, this one is correct for spelling corrector.
off the top of my head, you could split up your suggestions based on length and build a tree structure where children are longer variations of the shorter parent.
should be quite fast but i'm not sure about the code itself, i'm not very well-versed in c++

How do I iterate through a list in a TI-83 calculator program

I created a set of programs to calculate the area under a graph using various methods of approximation (midpoint, trapezoidal, simpson) for my Calculus class.
Here is an example of one of my programs (midpoint):
Prompt A,B,N
(A-B)/N->D
Input "Y1=", Y1
0->X
0->E
For(X,A+D/2,b-D/2,D)
Y1(x)+E->E
End
Disp E*D
Instead of applying these approximation rules to a function (Y1), I would like to apply them to a list of data (L1). How do I iterate through a list? I would need to be able to get the last index in the list in order for a "For Loop" to be any good. I can't do anything like L1.length like I would do in Java.
You can obtain the length of the list using dim(). That can be found in 2nd->LIST->OPS->dim(. Just make sure that you use a list variable otherwise dim() will complain about the type. You could then index into the list with a subscript.
e.g.,
{1, 2, 3, 4} -> L1
For (X, 1, dim(L1), 1)
Disp L1(X)
End
The for loop is the simplest way to iterate over a list in TI-Basic, as it is in many languages. Jeff Mercado already covered that, so I'll mention a few techniques that are powerful tools in specialized situation.
Mapping over lists
TI-Basic supports simple mapping operation over lists that have the same effect as a map function in any other language. TI-Basic support for this extends to most basic arithmetic function, and selection of other functions.
The syntax could not be simpler. If you want to add some number X to every element in some list L1 you type X+L1→L1.
seq(
Most for loops over a lists in TI-Basic can be replaced by cleverly constructed seq( command that will outperform the for loop in time and memory. The exceptions to this rule are loops that contain I/O or storing variables.
The syntax for this command can be quite confusing, so I recommend reading over this documentation before using it. In case that link dies, here's the most relevant information.
Command Summary
Creates a list by evaluating a formula with one variable taking on a
range of values, optionally skipping by a specified step.
Command Syntax
seq(formula, variable, start-value, end-value [, step])
Menu Location
While editing a program, press:
2nd LIST to enter the LIST menu RIGHT to enter the OPS submenu 5 to
choose seq(, or use arrows.
Calculator Compatibility
TI-83/84/+/SE
Token Size
1 byte
The documentation should do a good job explaining the syntax for seq(, so I'll just provide a sample use case.
If you want the square of every number between 1 and 100 you could do this
For Loop
DelVar L1100→dim(L1
for(A,1,100
A²→L1(A
End
or, this
seq
seq(A²,A,1,100→L1
The drawback of seq( is that you can't do any I/O or store any variables inside the expression.
Predefined list iteration function
Go to the LIST menu and check out all the operations under OPS and MATH. These predefined function are always going to be faster than a for loops or even a seq( expression designed to do the same thing.