CodeWars
離上一篇文章只過去了九天,不過做了幾道難題,雖然基本都是谷歌和某人幫大忙。。
記下來好一點 不然太難了很快就忘記了
- Pyramid Slide Down
給出一個數字金字塔,求得金字塔頂部到底部的連續數字之和。
Examples:
Test.assertEquals(longestSlideDown(
[[3],
[7, 4],
[2, 4, 6],
[8, 5, 9, 3]]),
23, "should work for small pyramids");
Test.assertEquals(longestSlideDown(
[[75],
[95, 64],
[17, 47, 82],
[18, 35, 87, 10],
[20, 4, 82, 47, 65],
[19, 1, 23, 75, 3, 34],
[88, 2, 77, 73, 7, 63, 67],
[99, 65, 4, 28, 6, 16, 70, 92],
[41, 41, 26, 56, 83, 40, 80, 70, 33],
[41, 48, 72, 33, 47, 32, 37, 16, 94, 29],
[53, 71, 44, 65, 25, 43, 91, 52, 97, 51, 14],
[70, 11, 33, 28, 77, 73, 17, 78, 39, 68, 17, 57],
[91, 71, 52, 38, 17, 14, 91, 43, 58, 50, 27, 29, 48],
[63, 66, 4, 68, 89, 53, 67, 30, 73, 16, 69, 87, 40, 31],
[ 4, 62, 98, 27, 23, 9, 70, 98, 73, 93, 38, 53, 60, 4, 23]]),
1074, "should work for medium pyramids");
解決方案:
function longestSlideDown (pyramid) {
var m = [];
function funMax(x,y){
if(x<0 || y< 0|| pyramid[x][y] === undefined)return -1;
if(m[x][y] === undefined)
m[x][y] = pyramid[x][y] + Math.max(funMax(x-1,y),funMax(x-1,y-1));
return m[x][y];
}
for(var i = 0;i<pyramid.length;i++)
m.push([]);
m[0][0] = pyramid[0][0];
for(var i = 0;i<pyramid.length;i++){
funMax(pyramid.length-1,i);
}
return Math.max(...m[pyramid.length-1]);
}
自底向上遍歷,尋找相加數最大的結果
2.Make a spiral
畫一個N×N的不能與自身接觸的蛇形螺旋出來,以二維矩陣表示(1爲蛇0爲空白):
Your task, is to create a NxN spiral with a given size.
For example, spiral with size 5 should look like this:
00000
....0
000.0
0...0
00000
and with the size 10:
0000000000
.........0
00000000.0
0......0.0
0.0000.0.0
0.0..0.0.0
0.0....0.0
0.000000.0
0........0
0000000000
Return value should contain array of arrays, of 0 and 1, for example for given size 5 result should be:
[[1,1,1,1,1],[0,0,0,0,1],[1,1,1,0,1],[1,0,0,0,1],[1,1,1,1,1]]
解決方案
var spiralize = function(size) {
// insert code here
let dir=[
{x:0, y:1},//右
{x:1, y:0},//下
{x:0, y:-1},//左
{x:-1,y:0},//上
];
let dir_times = 0;
let res = [];
for(let i=0;i<size;i++){
res.push([]);
for(let j=0;j<size;j++)
res[i].push(0);
}
let pos = {x:0,y:0};
let next,dnext,cur_dir;
let flag = 0;
while(true){
// 連續轉兩次就退出
if(flag ==2)break;
res[pos.x][pos.y] = 1;// 讓當前位置標記爲1
cur_dir = dir[dir_times%4]; // 當前的方向
next = {x:pos.x+cur_dir.x ,y:pos.y+cur_dir.y};// 計算下一步位置
if(!(next.x >=0 && next.x < size && next.y >=0 && next.y < size)){
// 越界轉向條件
dir_times++;
flag++;
continue;
}
dnext = {x:next.x + cur_dir.x ,y:next.y+cur_dir.y};// 計算此方向下一步再下一步位置
if(dnext.x >=0 && dnext.x < size && dnext.y >=0 && dnext.y < size && res[dnext.x][dnext.y] == 1){
// 下下步在界內並且已經標記則轉向,若在界外則無視
dir_times++;
flag++;
continue;
}
// 退出條件部分
dnext = {x:next.x + dir[(dir_times+1)%4].x ,y:next.y + dir[(dir_times+1)%4].y};// 計算下一步的下一個方向的位置
if(res[dnext.x][dnext.y] == 1){
// 下一步的下一個方向的位置已經被標記則也退出
break;
}
pos = next;
// 正常走了一步後就可以重置連續轉向標記
flag = 0;
}
return res;
}
第一次接觸這樣的題。
先定義四個方向增量,和一些輔助參數。
方向參數的循環用轉向次數控制,當前方向=(轉向次數%4)
計算下一步位置,如果越界了,就轉向,並用flag記錄這次轉向(flag的用處下面會說到)
還有一種轉向是真的走到該轉向的地方了,於是我計算了下一步再下一步的位置(下下步 的位置),如果下下步在界內並且已被標記,則意味着再走一步會碰壁。所以該轉向了。
常規流程就是上面那樣,編碼過程中遇到的困難是如何使它結束,
結束分兩種情況 一是前進發現碰壁,則轉向,轉向又發現碰壁,這樣轉向了兩次flag=2了則結束(比如example中的那個5×5的)。一般來說正常通過一步後flag置0
二是前進發現碰壁,轉向後發現和下一次轉向碰了,則結束(比如example中那個10×10的)
接觸的東西
工作中或是日常中經常會通過各種渠道接觸到碎片化的新知識(對我而言的新知識),說實話我並不知道該怎麼把他們消化成我自己的東西。
-
css in js ,似乎是一個很麻煩的東西,探究收穫比不大
-
基礎通用GPU紋理和紋理視頻壓縮參考編解碼器
https://github.com/binomialLLC/basis_universal
https://opensource.googleblog.com/2019/05/google-and-binomial-partner-to-open.html -
Math is Fun 數學樂 逆矩陣 代數的解釋,對理解圖形學基礎有幫助
https://www.shuxuele.com/algebra/matrix-inverse.html
https://www.shuxuele.com/