Quote from: Greenbank on 13 December, 2020, 02:32:53 pmQuote from: Davef on 13 December, 2020, 01:57:45 pmIf anyone is interested in how my simple solution to 13 day 2 works ... (click to show/hide)The basic problem is to find a (very large) number that satisfies some rule.Suppose your numbers are 17 67 231 ...The initial approach is to start at 1 and keep trying with increments of 1After 17 attempts you find the number 17 which satisfies your first requirement (but unfortunately no others). You could carry on looking one at a time for something that matches the first and second requirement, but you can skip some as you quickly realise only every 17th number will satisfy criteria 1, so you can change your step size to 17 and carry on until you find an answer that satisfies 17 and 67. At this point you can increase your step size to 17x67 and when you find the next 17x67x231You are soon leaping through the numbers skipping billions at a time. (click to show/hide)I think the differences I'm talking about are easily summed up by how people's code would handle a seemingly simple input that's designed to be difficult for solutions that don't use the ideal underlying algorithm/theorem. For example, how does your code handle this pathological input:-3,1000000000000037You can see that trying to find a solution for the 1000000000000037 bus by counting up 3 at a time is not going to be computeable in a reasonable timeframe.The more people attempt to 'optimise' it by going "ah, but with big values like this I can see that I can spot that and skip a whole bunch of values in one go and make it much faster" the more they are actually working their way towards the "proper" generalised algorithm/theorem that works in an optimal manner in all cases. (click to show/hide)You can actually evaluate the buses in descending order so in this case you would start off by skipping 1000000000000037 first
Quote from: Davef on 13 December, 2020, 01:57:45 pmIf anyone is interested in how my simple solution to 13 day 2 works ... (click to show/hide)The basic problem is to find a (very large) number that satisfies some rule.Suppose your numbers are 17 67 231 ...The initial approach is to start at 1 and keep trying with increments of 1After 17 attempts you find the number 17 which satisfies your first requirement (but unfortunately no others). You could carry on looking one at a time for something that matches the first and second requirement, but you can skip some as you quickly realise only every 17th number will satisfy criteria 1, so you can change your step size to 17 and carry on until you find an answer that satisfies 17 and 67. At this point you can increase your step size to 17x67 and when you find the next 17x67x231You are soon leaping through the numbers skipping billions at a time. (click to show/hide)I think the differences I'm talking about are easily summed up by how people's code would handle a seemingly simple input that's designed to be difficult for solutions that don't use the ideal underlying algorithm/theorem. For example, how does your code handle this pathological input:-3,1000000000000037You can see that trying to find a solution for the 1000000000000037 bus by counting up 3 at a time is not going to be computeable in a reasonable timeframe.The more people attempt to 'optimise' it by going "ah, but with big values like this I can see that I can spot that and skip a whole bunch of values in one go and make it much faster" the more they are actually working their way towards the "proper" generalised algorithm/theorem that works in an optimal manner in all cases.
If anyone is interested in how my simple solution to 13 day 2 works ... (click to show/hide)The basic problem is to find a (very large) number that satisfies some rule.Suppose your numbers are 17 67 231 ...The initial approach is to start at 1 and keep trying with increments of 1After 17 attempts you find the number 17 which satisfies your first requirement (but unfortunately no others). You could carry on looking one at a time for something that matches the first and second requirement, but you can skip some as you quickly realise only every 17th number will satisfy criteria 1, so you can change your step size to 17 and carry on until you find an answer that satisfies 17 and 67. At this point you can increase your step size to 17x67 and when you find the next 17x67x231You are soon leaping through the numbers skipping billions at a time.
Quote from: Croft on 13 December, 2020, 02:57:43 pmQuote from: Greenbank on 13 December, 2020, 02:11:20 pm (click to show/hide)Such an algorithm wouldn't be guaranteed to return the lowest possible answer if not all of the bus numbers were pairwise co-prime. (click to show/hide)Maybe I'm missing something, but surely if the bus numbers are not pairwise co-prime, there is no solution regardless of algorithm (e.g. {5,10} will never arrive a minute apart). (click to show/hide)Correct that there can't be a solution to {5,10} but what about:-5,x,x,x,x,10?(I think I've got the right amount of x's for it to have a solution)
Quote from: Greenbank on 13 December, 2020, 02:11:20 pm (click to show/hide)Such an algorithm wouldn't be guaranteed to return the lowest possible answer if not all of the bus numbers were pairwise co-prime. (click to show/hide)Maybe I'm missing something, but surely if the bus numbers are not pairwise co-prime, there is no solution regardless of algorithm (e.g. {5,10} will never arrive a minute apart).
(click to show/hide)Such an algorithm wouldn't be guaranteed to return the lowest possible answer if not all of the bus numbers were pairwise co-prime.
Doesn’t your favourite theorem require the bus numbers to be relatively prime too ?
After applying the mask, four bits are overwritten, three of which are different, and two of which are floating. Floating bits take on every possible combination of values; with two floating bits, four actual memory addresses are written:000000000000000000000000000000011010 (decimal 26)000000000000000000000000000000011011 (decimal 27)000000000000000000000000000000111010 (decimal 58)000000000000000000000000000000111011 (decimal 59)Next, the program is about to write to memory address 26 with a different bitmask:address: 000000000000000000000000000000011010 (decimal 26)mask: 00000000000000000000000000000000X0XXresult: 00000000000000000000000000000001X0XXThis results in an address with three floating bits, causing writes to eight memory addresses:000000000000000000000000000000010000 (decimal 16)000000000000000000000000000000010001 (decimal 17)000000000000000000000000000000010010 (decimal 18)000000000000000000000000000000010011 (decimal 19)000000000000000000000000000000011000 (decimal 24)000000000000000000000000000000011001 (decimal 25)000000000000000000000000000000011010 (decimal 26)000000000000000000000000000000011011 (decimal 27)The entire 36-bit address space still begins initialized to the value 0 at every address, and you still need the sum of all values left in memory at the end of the program. In this example, the sum is 208.
mask = 000000000000000000000000000000X1001Xmem[42] = 100mask = 00000000000000000000000000000000X0XXmem[26] = 1
Quotemask = 000000000000000000000000000000X1001Xmem[42] = 100mask = 00000000000000000000000000000000X0XXmem[26] = 1The first command writes "100" to 4 different addresses. The second command writes "1" to 8 addresses, 2 of which overwrite the 100s. Therefore what's left is 2*100+8*1.I can't see a sensible way of implementing it with a spreadsheet yet.
(click to show/hide)Yeah, the 'worst' mask in my input had 9 X's and so that's 512 different addresses it could modify. Given that, I used to a recursive function to set the actual memory. If the address contained an X it would call itself twice replacing the X with a 0 and a 1. If it didn't contain an X it would set the bit of memory to the value provided.Usual trick of using a hash/dict for memory rather than an array, as the memory in use can be quite spread out and sparse.But, yes, I think I had to re-read the description about 10 times more than I usually do, it just wouldn't sink in at first.
Quote from: grams on 14 December, 2020, 02:28:18 pmQuotemask = 000000000000000000000000000000X1001Xmem[42] = 100mask = 00000000000000000000000000000000X0XXmem[26] = 1The first command writes "100" to 4 different addresses. The second command writes "1" to 8 addresses, 2 of which overwrite the 100s. Therefore what's left is 2*100+8*1.I can't see a sensible way of implementing it with a spreadsheet yet.Oh, I see...yeah you might have to wheel a programming language out.
You can do bit operations in Google sheets. Haven’t looked at what you need to do but bit manipulation via ORs ANDs, shifts etc should not stop you using sheets.
Quote from: Lightning Phil on 14 December, 2020, 05:56:09 pmYou can do bit operations in Google sheets. Haven’t looked at what you need to do but bit manipulation via ORs ANDs, shifts etc should not stop you using sheets.That's not the problem. Part 1 was straightforward enough.The problem is storing the intermediate results of each write, and combining the overwrites to get the final total. Without hashtables or nested loops or a 2^36 array.There's probably some clever radical simplification of the problem.
Paging Diver300. Diver300 to the GSM Trimphone, please...
Occasionally there are 'easy' days to give people a break and let them catch up. (click to show/hide)I think the main thing today was teaching people that keeping every turn in an array and looping through the array to search for the previous mention wasn't going to work. Hence the use of a hash/dict to speed up this part of the searching.The only "trick", as you spotted, was to add the previous turn to the hash after considering the current turn.My perl solution takes close to 20s but perl's hashes are pretty generic and so integer->integer hash storage/lookup performance isn't optimised.If I can get some time today I'll rewrite it in C to see how fast that can go.I don't think there's any way of shorcutting the calculation. Various example series exists in OEIS with no mention of a way to generate arbitrary terms.
(click to show/hide)Interesting - I keep seeing talk of hashes, and have no idea what they are in this context. Google is... confusing. Is it simply another term for a dictionary?
$ gcc -ansi -pedantic -Wall -O4 15.c -o 15$ time ./15 2 3 12020: 7830000000: 6895259real 0m0.813suser 0m0.761ssys 0m0.052s