Phinlodaさんの問題に答えてみる

とりあえず元のネタは以下

自分が中級者かどうかは微妙なところではあるが、JavaPython でやってみた。両方ともテストコード付き。

Java

極々普通に実装。面白くもなんともない。最初は配列で書いたのだけど、テストで int の compare がちょっと面倒*1なことに気づいて 全部 List にしてしまった。
ついでに、テストコードでの結果の比較に文字列表現も利用してみたり。
参考:ObjectClub - JUnit 実践講座 - オブジェクトの文字列表現を活用しよう

import java.util.ArrayList;
import java.util.List;

public class Collect {
    public static List<List<Integer>> collect(List<Integer> source) {
        List<List<Integer>> result = new ArrayList<List<Integer>>();
        
        int index = 0;
        int length = source.size();
    
        while (index < length) {
            int n = source.get(index++);
            List<Integer> x = new ArrayList<Integer>(n);
            if (index + n > length) {
                break;
            }
            
            for (int i = 0; i < n; i++) {
                x.add(source.get(index + i));
            }
            
            result.add(x);
            index += n;
        }
        
        return result;
    }
}
import static org.junit.Assert.assertEquals;

import java.util.Arrays;
import java.util.List;

import org.junit.Test;


public class CollectTest {
    @Test
    public void testCollect1() {
        List<Integer> source = Arrays.asList(1, 5, 3, 55, -45, 6, 2, 8, 7, 0, 1, 2);
        List<List<Integer>> expected = Arrays.asList(
                Arrays.asList(5),
                Arrays.asList(55, -45, 6),
                Arrays.asList(8, 7),
                Arrays.asList(new Integer[0]),
                Arrays.asList(2)
        );
        
        List<List<Integer>> actual = Collect.collect(source);
        assertEquals(expected, actual);
        assertEquals("[[5], [55, -45, 6], [8, 7], [], [2]]", actual.toString());
    }

    @Test
    public void testCollect2() {
        List<Integer> source = Arrays.asList(1, 2, 3, 4);
        List<List<Integer>> expected = Arrays.asList(Arrays.asList(2));
        List<List<Integer>> actual = Collect.collect(source);
        assertEquals(expected, actual);
        assertEquals("[[2]]", actual);
    }
}

Python

generator で実装。値を取り出すところは iterator でやって、取り出す途中で StopIteration が送出されたらそこで停止と。
UnitTest に doctest を使ってみたけど、いいねこれ。テストコードが短い上にドキュメント=テストなもんだから、ドキュメントの不備も防げそう。

#!/usr/bin/env python

def collect(array):
    """
    >>> tuple(collect([1, 5, 3, 55, -45, 6, 2, 8, 7, 0, 1, 2]))
    ((5,), (55, -45, 6), (8, 7), (), (2,))

    >>> tuple(collect([1, 2, 3, 4]))
    ((2,),)
    """
    it = iter(array)
    while True:
        x = []
        try:
            n = it.next()
            for i in xrange(n):
                x.append(it.next())
        except StopIteration:
            return
        else:
            yield tuple(x)

def _test():
    import doctest
    doctest.testmod()

if __name__ == '__main__':
    _test()

*1:といっても数行のコード追加でいいんだけど