解题语言不限Java
谜题还有第二部分,不过是留给大家的,能解出第一题的,才能写第二题
又鸽了一天才翻完。
- Advent of Code Day 1 逆向验证码
- Advent of Code Day 2 损坏校验和
- Advent of Code Day 3 螺旋内存
- Advent of Code Day 4 高熵密码
- Advevnt of Code Day 5 曲折的蹦床迷宫
- Advent of Code Day 6 内存重分配
- Advent of Code Day 7 递归马戏团
- Advent of Code Day 8 注册表爱好者
- Advent of Code Day 9 流处理
- Advent of Code Day 11 六边形迷宫
题目内容
A debugger program here is having an issue: it is trying to repair a memory reallocation routine, but it keeps getting stuck in an infinite loop.
一个调试程序出了问题:它尝试重置一个内存重分配事务,但是它陷入了一个死循环。
In this area, there are sixteen memory banks; each memory bank can hold any number of blocks. The goal of the reallocation routine is to balance the blocks between the memory banks.
在这个区域有16个内存堆,每一个内存堆可以保持任意数量的内存块。这个事务的目标是平均内存块到所有的内存堆。
The reallocation routine operates in cycles. In each cycle, it finds the memory bank with the most blocks (ties won by the lowest-numbered memory bank) and redistributes those blocks among the banks. To do this, it removes all of the blocks from the selected bank, then moves to the next (by index) memory bank and inserts one of the blocks. It continues doing this until it runs out of blocks; if it reaches the last memory bank, it wraps around to the first one.
这个事务运行在一个循环里。每次循环,它会找到存有最多内存块的内存堆(如果有多个最大值,则取第一个堆)然后重新分配其中的内存块到其他的堆。为了达到目标,这个事务会提取目标堆得内存块,然后移动到下一个堆并将一个内存块放入直到全部分配完毕。如果放入的位置超过堆列表的长度,它会移动到列表开头。
The debugger would like to know how many redistributions can be done before a blocks-in-banks configuration is produced that has been seen before.
这个调试程序想要知道在多少次重新分配之后会出现死循环。
For example, imagine a scenario with only four memory banks:
举个例子,想像一个只有4个内存堆的列表 0,2,7,0
The third bank has the most blocks, so it is chosen for redistribution.
第三个堆有最多的块,所以程序会对这个堆进行重新分配。
Starting with the next bank (the fourth bank) and then continuing to the first bank, the second bank, and so on, the 7 blocks are spread out over the memory banks. The fourth, first, and second banks get two blocks each, and the third bank gets one back. The final result looks like this: 2 4 1 2.
从下一个堆(第四个)开始,然后到第一个堆,第二个堆……,所有七个块都会被分配到每一个内存堆里。第一,二,四堆会被分到2,第三个堆会被分到1。最后的结果是2,4,1,2
。
Next, the second bank is chosen because it contains the most blocks (four).
接下来,第二个堆是最多的(4个)。
Because there are four memory banks, each gets one block. The result is: 3 1 2 3.
因为这个有四个块,所以每个堆都加一。3,1,2,3
Now, there is a tie between the first and fourth memory banks, both of which have three blocks. The first bank wins the tie, and its three blocks are distributed evenly over the other three banks, leaving it with none: 0 2 3 4.
现在有两个相等的值,第一个和第四个。这两个都有三个块。第一个堆因为数字比较小,所以被选中,其中的块被平均分配到每一个堆。最后结果是0,2,3,4
。
The fourth bank is chosen, and its four blocks are distributed such that each of the four banks receives one: 1 3 4 1.
现在,第四个堆被选中,然后其中的四个块被分配到每一个堆里:1,3,4,1
The third bank is chosen, and the same thing happens: 2 4 1 2.
现在,第三个堆被选中,同样的事情发生了:2,4,1,2
At this point, we've reached a state we've seen before: 2 4 1 2 was already seen. The infinite loop is detected after the fifth block redistribution cycle, and so the answer in this example is 5.
这时,我们到一个重复发生的状态:2,4,1,2
所以我们在第五步找到了一个死循环,所以答案是5
Given the initial block counts in your puzzle input, how many redistribution cycles must be completed before a configuration is produced that has been seen before?
请问,根据你的谜题输入,多少次重分配之后会得到一个死循环。
解题思路
这个题目基本上,没有很多要分析的地方,所以我只放解法。
我做了三个函数
- 一个是分配函数,将选定的点分配到所有得到堆
- 一个是搜索函数,找到最大值
- 一个是检索函数,把当前状态和历史状态进行比较来找到相同的状态