Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

第 126 题:扑克牌问题 #245

Open
yygmind opened this issue Aug 15, 2019 · 75 comments
Open

第 126 题:扑克牌问题 #245

yygmind opened this issue Aug 15, 2019 · 75 comments

Comments

@yygmind
Copy link
Contributor

yygmind commented Aug 15, 2019

有一堆扑克牌,将牌堆第一张放到桌子上,再将接下来的牌堆的第一张放到牌底,如此往复;

最后桌子上的牌顺序为: (牌底) 1,2,3,4,5,6,7,8,9,10,11,12,13 (牌顶);

问:原来那堆牌的顺序,用函数实现。

@yygmind yygmind added the 字节 label Aug 15, 2019
@Kisnnnnn
Copy link

Kisnnnnn commented Aug 15, 2019

      let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
      let _arr = []

      function sortPoke() {
        while (arr.length > 0) {
          // 选择抽取哪张牌
          if (arr.length % 2 == 1) {
            _arr.push(arr.pop())
          } else {
            _arr.push(arr.shift())
          }
        }

        return _arr.reverse()
      }

      console.log(sortPoke())
      // [7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13]

不知道对不对,还请大神指教纠错。

@cb3570594
Copy link

cb3570594 commented Aug 15, 2019

var list = [1,2,3,4,5,6,7,8,9,10,11,12,13];
function fn(list){
    let curIndex = parseInt((list.length - 1) / 2);
    let cur = list.splice(curIndex, 1);
    if(list.length === 0) return cur;
    return [...fn(list), cur[0]];
}
fn(list);

(牌底)[13, 1, 12, 2, 11, 3, 10, 4, 9, 5, 8, 6, 7](牌顶)

@fengtomy
Copy link

const reverseResult = [];
const reverseSort = arr => {
  console.log("begin: ", arr, reverseResult);
  if (reverseResult.length) {
    reverseResult.unshift(reverseResult.pop());
  }
  if (arr.length) {
    reverseResult.unshift(arr.pop());
    console.log("end: ", arr, reverseResult);
    if (arr.length) {
      reverseSort(arr);
    }
  }
};

@FontEndArt
Copy link

先放一波验证方法 勿喷,等会扔出来我解题方法(上面大佬们写的解题方法比我的强得多)

function handle(arr = [
    1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13
]) {
    const result = [];
    for (let i = 0; i < arr.length; i++) {
        if (i % 2) {
            result.push({ value: arr[i] })
        } else {
            result.unshift({ value: arr[i] })
        }
    }
    result.unshift({ value: "牌顶" });
    result.push({ value: "牌底" });
    console.log(result);
}
handle([7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13]);
/* [ { value: '牌顶' },
  { value: 13 },
  { value: 12 },
  { value: 11 },
  { value: 10 },
  { value: 9 },
  { value: 8 },
  { value: 7 },
  { value: 6 },
  { value: 5 },
  { value: 4 },
  { value: 3 },
  { value: 2 },
  { value: 1 },
  { value: '牌底' } ]*/

@HCLQ
Copy link

HCLQ commented Aug 15, 2019

          if (arr.length % 2 == 1) {
            _arr.push(arr.pop())

这里从屁股拿出来再塞回屁股啊 ㄟ( ▔, ▔ )ㄏ

@FontEndArt
Copy link

第一印象搞出来的烂摊子。。。 自己都感觉很烂了。。

当个记录吧 希望半年后不会这么烂了

// 牌底 -> 牌顶
const arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];
const arr2 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12];

function handle(sortGroup) {
    const original = [];
    const len = sortGroup.length;
    const lastindex = len - 1;

    // 中间值
    let middleIndex = Math.floor(len / 2) - 1;

    // 如果是单数 从牌顶开始
    // 如果是双数 从牌底开始

    if (len % 2) {
        sortGroup = sortGroup.reverse();
        middleIndex ++;
    }

    for (let i = 0; i < len; i++) {
        if (i > middleIndex) {
            break;
        }
        original.unshift(sortGroup[i])
        if (len % 2 && i == middleIndex) {
            continue;
        }
        original.unshift(sortGroup[lastindex - i])
    }

    return original;
}

const result = handle(arr);
const result2 = handle(arr2);

// [ 7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13 ]
console.log(result);
// [ 7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1 ]
console.log(result2);

@HCLQ
Copy link

HCLQ commented Aug 15, 2019

function poke(arr) {
  let i = 1
  let out = []
  while (arr.length) {
    if (i % 2) {
      out.push(arr.shift())
    } else {
      arr.push(arr.shift())
    }
    i++
  }
  return out
}   
    

function reverse(arr) {
  let i = 1
  let out = []
  while (arr.length) {
    if (i % 2) {
      out.unshift(arr.pop())
    } else {
      out.unshift(out.pop())
    }
    i++
  }
  return out
}

reverse([1,2,3,4,5,6,7,8,9,10,11,12,13 ])
// [1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7]

@Polaris-tl
Copy link

Polaris-tl commented Aug 15, 2019

var origin = [],top_half;
var res = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13].reverse();
top_half = res.splice(0,Math.floor((res.length-1)/2) + 1).reverse();
for (let i of top_half.keys()){
    origin.push(top_half[i]);
    res[i] && origin.push(res[i]);
}
console.log(origin);

//[7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13]

@xunzhaoshitouyu
Copy link

var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];

function recovery(array) {
    const length = array.length;
    let newArray = [];
    for (let i = 0; i < length; i++) {
        if (i % 2 == 0) {
            newArray.push(array.pop())
        } else {
            newArray.push(array.shift())
        }
    }
    return newArray;
};

recovery(arr);
// [ 13, 1, 12, 2, 11, 3, 10, 4, 9, 5, 8, 6, 7 ]

@master-kolan
Copy link

function poke(arr) {
  let i = 1
  let out = []
  while (arr.length) {
    if (i % 2) {
      out.push(arr.shift())
    } else {
      arr.push(arr.shift())
    }
    i++
  }
  return out
}   
    

function reverse(arr) {
  let i = 1
  let out = []
  while (arr.length) {
    if (i % 2) {
      out.unshift(arr.pop())
    } else {
      out.unshift(out.pop())
    }
    i++
  }
  return out
}

reverse([1,2,3,4,5,6,7,8,9,10,11,12,13 ])
// [1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7]

看下来唯一一个对的,大家都是在原数组上操作pop和shift了。不过最后答案应该再反过来表示。

@FontEndArt
Copy link

@nssol-fengzhichao 啥意思

@liangmuren
Copy link

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
function sort(arr) {
    let pre = []
    while (arr.length > 1) {
        pre.push(arr.pop())
        pre.push(pre.shift())
    }
    pre.push(arr.pop())
    console.log(pre)
}
sort(arr)
// [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]

@JaniceDong
Copy link

@HCLQ 这位道友,我倒觉得做法是对的

@xiaowuhero666
Copy link

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
    let num = Math.ceil(arr.length/2);
    //判断奇偶性
    let flag = arr.length%2 === 0?true:false;
    let res = [];
    for(let i = 0;i<num;i++){
        if(flag){
           res.unshift(arr[i]);
           res.unshift(arr[arr.length-1-i])
        }else{
            res.unshift(arr[arr.length-1-i])
            if(i < num-1){
                res.unshift(arr[i]);
            }
        }
    }
    //结果是牌顶到排底
    console.log(res)
    //结果 [7, 6, 8, 5, 9, 4, 10, 3, 11, 2, 12, 1, 13]

@ToSaySomething
Copy link

ToSaySomething commented Aug 15, 2019

建议还是参考楼上的大佬们比较好,我只想写一下自己的想法,很废时间,不是很建议。
开始好像理解错了题意,最后桌子上的牌顺序为: (牌底) 1,2,3,4,5,6,7,8,9,10,11,12,13 (牌顶);
桌上的牌顺序是从下往上 1-n , 我推的是 从上往下 1-n ,推反了
(桌上的牌相当于一个栈,但没关系后面处理一下,把13当成了1,主要是反着推不出来 愁呀)
用数学举例,
结束 =》开始
1 =》 1
1 2 =》2 1
1 2 3 =》3 1 2
1 2 3 4 =》 4 2 3 1
1 2 3 4 5 =》 5 1 4 2 3
1 2 3 4 5 6 =》 6 3 5 1 4 2
1 2 3 4 5 6 7 =》 7 2 6 3 5 1 4
1 2 3 4 5 6 7 8 =》 8 4 7 2 6 3 5 1
1 2 3 4 5 6 7 8 9 =》 9 1 8 4 7 2 6 3 5
1 2 3 4 5 6 7 8 9 10 =》 10 5 9 1 8 4 7 2 6 3
1 2 3 4 5 6 7 8 9 10 11 =》 11 3 10 5 9 1 8 4 7 2 6
1 2 3 4 5 6 7 8 9 10 11 12 =》 12 6 11 3 10 5 9 1 8 4 7 2
1 2 3 4 5 6 7 8 9 10 11 12 13 =》 13 2 12 6 11 3 10 5 9 1 8 4 7
规律的话 1 2 3 4 5 =》5 1 4 2 3 进行循环得到 4 2 3 1
所以可以用前面的推出后面的

处理的话,可能是个取巧的方法,刚刚开始理解错了题意
(每个数+自己的结果 = 14),比如,把13当成1 即 13+1 = 14
[1 12 2 8 3 11 4 9 5 13 6 10 7]

@weiweixuan
Copy link

 let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
      function reduction(arr) {
        let newArr = [...arr],res = []
        while (newArr.length) res.push(!(newArr.length % 2) ? newArr.shift() : newArr.pop())
        return res.concat(newArr).reverse()
      }
      let res = reduction(arr)
      console.log(res)

@Nz-JiangHui
Copy link

再将接下来的牌堆的第一张放到牌底

这句是说放在新牌堆的底,还是旧牌堆的底?

@McCarthey
Copy link

/**
 * 逆向:即从桌牌到手牌
 * @param {*} 桌牌序列 arr 
 */
function recover(arr) {
    const res = []
    while (arr.length > 0) {
        if (res.length) {
            res.push(res.shift())
        }
        const item = arr.pop()
        res.push(item)
    }
    return res
}

/**
 * 正向:即从手牌到桌牌(用于检验结果)
 * @param {*} 手牌序列arr 
 */
function generate(arr) {
    const res = []
    while (arr.length > 0) {
        const item = arr.pop()
        res.push(item)
        if (arr.length) {
            arr.unshift(arr.pop())
        }
    }
    return res
}

recover([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])   // [7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1]
generate([7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1])  // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

@XcGuaN-miepia
Copy link

留个小小的见解
`/**

  • description: 管道函数执行
  • @param {Function} fns 执行函数数组
    */
    function pipe(...fns) {
    return function(x) {
    return fns.reduce(function(arg,fn) {
    return fn(arg)
    },x)
    }
    }

/**

  • description: 新卡组最后一张放到旧卡组第一张
  • @param {Object} card
    */
    function removeNewLastToOldFirst(card) {
    card.old = [card.new.pop(),...card.old];
    return card;
    }

/**

  • description: 旧卡组最后一张放到旧卡组第一张
  • @param {Object} card
    */
    function reverseLastToFisrt(card) {
    let last = card.old.pop();
    if(last) {
    card.old = [last,...card.old];
    }
    return card;
    }

/**

  • description: 卡片排序
  • @param {Object} card
    */
    function cardSort(card) {
    if(card.new.length > 0) {
    pipe(reverseLastToFisrt,removeNewLastToOldFirst)(card)
    cardSort(card)
    } else {
    return;
    }
    }

let card = {
old: [],
new: [1,2,3,4,5,6,7,8,9,10,11,12,13]
}
cardSort(card)

console.log(card) // { old: [ 1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7 ], new: [] }`

@TigerLiv
Copy link

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
function sort(arr) {
    let pre = []
    while (arr.length > 1) {
        pre.push(arr.pop())
        pre.push(pre.shift())
    }
    pre.push(arr.pop())
    console.log(pre)
}
sort(arr)
// [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]

我还是不理解这个 大佬 讲解一下为什么

@Dacredible
Copy link

再将接下来的牌堆的第一张放到牌底

这句是说放在新牌堆的底,还是旧牌堆的底?

是的,这个很关键。我猜测大概率是放到旧牌堆的底。

@nowherebutup
Copy link

@nssol-fengzhichao 啥意思

这个答案的顺序: 牌顶是 数组的第一项,按照出题人的套路: 牌顶是数组最后一项,
所以最好是答案再反过来

@liangmuren
Copy link

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
function sort(arr) {
    let pre = []
    while (arr.length > 1) {
        pre.push(arr.pop())
        pre.push(pre.shift())
    }
    pre.push(arr.pop())
    console.log(pre)
}
sort(arr)
// [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]

我还是不理解这个 大佬 讲解一下为什么

每次将桌上牌的最上面一张放到原牌堆顶,然后将原牌堆底的牌放到原牌堆顶

@nowherebutup
Copy link

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
function sort(arr) {
    let pre = []
    while (arr.length > 1) {
        pre.push(arr.pop())
        pre.push(pre.shift())
    }
    pre.push(arr.pop())
    console.log(pre)
}
sort(arr)
// [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]

精髓

@changchangge
Copy link

我就说怎么我做的和大家都不同,我理解的题目是从原先的牌堆a1中取出顶部一张到a2中,然后a1顶部取一张牌放在a1的地步,再从a1中取一张放a2中,如此循环。。。给了差评的我去撤销掉。。。大概是我理解错了吧。。。

@wasdxie
Copy link

wasdxie commented Aug 16, 2019

let tmp = [1,2,3,4,5,6,7,8,9,10,11,12,13]; 
let result = [];
let action = 'pop'
while(tmp.length != 0){
    let item = tmp[action]()
    if(action == 'pop'){
        action = 'shift'
    }else{
        action = 'pop'
    }
    result.push(item);
}
console.log(result); //打印出最后的牌顺序

@XINXINP
Copy link

XINXINP commented Aug 17, 2019

function sortPuke(arr) {
let keyList = [];//arr对应的key
let alenList = [];
let result = [];//最终结果
let spot = true;
if (arr.length === 1) {
return arr
}
if (arr.length > 1) {
for (let index = 0; index < arr.length; index++) {
alenList.push(index)
}
while (alenList.length) {
if (alenList.length === 1) {
keyList.push(alenList.shift())
}
if (spot && alenList.length > 1) {
keyList.push(alenList.shift())
}
if (!spot && alenList.length > 1) {
alenList.push(alenList.shift())
}
spot = !spot
}
}
for (let j = 0; j < arr.length; j++) {
result[keyList[j]] = arr[j]
}
return result;
}
console.log(sortPuke([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]));
//[ 1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7 ]

@lhyt
Copy link

lhyt commented Aug 18, 2019

// 复原
function recover(arr) {
  return arr.reduceRight((res, cur) => {
    if (res.length) {
      res.push(res.shift());
    }
    res.push(cur);
    return res;
  }, []);
}

const res = recover([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
console.log(res);

// 打乱,验证使用
function shuffle(arr, result = [], joinRes = true) {
  return arr.reduceRight((res, cur, index) => {
    res[res.joinRes ? 'result' : 'now'][res.joinRes ? 'push' : 'unshift'](cur);
    res.joinRes = !res.joinRes;
    if (!index && res.now.length) {
      shuffle(res.now, res.result, res.joinRes);
    }
    return res;
  }, { result, now: [], joinRes }).result;
}

console.log(shuffle(res));
点击展开查看打乱过程
结果: []
手上: 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1

1
12, 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2

1,2
8, 12, 7, 10, 6, 13, 5, 9, 4, 11, 3

1,2,3
11, 8, 12, 7, 10, 6, 13, 5, 9, 4

1,2,3
11, 8, 12, 7, 10, 6, 13, 5, 9, 4

1,2,3,4
9,11, 8, 12, 7, 10, 6, 13, 5

1,2,3,4,5
13,9,11, 8, 12, 7, 10, 6

1,2,3,4,5,6
10,13,9,11, 8, 12, 7

1,2,3,4,5,6,7
12, 10,13,9,11,8

1,2,3,4,5,6,7,8
11,12,10,13,9

1,2,3,4,5,6,7,8,9
13,11,12, 10

1,2,3,4,5,6,7,8,9,10
12,13,11

1,2,3,4,5,6,7,8,9,10,11
13, 12

1,2,3,4,5,6,7,8,9,10,11, 12
13

结果: 1,2,3,4,5,6,7,8,9,10,11, 12,13
手上: []

@ghost2113
Copy link

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
function sort(arr) {
    let pre = []
    while (arr.length > 1) {
        pre.push(arr.pop())
        pre.push(pre.shift())
    }
    pre.push(arr.pop())
    console.log(pre)
}
sort(arr)
// [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]

需要再翻转一下

@DaYesahh
Copy link

DaYesahh commented Sep 4, 2019

function paixu(){
let arrstart = [1,2,3,4,5,6,7,8,9,10,11,12,13];
let benlai = [];
let item;
let ben;
// 牌底---》牌顶
// 先把第一张拿出来
// 把剩下的第一个放到最后
// 循环往复
// 换算成代码
// [>>>>>>>>>>>>>] 右边是牌顶,牌顶远离桌面的
// item = benlai.pop() // 把牌顶(尾,用pop)那个拿出来就是第一张拿出来,
// arrstart.push(item) // 把这一个放到Arrsatrt的牌底(头,unshift)
// b = benlai.pop() // 把牌顶(尾用pop)拿出来,
// benlai.unshift(b) // 把这个值,放到牌底(头用unshift)
while(arrstart.length>1){
item = arrstart.pop();
console.log(item)
benlai.push(item);
ben = benlai.shift();
benlai.push(ben);
}
item = arrstart.pop();
benlai.push(item);
console.log(benlai.reverse())
}
paixu();
来自宝宝熊&&熊熊宝

@mrhuang2365
Copy link

  • 发牌:
function f1(arr){
	var newArr = [];
	let status = true;
	while (arr.length > 0) {
		var index = arr.length - 1;
		var item = arr.splice(index, 1)[0];
		if (status || (index === 0)) {
			newArr.push(item)
			status = false;
		} else {
			arr.unshift(item)
			status = true;
		}
	}
	return newArr
}
  • 还原
function f2(arr){
	return arr.reverse().reduce((a, b, c) => {
        return c > 1 ? a.concat(a.shift(), b): a.concat(b)
    }, [])
}

@panhonghang
Copy link

panhonghang commented Oct 8, 2019

先写出来正序的方法再改成倒叙,解决起来就会简单一些!

 /**
 * @description: 扑克牌问题正序
 * @param {type} {number[]} A
 * @return: {number[]} res
 */

var sortPokeOrder = function(A){
    let res = [];
    let length = A.length;

    while(length > 0){
        res.push(A.shift());
        A.push(A.shift());
        length--;
    }

    console.log('这是正序',res);
    
    return res;
}

sortPokeOrder([1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7])

/**
 * @description: 扑克牌问题倒序
 * @param {type} {number[]} A
 * @return: {number[]} res
 */

var sortPoke = function(A){
    A.reverse();
    let res = [];
    let length = A.length;

    while(length > 0){
        res.unshift(A.pop());
        A.unshift(A.pop());
        length--;
    }
    res.reverse();

    console.log('这是倒叙',res)
    return res;
}

sortPoke([1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7])

@RainRx
Copy link

RainRx commented Oct 11, 2019

function reverse(arr) {
  let i = 1
  let out = []
  while (arr.length) {
    if (i % 2) {
      out.push(arr.pop())
    } else {
      out.push(out.shift())
    }
    i++
  }
  return out
}

@sumshare
Copy link

sumshare commented Oct 14, 2019

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
let origin = [];
function sort(arr) {
  if (arr.length == 0) {
    return
  }
  let n = arr.pop();
  origin.unshift(n);
 // 最后一手不交换
  if (arr.length > 0) {
    let tail = origin.pop();
    origin.unshift(tail);
  }
  console.log(origin.join(','))
  sort(arr)
}
sort(arr)
console.log(origin.join(','))
/*
 1,12,2,8,3,11,4,9,5,13,6,10,7
*/

@Hunterang
Copy link

       function poker(arr) {
         let collect = []
         while (arr.length) {
           collect.push(arr.pop())

           if(collect.length>1 && arr.length) {

             collect = [...collect.slice(1), collect[0] ]

           }
         }
         return collect
       }

@JackFGreen
Copy link

/**
有一堆扑克牌,将牌堆第一张放到桌子上,再将接下来的牌堆的第一张放到牌底,如此往复;

最后桌子上的牌顺序为: (牌底) 1,2,3,4,5,6,7,8,9,10,11,12,13 (牌顶);

问:原来那堆牌的顺序,用函数实现。
 */
const res = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

/**
=> 231
32
3
<= 123

=> 4231
342
43
4
<= 1234

=> 34251
5342
453
54
5
<= 12345
 */
function sort(data) {
  const arr = []
  let i = 1
  while (data.length) {
    const top = data.pop()
    if (i % 2 === 0) {
      data.unshift(top)
    } else {
      arr.push(top)
    }
    i++
  }
  return arr
}

function sortReverse(data) {
  const arr = []
  let len = data.length
  while (len) {
    const top = data.pop()
    if (arr.length > 1) {
      const last = arr.shift()
      arr.push(last)
    }
    arr.push(top)
    len--
  }
  return arr
}

const origin = sortReverse([...res])
console.log(origin)

const result = sort(origin)
console.log(result)

console.log(JSON.stringify(result) === JSON.stringify(res))

@Jesseszhang
Copy link

有一堆扑克牌,将牌堆第一张放到桌子上,再将接下来的牌堆的第一张放到牌底,如此往复;

最后桌子上的牌顺序为: (牌底) 1,2,3,4,5,6,7,8,9,10,11,12,13 (牌顶)

问:原来那堆牌的顺序,用函数实现。

function reverse(arr) {
  let i = 1
  let out = []
  while (arr.length) {
    if (i % 2) {
      out.unshift(arr.pop())
    } else {
      out.unshift(out.pop())
    }
    i++
  }
  return out
}
    
有一堆扑克牌,将牌堆第一张放到桌子上,再将桌子上牌堆的最后一张放到牌顶,如此往复;

最后桌子上的牌顺序为: (牌底) 1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7 (牌顶)

问:原来那堆牌的顺序,用函数实现。

function poke(arr) {
  let i = 1
  let out = []
  while (arr.length) {
    if (i % 2) {
      out.push(arr.shift())
    } else {
      arr.push(arr.shift())
    }
    i++
  }
  return out
}   

这样理解是不是会容易很多?

@Linkontoask
Copy link

function sortPoke () {
    const right = [1,2,3,4,5,6,7,8,9,10,11,12,13]
    const left = right.splice(0, (right.length | 0) / 2)
    var r = []
    while (left.length || right.length) {
        const r1 = right.shift()
        const r2 = left.pop()
        if (r1) r.push(r1)
        if (r2) r.push(r2)
    }
    console.log(r)
}

@whosesmile
Copy link

function restore(poke) {
  let arr = [];
  while (poke.length) {
    arr.push(poke.pop());
    arr.push(arr.shift());
  }
  // 最后回滚多走的一步
  arr.unshift(arr.pop());
  return arr;
}

@P-der
Copy link

P-der commented Mar 20, 2020

function handle(oldArr) {
    var newArr = [oldArr[oldArr.length-1]]
    var flag = true
    for(let i = oldArr.length-2;i>=0;i--){
        var a = newArr.pop()
        newArr.unshift(a)
        newArr.unshift(oldArr[i])
    }
    return newArr
}
let arr = [1,2,3,4,5,6,7,8,9,10,11,12,13]
console.log(handle(arr))

@yangjiedage
Copy link

从牌桌拿回的时候,先要把最后一张置顶,也就是 result.unshift(result.pop())
之后就是基本操作

var data = [1,2,3,4,5,6,7,8,9,10,11,12,13]

function bar(data) {
  let result = []

  for(let i = data.length - 1; i >= 0; i--) {
    if(result.length === 0 || result.length === 1) {
      result.unshift(data[i])
      continue
    }
    
    result.unshift(result.pop())
    result.unshift(data[i])
  }
  console.log(result) //[ 1, 12, 2,  8, 3, 11, 4,  9, 5, 13, 6, 10, 7]
}
bar(data)

@ron0115
Copy link

ron0115 commented May 12, 2020

写一下自己的理解

// arr : A(牌堆): 底 【1, 。。。。, 13】 顶

// res:  B (手里):  底 【】 顶

// 原操作:B顶 => A顶   B顶 => B底 (如果B有多张)
// 逆向操作:B底 => B顶 (如果B有多张)  A顶 => B顶
const reverse = arr => {
  const res = [];
  while (arr.length > 0) {
    if (res.length) {
      res.push(res.shift());
    }
    const item = arr.pop();
    res.push(item);
  }
  return res;
};

// 输出 手里牌
// 底  [ 7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1 ]  顶

@BacteriaZHANG
Copy link

执行一个逆向操作就好了,从桌上牌顶拿一张放到手中牌顶,再把手里的牌底一张移到牌顶,如此循环

function resumePoke(arr) {
  let pre = []
  let len = arr.length

  while (arr.length) {
    pre.push(arr.pop())
    // 手里的牌大于 1 张才移动,桌上牌拿空时则不移动
    if (pre.length > 1 && pre.length < len) {
      pre.push(pre.shift())
    }
  }

  console.log('pre', pre)
  return pre
}
resumePoke([1,2,3,4,5,6,7,8,9,10,11,12,13])
// pre (13) [7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1]

@trymoremore
Copy link

trymoremore commented Jun 23, 2020

var r = [];
const change = num =>{let t = r.pop();r.unshift(num,t);}
[1,2,3,4,5,6,7,8,9,10,11,12,13].reverse().map(v=>{change(v);})

@wabRul
Copy link

wabRul commented Sep 2, 2020

function reduction(arr) {
  let res = []
  while (arr.length) {
    if (res.length) {
      res.push(res.shift())
    }
    res.push(arr.pop())
  }
  return res
}
reduction([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])
// [7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1]

@shoestrong
Copy link

生成动画
弄了一个图

@z-Joy
Copy link

z-Joy commented Oct 10, 2020

let arr = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13];

function pokeOrigin(arr) {
    let temp = arr.reverse();
    let res = [];
    while (temp.length > 0) {
        if (res.length) {
            res.unshift(res.pop())
        }
        res.unshift(temp.shift())
    }
     console.log(res);
    return res
}

// var origin =  [1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7]


// function pokeCheck(arr) {
//     let res = [];
//     count = 0;
//     while (arr.length) {
//         if (count % 2 === 0) {
//             res.push(arr.shift());
//         } else {
//             arr[arr.length - 1] = arr.shift();
//         }
//         count++;
//     }

//     console.log(res);
//     return res;
// }


// pokeCheck(origin);

@xxleyi
Copy link

xxleyi commented Oct 31, 2020

/**
 * 逆向:即从桌牌到手牌
 * @param {*} 桌牌序列 arr 
 */
function recover(arr) {
    const res = []
    while (arr.length > 0) {
        if (res.length) {
            res.push(res.shift())
        }
        const item = arr.pop()
        res.push(item)
    }
    return res
}

/**
 * 正向:即从手牌到桌牌(用于检验结果)
 * @param {*} 手牌序列arr 
 */
function generate(arr) {
    const res = []
    while (arr.length > 0) {
        const item = arr.pop()
        res.push(item)
        if (arr.length) {
            arr.unshift(arr.pop())
        }
    }
    return res
}

recover([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13])   // [7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1]
generate([7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1])  // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

大神的思路总是这么清晰,我这个菜鸡只能学习一波。不过倒是发现了一个可优化的点:数组的 shift 和 unshift 操作复杂度为线性,面试时有意将其优化掉应该会是个亮点。

/**
 * 逆向:即从桌牌到手牌
 * @param {*} 桌牌序列 arr 
 */
function recover(arr) {
    const res = []
    let i = 0
    while (arr.length > 0) {
        if (res.length) {
            res.push(res[i++])
        }
        const item = arr.pop()
        res.push(item)
    }
    return res.slice(i)
}

/**
 * 正向:即从手牌到桌牌(用于检验结果)
 * @param {*} 手牌序列arr 
 */
function generate(arr) {
    const res = [], l = arr.length
    let i = 0
    arr = arr.reverse()
    while (res.length < l) {
        const item = arr[i++]
        res.push(item)
        if (res.length < l) {
            arr.push(arr[i++])
        }
    }
    return res
}

console.log(recover([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]))   // [7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1]
console.log(generate([7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1]))  // [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]

@Alexzjt
Copy link

Alexzjt commented Nov 6, 2020

function poker(array = []) {
    let origin = [];
    while (array.length !== 0) {
        if (origin.length > 0) {
            origin.push(origin.shift());
        }
        origin.push(array.pop());
    }
    return origin;
}

console.log(poker([1,2,3,4,5,6,7,8,9,10,11,12,13]));

//[7, 10, 6, 13, 5, 9, 4, 11, 3,  8, 2, 12, 1]

@hms181231
Copy link

hms181231 commented Dec 10, 2020

function reverses(data = []) {
  let result = [];

  while (data.length) {
    let prev = result.shift();

    if (prev) {
      result.push(prev);
    }

    result.push(data.pop());
  }

  return result;
}

reverses([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]);
// [7, 10, 6, 13, 5, 9, 4, 11, 3, 8, 2, 12, 1]

@tryingpzm
Copy link

function poke(arr) {
  let i = 1
  let out = []
  while (arr.length) {
    if (i % 2) {
      out.push(arr.shift())
    } else {
      arr.push(arr.shift())
    }
    i++
  }
  return out
}   
    

function reverse(arr) {
  let i = 1
  let out = []
  while (arr.length) {
    if (i % 2) {
      out.unshift(arr.pop())
    } else {
      out.unshift(out.pop())
    }
    i++
  }
  return out
}

reverse([1,2,3,4,5,6,7,8,9,10,11,12,13 ])
// [1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7]

看上的答案心都凉了,终于看到了一样的

@woai3c
Copy link

woai3c commented Dec 30, 2020

const data = [1,2,3,4,5,6,7,8,9,10,11,12,13]

// 将操作倒放即可
// 原来是从牌顶上拿一张牌放到桌子上,再将牌顶的牌放到牌底
// 倒放:将牌底的牌放到牌顶,再从桌子上拿一张牌放到牌顶
function reverse(data) {
    const result = []
    while (data.length) {
        // 由于一开始 result 没有牌,不能执行 “将牌底的牌放到牌底” 这一步操作,所以跳过
        if (result.length) {
            result.unshift(result.pop())
        }
        
        result.unshift(data.pop())
    }

    return result
}

console.log(reverse(data)) // [1, 12, 2, 8, 3, 11, 4, 9, 5, 13, 6, 10, 7]

@miniflycn
Copy link

function reverse(cur) {
    const res = []
    let item
    while (item = cur.pop()) {
        res.push(item)
        res.push(res.shift())
    }
    res.unshift(res.pop())
    return res
}

@ToSaySomething
Copy link

ToSaySomething commented Apr 16, 2022 via email

@xuhen
Copy link

xuhen commented Dec 2, 2022

// 这个问题是个逆操作问题
// 正向是先取牌,后将牌放到牌底。
// 逆操作就是先将牌放到牌顶再取回放牌顶
function recoverCards(cards) {
    const origin = [];
    const desk = [...cards];

    while (desk.length) {
        // 判断牌数为空的情况
        if (origin.length) {
            const t = origin.shift();
            origin.push(t);
        }
        const card = desk.pop();

        origin.push(card);

    }

    return origin;
}

@ToSaySomething
Copy link

ToSaySomething commented Dec 2, 2022 via email

@LoveSleepMouse
Copy link

function test(list) {
        const index = Math.round((list.length - 1) / 2);
        const leftArr = list.slice(0, index);
        const rightArr = list.slice(index);
        const arr = [];
        while (leftArr.length || rightArr.length) {
          const left = leftArr.shift();
          const right = rightArr.pop();
          left && arr.push(left);
          right && arr.push(right);
        }
        console.log(arr);
      }

      function shortTest(list) {
        let index = 1;
        const arr = [];
        while (list.length) {
          if (index % 2) {
            arr.push(list.shift());
          } else {
            arr.push(list.pop());
          }
          index++;
        }
        console.log(arr);
      }

@ToSaySomething
Copy link

ToSaySomething commented Feb 13, 2023 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests