Behaviour of guess in case of a NULL dict

Hello,

assume dict == NULL and k = 5 and the user presses enter on the input "sevens" do we need to return "seven" or "sevens" as the return value of guess?

I guess this boils down to the question: If dict == NULL, do we need to actually collect all the garbage the user (= the testserver) produces and faithfully represent it? By this I mean:

  1. Do we need to remove the newline character in this case?
  2. Do we need to return everything that is passed, i.e. if input is a string of length 253646, do we need to actually return all 253646 characters or just k many?
  3. Do we need to change upper case to lower case for this?

Essentially, is guess(NULL, k) for arbitrary k just a function that queries user input once and then returns it without any sort of sanitation (or maybe it just removes the newline)?

Also why even handle this case? This just forces people into using realloc for no good reason.

Does this answer your question?

Thanks for the fast reply, but not really.

Any otherwise valid length means “length at least k” by the specification of guess in the project documentation, so that would mean I would have to read the remaining characters. Is that correct?

Also “only letters” doesn’t imply that we have to “lower” them. So do we need to?

It would be nice to get a definitive specification here, otherwise I have to guess why the guess_null test is failing for me and that is ultimately a waste of time because it is not even relevant to playing the game.

@Marcel.Ullrich I guess my question was stated poorly, let me rephrase it. Are we supposed to implement this?
guess

1 Like

“The check” in the project description refers to the check of containment in the dictionary.
You should still replace the upper with lower letters.
A null dictionary only changes the dictionary lookup part.

Even if it would force realloc, it would be a chance to learn how to correctly perform memory reallocation in a safe way :wink: .

With the NULL way, the guess function becomes more robust and general.
For once, the edge case of a non-existing dictionary is handled at the caller site in a semantically meaningful way (and a way some users might expect/want).

It also allows for easier extension of your wordle program. For instance, you can handle some error cases if null dictionary if you choose so (for instance invalid or empty dictionary files or unsuitable dictionary files for quantum wordle).

Additionally, it allows you to write simpler more modular unit and integration tests for guess. And you can play wordle even if you do not know that many English words without needing a 11MB dictionary file.

A partly (without IO and a bit informal) specification is: (no guarantee for completeness, but the idea should be hopefully clear):

\begin{align*} S=\{(\sigma,\sigma') ~ \mid &\\ & \sigma' ~dict = \sigma ~dict \land \sigma ' ~k = \sigma ~k~ \land \\ & ([dict]\sigma = W \lor \sigma ~dict = NULL) ~\land \\ & [return]\sigma' = s \land (\sigma ~dict \neq NULL \to s\in W) ~ \land \\ & |s|=\sigma~ k \land (\forall c\in s.~'a'\leq s\leq 'z') \\ \}& \end{align*}

[\cdot]\sigma should be a semantic interpretation of datastructures.

“The check” in the project description refers to the check of containment in the dictionary.
You should still replace the upper with lower letters.[/quote]

Thanks, this clears up a lot.

Even if it would force realloc, it would be a chance to learn how to correctly perform memory reallocation in a safe way :wink: .

I was indeed wrong, getline reallocates automatically if handed a NULL buffer. (albeit by initially allocating 120 bytes of memory which is probably inefficient for our purposes) I appreciate the points made in the lecture, but it just boils down to using realloc and employing a trick (allocating twice the size each time) that I only know to work because somebody with a more complete understanding of memory management told me about it.

A partly (without IO and a bit informal) specification is: (no guarantee for completeness, but the idea should be hopefully clear): /* specification */

I think you meant to write [return]\sigma' = s, because return has no value assigned before execution?
If that is the case your specification forces the return value to have length k which is not how I read the project documentation. From my understanding the only thing that prevents words of length >k of being returned is the dict being non-NULL. (i.e. lookup automatically returns false if the word is to long) and if that is not the case there is nothing in the documentation stating that the word should have no more than k letters.

It is a pretty neat trick.
If you are interested to learn more about it, you can look up amortized analysis. You will learn more about it if you take the Grundzüge Algorithmen und Datenstrukturen lecture.

Yes, thanks.

You are right, the case of a too-long word with a NULL dictionary is underspecified. You may accept or reject them.

1 Like

Indeed, this has “later” been clarified in the forum. See Guessed size and nullpointer

getline indeed seems like what you would want to use here.
Especially since it automates memory allocation for you, making it comparatively easy to properly catch all kinds of wrong input, including those that we do not test for.

2 Likes