|
antoniu200 wrote: I did, sorry for that.
No problem, lets just move forward.
antoniu200 wrote: As for the restrictions, the output of a string similar to 999[a999[c]]999[x999[y]] would go over the said 100,000 characters limit of the output, basically meaning that such test cases aren't given.
I would be very surprised if your code is not being tested for invalid input. In fact the memory restrictions directly imply that your code is being tested for invalid input.
antoniu200 wrote: I just tested this code on Leetcode (after I converted it to a Class Solution ) and I got it accepted,
Yes, your code appears to actually work even though the architecture is unusual. I gave it some very complex input and it appeared to pass them all. However I cannot guarantee this... because I only spent a few minutes fuzzing it.
Are you developing on Windows or Linux?
Best Wishes,
-David Delaune
|
|
|
|
|
I'm developing on Windows. But the code is evaluated on a Linux Ubuntu machine.
|
|
|
|
|
antoniu200 wrote: But the code is evaluated on a Linux Ubuntu machine.
Yes, I told you this in my first reply. The 8MB local stack size strongly infers a Linux based operating system.
antoniu200 wrote: I'm developing on Windows.
Ok, I was asking because you can use setrlimit on Linux to catch when your process exceeds 64MB of memory usage. You can also use it to limit your program to 0.6 seconds.
On Windows you could use SetProcessWorkingSetSizeEx but you would need to do alot more work... such as attaching to a job object with the CreateJobObject function. It's too much work to do this programmatically. You would be better off using perfmon on Windows to detect if your program will exceed 64MB memory usage.
You will probably lose your mind again... but I am fairly certain that your code is failing these Restrictions and clarifications test rules.
Best Wishes,
-David Delaune
|
|
|
|
|
I'm fairly sure you just don't get it. The resulting string can be as big as 100'000 characters long, as stated by the Restrictions. Now, how much memory does that use? 100'000 * 8 / 8 / 1024 = 97.6 KB.
If I'm in any way seeing this wrong and Wrong Answer should be Caught Fatal Signal 11, please explain as thorough as you can, because I just don't see why would it go over the 100 KB mark, for tests that are meant not to result in a string longer than 100'000 characters.
|
|
|
|
|
Well,
I can easily make your program utilize over 1GB of memory simply by passing a large input string.
antoniu200 wrote: The resulting string can be as big as 100'000 characters long, as stated by the Restrictions. Now, how much memory does that use? 100'000 * 8 / 8 / 1024 = 97.6 KB.
I agree. In fact that's exactly how you could detect whether or not you should process the user input. As you are parsing the input I would recommend multiplying to see if the resulting string would surpass 64MB.
antoniu200 wrote: If I'm in any way seeing this wrong and Wrong Answer should be Caught Fatal Signal 11
Ok, well maybe something is wrong with your parser. But I've tested your code against quite a few test vectors:
10[b12[ca]]
3[a]2[bc]
3[a2[c]]
2[abc]3[cd]ef
3[a3[b]1[ab]]
3[b2[ca]]
Your code seems to be passing all of the tests I can throw at it. This is why I think you must be failing one of the test restrictions.
Best Wishes,
-David Delaune
|
|
|
|
|
There's a couple of things I can think of:
1) there's no end-of-line char output. The specs don't say that it should, but that might be causing a fail.
2) the program, as given, only processes one input line per run. Again, the specs as given, do not say you need to process multiple lines of input, but again, that might be the cause of fail.
|
|
|
|
|
The only advice I can give so far is that you should consider all kinds of test cases that you can think of, determine the expected result, and see if your code provides these results.
The key is to think of all corner cases, such as unmatched brackets, opening brackets without a leading number, nested brackets, etc.. I'm not even sure how the first two should be dealt with - do you know?
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
Let's assume you have a 1 MByte memory, divided into 8 equal sized sectors. Then your address (or register) range occupies 1048576 addresses (or registers). Instead, you could have a state variable that occupies 1 register that selects the current sector. Then you only need 1 + 262144 registers to access the entire memory (of course, it's more inefficient because every once in a while you need an extra write in order to switch sector). My question is, does this technique have a conventional name?
|
|
|
|
|
Memory management, often specifically called bank switching: Memory management unit - Wikipedia[^]
I used to use it in a Z80 clone called the HD64180 which included a MMU to expand the 16 bit address space of the Z80 processor (i.e 64Kbyte) to 1Meg by dividing the processor address space into three banks and assigning them to different areas in the 1MB space. So your ROM was in Bank0, say, and that where the core software was (interrupts, threading, bank control, important stuff you needed all the time), Bank1 was your "user code", and Bank2 was your RAM - and you swapped the banks in and out as needed. Took a bit of work to get it straight in your head (it wasn't the most obvious implementation or an MMU) but it worked pretty well in practice as long as you paid attention.
Sent from my Amstrad PC 1640
Never throw anything away, Griff
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Yup, The C=ommodore Plus 4 and C=16/116 also used Bank switching to get the full 16 bit address space accessible for BASIC while keeping the OS in the ROM(s). I've heard the C=64 already had the same technology in hardware, but Basic 2 didn't support it. Therefore only the memory area unused for the OS was available for BASIC programs.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|
|
Memory paging most often used in Virtual Memory systems.
In vino veritas
|
|
|
|
|
What if I was to turn that sector selector into a uint32_t so that I can move the "window" freely (even across sector boundaries), does this have a different name? The reason I ask is that I want to name my registers appropriately. Today they are named SLIDING_WINDOW_BUFFER_position, SLIDING_WINDOW_BUFFER_start and SLIDING_WINDOW_BUFFER_endExcl but I have a feeling this is called something else.
|
|
|
|
|
This is starting to sound like the ancient x86 segmented memory. 20 bit addresses (1MB) were made up of a 16 bit segment (shifted left 4) added to a 16 bit offset. The 8086 for example had 4 segment registers IIRC, CS (code), DS (data), SS (stack) and ES (extra).
Cheers,
Peter
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
From what I can work out you are still building a Virtual Memory system what you are calling the sector selector is the page index and the memory window size itself is the page size.
Memory segmentation - Wikipedia[^]
Quote: Segmentation with paging
Instead of an actual memory location the segment information includes the address of a page table for the segment. If that is the case you are building a page table for a Virtual Memory Implementation
Page table - Wikipedia[^]
The Virtual space can be bigger, 1:1 or smaller than the real memory space.
Even on Flash Memory we still call them pages and a group of pages become a block.
That also holds for the old superVGA (VESA) standard where you have blocks being made up of pages of a set granularity
Although in both those cases we do call the selector a "bank selector" or a "block selector" as opposed to a "page index"
Sliding Window tends to be used as a term on transmission protocols
Realistically we understand what you are doing and it's only a name.
In vino veritas
modified 13-Aug-19 12:02pm.
|
|
|
|
|
|
kuleen wrote: how to convert afl to c
What is "afl"?
Australian Football League?
|
|
|
|
|
Probably be rewriting it.
|
|
|
|
|
I'm setting a CTreeCtrl item item font to Italic by handling the NM_CUSTOMDRAW message and setting the font with SelectObject.
This is working.
void MyTree::OnNMCustomdraw(NMHDR *pNMHDR, LRESULT *pResult)
{
NMTVCUSTOMDRAW *itemToDraw = reinterpret_cast<NMTVCUSTOMDRAW*>>(pNMHDR);
switch (itemToDraw->nmcd.dwDrawStage)
{
case CDDS_PREPAINT:
*pResult = CDRF_NOTIFYITEMDRAW;
return;
case CDDS_ITEMPREPAINT:
{
HTREEITEM item = reinterpret_cast<HTREEITEM>(itemToDraw->nmcd.dwItemSpec);
if (!m_IsItalicFontCreated) {
CFont* currentFont = GetFont();
LOGFONT logfont;
currentFont->GetLogFont(&logfont);
logfont.lfItalic = TRUE;
m_ItalicFont.CreateFontIndirect(&logfont);
m_IsItalicFontCreated = true;
}
if (m_IsItalicFontCreated)
{
::SelectObject(itemToDraw->nmcd.hdc, m_ItalicFont);
*pResult = CDRF_NEWFONT;
}
}
return;
}
*pResult = 0;
}
But at some point I need to check an item current font; to see if a tree item is in italic.
The CTreeCtrl's item data (CTreeCtrl::SetItemData) is already used to hold data for each item.
Is it possible to do it ? I can't see in the documentation anything I can use.
There is a lItemlParam in the NMCUSTOMDRAW struct, I'm not certain if I could use this to some some simple data ? or even if it is persistent.
Any suggestions ?
Thanks.
I'd rather be phishing!
|
|
|
|
|
You could implement the method in your MyTree class that would return true if italic font was created.
Something like
bool MyTree::IsItalicFontCreated()
{
return m_IsItalicFontCreated;
}
|
|
|
|
|
That only tells me the font is created, but not if it was set to one particular tree item.
I'd rather be phishing!
|
|
|
|
|
Maximilien wrote: The CTreeCtrl's item data (CTreeCtrl::SetItemData) is already used to hold data for each item.
You could extend your data adding the font type (create a struct containing all the necessary data and set the pointer to the struct instance as an ItemData)
|
|
|
|
|
Yes, I'm looking into that.
Thanks.
I'd rather be phishing!
|
|
|
|
|
Fighting to solve old plan C errors, I met another issue: error C2143: syntax error
I have the following code:
typedef struct test test_t;
struct test
{
const char* name;
const char* name_option;
...
...
};
and
test_t test_123 = {
.name = "Bibi", .name_option = "Bibi_One",
};
How can I get rig of this error ?
|
|
|
|
|
This form of initialization is valid in GNU C, and is valid in other compilers only if they support C99 or later. I don't remember off-hand whether this is supported in C++.
You can make this compatible with C89 by adding the missing initializers, e.g.:
test_t test123 = { "Bibi", "Bibi_one", foo, bar };
Where foo and bar are the values for missing members in the struct.
Freedom is the freedom to say that two plus two make four. If that is granted, all else follows.
-- 6079 Smith W.
|
|
|
|
|
Get rid of the member names in the initalization, it's not valid in C++. You can only pass values, and these will be used to initialize the members of the struct in the order of their definition. You don't need to provide values for all members - if you don't, the rest will use default values:
test_t test_123 = { "Bibi", "Bibi_One" }; Special case: if you try to initialize a C array in this manner with less values than it's size, the remainder of the array will be initialized with the last value of your initializer list. This code will initialize your entire array with 1s:
int my_array[9] = {1}; You can read up on this topic in many articles on the web, just use the correct search term: initializer list.
GOTOs are a bit like wire coat hangers: they tend to breed in the darkness, such that where there once were few, eventually there are many, and the program's architecture collapses beneath them. (Fran Poretto)
|
|
|
|