Weekly Code Puzzle "Dreidel Dreidel"

Tis the holiday season, so we have a holiday themed puzzle. But first...

Results from last week "Connect Four"

Last week our challenge was to write a program that could take a connect four board and tell you who the winner was. The thing I like best about this puzzle is that it is something that a human can do intuitively and quickly but breaking the task down into steps that a computer can understand can get complicated quickly.

The "Who's on first" award:

This award goes to Brian Bugh for finnishing the puzzle faster than anyone else

function connectFour(board) {  
    var state = {full: true, R: false, Y: false}

    for (x = 0; x < 6; x++) {
        for (y = 0; y < 7; y++) {
            if (board[x][y] === '-') {
                state["full"] = false;
            } else {
                if ((y < 4 && board[x][y+1] === board[x][y] && board[x][y+2] === board[x][y] && board[x][y+3] === board[x][y]) ||
                    (x < 3 && board[x+1][y] === board[x][y] && board[x+2][y] === board[x][y] && board[x+3][y] === board[x][y]) ||
                    (y > 2 && x < 3 && board[x+1][y-1] === board[x][y] && board[x+2][y-2] === board[x][y] && board[x+3][y-3] === board[x][y]) ||
                    (y < 4 && x < 3 && board[x+1][y+1] === board[x][y] && board[x+2][y+2] === board[x][y] && board[x+3][y+3] === board[x][y])) {
                      state[board[x][y]] = true;
                }
            }
        }
    }

    if (state["full"] && !state["R"] && !state["Y"]) {
        return "draw";
    } else if ((state["R"] && !state["Y"]) || (state["Y"] && !state["R"])) {
        return (state['R']) ? 'R' : 'Y'
    } else {
        return "in progress";
    }
}

His code works by stepping over every position on the board and then checking in every direction to see if there are 4 in a row.

The "Edge Tech" award:

This award goes to Aaron Brager

function connectFour(board) {  
  horizontal = straight(board, true);
  if (horizontal) return horizontal;

  vertical = straight(board, false);
  if (vertical) return vertical;

  diag = diagonal(board);
  if (diag) return diag;

  if([].concat.apply([], board).indexOf('-') >= 0) return "in progress"

  return "draw";
}

function straight(board, horizontal) {  
  function row(board, i) { return board[i]; }
  function column(board, i) { return board.map(function(value,index) { return value[i]; }); }

  row_count = horizontal ? 6 : 7;
  col_max = horizontal ? 4 : 3;

  for (i = 0; i < row_count; i++) {
    this_row = horizontal ? row(board, i) : column(board, i);
    for (j = 0; j < col_max; j++) {
      var winner = check_slice(this_row.slice(j, j + 4));
      if (winner) return winner;
    }    
  }
}

function diagonal(board) {  
  var winner;

  for (i = 0; i < 3; i++) {
    for (j = 0; j < 7; j++) {
      if (j < 4) {
        winner = check_slice([board[i][j], board[i+1][j+1], board[i+2][j+2], board[i+3][j+3]]);
        if (winner) return winner;
      }
      if (j > 2) {
        winner = check_slice([board[i][j], board[i+1][j-1], board[i+2][j-2], board[i+3][j-3]]);
        if (winner) return winner;
      }
    }
  }
}

function check_slice(slice) {  
  set = new Set(slice);
  if (set.size == 1 && (set.has("R") || set.has("Y"))) {
    return Array.from(set)[0];
  }
}

The he get's this award is for clever use of the ES6 Set object to determine if a slice of 4 spaces are the same.

function check_slice(slice) {  
  set = new Set(slice);
  if (set.size == 1 && (set.has("R") || set.has("Y"))) {
    return Array.from(set)[0];
  }
}

This week: "Dreidel Dreidel"

http://www.codewars.com/kata/dreidel-dreidel

Let's play a fun gambling game. A dreidel has four sides. Below are the descriptions for each of them:

  1. Nun - nothing happens
  2. Gimel - you take the pot!
  3. Hei - you take half the pot
  4. Shin - you put a piece into the pot

So here's how we play. You, being a raging gambling addict, start with all of your hard earned coins - oy vei! The pot will also have some non-negative amount of coins when the game begins. Create a function that given an array of dreidel rolls ordered from first to last (so rolls[0] is the first roll and rolls[rolls.length - 1] is the last roll), the number of coins in your account, and the number of coins in the pot, returns the number of coins left in your account after the last roll.

For this week I have an extra challenge for you. If you find the puzzle too easy try to utilize a language feature or programming technique that you are less familiar with. See how interesting and unique your solution can be.

Please follow these instructions to get the link to your solution and email that link to weeklypuzzle@bloc.io or tweet it at @BlocPuzzle. Submit by Friday December 11 9am PST to be included.