我参加编程冠军赛的比赛结束了。 我在排位赛中表现出色,已经解决了6个问题中的4个,并且排在第20位,所以希望前20名也会进入决赛。
但不幸的是,它甚至没有进入前100名。 战斗结束后,他们不再挥舞拳头,但我能够解决另外几项任务。 我提请您注意我已经解决的所有任务。
特别感谢您对解决方案的帮助:
miraage toster.ru/用户/ miraageprofesor08 toster.ru/用户/ profesor08SmthTo toster.ru/user/SmthToRAX7 toster.ru/用户/ RAX7dimoff66 toster.ru/user/dimoff66vk.com/vladilen.minin最后一轮
A.来自并行Universe的异步API。 (15分)
条件。您的并行Universe开发人员已经将新的航天器控制库发送给您。 因为 宇宙飞船是一件很复杂的事情,那么图书馆的API相当“沉重”,确切的方法数量是未知的,当然,没有文档。 但是,众所周知,在平行宇宙中,人们走在天花板上,白天睡觉,晚上工作,并且仅使用异步函数,并且始终将回调作为第一个参数。 奇怪的家伙! 在地球上很长一段时间里,每个人都写着诺言。 但是,该库需要集成到项目中。 因此,您收到了编写包装程序的任务,该包装程序将提供相同的API,但应有尽有。
输入格式
源API示例:
const api = { a: { b: { c: callback => setTimeout(() => callback(null, 'hello'), 100) } }, aa: { bb: (callback, x, y) => setTimeout(() => callback(null, x + y), 200) } };
输出格式
提交您的解决方案为:
module.exports = function promisify(api) {
用法示例:
const promisedApi = promisify(api); promisedApi.abc() .then(res => console.log(res));
注意事项
如果在调用源API时发生错误,则包装器应返回被拒绝的Promise,回调始终使用第一个参数接受错误:
callback(error, data)
在原始API中,可能有常量(数字,字符串和布尔值),需要按原样返回它们:
api.foo.myConst = 1; promisedApi.foo.myConst === 1;
包装器的初始化应该是“懒惰的”:源API可以具有大量的命名空间,并且在使用它们时需要访问它们。
解决方案在比赛中,我没有完全解决问题,因此在15个可能的解决方案中得到12.86分。 我使用了递归来绕过所有属性,并且如果它是一个函数,则将其混杂。
测试结束后,我使用Proxy对象完成了解决方案。 只有这样的选项才能通过所有测试。 以下是考虑到改进的解决方案。
function promisify (obj) { const cache = {} return new Proxy(obj, { get (target, prop) { const value = target[prop] const type = Object.prototype.toString.call(value) if (type === '[object Object]') { cache[prop] = promisify(value)
请注意,node js已经具有这样的实用程序
nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_promisify_original ,仅它接受其回调是最后一个参数而不是第一个参数的函数。
关于代理的全部信息:
Learn.javascript.ru/proxywww.youtube.com/watch?v=np08WdS9OXgB.平日实习生(15分)
条件。Yandex团队有一名实习生Stepan。 时间已经用完,但他没有时间进行页面布局。 根据此任务的布局,帮助Stepan组成其中之一。
页面的左边缘和顶部边缘不应有缩进。 另外,无法使用图像。 这是布局:

如您所见,布局由两种大小的图块组成:标准图块和两倍图块。 标准图块占据屏幕宽度的1/3,是屏幕宽度的两倍-2/3。 固定图块高度-200像素。 瓦片之间的距离为20像素。
标准图块的背景色是#8a2be2,双色的颜色是#000。
结果,您应该获得一个带有布局的HTML页面。 页面大小不得超过10 KB。
请注意:
模板中只能写入模板和样式-无法使用JavaScript和图片;
最初,提出了以下html文件:
github.com/vito2005/YandexCompetition/blob/master/final-2019/B/original.html解决方案原则上,您可以不使用源文件。 但是我仍然以此为基础。
从标记中删除了字体和脚本,以减轻文件的重量。
然后,他添加了6个div并将其包裹在包装纸中。
通过显示屏进行化妆:网格
结果如下:
<html> <head> <meta charset="utf-8"/> <meta http-equiv="X-UA-Compatible" content="IE=edge"/> <style> body { margin: 0; padding: 0; } .wrapper { display: grid; grid-template-columns: repeat(3, 1fr); grid-gap: 20px; } .banner1, .banner2, .banner3, .banner4, .banner7 { background: #8a2be2; height: 200px; } .banner5 { background: #000; grid-column: 2 / 4; } .banner6 { background: #000; grid-column: 1 / 3; } </style> </head> <body> <div class="wrapper"> <div class="banner1"></div> <div class="banner2"></div> <div class="banner3"></div> <div class="banner4"></div> <div class="banner5"></div> <div class="banner6"></div> <div class="banner7"></div> </div> </body> </html>
C.完美矩形(40分)
条件。鲍勃是一位表现主义艺术家。 他的所有作品在白色背景上均被严格着色为垂直矩形。
最近,他的作品发表在著名杂志Top Art的网站上。 鲍勃决定仔细看一下他的画布,放大页面,对他完美的矩形的模糊角落和模糊边缘感到震惊。
作为一个彻底的人,他研究了这个问题,并决定将他的杰作转换为HTML,以便线条在任何角度和任何比例下都保持完美。 为了实现他的计划,他选择了您。
给他写一个可以从图片生成html的服务。
输入格式
输入是一个字符串,其中包含base64中的图片
输出格式
返回traceImage函数,该函数接受到图片的链接作为输入,并返回解析为字符串的Promise。 该行的布局应重复此图片。
提交您的解决方案为:
function traceImage(imageSrc) {
注意事项
图片可以是任何尺寸
图片不透明
空白像素颜色-白色(r,g,b):( 255、255、255)
该图显示了1个彩色的不透明矩形
所有线都是水平或垂直的。
该代码在浏览器中运行
例子
图片在base64中以字符串形式给出(以将其传递给函数的形式):
gist.github.com/senaev/50460323558db543256cb7f196e7d81d
对于这样的图片,您可以生成一行:
<div> <div style=" position: absolute; width: 11px; height: 15px; top: 135px; left: 109px; background-color: rgb(255, 255, 0); "></div> </div>
解决方案解决方案的本质是创建一个画布以适合图像,在其中绘制图片并开始使用getImageData获取有关每个像素颜色的信息,然后保留从左上边缘对像素进行迭代直到获得白色像素的过程。 接下来,继续沿水平和垂直轴对像素进行排序,直到再次遇到白色像素,从而获得矩形的宽度和高度。
本文详细介绍了如何使用canvas和使用getImageData。
code.tutsplus.com/en/tutorials/canvas-from-scratch-pixel-manipulation--net-20573不幸的是,我的代码没有通过所有测试,并在40分中获得了30分,而且我仍然无法理解错误,如果您指出这些缺点,我将不胜感激:
function traceImage (imgSrc) { function loadImg (src) { return new Promise((resolve, reject) => { if (typeof src !== 'string') reject('wrong data') const img = new Image() img.addEventListener('load', () => resolve(img)) img.addEventListener('error', err => reject(err)) img.src = src }) } function calcElementFromImage (img) { const TRANSPARENT_COLOR = [255, 255, 255, 1] const colorFromData = (data, i) => { return [data[i], data[i + 1], data[i + 2], data[i + 3] / 255] } const w = img.naturalWidth const h = img.naturalHeight const canvas = document.createElement('canvas') canvas.width = w canvas.height = h const ctx = canvas.getContext('2d') ctx.drawImage(img, 0, 0, w, h) const data = ctx.getImageData(0, 0, w, h).data let top, left, bgColor let lastIndex = 0 for (let i = lastIndex; i < data.length; i += 4) { const color = colorFromData(data, i) if (!color.every((c, i) => c === TRANSPARENT_COLOR[i])) { const px = i / 4 left = px % w top = px / w | 0 bgColor = color lastIndex = i break } } let width const maxLeftIndex = (w - left) * 4 + lastIndex for (let i = lastIndex; i < maxLeftIndex; i += 4) { const color = colorFromData(data, i) if (color.every((c, i) => c === TRANSPARENT_COLOR[i])) { const x = i / 4 % w width = x - left break } } let height const maxTopIndex = (h - top - 1) * w * 4 + lastIndex const hStep = w * 4 for (let i = lastIndex; i < maxTopIndex; i += hStep) { const color = colorFromData(data, i) if (color.every((c, i) => c === TRANSPARENT_COLOR[i])) { const y = i / 4 / w | 0 height = y - top break } } bgColor = Object.values(bgColor).join(',') return { parentWidth: w, parentHeight: h, top, left, width, height, bgColor } } return loadImg(imgSrc).then(img => { const data = calcElementFromImage(img) const { parentWidth, parentHeight, top, left, width, height, bgColor } = data const div = `<div style=" position: relative; width: ${parentWidth}px; height: ${parentHeight}px;"> <div style=" position: absolute; top: ${top}px; left: ${left}px; width: ${width}px; height: ${height}px; background-color: rgba(${bgColor})"></div> </div>` return Promise.resolve(div) }) }
D.骑马(40分)。
条件。根纳季(Gennady)是知识分子。 他喜欢结识有趣的人。 但是,作为一个审慎和不可置信的人,他只能在Internet上执行此操作。 最近,根纳迪(Gennady)发现可以在国际象棋论坛上找到智商相当的对话者,但麻烦之处在于根纳迪(Gennady)不能下象棋,并且所有老师都基于javascript,因此,根纳迪(Gennady)谨慎地禁用了javascript,以避免感染病毒的可能性。
为了帮助Gennady,我们建议编写一个不带JavaScript的下棋教程,以显示马的行走方式。 老师应该看起来像一个棋盘。 您单击笼子-它们会向您显示马从该笼子可以去的地方。
输入格式
加载绘制棋盘时的html文档
输出格式
该任务将在真实的浏览器(Chrome 77)中进行测试。
您的html文档将被加载到浏览器中。 机器人单击进入国际象棋字段的各个单元,并在单击后拍摄屏幕截图。
屏幕截图必须符合参考
例子

注意事项
- CSS和HTML实现。 无法使用Javascript。
- 整个布局应为正方形,没有阴影,渐变,圆角等。
- 像元宽度和高度-30像素
- 国际象棋字段在左上角的页面上,没有缩进
- 所选单元格颜色#ff0000
- 数字#0000ff可以进入的单元格颜色
- 浅单元格颜色#f4cd8d
- 暗单元格的颜色#745853
- 左上方的单元格灯
- 最初没有选择单元格
通过单击特定的单元格进行选择,并保留到下一次单击为止
解决方案不幸的是,在分配的4个小时中,我无法完全提供解决方案,我设法进行了布局并单击单元格,并且仅在比赛结束后,在没有论坛同事的帮助下,我仍然完成了这项任务。
因此,要做的第一件事是为每个单元格放置输入type = radio,在它们上贴标签,通过display:grid设置布局,并通过grid-template-columns将其分为8列:重复(8,30px)。 我花了很多时间来安排可能的骑马动作。
困难之处在于,在CSS中,您无法设置先前元素的样式。
在这种情况下,它是无法解决的(当样式需要同时使用上一个和下一个时)。
因此,为了不污染标记,我决定添加伪元素,这些伪元素由绝对值定位并通过线性渐变绘制的背景定位为正方形。 我花了很多时间,但没有解决,但是我被告知一个很好的解决方案:为所选单元格设置8种蓝色阴影,并按需要进行排列。
结果如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> <style>.white { background: #f4cd8d; } .black { background: #746864; } body { margin: 0; display: flex } div { display: grid; grid-template-columns: repeat(8, 30px); overflow: hidden; } input { display: none; } label { width: 30px; height: 30px; background: #f4cd8d; display: block; position: relative; } input[type="radio"]:checked + label { background: #FF0000; box-shadow: -30px -60px 0 0 #0000FF, -60px -30px 0 0 #0000FF, 30px -60px 0 0 #0000FF, 60px -30px 0 0 #0000FF, -30px 60px 0 0 #0000FF, -60px 30px 0 0 #0000FF, 30px 60px 0 0 #0000FF, 60px 30px 0 0 #0000FF; z-index: 100; position: relative; } </style> </head> <body> <div> <input type="radio" name="tag" id="a1"> <label class="white a1" for="a1"></label> <input type="radio" name="tag" id="b1"> <label class="black b1" for="b1"></label> <input type="radio" name="tag" id="c1"> <label class="white c1" for="c1"></label> <input type="radio" name="tag" id="d1"> <label class="black d1" for="d1"></label> <input type="radio" name="tag" id="e1"> <label class="white e1" for="e1"></label> <input type="radio" name="tag" id="f1"> <label class="black f1" for="f1"></label> <input type="radio" name="tag" id="g1"> <label class="white g1" for="g1"></label> <input type="radio" name="tag" id="h1"> <label class="black h1" for="h1"></label> ........... ........... <input type="radio" name="tag" id="a8"> <label class="black a8" for="a8"></label> <input type="radio" name="tag" id="b8"> <label class="white b8" for="b8"></label> <input type="radio" name="tag" id="c8"> <label class="black c8" for="c8"></label> <input type="radio" name="tag" id="d8"> <label class="white d8" for="d8"></label> <input type="radio" name="tag" id="e8"> <label class="black e8" for="e8"></label> <input type="radio" name="tag" id="f8"> <label class="white f8" for="f8"></label> <input type="radio" name="tag" id="g8"> <label class="black g8" for="g8"></label> <input type="radio" name="tag" id="h8"> <label class="white h8" for="h8"></label> </div> </body> </html>
链接到工作版本待续...