"Technical" problems
There are tasks in which everything seems to be clear what to do, it seems that there is no need to invent an algorithm, there are no problems with work time — but nevertheless the task seems difficult, and it is unclear from which end to approach it (this, of course, is not a strict definition). Such tasks are commonly called "technique" tasks, often they are some kind of text processing tasks, etc.
It is difficult to come up with any universal recommendations for such tasks, but there are a couple of useful considerations.
Firstly, such tasks usually have a lot of ways to solve them, but some are easier to write, and some are more complex. Therefore, before rushing to write code, you need to think, try to come up with several different approaches and choose the one that will be easier and more reliable to implement.
Secondly, even if the task itself looks complicated, its solution can often be divided into several stages, each of which is relatively simple. Then you don't have to try to write a solution in one big loop that will do everything you need at once. Write a solution that will consist of several parts, each of which will individually do a small part of the work.
For example, suppose you need to process a text in which you need to process words and sentences in some special way. Then first write a code that will only split the input text into sentences; as a result, you will get an array of sentences. Then write a code that will take one sentence and break it into words. As a result, you will get a two—dimensional array of words: each row of the array is the words of one sentence. And only then write what is necessary according to the condition of the task.
Or, even better, write a function that will accept one sentence as input and will process it properly. And then in the main code you will not need a two-dimensional array, you will just split the text into sentences and feed them to this function one by one, and as a result, inside the function you are dealing with only one sentence. If you need to process words in a special way, then write another function that processes one word, and call it from the function that processes the sentence.
A slightly more detailed example (I've already written about it somewhere) — let the text be given to you, it is necessary to normalize capital letters (make capital letters after dots, and small ones in other places), remove double spaces, add spaces after punctuation marks, and output, transferring words so that each line is no longer than 80 characters — then you don't have to rush to do everything at once, too. Write a program that first normalizes capital letters. Then it will remove the double spaces. Then he will add spaces where necessary (maybe it will be convenient to combine it with the previous or the next item, here you can organize the code in different ways, it already depends on the specific details of the task). Then it will break the text into words. Then it will output the text divided into lines as it should.
Another example — let you need to calculate the value of the polynomial, i.e. given a string of the form 2*x^2+3*x+5
, and the value of x
, you need to calculate the value of the polynomial. It's not as difficult as it seems, you just need to first split the polynomial string into terms, then separate the coefficient and degree in each term, and then everything is just counted.
In general, the general principle is this: try to write code so that in each place of the program you need to keep as little information in your head as possible. Both in terms of the data and variables that you use, and in terms of the requirements that you need to fulfill. If you understand that you need one variable in one place of the code, and the other in another, then think about whether it is possible to spread the code so that you don't have to think about the second variable in the first place, etc.
A small comment on the same topic, although not explicitly related to the tasks of the technique. Suppose, for example, you need to count the sums of elements in the rows of a two-dimensional array in the program:
Pascal | Python |
var a:array[1..100,1..100] of integer; s:integer; ... for i:=1 to n do begin s:=0; for j:=1 to m do s:=s+a[i,j]; ... doing something with s ... doing something else end; ... |
# a -- two-dimensional array for i in range(n): s = 0 for j in range(m): s += a[i][j] ... doing something with s ... doing something else ... |
You can write as it is written above. Or you can do it like that — and many of you write exactly like that:
Pascal | Python |
var a:array[1..100,1..100] of integer; s:integer; ... s:=0; for i:=1 to n do begin for j:=1 to m do s:=s+a[i,j]; ... doing something with s ... doing something else s:=0; end; ... |
# a -- two-dimensional array s = 0 for i in range(n): for j in range(m): s += a[i][j] ... doing something with s ... doing something else s = 0 ... |
The difference is that in the first code you will take the variable s
before use, and in the second code — after.
So, I strongly recommend that you write exactly as in the first version. Because in the second option, you need to remember that s
should be zero at the end of the loop iteration, but not in the first option. In the first variant, you don't care at all what s
is equal to at the entrance to the loop, and what it is equal to at the end of the loop. In the first variant, we can say that the whole life of the variable s
is limited to three lines of code, you do not need to remember and think about it outside of these three lines. Therefore, in the first option, you need to think less and remember less, so it is simpler and more reliable.
An elementary example of how something can go wrong in the second option - let you decide to write continue
somewhere inside the i
loop. And that's it, you missed the assignment s=0
.