カード配り問題
10分でコーディング|プログラミングに自信があるやつこい!!を見て、僕だったらどう書くかなと考えた。
まず、10分で解くことを目標に急いで書いた物。最後のほう読むの忘れて引数名などをミスった。
function range(start, end) { var a = []; var i; for (i = start; i < end; i++) { a.push(i); } return a; } function distribute(number, cards) { return cards.length < number ? range(0, number).map(function () { return ""; }) : range(0, cards.length - cards.length % number).map(function (i) { return { card: cards.charAt(i), by: i % number }; }).sort(function (a, b) { return a.by - b.by; }).reduce(function (cards, card) { return card.by >= cards.length ? [card.card].concat(cards) : [cards[0] + card.card].concat(cards.slice(1)); }, []) .reverse(); }
8分くらいで途中まで書いて、残りの2分でテストしつつcards.length < number
の場合の条件分岐を追加…。
とりあえず10分で解けることは分かったので、
var eqv = function (a, b) { return a.length == b.length && a.every(function (value, i) { return value == b[i]; }); }; console.assert(eqv(distribute(3, "123123123"), ["111","222","333"])); console.assert(eqv(distribute(4, "123123123"), ["12","23","31","12"])); console.assert(eqv(distribute(6, "012345012345012345"), ["000", "111", "222", "333", "444", "555"])); console.assert(eqv(distribute(4, "111122223333"), ["123", "123", "123", "123"])); console.assert(eqv(distribute(1, "012345012345012345"), ["012345012345012345"])); console.assert(eqv(distribute(6, "01234"), ["", "", "", "", "", ""])); console.assert(eqv(distribute(2, ""), ["", ""]));
テストを追加。人間のようにカードを一枚ずつ分配するのではなく、一度にプレーヤーに配れば、もっと簡単にできるよなあ…、と思って書いたら
function distribute(number, cards) { return range(0, number).map(function (player) { return range(0, cards.length - cards.length % number) .filter(function (i) { return i % number == player; }) .map(function (i) { return cards.charAt(i); }) .join(""); }); }
こんな感じになった。んー…。まあマシにはなったけど、10分で出来ないと意味ないなあ。(オチ無し)