Algorithm for solving this distributing beads puzzle?

前端 未结 2 909
故里飘歌
故里飘歌 2021-02-08 23:48

Lets say you have a circle (like below) with N spots, and you have N beads distributed in the slots.

Here\'s an example:

Each

2条回答
  •  难免孤独
    2021-02-09 00:12

    I implemented this in MATLAB. It relies on much the same logic as trincot's excellent answer. In this implementation, which also runs in O(n) time, the first step is to find a space to start where one bead should remain unmoved. I've yet to prove that this always works out to an optimal solution, but maybe I'll come back to it.

    Oh, and this code also relies on the square pyramid formula https://en.wikipedia.org/wiki/Square_pyramidal_number

    clear; 
    %// inputBps (beads per space) will be our starting point.
    %// inputBps=[2 0 3 0 0 0 4 0 1 0 1 0 1 2];
    %// inputBps=[2 0 2 0 0 2];
    %// inputBps=[1 1 1 1 1];
    inputBps=[3 0 1 0 1 0 2 2 2 1 1 0 1 0];
    
    %// This first block of code finds a good place to start.
    %// We find a candidate for a bead that should not move.
    okStart = 1;
    stack = 0;
    for i=1:length(inputBps)
        if inputBps(i)>1
            stack = stack + inputBps(i)-1;
        end
        if inputBps(i)==0 && stack<=0
            okStart = i+1;
        end
        if inputBps(i)==0 && stack>0
            stack=stack-1;
        end
    end
    
    %// This lets us start at the space we found above.
    bps = [inputBps(okStart:end) inputBps(1:okStart-1)];
    
    sum=0;
    nextFree=1;
    for k=1:length(bps)
        %// firstMoves are the moves that all the beads
        %// in a space have to take because they were "forced out."
        firstMoves = nextFree-k;
    
        %// Say firstMoves=3 and bps(k)=2. Then our our two beads
        %// moved three spaces and four spaces, like this:
        %// sum = sum + 3^2 + 4^2.  Rewriting:
        %// sum = sum + (1^2 + 2^2 + 3^2 + 4^2) - (1^2 + 2^2)
        sum = sum + squares( bps(k) + firstMoves - 1 ) - squares( firstMoves-1 );
    
        %// Now calculate the next space that can accept a bead.
        nextFree = nextFree+bps(k);
    end
    

    .

    function [ y ] = squares( x )
    %SQUARES Returns sqaure payramid of input
    y = x*(x+1)*(2*x+1) / 6 ;
    end
    

    And the result for the problem in the question:

    sum =
    
        60
    

提交回复
热议问题